diff -Nru a/Documentation/Changes b/Documentation/Changes
--- a/Documentation/Changes	Thu Jan 16 18:23:07 2003
+++ b/Documentation/Changes	Thu Jan 16 18:23:07 2003
@@ -52,7 +52,7 @@
 o  Gnu make               3.78                    # make --version
 o  binutils               2.9.5.0.25              # ld -v
 o  util-linux             2.10o                   # fdformat --version
-o  module-init-tools      0.9                     # rmmod -V
+o  module-init-tools      0.9.8                   # rmmod -V
 o  e2fsprogs              1.29                    # tune2fs
 o  jfsutils               1.0.14                  # fsck.jfs -V
 o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
diff -Nru a/Documentation/crypto/api-intro.txt b/Documentation/crypto/api-intro.txt
--- a/Documentation/crypto/api-intro.txt	Thu Jan 16 18:23:06 2003
+++ b/Documentation/crypto/api-intro.txt	Thu Jan 16 18:23:06 2003
@@ -80,6 +80,10 @@
   alias digest_null crypto_null
   alias compress_null crypto_null
 
+The SHA384 algorithm shares code within the SHA512 module, so you'll
+also need:
+  alias sha384 sha512
+
 
 DEVELOPER NOTES
 
@@ -182,7 +186,7 @@
   Andrew Tridgell and Steve French (MD4)
   Colin Plumb (MD5)
   Steve Reid (SHA1)
-  Jean-Luc Cooke (SHA256)
+  Jean-Luc Cooke (SHA256, SHA384, SHA512)
   Kazunori Miyazawa / USAGI (HMAC)
   Matthew Skala (Twofish)
   Dag Arne Osvik (Serpent)
@@ -201,9 +205,11 @@
   Werner Koch
   Marc Mutz
 
-SHA256 algorithm contributors:
+SHA256/384/512 algorithm contributors:
   Andrew McDonald
-
+  Kyle McMartin
+  Herbert Valerio Riedel
+  
 AES algorithm contributors:
   Alexander Kjeldaas
   Herbert Valerio Riedel
diff -Nru a/Documentation/driver-model/bus.txt b/Documentation/driver-model/bus.txt
--- a/Documentation/driver-model/bus.txt	Thu Jan 16 18:23:06 2003
+++ b/Documentation/driver-model/bus.txt	Thu Jan 16 18:23:06 2003
@@ -32,8 +32,8 @@
 optionally initialize the match callback.
 
 struct bus_type pci_bus_type = {
-       name:	"pci",
-       match:	pci_bus_match,
+       .name	= "pci",
+       .match	= pci_bus_match,
 };
 
 The structure should be exported to drivers in a header file:
diff -Nru a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt
--- a/Documentation/driver-model/driver.txt	Thu Jan 16 18:23:06 2003
+++ b/Documentation/driver-model/driver.txt	Thu Jan 16 18:23:06 2003
@@ -49,14 +49,14 @@
 being converted completely to the new model. 
 
 static struct device_driver eepro100_driver = {
-       name:		"eepro100",
-       bus:		&pci_bus_type,
-       devclass:	&ethernet_devclass,	/* when it's implemented */
+       .name		= "eepro100",
+       .bus		= &pci_bus_type,
+       .devclass	= &ethernet_devclass,	/* when it's implemented */
        
-       probe:		eepro100_probe,
-       remove:		eepro100_remove,
-       suspend:		eepro100_suspend,
-       resume:		eepro100_resume,
+       .probe		= eepro100_probe,
+       .remove		= eepro100_remove,
+       .suspend		= eepro100_suspend,
+       .resume		= eepro100_resume,
 };
 
 Most drivers will not be able to be converted completely to the new
@@ -81,15 +81,15 @@
 like (using the eepro100 driver again):
 
 static struct pci_driver eepro100_driver = {
-       id_table:       eepro100_pci_tbl,
-       driver:	       {
-		name:		"eepro100",
-		bus:		&pci_bus_type,
-		devclass:	&ethernet_devclass,	/* when it's implemented */
-		probe:		eepro100_probe,
-		remove:		eepro100_remove,
-		suspend:		eepro100_suspend,
-		resume:		eepro100_resume,
+       .id_table       = eepro100_pci_tbl,
+       .driver	       = {
+		.name		= "eepro100",
+		.bus		= &pci_bus_type,
+		.devclass	= &ethernet_devclass,	/* when it's implemented */
+		.probe		= eepro100_probe,
+		.remove		= eepro100_remove,
+		.suspend	= eepro100_suspend,
+		.resume		= eepro100_resume,
        },
 };
 
diff -Nru a/Documentation/driver-model/overview.txt b/Documentation/driver-model/overview.txt
--- a/Documentation/driver-model/overview.txt	Thu Jan 16 18:23:05 2003
+++ b/Documentation/driver-model/overview.txt	Thu Jan 16 18:23:05 2003
@@ -86,11 +86,11 @@
 This can be done permanently by providing the following entry into the
 /etc/fstab (under the provision that the mount point does exist, of course):
 
-none     	/devices	sysfs    defaults		0	0
+none     	/sys	sysfs    defaults		0	0
 
 Or by hand on the command line:
 
-~: mount -t sysfs none /devices
+# mount -t sysfs sysfs /devices
 
 Whenever a device is inserted into the tree, a directory is created for it.
 This directory may be populated at each layer of discovery - the global layer,
diff -Nru a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
--- a/Documentation/filesystems/sysfs.txt	Thu Jan 16 18:23:05 2003
+++ b/Documentation/filesystems/sysfs.txt	Thu Jan 16 18:23:05 2003
@@ -6,12 +6,6 @@
 10 January 2003
 
 
-Note (17 Oct 2002): the name has just been changed from sysfs to
-sysfs. Updates to the documentation will come soon; after the
-conversion to use it is completely finished.
-
-
-
 What it is:
 ~~~~~~~~~~~
 
@@ -271,8 +265,8 @@
 span multiple bus types).
 
 
-More information can device-model specific features can be found in
-Documentation/device-model/. 
+More information can driver-model specific features can be found in
+Documentation/driver-model/. 
 
 
 TODO: Finish this section.
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Thu Jan 16 18:23:06 2003
+++ b/MAINTAINERS	Thu Jan 16 18:23:06 2003
@@ -1901,11 +1901,11 @@
 S:	Maintained
 
 USB SCANNER DRIVER
-P:	Brian Beattie
-M:	beattie@beattie-home.net
+P:	Henning Meier-Geinitz
+M:	henning@meier-geinitz.de
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
-W:	http://www.beattie-home.net/linux
+W:	http://www.meier-geinitz.de/kernel/
 S:	Maintained
 
 USB SE401 DRIVER
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Thu Jan 16 18:23:05 2003
+++ b/Makefile	Thu Jan 16 18:23:05 2003
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 58
+SUBLEVEL = 59
 EXTRAVERSION =
 
 # *DOCUMENTATION*
@@ -393,6 +393,17 @@
 .PHONY: prepare
 prepare: include/linux/version.h include/asm include/config/MARKER
 	@echo '  Starting the build. KBUILD_BUILTIN=$(KBUILD_BUILTIN) KBUILD_MODULES=$(KBUILD_MODULES)'
+
+#	We need to build init/vermagic.o before descending since all modules
+#	(*.ko) need it already
+
+ifdef CONFIG_MODULES
+
+prepare: init/vermagic.o
+
+init/vermagic.o: include/linux/version.h
+
+endif
 
 #	This can be used by arch/$ARCH/Makefile to preprocess
 #	their vmlinux.lds.S file
diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig
--- a/arch/alpha/Kconfig	Thu Jan 16 18:23:06 2003
+++ b/arch/alpha/Kconfig	Thu Jan 16 18:23:06 2003
@@ -65,6 +65,7 @@
 	  LX164               AlphaPC164-LX
 	  Miata               Personal Workstation 433a, 433au, 500a,
 	  500au, 600a, or 600au
+	  Marvel              AlphaServer ES47 / ES80 / GS1280
 	  Mikasa              AS 1000
 	  Noname              AXPpci33, UDB (Multia)
 	  Noritake            AS 1000A, AS 600A, AS 800
@@ -75,7 +76,7 @@
 	  Sable               AS 2000, AS 2100
 	  Shark		      DS 20L
 	  Takara              Takara
-	  Titan               Privateer
+	  Titan               AlphaServer ES45 / DS25
 	  Wildfire            AlphaServer GS 40/80/160/320
 
 	  If you don't know what to do, choose "generic".
@@ -172,6 +173,11 @@
 	  A technical overview of this board is available at
 	  <http://www.unix-ag.org/Linux-Alpha/Architectures/LX164.html>.
 
+config ALPHA_MARVEL
+	bool "Marvel"
+	help
+	  AlphaServer ES47 / ES80 / GS1280 based on EV7.
+
 config ALPHA_MIATA
 	bool "Miata"
 	help
@@ -238,6 +244,8 @@
 
 config ALPHA_TITAN
 	bool "Titan"
+	help
+	  AlphaServer ES45/DS25 SMP based on EV68 and Titan chipset.
 
 config ALPHA_WILDFIRE
 	bool "Wildfire"
@@ -301,6 +309,11 @@
 	  information about which PCI hardware does work under Linux and which
 	  doesn't.
 
+config ALPHA_CORE_AGP
+	bool
+	depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL
+	default y
+
 config ALPHA_NONAME
 	bool
 	depends on ALPHA_BOOK1 || ALPHA_NONAME_CH
@@ -387,7 +400,7 @@
 
 config ALPHA_EV6
 	bool
-	depends on ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_DP264 || ALPHA_EIGER
+	depends on ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_DP264 || ALPHA_EIGER || ALPHA_MARVEL
 	default y
 
 config ALPHA_TSUNAMI
@@ -397,11 +410,16 @@
 
 config ALPHA_EV67
 	bool "EV67 (or later) CPU (speed > 600MHz)?" if ALPHA_DP264 || ALPHA_EIGER
-	default y if ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK
+	default y if ALPHA_NAUTILUS || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
 	help
 	  Is this a machine based on the EV67 core?  If in doubt, select N here
 	  and the machine will be treated as an EV6.
 
+config ALPHA_EV7
+	bool
+	depends on ALPHA_MARVEL
+	default y
+
 config ALPHA_MCPCIA
 	bool
 	depends on ALPHA_RAWHIDE
@@ -419,7 +437,7 @@
 
 config ALPHA_SRM
 	bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
-	default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK
+	default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
 	---help---
 	  There are two different types of booting firmware on Alphas: SRM,
 	  which is command line driven, and ARC, which uses menus and arrow
@@ -461,7 +479,7 @@
 
 config SMP
 	bool "Symmetric multi-processing support"
-	depends on ALPHA_SABLE || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK
+	depends on ALPHA_SABLE || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
 	---help---
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, like most personal computers, say N. If
@@ -535,6 +553,7 @@
 	bool "Verbose Machine Checks"
 
 source "drivers/pci/Kconfig"
+source "drivers/eisa/Kconfig"
 
 config HOTPLUG
 	bool "Support for hot-pluggable devices"
@@ -771,6 +790,15 @@
 	  For further information, please read <file:Documentation/ide.txt>.
 
 	  If unsure, say Y.
+
+config IDE_MAX_HWIFS 
+	int "Max IDE interfaces"
+	depends on IDE
+	default 4
+	help
+	  This is the maximum number of IDE hardware interfaces that will
+	  be supported by the driver. Make sure it is at least as high as
+	  the number IDE interfaces in your system.
 
 source "drivers/ide/Kconfig"
 
diff -Nru a/arch/alpha/Makefile b/arch/alpha/Makefile
--- a/arch/alpha/Makefile	Thu Jan 16 18:23:06 2003
+++ b/arch/alpha/Makefile	Thu Jan 16 18:23:06 2003
@@ -96,6 +96,10 @@
 core-$(CONFIG_MATHEMU)  += arch/alpha/math-emu/
 libs-y			+= arch/alpha/lib/
 
+# export what is needed by arch/alpha/boot/Makefile
+LIBS_Y := $(patsubst %/, %/lib.a, $(libs-y))
+export LIBS_Y
+
 boot := arch/alpha/boot
 
 #Default target when executing make with no arguments
diff -Nru a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile
--- a/arch/alpha/boot/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/boot/Makefile	Thu Jan 16 18:23:05 2003
@@ -72,8 +72,11 @@
 LDFLAGS_bootloader  := -static -uvsprintf -T  #-N -relax
 LDFLAGS_bootpheader := -static -uvsprintf -T  #-N -relax
 
-$(obj)/bootloader: $(obj)/bootloader.lds $(obj)/head.o $(obj)/main.o FORCE
+OBJ_bootlx   := $(obj)/head.o $(obj)/main.o
+OBJ_bootph   := $(obj)/head.o $(obj)/bootp.o
+
+$(obj)/bootloader: $(obj)/bootloader.lds $(OBJ_bootlx) FORCE
 	$(call if_changed,ld)
 
-$(obj)/bootpheader: $(obj)/bootloader.lds $(obj)/head.o $(obj)/bootp.o FORCE
+$(obj)/bootpheader: $(obj)/bootloader.lds $(OBJ_bootph) $(LIBS_Y) FORCE
 	$(call if_changed,ld)
diff -Nru a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
--- a/arch/alpha/kernel/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/Makefile	Thu Jan 16 18:23:05 2003
@@ -6,7 +6,7 @@
 
 EXTRA_AFLAGS	:= $(CFLAGS)
 
-export-objs := alpha_ksyms.o
+export-objs := alpha_ksyms.o core_marvel.o core_titan.o
 
 obj-y    := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
 	    irq_alpha.o signal.o setup.o ptrace.o time.o semaphore.o \
@@ -21,18 +21,19 @@
 ifdef CONFIG_ALPHA_GENERIC
 
 obj-y 	 += core_apecs.o core_cia.o core_irongate.o core_lca.o \
-	    core_mcpcia.o core_polaris.o core_t2.o core_tsunami.o \
-	    core_titan.o core_wildfire.o
+	    core_marvel.o core_mcpcia.o core_polaris.o core_t2.o \
+	    core_tsunami.o core_titan.o core_wildfire.o
 
 obj-y	 += sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \
-	    sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o sys_titan.o \
-	    sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \
-	    sys_sable.o sys_sio.o sys_sx164.o sys_takara.o \
-	    sys_wildfire.o
+	    sys_jensen.o sys_marvel.o sys_miata.o sys_mikasa.o sys_nautilus.o \
+	    sys_titan.o sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \
+	    sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_wildfire.o
 
 obj-y	 += irq_pyxis.o irq_i8259.o irq_srm.o
 
-obj-y	 += es1888.o smc37c669.o smc37c93x.o ns87312.o
+obj-y    += err_titan.o err_marvel.o
+
+obj-y	 += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o
 
 else
 
@@ -41,6 +42,7 @@
 obj-$(CONFIG_ALPHA_CIA)		+= core_cia.o
 obj-$(CONFIG_ALPHA_IRONGATE)	+= core_irongate.o
 obj-$(CONFIG_ALPHA_LCA)		+= core_lca.o
+obj-$(CONFIG_ALPHA_MARVEL)	+= core_marvel.o gct.o
 obj-$(CONFIG_ALPHA_MCPCIA)	+= core_mcpcia.o
 obj-$(CONFIG_ALPHA_POLARIS)	+= core_polaris.o
 obj-$(CONFIG_ALPHA_T2)		+= core_t2.o
@@ -62,11 +64,13 @@
 				   smc37c93x.o
 obj-$(CONFIG_ALPHA_DP264)	+= sys_dp264.o irq_i8259.o es1888.o smc37c669.o
 obj-$(CONFIG_ALPHA_SHARK)	+= sys_dp264.o irq_i8259.o es1888.o smc37c669.o
-obj-$(CONFIG_ALPHA_TITAN)	+= sys_titan.o irq_i8259.o smc37c669.o
+obj-$(CONFIG_ALPHA_TITAN)	+= sys_titan.o irq_i8259.o smc37c669.o \
+				   err_titan.o
 obj-$(CONFIG_ALPHA_EB64P)	+= sys_eb64p.o irq_i8259.o
 obj-$(CONFIG_ALPHA_EB66)	+= sys_eb64p.o irq_i8259.o
 obj-$(CONFIG_ALPHA_EIGER)	+= sys_eiger.o irq_i8259.o
 obj-$(CONFIG_ALPHA_JENSEN)	+= sys_jensen.o pci-noop.o irq_i8259.o
+obj-$(CONFIG_ALPHA_MARVEL)	+= sys_marvel.o err_marvel.o
 obj-$(CONFIG_ALPHA_MIATA)	+= sys_miata.o irq_pyxis.o irq_i8259.o \
 				   es1888.o smc37c669.o
 obj-$(CONFIG_ALPHA_MIKASA)	+= sys_mikasa.o irq_i8259.o irq_srm.o
diff -Nru a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
--- a/arch/alpha/kernel/alpha_ksyms.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/alpha_ksyms.c	Thu Jan 16 18:23:05 2003
@@ -217,16 +217,23 @@
 EXPORT_SYMBOL(smp_call_function_on_cpu);
 EXPORT_SYMBOL(atomic_dec_and_lock);
 #ifdef CONFIG_DEBUG_SPINLOCK
-EXPORT_SYMBOL(spin_unlock);
+EXPORT_SYMBOL(_raw_spin_unlock);
 EXPORT_SYMBOL(debug_spin_lock);
 EXPORT_SYMBOL(debug_spin_trylock);
 #endif
 #ifdef CONFIG_DEBUG_RWLOCK
-EXPORT_SYMBOL(write_lock);
-EXPORT_SYMBOL(read_lock);
+EXPORT_SYMBOL(_raw_write_lock);
+EXPORT_SYMBOL(_raw_read_lock);
 #endif
 EXPORT_SYMBOL(cpu_present_mask);
 #endif /* CONFIG_SMP */
+
+/*
+ * NUMA specific symbols
+ */
+#ifdef CONFIG_DISCONTIGMEM
+EXPORT_SYMBOL(node_data);
+#endif /* CONFIG_DISCONTIGMEM */
 
 EXPORT_SYMBOL(rtc_lock);
 
diff -Nru a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/kernel/core_marvel.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,1121 @@
+/*
+ *	linux/arch/alpha/kernel/core_marvel.c
+ *
+ * Code common to all Marvel based systems.
+ */
+
+#include <linux/config.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_marvel.h>
+#undef __EXTERN_INLINE
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/mc146818rtc.h>
+#include <linux/rtc.h>
+#include <linux/module.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/smp.h>
+#include <asm/hwrpb.h>
+#include <asm/gct.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/rtc.h>
+
+#include <linux/bootmem.h>
+
+#include "proto.h"
+#include "pci_impl.h"
+
+
+/*
+ * Debug helpers
+ */
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
+# define DBG_CFG(args) printk args
+#else
+# define DBG_CFG(args)
+#endif
+
+
+/*
+ * Private data
+ */
+static struct io7 *io7_head = NULL;
+
+
+/*
+ * Helper functions
+ */
+static unsigned long __attribute__ ((unused))
+read_ev7_csr(int pe, unsigned long offset)
+{
+	ev7_csr *ev7csr = EV7_CSR_KERN(pe, offset);
+	unsigned long q;
+
+	mb();
+	q = ev7csr->csr;
+	mb();
+
+	return q;
+}
+
+static void __attribute__ ((unused))
+write_ev7_csr(int pe, unsigned long offset, unsigned long q)
+{
+	ev7_csr *ev7csr = EV7_CSR_KERN(pe, offset);
+
+	mb();
+	ev7csr->csr = q;
+	mb();
+}
+
+static char * __init
+mk_resource_name(int pe, int port, char *str)
+{
+	char tmp[80];
+	char *name;
+	
+	sprintf(tmp, "PCI %s PE %d PORT %d", str, pe, port);
+	name = alloc_bootmem(strlen(tmp) + 1);
+	strcpy(name, tmp);
+
+	return name;
+}
+
+inline struct io7 *
+marvel_next_io7(struct io7 *prev)
+{
+	return (prev ? prev->next : io7_head);
+}
+
+struct io7 *
+marvel_find_io7(int pe)
+{
+	struct io7 *io7;
+
+	for (io7 = io7_head; io7 && io7->pe != pe; io7 = io7->next)
+		continue;
+
+	return io7;
+}
+
+static struct io7 * __init
+alloc_io7(unsigned int pe)
+{
+	struct io7 *io7;
+	struct io7 *insp;
+	int h;
+
+	if (marvel_find_io7(pe)) {
+		printk(KERN_WARNING "IO7 at PE %d already allocated!\n", pe);
+		return NULL;
+	}
+
+	io7 = alloc_bootmem(sizeof(*io7));
+	io7->pe = pe;
+	io7->irq_lock = SPIN_LOCK_UNLOCKED;
+
+	for (h = 0; h < 4; h++) {
+		io7->ports[h].io7 = io7;
+		io7->ports[h].port = h;
+		io7->ports[h].enabled = 0; /* default to disabled */
+	}
+
+	/*
+	 * Insert in pe sorted order.
+	 */
+	if (NULL == io7_head)			/* empty list */
+		io7_head = io7;	
+	else if (io7_head->pe > io7->pe) {	/* insert at head */
+		io7->next = io7_head;
+		io7_head = io7;
+	} else {				/* insert at position */
+		for (insp = io7_head; insp; insp = insp->next) {
+			if (insp->pe == io7->pe) {
+				printk(KERN_ERR "Too many IO7s at PE %d\n", 
+				       io7->pe);
+				return NULL;
+			}
+
+			if (NULL == insp->next || 
+			    insp->next->pe > io7->pe) { /* insert here */
+				io7->next = insp->next;
+				insp->next = io7;
+				break;
+			}
+		}
+
+		if (NULL == insp) { /* couldn't insert ?!? */
+			printk(KERN_WARNING "Failed to insert IO7 at PE %d "
+			       " - adding at head of list\n", io7->pe);
+			io7->next = io7_head;
+			io7_head = io7;
+		}
+	}
+	
+	return io7;
+}
+
+void
+io7_clear_errors(struct io7 *io7)
+{
+	io7_port7_csrs *p7csrs;
+	io7_ioport_csrs *csrs;
+	int port;
+
+
+	/*
+	 * First the IO ports.
+	 */
+	for (port = 0; port < 4; port++) {
+		csrs = IO7_CSRS_KERN(io7->pe, port);
+
+		csrs->POx_ERR_SUM.csr = -1UL;
+		csrs->POx_TLB_ERR.csr = -1UL;
+		csrs->POx_SPL_COMPLT.csr = -1UL;
+		csrs->POx_TRANS_SUM.csr = -1UL;
+	}
+
+	/*
+	 * Then the common ones.
+	 */
+	p7csrs = IO7_PORT7_CSRS_KERN(io7->pe);
+
+	p7csrs->PO7_ERROR_SUM.csr = -1UL;
+	p7csrs->PO7_UNCRR_SYM.csr = -1UL;
+	p7csrs->PO7_CRRCT_SYM.csr = -1UL;
+}
+
+
+/*
+ * IO7 PCI, PCI/X, AGP configuration.
+ */
+static void __init
+io7_init_hose(struct io7 *io7, int port)
+{
+	static int hose_index = 0;
+
+	struct pci_controller *hose = alloc_pci_controller();
+	struct io7_port *io7_port = &io7->ports[port];
+	io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, port);
+	int i;
+
+	hose->index = hose_index++;	/* arbitrary */
+	
+	/*
+	 * We don't have an isa or legacy hose, but glibc expects to be
+	 * able to use the bus == 0 / dev == 0 form of the iobase syscall
+	 * to determine information about the i/o system. Since XFree86 
+	 * relies on glibc's determination to tell whether or not to use
+	 * sparse access, we need to point the pci_isa_hose at a real hose
+	 * so at least that determination is correct.
+	 */
+	if (hose->index == 0)
+		pci_isa_hose = hose;
+
+	io7_port->csrs = csrs;
+	io7_port->hose = hose;
+	hose->sysdata = io7_port;
+
+	hose->io_space = alloc_resource();
+	hose->mem_space = alloc_resource();
+
+	/*
+	 * Base addresses for userland consumption. Since these are going
+	 * to be mapped, they are pure physical addresses.
+	 */
+	hose->sparse_mem_base = hose->sparse_io_base = 0;
+	hose->dense_mem_base = IO7_MEM_PHYS(io7->pe, port);
+	hose->dense_io_base = IO7_IO_PHYS(io7->pe, port);
+
+	/*
+	 * Base addresses and resource ranges for kernel consumption.
+	 */
+	hose->config_space_base = (unsigned long)IO7_CONF_KERN(io7->pe, port);
+
+	hose->io_space->start = (unsigned long)IO7_IO_KERN(io7->pe, port);
+	hose->io_space->end = hose->io_space->start + IO7_IO_SPACE - 1;
+	hose->io_space->name = mk_resource_name(io7->pe, port, "IO");
+	hose->io_space->flags = IORESOURCE_IO;
+
+	hose->mem_space->start = (unsigned long)IO7_MEM_KERN(io7->pe, port);
+	hose->mem_space->end = hose->mem_space->start + IO7_MEM_SPACE - 1;
+	hose->mem_space->name = mk_resource_name(io7->pe, port, "MEM");
+	hose->mem_space->flags = IORESOURCE_MEM;
+
+	if (request_resource(&ioport_resource, hose->io_space) < 0)
+		printk(KERN_ERR "Failed to request IO on hose %d\n", 
+		       hose->index);
+	if (request_resource(&iomem_resource, hose->mem_space) < 0)
+		printk(KERN_ERR "Failed to request MEM on hose %d\n", 
+		       hose->index);
+
+	/*
+	 * Save the existing DMA window settings for later restoration.
+	 */
+	for (i = 0; i < 4; i++) {
+		io7_port->saved_wbase[i] = csrs->POx_WBASE[i].csr;
+		io7_port->saved_wmask[i] = csrs->POx_WMASK[i].csr;
+		io7_port->saved_tbase[i] = csrs->POx_TBASE[i].csr;
+	}
+
+	/*
+	 * Set up the PCI to main memory translation windows.
+	 *
+	 * Window 0 is scatter-gather 8MB at 8MB
+	 * Window 1 is direct access 1GB at 2GB
+	 * Window 2 is scatter-gather (up-to) 1GB at 3GB
+	 * Window 3 is disabled
+	 */
+
+	/*
+	 * TBIA before modifying windows.
+	 */
+	marvel_pci_tbi(hose, 0, -1);
+
+	/*
+	 * Set up window 0 for scatter-gather 8MB at 8MB.
+	 */
+	hose->sg_isa = iommu_arena_new_node(marvel_cpuid_to_nid(io7->pe),
+					    hose, 0x00800000, 0x00800000, 0);
+	hose->sg_isa->align_entry = 8;	/* cache line boundary */
+	csrs->POx_WBASE[0].csr = 
+		hose->sg_isa->dma_base | wbase_m_ena | wbase_m_sg;
+	csrs->POx_WMASK[0].csr = (hose->sg_isa->size - 1) & wbase_m_addr;
+	csrs->POx_TBASE[0].csr = virt_to_phys(hose->sg_isa->ptes);
+
+	/*
+	 * Set up window 1 for direct-mapped 1GB at 2GB.
+	 */
+	csrs->POx_WBASE[1].csr = __direct_map_base | wbase_m_ena;
+	csrs->POx_WMASK[1].csr = (__direct_map_size - 1) & wbase_m_addr;
+	csrs->POx_TBASE[1].csr = 0;
+
+	/*
+	 * Set up window 2 for scatter-gather (up-to) 1GB at 3GB.
+	 */
+	hose->sg_pci = iommu_arena_new_node(marvel_cpuid_to_nid(io7->pe),
+					    hose, 0xc0000000, 0x40000000, 0);
+	hose->sg_pci->align_entry = 8;	/* cache line boundary */
+	csrs->POx_WBASE[2].csr = 
+		hose->sg_pci->dma_base | wbase_m_ena | wbase_m_sg;
+	csrs->POx_WMASK[2].csr = (hose->sg_pci->size - 1) & wbase_m_addr;
+	csrs->POx_TBASE[2].csr = virt_to_phys(hose->sg_pci->ptes);
+
+	/*
+	 * Disable window 3.
+	 */
+	csrs->POx_WBASE[3].csr = 0;
+
+	/*
+	 * Make sure that the AGP Monster Window is disabled.
+	 */
+	csrs->POx_CTRL.csr &= ~(1UL << 61);
+
+#if 1
+	printk("FIXME: disabling master aborts\n");
+	csrs->POx_MSK_HEI.csr &= ~(3UL << 14);
+#endif
+	/*
+	 * TBIA after modifying windows.
+	 */
+	marvel_pci_tbi(hose, 0, -1);
+}
+
+static void __init
+marvel_init_io7(struct io7 *io7)
+{
+	int i;
+
+	printk("Initializing IO7 at PID %d\n", io7->pe);
+
+	/*
+	 * Get the Port 7 CSR pointer.
+	 */
+	io7->csrs = IO7_PORT7_CSRS_KERN(io7->pe);
+
+	/*
+	 * Init this IO7's hoses.
+	 */
+	for (i = 0; i < IO7_NUM_PORTS; i++) {
+		io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, i);
+		if (csrs->POx_CACHE_CTL.csr == 8) {
+			io7->ports[i].enabled = 1;
+			io7_init_hose(io7, i);
+		}
+	}
+}
+
+void
+marvel_io7_present(gct6_node *node)
+{
+	int pe;
+
+	if (node->type != GCT_TYPE_HOSE ||
+	    node->subtype != GCT_SUBTYPE_IO_PORT_MODULE) 
+		return;
+
+	pe = (node->id >> 8) & 0xff;
+	printk("Found an IO7 at PID %d\n", pe);
+
+	alloc_io7(pe);
+}
+
+static void __init
+marvel_init_vga_hose(void)
+{
+#ifdef CONFIG_VGA_HOSE
+	u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
+
+	if (pu64[7] == 3) {	/* TERM_TYPE == graphics */
+		struct pci_controller *hose = NULL;
+		int h = (pu64[30] >> 24) & 0xff; /* TERM_OUT_LOC, hose # */
+		struct io7 *io7;
+		int pid, port;
+
+		/* FIXME - encoding is going to have to change for Marvel
+		 *         since hose will be able to overflow a byte...
+		 *         need to fix this decode when the console 
+		 *         changes its encoding
+		 */
+		printk("console graphics is on hose %d (console)\n", h);
+
+		/*
+		 * The console's hose numbering is:
+		 *
+		 *	hose<n:2>: PID
+		 *	hose<1:0>: PORT
+		 *
+		 * We need to find the hose at that pid and port
+		 */
+		pid = h >> 2;
+		port = h & 3;
+		if ((io7 = marvel_find_io7(pid)))
+			hose = io7->ports[port].hose;
+
+		if (hose) {
+			printk("Console graphics on hose %d\n", hose->index);
+			pci_vga_hose = hose;
+		}
+	}
+#endif /* CONFIG_VGA_HOSE */
+}
+
+gct6_search_struct gct_wanted_node_list[] = {
+	{ GCT_TYPE_HOSE, GCT_SUBTYPE_IO_PORT_MODULE, marvel_io7_present },
+	{ 0, 0, NULL }
+};
+
+/*
+ * In case the GCT is not complete, let the user specify PIDs with IO7s
+ * at boot time. Syntax is 'io7=a,b,c,...,n' where a-n are the PIDs (decimal)
+ * where IO7s are connected
+ */
+static int __init
+marvel_specify_io7(char *str)
+{
+	unsigned long pid;
+	struct io7 *io7;
+	char *pchar;
+
+	do {
+		pid = simple_strtoul(str, &pchar, 0);
+		if (pchar != str) {
+			printk("User-specified IO7 at PID %lu\n", pid);
+			io7 = alloc_io7(pid);
+			if (io7) marvel_init_io7(io7);
+		}
+
+		if (pchar == str) pchar++;
+		str = pchar;
+	} while(*str);
+
+	return 0;
+}
+__setup("io7=", marvel_specify_io7);
+
+void __init
+marvel_init_arch(void)
+{
+	struct io7 *io7;
+
+	/* With multiple PCI busses, we play with I/O as physical addrs.  */
+	ioport_resource.end = ~0UL;
+	iomem_resource.end = ~0UL;
+
+	/* PCI DMA Direct Mapping is 1GB at 2GB.  */
+	__direct_map_base = 0x80000000;
+	__direct_map_size = 0x40000000;
+
+	/* Parse the config tree.  */
+	gct6_find_nodes(GCT_NODE_PTR(0), gct_wanted_node_list);
+
+	/* Init the io7s.  */
+	for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); ) 
+		marvel_init_io7(io7);
+
+	/* Check for graphic console location (if any).  */
+	marvel_init_vga_hose();
+}
+
+void
+marvel_kill_arch(int mode)
+{
+}
+
+
+/*
+ * PCI Configuration Space access functions
+ *
+ * Configuration space addresses have the following format:
+ *
+ * 	|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ * 	|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * 	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 	|B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|R|R|
+ * 	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *	 n:24	reserved for hose base
+ *	23:16	bus number (8 bits = 128 possible buses)
+ *	15:11	Device number (5 bits)
+ *	10:8	function number
+ *	 7:2	register number
+ *  
+ * Notes:
+ *	IO7 determines whether to use a type 0 or type 1 config cycle
+ *	based on the bus number. Therefore the bus number must be set 
+ *	to 0 for the root bus on any hose.
+ *	
+ *	The function number selects which function of a multi-function device 
+ *	(e.g., SCSI and Ethernet).
+ * 
+ */
+
+static inline unsigned long
+build_conf_addr(struct pci_controller *hose, u8 bus, 
+		unsigned int devfn, int where)
+{
+	return (hose->config_space_base | (bus << 16) | (devfn << 8) | where);
+}
+
+static unsigned long
+mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where)
+{
+	struct pci_controller *hose = pbus->sysdata;
+	struct io7_port *io7_port;
+	unsigned long addr = 0;
+	u8 bus = pbus->number;
+
+	if (!hose)
+		return addr;
+
+	/* Check for enabled.  */
+	io7_port = hose->sysdata;
+	if (!io7_port->enabled)
+		return addr;
+
+	if (hose->first_busno == bus) {
+		/* Don't support idsel > 20 on primary bus.  */
+		if (devfn >= PCI_DEVFN(21, 0))
+			return addr;
+		bus = 0;
+	}
+
+	addr = build_conf_addr(hose, bus, devfn, where);
+
+	DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+	return addr;
+}
+
+static int
+marvel_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+		   int size, u32 *value)
+{
+	unsigned long addr;
+	
+	if (0 == (addr = mk_conf_addr(bus, devfn, where)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	switch(size) {
+	case 1:	
+		*value = __kernel_ldbu(*(vucp)addr);
+		break;
+	case 2:	
+		*value = __kernel_ldwu(*(vusp)addr);
+		break;
+	case 4:	
+		*value = *(vuip)addr;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+marvel_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+		    int size, u32 value)
+{
+	unsigned long addr;
+	
+	if (0 == (addr = mk_conf_addr(bus, devfn, where)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	switch (size) {
+	case 1:
+		__kernel_stb(value, *(vucp)addr);
+		mb();
+		__kernel_ldbu(*(vucp)addr);
+		break;
+	case 2:
+		__kernel_stw(value, *(vusp)addr);
+		mb();
+		__kernel_ldwu(*(vusp)addr);
+		break;
+	case 4:
+		*(vuip)addr = value;
+		mb();
+		*(vuip)addr;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops marvel_pci_ops =
+{
+	.read =		marvel_read_config,
+	.write = 	marvel_write_config,
+};
+
+
+/*
+ * Other PCI helper functions.
+ */
+void
+marvel_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
+{
+	io7_ioport_csrs *csrs = ((struct io7_port *)hose->sysdata)->csrs;
+
+	wmb();
+	csrs->POx_SG_TBIA.csr = 0;
+	mb();
+	csrs->POx_SG_TBIA.csr;
+}
+
+
+/*
+ * IO map support.
+ */
+unsigned long
+marvel_ioremap(unsigned long addr, unsigned long size)
+{
+	struct pci_controller *hose;
+	unsigned long baddr, last;
+	struct vm_struct *area;
+	unsigned long vaddr;
+	unsigned long *ptes;
+	unsigned long pfn;
+
+	/*
+	 * Adjust the addr.
+	 */ 
+#ifdef CONFIG_VGA_HOSE
+	if (pci_vga_hose && __marvel_is_mem_vga(addr)) {
+		addr += pci_vga_hose->mem_space->start;
+	}
+#endif
+
+	if (!marvel_is_ioaddr(addr)) return 0UL;
+
+	/*
+	 * Find the hose.
+	 */
+	for (hose = hose_head; hose; hose = hose->next) {
+		if ((addr >> 32) == (hose->mem_space->start >> 32))
+			break; 
+	}
+	if (!hose)
+		return 0UL;
+
+	/*
+	 * We have the hose - calculate the bus limits.
+	 */
+	baddr = addr - hose->mem_space->start;
+	last = baddr + size - 1;
+
+	/*
+	 * Is it direct-mapped?
+	 */
+	if ((baddr >= __direct_map_base) && 
+	    ((baddr + size - 1) < __direct_map_base + __direct_map_size)) 
+		return IDENT_ADDR | (baddr - __direct_map_base);
+
+	/* 
+	 * Check the scatter-gather arena.
+	 */
+	if (hose->sg_pci &&
+	    baddr >= (unsigned long)hose->sg_pci->dma_base &&
+	    last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size){
+
+		/*
+		 * Adjust the limits (mappings must be page aligned)
+		 */
+		baddr -= hose->sg_pci->dma_base;
+		last -= hose->sg_pci->dma_base;
+		baddr &= PAGE_MASK;
+		size = PAGE_ALIGN(last) - baddr;
+
+		/*
+		 * Map it.
+		 */
+		area = get_vm_area(size, VM_IOREMAP);
+		if (!area) return (unsigned long)NULL;
+		ptes = hose->sg_pci->ptes;
+		for (vaddr = (unsigned long)area->addr; 
+		    baddr <= last; 
+		    baddr += PAGE_SIZE, vaddr += PAGE_SIZE) {
+			pfn = ptes[baddr >> PAGE_SHIFT];
+			if (!(pfn & 1)) {
+				printk("ioremap failed... pte not valid...\n");
+				vfree(area->addr);
+				return 0UL;
+			}
+			pfn >>= 1;	/* make it a true pfn */
+			
+			if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), 
+						     pfn << PAGE_SHIFT, 
+						     PAGE_SIZE, 0)) {
+				printk("FAILED to map...\n");
+				vfree(area->addr);
+				return 0UL;
+			}
+		}
+
+		flush_tlb_all();
+
+		vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);
+
+		return vaddr;
+	}
+
+	/*
+	 * Not found - assume legacy ioremap.
+	 */
+	return addr;
+}
+
+void
+marvel_iounmap(unsigned long addr)
+{
+	if (((long)addr >> 41) == -2)
+		return;	/* kseg map, nothing to do */
+	if (addr)
+		return vfree((void *)(PAGE_MASK & addr)); 
+}
+
+#ifndef CONFIG_ALPHA_GENERIC
+EXPORT_SYMBOL(marvel_ioremap);
+EXPORT_SYMBOL(marvel_iounmap);
+#endif
+
+/*
+ * SRMCons support
+ *
+ * Marvel doesn't have a real serial console -- it's either graphics or 
+ * server management based. If we're running on the server management based
+ * console, allow the srmcons callback driver to be a console device.
+ */
+int
+marvel_srmcons_allowed(void)
+{
+	u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
+
+	return (pu64[7] == 2);
+}
+
+
+/*
+ * RTC Support
+ */
+struct marvel_rtc_access_info {
+	unsigned long function;
+	unsigned long index;
+	unsigned long data;
+};
+
+static void
+__marvel_access_rtc(void *info)
+{
+	struct marvel_rtc_access_info *rtc_access = info;
+
+	register unsigned long __r0 __asm__("$0");
+	register unsigned long __r16 __asm__("$16") = rtc_access->function;
+	register unsigned long __r17 __asm__("$17") = rtc_access->index;
+	register unsigned long __r18 __asm__("$18") = rtc_access->data;
+	
+	__asm__ __volatile__(
+		"call_pal %4 # cserve rtc"
+		: "=r"(__r16), "=r"(__r17), "=r"(__r18), "=r"(__r0)
+		: "i"(PAL_cserve), "0"(__r16), "1"(__r17), "2"(__r18)
+		: "$1", "$22", "$23", "$24", "$25");
+
+	rtc_access->data = __r0;
+}
+
+u8
+__marvel_rtc_io(int write, u8 b, unsigned long addr)
+{
+	struct marvel_rtc_access_info rtc_access = {0, };
+	static u8 index = 0;
+	u8 ret = 0;
+
+	switch(addr) {
+	case 0x70:					/* RTC_PORT(0) */
+		if (write) index = b;
+		ret = index;
+		break;
+
+	case 0x71:					/* RTC_PORT(1) */
+		rtc_access.index = index;
+		rtc_access.data = BCD_TO_BIN(b);
+		rtc_access.function = 0x49;		/* GET_TOY */
+		if (write) rtc_access.function = 0x48;	/* PUT_TOY */
+
+#if CONFIG_SMP
+		if (smp_processor_id() != boot_cpuid)
+			smp_call_function_on_cpu(__marvel_access_rtc,
+						 &rtc_access,
+						 1,	/* retry */
+						 1,	/* wait  */
+						 1UL << boot_cpuid);
+		else
+			__marvel_access_rtc(&rtc_access);
+#else
+		__marvel_access_rtc(&rtc_access);
+#endif
+		ret = BIN_TO_BCD(rtc_access.data);
+		
+		break;
+
+	default:
+		printk(KERN_WARNING "Illegal RTC port %lx\n", addr);
+		break;
+	}
+
+	return ret;
+}
+
+
+/*
+ * NUMA Support
+ */
+/**********
+ * FIXME - for now each cpu is a node by itself 
+ *              -- no real support for striped mode 
+ **********
+ */
+int
+marvel_pa_to_nid(unsigned long pa)
+{
+	int cpuid;
+
+	if ((pa >> 43) & 1) 	/* I/O */ 
+		cpuid = (~(pa >> 35) & 0xff);
+	else			/* mem */
+		cpuid = ((pa >> 34) & 0x3) | ((pa >> (37 - 2)) & (0x1f << 2));
+
+	return marvel_cpuid_to_nid(cpuid);
+}
+
+int
+marvel_cpuid_to_nid(int cpuid)
+{
+	return cpuid;
+}
+
+unsigned long
+marvel_node_mem_start(int nid)
+{
+	unsigned long pa;
+
+	pa = (nid & 0x3) | ((nid & (0x1f << 2)) << 1);
+	pa <<= 34;
+
+	return pa;
+}
+
+unsigned long
+marvel_node_mem_size(int nid)
+{
+	return 16UL * 1024 * 1024 * 1024; /* 16GB */
+}
+
+
+/* 
+ * AGP GART Support.
+ */
+#include <linux/agp_backend.h>
+#include <asm/agp_backend.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#define MARVEL_AGP_APER_SIZE (64 * 1024 * 1024)
+
+struct marvel_agp_aperture {
+	struct pci_iommu_arena *arena;
+	long pg_start;
+	long pg_count;
+};
+
+static int
+marvel_agp_setup(alpha_agp_info *agp)
+{
+	struct marvel_agp_aperture *aper;
+
+	aper = kmalloc(sizeof(*aper), GFP_KERNEL);
+	if (aper == NULL) return -ENOMEM;
+
+	aper->arena = agp->hose->sg_pci;
+	aper->pg_count = MARVEL_AGP_APER_SIZE / PAGE_SIZE;
+	aper->pg_start = iommu_reserve(aper->arena, aper->pg_count,
+				       aper->pg_count - 1);
+
+	if (aper->pg_start < 0) {
+		printk(KERN_ERR "Failed to reserve AGP memory\n");
+		kfree(aper);
+		return -ENOMEM;
+	}
+
+	agp->aperture.bus_base = 
+		aper->arena->dma_base + aper->pg_start * PAGE_SIZE;
+	agp->aperture.size = aper->pg_count * PAGE_SIZE;
+	agp->aperture.sysdata = aper;
+
+	return 0;
+}
+
+static void
+marvel_agp_cleanup(alpha_agp_info *agp)
+{
+	struct marvel_agp_aperture *aper = agp->aperture.sysdata;
+	int status;
+
+	status = iommu_release(aper->arena, aper->pg_start, aper->pg_count);
+	if (status == -EBUSY) {
+		printk(KERN_WARNING
+		       "Attempted to release bound AGP memory - unbinding\n");
+		iommu_unbind(aper->arena, aper->pg_start, aper->pg_count);
+		status = iommu_release(aper->arena, aper->pg_start, 
+				       aper->pg_count);
+	}
+	if (status < 0)
+		printk(KERN_ERR "Failed to release AGP memory\n");
+
+	kfree(aper);
+	kfree(agp);
+}
+
+static int
+marvel_agp_configure(alpha_agp_info *agp)
+{
+	io7_ioport_csrs *csrs = ((struct io7_port *)agp->hose->sysdata)->csrs;
+	struct io7 *io7 = ((struct io7_port *)agp->hose->sysdata)->io7;
+	unsigned int new_rate = 0;
+	unsigned long agp_pll;
+
+	/*
+	 * Check the requested mode against the PLL setting.
+	 * The agpgart_be code has not programmed the card yet,
+	 * so we can still tweak mode here.
+	 */
+	agp_pll = io7->csrs->POx_RST[IO7_AGP_PORT].csr;
+	switch(IO7_PLL_RNGB(agp_pll)) {
+	case 0x4:				/* 2x only */
+		/* 
+		 * The PLL is only programmed for 2x, so adjust the
+		 * rate to 2x, if necessary.
+		 */
+		if (agp->mode.bits.rate != 2) 
+			new_rate = 2;
+		break;
+
+	case 0x6:				/* 1x / 4x */
+		/*
+		 * The PLL is programmed for 1x or 4x.  Don't go faster
+		 * than requested, so if the requested rate is 2x, use 1x.
+		 */
+		if (agp->mode.bits.rate == 2) 
+			new_rate = 1;
+		break;
+
+	default:				/* ??????? */
+		/*
+		 * Don't know what this PLL setting is, take the requested
+		 * rate, but warn the user.
+		 */
+		printk("%s: unknown PLL setting RNGB=%lx (PLL6_CTL=%016lx)\n",
+		       __FUNCTION__, IO7_PLL_RNGB(agp_pll), agp_pll);
+		break;
+	}
+
+	/*
+	 * Set the new rate, if necessary.
+	 */
+	if (new_rate) {
+		printk("Requested AGP Rate %dX not compatible "
+		       "with PLL setting - using %dX\n",
+		       agp->mode.bits.rate,
+		       new_rate);
+
+		agp->mode.bits.rate = new_rate;
+	}
+		
+	printk("Enabling AGP on hose %d: %dX%s RQ %d\n", 
+	       agp->hose->index, agp->mode.bits.rate, 
+	       agp->mode.bits.sba ? " - SBA" : "", agp->mode.bits.rq);
+
+	csrs->AGP_CMD.csr = agp->mode.lw;
+
+	return 0;
+}
+
+static int 
+marvel_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem)
+{
+	struct marvel_agp_aperture *aper = agp->aperture.sysdata;
+	return iommu_bind(aper->arena, aper->pg_start + pg_start, 
+			  mem->page_count, mem->memory);
+}
+
+static int 
+marvel_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem)
+{
+	struct marvel_agp_aperture *aper = agp->aperture.sysdata;
+	return iommu_unbind(aper->arena, aper->pg_start + pg_start,
+			    mem->page_count);
+}
+
+static unsigned long
+marvel_agp_translate(alpha_agp_info *agp, dma_addr_t addr)
+{
+	struct marvel_agp_aperture *aper = agp->aperture.sysdata;
+	unsigned long baddr = addr - aper->arena->dma_base;
+	unsigned long pte;
+
+	if (addr < agp->aperture.bus_base ||
+	    addr >= agp->aperture.bus_base + agp->aperture.size) {
+		printk("%s: addr out of range\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	pte = aper->arena->ptes[baddr >> PAGE_SHIFT];
+	if (!(pte & 1)) {
+		printk("%s: pte not valid\n", __FUNCTION__);
+		return -EINVAL;
+	} 
+	return (pte >> 1) << PAGE_SHIFT;
+}
+
+struct alpha_agp_ops marvel_agp_ops =
+{
+	.setup		= marvel_agp_setup,
+	.cleanup	= marvel_agp_cleanup,
+	.configure	= marvel_agp_configure,
+	.bind		= marvel_agp_bind_memory,
+	.unbind		= marvel_agp_unbind_memory,
+	.translate	= marvel_agp_translate
+};
+
+alpha_agp_info *
+marvel_agp_info(void)
+{
+	struct pci_controller *hose;
+	io7_ioport_csrs *csrs;
+	alpha_agp_info *agp;
+	struct io7 *io7;
+
+	/*
+	 * Find the first IO7 with an AGP card.
+	 *
+	 * FIXME -- there should be a better way (we want to be able to
+	 * specify and what if the agp card is not video???)
+	 */
+	hose = NULL;
+	for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) {
+		struct pci_controller *h;
+		vuip addr;
+
+		if (!io7->ports[IO7_AGP_PORT].enabled)
+			continue;
+
+		h = io7->ports[IO7_AGP_PORT].hose;
+		addr = (vuip)build_conf_addr(h, 0, PCI_DEVFN(5, 0), 0);
+
+		if (*addr != 0xffffffffu) {
+			hose = h;
+			break;
+		}
+	}
+
+	printk("MARVEL - using hose %d as AGP\n", hose->index);
+
+	if (!hose || !hose->sg_pci)
+		return NULL;
+
+	/* 
+	 * Get the csrs from the hose.
+	 */
+	csrs = ((struct io7_port *)hose->sysdata)->csrs;
+
+	/*
+	 * Allocate the info structure.
+	 */
+	agp = kmalloc(sizeof(*agp), GFP_KERNEL);
+
+	/*
+	 * Fill it in.
+	 */
+	agp->type = 0 /* FIXME: ALPHA_CORE_AGP */;
+	agp->hose = hose;
+	agp->private = NULL;
+	agp->ops = &marvel_agp_ops;
+
+	/*
+	 * Aperture - not configured until ops.setup().
+	 */
+	agp->aperture.bus_base = 0;
+	agp->aperture.size = 0;
+	agp->aperture.sysdata = NULL;
+
+	/*
+	 * Capabilities.
+	 *
+	 * NOTE: IO7 reports through AGP_STAT that it can support a read queue
+	 *       depth of 17 (rq = 0x10). It actually only supports a depth of
+	 * 	 16 (rq = 0xf).
+	 */
+	agp->capability.lw = csrs->AGP_STAT.csr;
+	agp->capability.bits.rq = 0xf;
+	
+	/*
+	 * Mode.
+	 */
+	agp->mode.lw = csrs->AGP_CMD.csr;
+
+	return agp;
+}
diff -Nru a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c
--- a/arch/alpha/kernel/core_titan.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/core_titan.c	Thu Jan 16 18:23:05 2003
@@ -5,15 +5,20 @@
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/vmalloc.h>
 
+#include <asm/hwrpb.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
 #include <asm/smp.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
 
 #define __EXTERN_INLINE inline
 #include <asm/io.h>
@@ -25,8 +30,6 @@
 #include "proto.h"
 #include "pci_impl.h"
 
-unsigned TITAN_agp = 0;
-
 /* Save Titan configuration data as the console had it set up.  */
 
 struct
@@ -49,6 +52,31 @@
 # define DBG_CFG(args)
 #endif
 
+
+/*
+ * Routines to access TIG registers.
+ */
+static inline volatile unsigned long *
+mk_tig_addr(int offset)
+{
+	return (volatile unsigned long *)(TITAN_TIG_SPACE + (offset << 6));
+}
+
+static inline u8 
+titan_read_tig(int offset, u8 value)
+{
+	volatile unsigned long *tig_addr = mk_tig_addr(offset);
+	return (u8)(*tig_addr & 0xff);
+}
+
+static inline void 
+titan_write_tig(int offset, u8 value)
+{
+	volatile unsigned long *tig_addr = mk_tig_addr(offset);
+	*tig_addr = (unsigned long)value;
+}
+
+
 /*
  * Given a bus, device, and function number, compute resulting
  * configuration space address
@@ -179,13 +207,16 @@
 	volatile unsigned long *csr;
 	unsigned long value;
 
-	/* Get the right hose */
+	/* Get the right hose.  */
 	port = &pachip->g_port;
 	if (hose->index & 2) 
 		port = &pachip->a_port;
 
 	/* We can invalidate up to 8 tlb entries in a go.  The flush
-	   matches against <31:16> in the pci address.  */
+	   matches against <31:16> in the pci address.  
+	   Note that gtlbi* and atlbi* are in the same place in the g_port
+	   and a_port, respectively, so the g_port offset can be used
+	   even if hose is an a_port */
 	csr = &port->port_specific.g.gtlbia.csr;
 	if (((start ^ end) & 0xffff0000) == 0)
 		csr = &port->port_specific.g.gtlbiv.csr;
@@ -200,9 +231,7 @@
 	*csr;
 }
 
-#define FN __FUNCTION__
-
-static int __init
+static int
 titan_query_agp(titan_pachip_port *port)
 {
 	union TPAchipPCTL pctl;
@@ -213,36 +242,6 @@
 	return pctl.pctl_r_bits.apctl_v_agp_present;
 
 }
-static void __init
-titan_init_agp(titan_pachip_port *port, struct pci_controller *hose)
-{
-	union TPAchipPCTL pctl;
-
-	if (!titan_query_agp(port))
-		return;
-
-	printk("AGP present on hose %d\n", hose->index);
-
-	/* get APCTL */
-	pctl.pctl_q_whole = port->pctl.csr;
-
-
-	pctl.pctl_r_bits.apctl_v_agp_en = 1;	/* enable AGP */
-	pctl.pctl_r_bits.apctl_v_agp_lp_rd = 0;	
-	pctl.pctl_r_bits.apctl_v_agp_hp_rd = 0;	
-
-	port->pctl.csr = pctl.pctl_q_whole;
-
-	TITAN_agp |= 1 << hose->index;
-
-#ifdef CONFIG_VGA_HOSE	
-	/* is a graphics card on the AGP? (always device 5) */
-	if (hose != NULL &&
-	    __kernel_ldwu(*(vusp)(hose->config_space_base + 0x280a)) == 
-	    PCI_CLASS_DISPLAY_VGA)
-		set_vga_hose(hose);
-#endif
-}
 
 static void __init
 titan_init_one_pachip_port(titan_pachip_port *port, int index)
@@ -255,10 +254,13 @@
 	hose->io_space = alloc_resource();
 	hose->mem_space = alloc_resource();
 
-	/* This is for userland consumption.  For some reason, the 40-bit
-	   PIO bias that we use in the kernel through KSEG didn't work for
-	   the page table based user mappings.  So make sure we get the
-	   43-bit PIO bias.  */
+	/*
+	 * This is for userland consumption.  The 40-bit PIO bias that we 
+	 * use in the kernel through KSEG doesn't work in the page table 
+	 * based user mappings. (43-bit KSEG sign extends the physical
+	 * address from bit 40 to hit the I/O bit - mapped addresses don't).
+	 * So make sure we get the 43-bit PIO bias.  
+	 */
 	hose->sparse_mem_base = 0;
 	hose->sparse_io_base = 0;
 	hose->dense_mem_base
@@ -284,9 +286,6 @@
 	if (request_resource(&iomem_resource, hose->mem_space) < 0)
 		printk(KERN_ERR "Failed to request MEM on hose %d\n", index);
 
-	/* It's safe to call this for both G-Ports and A-Ports */
-	titan_init_agp(port, hose);
-
 	/*
 	 * Save the existing PCI window translations.  SRM will 
 	 * need them when we go to reboot.
@@ -310,39 +309,41 @@
 	/*
 	 * Set up the PCI to main memory translation windows.
 	 *
-	 * Note: Window 3 on Titan is Scatter-Gather ONLY
+	 * Note: Window 3 on Titan is Scatter-Gather ONLY.
 	 *
 	 * Window 0 is scatter-gather 8MB at 8MB (for isa)
-	 * Window 1 is scatter-gather (up to) 1GB at 1GB
-	 * Window 2 is direct access 2GB at 2GB
+	 * Window 1 is direct access 1GB at 2GB
+	 * Window 2 is scatter-gather 1GB at 3GB
 	 */
 	hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
 	hose->sg_isa->align_entry = 8; /* 64KB for ISA */
 
-	hose->sg_pci = iommu_arena_new(hose, 0x40000000,
-				       size_for_memory(0x40000000), 0);
+	hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x40000000, 0);
 	hose->sg_pci->align_entry = 4; /* Titan caches 4 PTEs at a time */
 
-	__direct_map_base = 0x80000000;
-	__direct_map_size = 0x80000000;
-
 	port->wsba[0].csr = hose->sg_isa->dma_base | 3;
 	port->wsm[0].csr  = (hose->sg_isa->size - 1) & 0xfff00000;
 	port->tba[0].csr  = virt_to_phys(hose->sg_isa->ptes);
 
-	port->wsba[1].csr = hose->sg_pci->dma_base | 3;
-	port->wsm[1].csr  = (hose->sg_pci->size - 1) & 0xfff00000;
-	port->tba[1].csr  = virt_to_phys(hose->sg_pci->ptes);
-
-	port->wsba[2].csr = 0x80000000 | 1;
-	port->wsm[2].csr  = (0x80000000 - 1) & 0xfff00000;
-	port->tba[2].csr  = 0;
+	port->wsba[1].csr = __direct_map_base | 1;
+	port->wsm[1].csr  = (__direct_map_size - 1) & 0xfff00000;
+	port->tba[1].csr  = 0;
+
+	port->wsba[2].csr = hose->sg_pci->dma_base | 3;
+	port->wsm[2].csr  = (hose->sg_pci->size - 1) & 0xfff00000;
+	port->tba[2].csr  = virt_to_phys(hose->sg_pci->ptes);
 
 	port->wsba[3].csr = 0;
 
-	/* Enable the Monster Window to make DAC pci64 possible. */
+	/* Enable the Monster Window to make DAC pci64 possible.  */
 	port->pctl.csr |= pctl_m_mwin;
 
+	/*
+	 * If it's an AGP port, initialize agplastwr.
+	 */
+	if (titan_query_agp(port)) 
+		port->port_specific.a.agplastwr.csr = __direct_map_base;
+
 	titan_pci_tbi(hose, 0, -1);
 }
 
@@ -360,25 +361,51 @@
 		titan_init_one_pachip_port(&pachip1->a_port, 3);/* hose 3 */
 }
 
+static void __init
+titan_init_vga_hose(void)
+{
+#ifdef CONFIG_VGA_HOSE
+	u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
+
+	if (pu64[7] == 3) {	/* TERM_TYPE == graphics */
+		struct pci_controller *hose;
+		int h = (pu64[30] >> 24) & 0xff;	/* console hose # */
+
+		/*
+		 * Our hose numbering matches the console's, so just find
+		 * the right one...
+		 */
+		for (hose = hose_head; hose; hose = hose->next) {
+			if (hose->index == h) break;
+		}
+
+		if (hose) {
+			printk("Console graphics on hose %d\n", hose->index);
+			pci_vga_hose = hose;
+		}
+	}
+#endif /* CONFIG_VGA_HOSE */
+}
+
 void __init
 titan_init_arch(void)
 {
 #if 0
-	printk("%s: titan_init_arch()\n", FN);
-	printk("%s: CChip registers:\n", FN);
-	printk("%s: CSR_CSC 0x%lx\n", FN, TITAN_cchip->csc.csr);
-	printk("%s: CSR_MTR 0x%lx\n", FN, TITAN_cchip->mtr.csr);
-	printk("%s: CSR_MISC 0x%lx\n", FN, TITAN_cchip->misc.csr);
-	printk("%s: CSR_DIM0 0x%lx\n", FN, TITAN_cchip->dim0.csr);
-	printk("%s: CSR_DIM1 0x%lx\n", FN, TITAN_cchip->dim1.csr);
-	printk("%s: CSR_DIR0 0x%lx\n", FN, TITAN_cchip->dir0.csr);
-	printk("%s: CSR_DIR1 0x%lx\n", FN, TITAN_cchip->dir1.csr);
-	printk("%s: CSR_DRIR 0x%lx\n", FN, TITAN_cchip->drir.csr);
-
-	printk("%s: DChip registers:\n", FN);
-	printk("%s: CSR_DSC 0x%lx\n", FN, TITAN_dchip->dsc.csr);
-	printk("%s: CSR_STR 0x%lx\n", FN, TITAN_dchip->str.csr);
-	printk("%s: CSR_DREV 0x%lx\n", FN, TITAN_dchip->drev.csr);
+	printk("%s: titan_init_arch()\n", __FUNCTION__);
+	printk("%s: CChip registers:\n", __FUNCTION__);
+	printk("%s: CSR_CSC 0x%lx\n", __FUNCTION__, TITAN_cchip->csc.csr);
+	printk("%s: CSR_MTR 0x%lx\n", __FUNCTION__, TITAN_cchip->mtr.csr);
+	printk("%s: CSR_MISC 0x%lx\n", __FUNCTION__, TITAN_cchip->misc.csr);
+	printk("%s: CSR_DIM0 0x%lx\n", __FUNCTION__, TITAN_cchip->dim0.csr);
+	printk("%s: CSR_DIM1 0x%lx\n", __FUNCTION__, TITAN_cchip->dim1.csr);
+	printk("%s: CSR_DIR0 0x%lx\n", __FUNCTION__, TITAN_cchip->dir0.csr);
+	printk("%s: CSR_DIR1 0x%lx\n", __FUNCTION__, TITAN_cchip->dir1.csr);
+	printk("%s: CSR_DRIR 0x%lx\n", __FUNCTION__, TITAN_cchip->drir.csr);
+
+	printk("%s: DChip registers:\n", __FUNCTION__);
+	printk("%s: CSR_DSC 0x%lx\n", __FUNCTION__, TITAN_dchip->dsc.csr);
+	printk("%s: CSR_STR 0x%lx\n", __FUNCTION__, TITAN_dchip->str.csr);
+	printk("%s: CSR_DREV 0x%lx\n", __FUNCTION__, TITAN_dchip->drev.csr);
 #endif
 
 	boot_cpuid = __hard_smp_processor_id();
@@ -387,8 +414,15 @@
 	ioport_resource.end = ~0UL;
 	iomem_resource.end = ~0UL;
 
-	/* Init the PA chip(s) */
+	/* PCI DMA Direct Mapping is 1GB at 2GB.  */
+	__direct_map_base = 0x80000000;
+	__direct_map_size = 0x40000000;
+
+	/* Init the PA chip(s).  */
 	titan_init_pachips(TITAN_pachip0, TITAN_pachip1);
+
+	/* Check for graphic console location (if any).  */
+	titan_init_vga_hose();
 }
 
 static void
@@ -417,8 +451,8 @@
 	int pchip1_present = TITAN_cchip->csc.csr & 1L<<14;
 
 	if (pchip1_present) {
-		titan_kill_one_pachip_port(&pachip0->g_port, 1);
-		titan_kill_one_pachip_port(&pachip0->a_port, 3);
+		titan_kill_one_pachip_port(&pachip1->g_port, 1);
+		titan_kill_one_pachip_port(&pachip1->a_port, 3);
 	}
 	titan_kill_one_pachip_port(&pachip0->g_port, 0);
 	titan_kill_one_pachip_port(&pachip0->a_port, 2);
@@ -430,38 +464,336 @@
 	titan_kill_pachips(TITAN_pachip0, TITAN_pachip1);
 }
 
-static inline void
-titan_pci_clr_err_1(titan_pachip *pachip)
+
+/*
+ * IO map support.
+ */
+unsigned long
+titan_ioremap(unsigned long addr, unsigned long size)
 {
-	unsigned int jd;
+	int h = (addr & TITAN_HOSE_MASK) >> TITAN_HOSE_SHIFT;
+	unsigned long baddr = addr & ~TITAN_HOSE_MASK;
+	unsigned long last = baddr + size - 1;
+	struct pci_controller *hose;	
+	struct vm_struct *area;
+	unsigned long vaddr;
+	unsigned long *ptes;
+	unsigned long pfn;
 
-	jd = pachip->g_port.port_specific.g.gperror.csr;
-	pachip->g_port.port_specific.g.gperror.csr = jd;
-	mb();
-	pachip->g_port.port_specific.g.gperror.csr;
+	/*
+	 * Adjust the addr.
+	 */ 
+#ifdef CONFIG_VGA_HOSE
+	if (pci_vga_hose && __titan_is_mem_vga(addr)) {
+		h = pci_vga_hose->index;
+		addr += pci_vga_hose->mem_space->start;
+	}
+#endif
+
+	/*
+	 * Find the hose.
+	 */
+	for (hose = hose_head; hose; hose = hose->next)
+		if (hose->index == h) break;
+	if (!hose) return (unsigned long)NULL;
+
+	/*
+	 * Is it direct-mapped?
+	 */
+	if ((baddr >= __direct_map_base) && 
+	    ((baddr + size - 1) < __direct_map_base + __direct_map_size)) 
+		return addr - __direct_map_base + TITAN_MEM_BIAS;
+
+	/* 
+	 * Check the scatter-gather arena.
+	 */
+	if (hose->sg_pci &&
+	    baddr >= (unsigned long)hose->sg_pci->dma_base &&
+	    last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size){
+
+		/*
+		 * Adjust the limits (mappings must be page aligned)
+		 */
+		baddr -= hose->sg_pci->dma_base;
+		last -= hose->sg_pci->dma_base;
+		baddr &= PAGE_MASK;
+		size = PAGE_ALIGN(last) - baddr;
+
+		/*
+		 * Map it
+		 */
+		area = get_vm_area(size, VM_IOREMAP);
+		if (!area) return (unsigned long)NULL;
+		ptes = hose->sg_pci->ptes;
+		for (vaddr = (unsigned long)area->addr; 
+		    baddr <= last; 
+		    baddr += PAGE_SIZE, vaddr += PAGE_SIZE) {
+			pfn = ptes[baddr >> PAGE_SHIFT];
+			if (!(pfn & 1)) {
+				printk("ioremap failed... pte not valid...\n");
+				vfree(area->addr);
+				return (unsigned long)NULL;
+			}
+			pfn >>= 1;	/* make it a true pfn */
+			
+			if (__alpha_remap_area_pages(VMALLOC_VMADDR(vaddr), 
+						     pfn << PAGE_SHIFT, 
+						     PAGE_SIZE, 0)) {
+				printk("FAILED to map...\n");
+				vfree(area->addr);
+				return (unsigned long)NULL;
+			}
+		}
+
+		flush_tlb_all();
+
+		vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);
+		return vaddr;
+	}
+
+	/*
+	 * Not found - assume legacy ioremap.
+	 */
+	return addr + TITAN_MEM_BIAS;
+
+}
+
+void
+titan_iounmap(unsigned long addr)
+{
+	if (((long)addr >> 41) == -2)
+		return;	/* kseg map, nothing to do */
+	if (addr)
+		vfree((void *)(PAGE_MASK & addr)); 
+}
+
+#ifndef CONFIG_ALPHA_GENERIC
+EXPORT_SYMBOL(titan_ioremap);
+EXPORT_SYMBOL(titan_iounmap);
+#endif
+
+/*
+ * AGP GART Support.
+ */
+#include <linux/agp_backend.h>
+#include <asm/agp_backend.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#define TITAN_AGP_APER_SIZE (64 * 1024 * 1024)
+
+struct titan_agp_aperture {
+	struct pci_iommu_arena *arena;
+	long pg_start;
+	long pg_count;
+};
+
+static int
+titan_agp_setup(alpha_agp_info *agp)
+{
+	struct titan_agp_aperture *aper;
+
+	aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL);
+	if (aper == NULL)
+		return -ENOMEM;
+
+	aper->arena = agp->hose->sg_pci;
+	aper->pg_count = TITAN_AGP_APER_SIZE / PAGE_SIZE;
+	aper->pg_start = iommu_reserve(aper->arena, aper->pg_count,
+				       aper->pg_count - 1);
+	if (aper->pg_start < 0) {
+		printk(KERN_ERR "Failed to reserve AGP memory\n");
+		kfree(aper);
+		return -ENOMEM;
+	}
+
+	agp->aperture.bus_base = 
+		aper->arena->dma_base + aper->pg_start * PAGE_SIZE;
+	agp->aperture.size = aper->pg_count * PAGE_SIZE;
+	agp->aperture.sysdata = aper;
+
+	return 0;
 }
 
-static inline void
-titan_pci_clr_err(void)
+static void
+titan_agp_cleanup(alpha_agp_info *agp)
 {
-	titan_pci_clr_err_1(TITAN_pachip0);
+	struct titan_agp_aperture *aper = agp->aperture.sysdata;
+	int status;
 
-	if (TITAN_cchip->csc.csr & 1L<<14)
-	    titan_pci_clr_err_1(TITAN_pachip1);
+	status = iommu_release(aper->arena, aper->pg_start, aper->pg_count);
+	if (status == -EBUSY) {
+		printk(KERN_WARNING 
+		       "Attempted to release bound AGP memory - unbinding\n");
+		iommu_unbind(aper->arena, aper->pg_start, aper->pg_count);
+		status = iommu_release(aper->arena, aper->pg_start, 
+				       aper->pg_count);
+	}
+	if (status < 0)
+		printk(KERN_ERR "Failed to release AGP memory\n");
+
+	kfree(aper);
+	kfree(agp);
 }
 
-void
-titan_machine_check(unsigned long vector, unsigned long la_ptr,
-		      struct pt_regs * regs)
+static int
+titan_agp_configure(alpha_agp_info *agp)
 {
-	/* clear error before any reporting. */
-	mb();
-	draina();
-	titan_pci_clr_err();
-	wrmces(0x7);
-	mb();
+	union TPAchipPCTL pctl;
+	titan_pachip_port *port = agp->private;
+	pctl.pctl_q_whole = port->pctl.csr;
+
+	/* Side-Band Addressing? */
+	pctl.pctl_r_bits.apctl_v_agp_sba_en = agp->mode.bits.sba;
+
+	/* AGP Rate? */
+	pctl.pctl_r_bits.apctl_v_agp_rate = 0;		/* 1x */
+	if (agp->mode.bits.rate & 2) 
+		pctl.pctl_r_bits.apctl_v_agp_rate = 1;	/* 2x */
+#if 0
+	if (agp->mode.bits.rate & 4) 
+		pctl.pctl_r_bits.apctl_v_agp_rate = 2;	/* 4x */
+#endif
+	
+	/* RQ Depth? */
+	pctl.pctl_r_bits.apctl_v_agp_hp_rd = 2;
+	pctl.pctl_r_bits.apctl_v_agp_lp_rd = 7;
+
+	/*
+	 * AGP Enable.
+	 */
+	pctl.pctl_r_bits.apctl_v_agp_en = agp->mode.bits.enable;
+
+	/* Tell the user.  */
+	printk("Enabling AGP: %dX%s\n", 
+	       1 << pctl.pctl_r_bits.apctl_v_agp_rate,
+	       pctl.pctl_r_bits.apctl_v_agp_sba_en ? " - SBA" : "");
+	       
+	/* Write it.  */
+	port->pctl.csr = pctl.pctl_q_whole;
+	
+	/* And wait at least 5000 66MHz cycles (per Titan spec).  */
+	udelay(100);
+
+	return 0;
+}
+
+static int 
+titan_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem)
+{
+	struct titan_agp_aperture *aper = agp->aperture.sysdata;
+	return iommu_bind(aper->arena, aper->pg_start + pg_start, 
+			  mem->page_count, mem->memory);
+}
+
+static int 
+titan_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem)
+{
+	struct titan_agp_aperture *aper = agp->aperture.sysdata;
+	return iommu_unbind(aper->arena, aper->pg_start + pg_start,
+			    mem->page_count);
+}
+
+static unsigned long
+titan_agp_translate(alpha_agp_info *agp, dma_addr_t addr)
+{
+	struct titan_agp_aperture *aper = agp->aperture.sysdata;
+	unsigned long baddr = addr - aper->arena->dma_base;
+	unsigned long pte;
+
+	if (addr < agp->aperture.bus_base ||
+	    addr >= agp->aperture.bus_base + agp->aperture.size) {
+		printk("%s: addr out of range\n", __FUNCTION__);
+		return -EINVAL;
+	}
 
-	process_mcheck_info(vector, la_ptr, regs, "TITAN",
-			    mcheck_expected(smp_processor_id()));
+	pte = aper->arena->ptes[baddr >> PAGE_SHIFT];
+	if (!(pte & 1)) {
+		printk("%s: pte not valid\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	return (pte >> 1) << PAGE_SHIFT;
 }
 
+struct alpha_agp_ops titan_agp_ops =
+{
+	setup:		titan_agp_setup,
+	cleanup:	titan_agp_cleanup,
+	configure:	titan_agp_configure,
+	bind:		titan_agp_bind_memory,
+	unbind:		titan_agp_unbind_memory,
+	translate:	titan_agp_translate
+};
+
+alpha_agp_info *
+titan_agp_info(void)
+{
+	alpha_agp_info *agp;
+	struct pci_controller *hose;
+	titan_pachip_port *port;
+	int hosenum = -1;
+	union TPAchipPCTL pctl;
+
+	/*
+	 * Find the AGP port.
+	 */
+	port = &TITAN_pachip0->a_port;
+	if (titan_query_agp(port))
+		hosenum = 2;
+	if (hosenum < 0 && 
+	    titan_query_agp(port = &TITAN_pachip1->a_port)) 
+		hosenum = 3;
+	
+	/*
+	 * Find the hose the port is on.
+	 */
+	for (hose = hose_head; hose; hose = hose->next)
+		if (hose->index == hosenum)
+			break;
+
+	if (!hose || !hose->sg_pci)
+		return NULL;
+
+	/*
+	 * Allocate the info structure.
+	 */
+	agp = kmalloc(sizeof(*agp), GFP_KERNEL);
+
+	/*
+	 * Fill it in.
+	 */
+	agp->type = 0 /* FIXME: ALPHA_CORE_AGP */;
+	agp->hose = hose;
+	agp->private = port;
+	agp->ops = &titan_agp_ops;
+
+	/*
+	 * Aperture - not configured until ops.setup().
+	 *
+	 * FIXME - should we go ahead and allocate it here?
+	 */
+	agp->aperture.bus_base = 0;
+	agp->aperture.size = 0;
+	agp->aperture.sysdata = NULL;
+
+	/*
+	 * Capabilities.
+	 */
+	agp->capability.lw = 0;
+	agp->capability.bits.rate = 3; 	/* 2x, 1x */
+	agp->capability.bits.sba = 1;
+	agp->capability.bits.rq = 7;	/* 8 - 1 */
+
+	/*
+	 * Mode.
+	 */
+	pctl.pctl_q_whole = port->pctl.csr;
+	agp->mode.lw = 0;
+	agp->mode.bits.rate = 1 << pctl.pctl_r_bits.apctl_v_agp_rate;
+	agp->mode.bits.sba = pctl.pctl_r_bits.apctl_v_agp_sba_en;
+	agp->mode.bits.rq = 7;	/* RQ Depth? */
+	agp->mode.bits.enable = pctl.pctl_r_bits.apctl_v_agp_en;
+
+	return agp;
+}
diff -Nru a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c
--- a/arch/alpha/kernel/core_tsunami.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/core_tsunami.c	Thu Jan 16 18:23:05 2003
@@ -357,7 +357,6 @@
 tsunami_init_arch(void)
 {
 #ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
-	extern asmlinkage void entInt(void);
 	unsigned long tmp;
 	
 	/* Ho hum.. init_arch is called before init_IRQ, but we need to be
diff -Nru a/arch/alpha/kernel/core_wildfire.c b/arch/alpha/kernel/core_wildfire.c
--- a/arch/alpha/kernel/core_wildfire.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/core_wildfire.c	Thu Jan 16 18:23:05 2003
@@ -442,6 +442,33 @@
 	.write =	wildfire_write_config,
 };
 
+
+/*
+ * NUMA Support
+ */
+int wildfire_pa_to_nid(unsigned long pa)
+{
+	return pa >> 36;
+}
+
+int wildfire_cpuid_to_nid(int cpuid)
+{
+	/* assume 4 CPUs per node */
+	return cpuid >> 2;
+}
+
+unsigned long wildfire_node_mem_start(int nid)
+{
+	/* 64GB per node */
+	return (unsigned long)nid * (64UL * 1024 * 1024 * 1024);
+}
+
+unsigned long wildfire_node_mem_size(int nid)
+{
+	/* 64GB per node */
+	return 64UL * 1024 * 1024 * 1024;
+}
+
 #if DEBUG_DUMP_REGS
 
 static void __init
diff -Nru a/arch/alpha/kernel/err_impl.h b/arch/alpha/kernel/err_impl.h
--- a/arch/alpha/kernel/err_impl.h	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/err_impl.h	Thu Jan 16 18:23:05 2003
@@ -146,3 +146,17 @@
 extern int cdl_register_subpacket_annotation(struct el_subpacket_annotation *);
 extern int cdl_register_subpacket_handler(struct el_subpacket_handler *);
 
+/*
+ * err_marvel.c
+ */
+extern void marvel_machine_check(u64, u64, struct pt_regs *);
+extern void marvel_register_error_handlers(void);
+
+/*
+ * err_titan.c
+ */
+extern int titan_process_logout_frame(struct el_common *, int);
+extern void titan_machine_check(u64, u64, struct pt_regs *);
+extern void titan_register_error_handlers(void);
+extern int privateer_process_logout_frame(struct el_common *, int);
+extern void privateer_machine_check(u64, u64, struct pt_regs *);
diff -Nru a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/kernel/err_marvel.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,57 @@
+/*
+ *	linux/arch/alpha/kernel/err_marvel.c
+ *
+ *	Copyright (C) 2001 Jeff Wiedemeier (Compaq Computer Corporation)
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/console.h>
+#include <asm/core_marvel.h>
+#include <asm/hwrpb.h>
+#include <asm/smp.h>
+
+#include "err_impl.h"
+#include "proto.h"
+
+
+void
+marvel_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+{
+	struct el_subpacket *el_ptr = (struct el_subpacket *)la_ptr;
+
+	/*
+	 * Sync the processor
+	 */
+	mb();
+	draina();
+
+	el_process_subpacket(el_ptr);
+
+	switch(vector) {
+	case SCB_Q_SYSEVENT:
+		printk(KERN_CRIT "MARVEL SYSEVENT %ld\n", vector);
+		break;
+	case SCB_Q_SYSMCHK:
+	case SCB_Q_SYSERR:
+		printk(KERN_CRIT "MARVEL SYSMCHK/ERR %ld\n", vector);
+		break;
+	default:
+		/* Don't know it - pass it up.  */
+		return ev7_machine_check(vector, la_ptr, regs);
+	}	
+
+        /* Release the logout frame.  */
+	wrmces(0x7);
+	mb();
+}
+
+void
+marvel_register_error_handlers(void)
+{
+	ev7_register_error_handlers();
+}
diff -Nru a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/kernel/err_titan.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,747 @@
+/*
+ *	linux/arch/alpha/kernel/err_titan.c
+ *
+ *	Copyright (C) 2000 Jeff Wiedemeier (Compaq Computer Corporation)
+ *
+ *	Error handling code supporting TITAN systems
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/core_titan.h>
+#include <asm/hwrpb.h>
+#include <asm/smp.h>
+
+#include "err_impl.h"
+#include "proto.h"
+
+
+static int
+titan_parse_c_misc(u64 c_misc, int print)
+{
+	char *src;
+	int nxs = 0;
+	int status = MCHK_DISPOSITION_REPORT;
+
+#define TITAN__CCHIP_MISC__NXM		(1UL << 28)
+#define TITAN__CCHIP_MISC__NXS__S	(29)
+#define TITAN__CCHIP_MISC__NXS__M	(0x7)
+
+	if (!(c_misc & TITAN__CCHIP_MISC__NXM))
+		return MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+#ifdef CONFIG_VERBOSE_MCHECK
+	if (!print)
+		return status;
+
+	nxs = EXTRACT(c_misc, TITAN__CCHIP_MISC__NXS);
+	switch(nxs) {
+	case 0:	/* CPU 0 */
+	case 1:	/* CPU 1 */
+	case 2:	/* CPU 2 */
+	case 3:	/* CPU 3 */
+		src = "CPU";
+		/* num is already the CPU number */
+		break;
+	case 4:	/* Pchip 0 */
+	case 5:	/* Pchip 1 */
+		src = "Pchip";
+		nxs -= 4;
+		break;
+	default:/* reserved */
+		src = "Unknown, NXS =";
+		/* leave num untouched */
+		break;
+	}
+
+	printk("%s    Non-existent memory access from: %s %d\n", 
+	       err_print_prefix, src, nxs);
+#endif /* CONFIG_VERBOSE_MCHECK */
+
+	return status;
+}
+
+static int
+titan_parse_p_serror(int which, u64 serror, int print)
+{
+	int status = MCHK_DISPOSITION_REPORT;
+
+#ifdef CONFIG_VERBOSE_MCHECK
+	char *serror_src[] = {"GPCI", "APCI", "AGP HP", "AGP LP"};
+	char *serror_cmd[] = {"DMA Read", "DMA RMW", "SGTE Read", "Reserved"};
+#endif /* CONFIG_VERBOSE_MCHECK */
+
+#define TITAN__PCHIP_SERROR__LOST_UECC	(1UL << 0)
+#define TITAN__PCHIP_SERROR__UECC	(1UL << 1)
+#define TITAN__PCHIP_SERROR__CRE	(1UL << 2)
+#define TITAN__PCHIP_SERROR__NXIO	(1UL << 3)
+#define TITAN__PCHIP_SERROR__LOST_CRE	(1UL << 4)
+#define TITAN__PCHIP_SERROR__ECCMASK	(TITAN__PCHIP_SERROR__UECC |	  \
+					 TITAN__PCHIP_SERROR__CRE)
+#define TITAN__PCHIP_SERROR__ERRMASK	(TITAN__PCHIP_SERROR__LOST_UECC | \
+					 TITAN__PCHIP_SERROR__UECC |	  \
+					 TITAN__PCHIP_SERROR__CRE |	  \
+					 TITAN__PCHIP_SERROR__NXIO |	  \
+					 TITAN__PCHIP_SERROR__LOST_CRE)
+#define TITAN__PCHIP_SERROR__SRC__S	(52)
+#define TITAN__PCHIP_SERROR__SRC__M	(0x3)
+#define TITAN__PCHIP_SERROR__CMD__S	(54)
+#define TITAN__PCHIP_SERROR__CMD__M	(0x3)
+#define TITAN__PCHIP_SERROR__SYN__S	(56)
+#define TITAN__PCHIP_SERROR__SYN__M	(0xff)
+#define TITAN__PCHIP_SERROR__ADDR__S	(15)
+#define TITAN__PCHIP_SERROR__ADDR__M	(0xffffffffUL)
+
+	if (!(serror & TITAN__PCHIP_SERROR__ERRMASK))
+		return MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+#ifdef CONFIG_VERBOSE_MCHECK
+	if (!print)
+		return status;
+
+	printk("%s  PChip %d SERROR: %016lx\n", 
+	       err_print_prefix, which, serror);
+	if (serror & TITAN__PCHIP_SERROR__ECCMASK) {
+		printk("%s    %sorrectable ECC Error:\n"
+		       "      Source: %-6s  Command: %-8s  Syndrome: 0x%08x\n"
+		       "      Address: 0x%lx\n", 
+		       err_print_prefix,
+		       (serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C",
+		       serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)],
+		       serror_cmd[EXTRACT(serror, TITAN__PCHIP_SERROR__CMD)],
+		       (unsigned)EXTRACT(serror, TITAN__PCHIP_SERROR__SYN),
+		       EXTRACT(serror, TITAN__PCHIP_SERROR__ADDR));
+	}
+	if (serror & TITAN__PCHIP_SERROR__NXIO)
+		printk("%s    Non Existent I/O Error\n", err_print_prefix);
+	if (serror & TITAN__PCHIP_SERROR__LOST_UECC)
+		printk("%s    Lost Uncorrectable ECC Error\n", 
+		       err_print_prefix);
+	if (serror & TITAN__PCHIP_SERROR__LOST_CRE)
+		printk("%s    Lost Correctable ECC Error\n", err_print_prefix);
+#endif /* CONFIG_VERBOSE_MCHECK */
+
+	return status;
+}
+
+static int 
+titan_parse_p_perror(int which, int port, u64 perror, int print)
+{
+	int cmd;
+	unsigned long addr;
+	int status = MCHK_DISPOSITION_REPORT;
+
+#ifdef CONFIG_VERBOSE_MCHECK
+	char *perror_cmd[] = { "Interrupt Acknowledge", "Special Cycle",
+			       "I/O Read",	       	"I/O Write",
+			       "Reserved",	       	"Reserved",
+			       "Memory Read",		"Memory Write",
+			       "Reserved",		"Reserved",
+			       "Configuration Read",	"Configuration Write",
+			       "Memory Read Multiple",	"Dual Address Cycle",
+			       "Memory Read Line","Memory Write and Invalidate"
+	};
+#endif /* CONFIG_VERBOSE_MCHECK */
+
+#define TITAN__PCHIP_PERROR__LOST	(1UL << 0)
+#define TITAN__PCHIP_PERROR__SERR	(1UL << 1)
+#define TITAN__PCHIP_PERROR__PERR	(1UL << 2)
+#define TITAN__PCHIP_PERROR__DCRTO	(1UL << 3)
+#define TITAN__PCHIP_PERROR__SGE	(1UL << 4)
+#define TITAN__PCHIP_PERROR__APE	(1UL << 5)
+#define TITAN__PCHIP_PERROR__TA		(1UL << 6)
+#define TITAN__PCHIP_PERROR__DPE	(1UL << 7)
+#define TITAN__PCHIP_PERROR__NDS	(1UL << 8)
+#define TITAN__PCHIP_PERROR__IPTPR	(1UL << 9)
+#define TITAN__PCHIP_PERROR__IPTPW	(1UL << 10)
+#define TITAN__PCHIP_PERROR__ERRMASK	(TITAN__PCHIP_PERROR__LOST |	\
+					 TITAN__PCHIP_PERROR__SERR |	\
+					 TITAN__PCHIP_PERROR__PERR |	\
+					 TITAN__PCHIP_PERROR__DCRTO |	\
+					 TITAN__PCHIP_PERROR__SGE |	\
+					 TITAN__PCHIP_PERROR__APE |	\
+					 TITAN__PCHIP_PERROR__TA |	\
+					 TITAN__PCHIP_PERROR__DPE |	\
+					 TITAN__PCHIP_PERROR__NDS |	\
+					 TITAN__PCHIP_PERROR__IPTPR |	\
+					 TITAN__PCHIP_PERROR__IPTPW)
+#define TITAN__PCHIP_PERROR__DAC	(1UL << 47)
+#define TITAN__PCHIP_PERROR__MWIN	(1UL << 48)
+#define TITAN__PCHIP_PERROR__CMD__S	(52)
+#define TITAN__PCHIP_PERROR__CMD__M	(0x0f)
+#define TITAN__PCHIP_PERROR__ADDR__S	(14)
+#define TITAN__PCHIP_PERROR__ADDR__M	(0x1ffffffff)
+
+	if (!(perror & TITAN__PCHIP_PERROR__ERRMASK))
+		return MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+	cmd = EXTRACT(perror, TITAN__PCHIP_PERROR__CMD);
+	addr = EXTRACT(perror, TITAN__PCHIP_PERROR__ADDR) << 2;
+
+	/*
+	 * Initializing the BIOS on a video card on a bus without
+	 * a south bridge (subtractive decode agent) can result in 
+	 * master aborts as the BIOS probes the capabilities of the
+	 * card. XFree86 does such initialization. If the error
+	 * is a master abort (No DevSel as PCI Master) and the command
+	 * is an I/O read or write below the address where we start
+	 * assigning PCI I/O spaces (SRM uses 0x1000), then mark the
+	 * error as dismissable so starting XFree86 doesn't result
+	 * in a series of uncorrectable errors being reported. Also
+	 * dismiss master aborts to VGA frame buffer space
+	 * (0xA0000 - 0xC0000) and legacy BIOS space (0xC0000 - 0x100000)
+	 * for the same reason.
+	 *
+	 * Also mark the error dismissible if it looks like the right
+	 * error but only the Lost bit is set. Since the BIOS initialization
+	 * can cause multiple master aborts and the error interrupt can
+	 * be handled on a different CPU than the BIOS code is run on,
+	 * it is possible for a second master abort to occur between the
+	 * time the PALcode reads PERROR and the time it writes PERROR
+	 * to acknowledge the error. If this timing happens, a second
+	 * error will be signalled after the first, and if no additional
+	 * errors occur, will look like a Lost error with no additional 
+	 * errors on the same transaction as the previous error.
+	 */
+	if (((perror & TITAN__PCHIP_PERROR__NDS) || 
+	     ((perror & TITAN__PCHIP_PERROR__ERRMASK) == 
+	      TITAN__PCHIP_PERROR__LOST)) &&
+	    ((((cmd & 0xE) == 2) && (addr < 0x1000)) ||
+	     (((cmd & 0xE) == 6) && (addr >= 0xA0000) && (addr < 0x100000)))) {
+		status = MCHK_DISPOSITION_DISMISS;
+	}
+
+#ifdef CONFIG_VERBOSE_MCHECK
+	if (!print) 
+		return status;
+
+	printk("%s  PChip %d %cPERROR: %016lx\n", 
+	       err_print_prefix, which, 
+	       port ? 'A' : 'G', perror);
+	if (perror & TITAN__PCHIP_PERROR__IPTPW)
+		printk("%s    Invalid Peer-to-Peer Write\n", err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__IPTPR)
+		printk("%s    Invalid Peer-to-Peer Read\n", err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__NDS)
+		printk("%s    No DEVSEL as PCI Master [Master Abort]\n",
+		       err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__DPE)
+		printk("%s    Data Parity Error\n", err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__TA)
+		printk("%s    Target Abort\n", err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__APE)
+		printk("%s    Address Parity Error\n", err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__SGE)
+		printk("%s    Scatter-Gather Error, Invalid PTE\n", 
+		       err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__DCRTO)
+		printk("%s    Delayed-Completion Retry Timeout\n", 
+		       err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__PERR)
+		printk("%s    PERR Asserted\n", err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__SERR)
+		printk("%s    SERR Asserted\n", err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__LOST)
+		printk("%s    Lost Error\n", err_print_prefix);
+	printk("%s      Command: 0x%x - %s\n"
+		 "      Address: 0x%lx\n",
+	       err_print_prefix,
+	       cmd, perror_cmd[cmd],
+	       addr);
+	if (perror & TITAN__PCHIP_PERROR__DAC)
+		printk("%s      Dual Address Cycle\n", err_print_prefix);
+	if (perror & TITAN__PCHIP_PERROR__MWIN)
+		printk("%s      Hit in Monster Window\n", err_print_prefix);
+#endif /* CONFIG_VERBOSE_MCHECK */
+
+	return status;
+}
+
+static int
+titan_parse_p_agperror(int which, u64 agperror, int print)
+{
+	int cmd, len;
+	unsigned long addr;
+	int status = MCHK_DISPOSITION_REPORT;
+
+#ifdef CONFIG_VERBOSE_MCHECK
+	char *agperror_cmd[] = { "Read (low-priority)",	"Read (high-priority)",
+				 "Write (low-priority)",
+				 "Write (high-priority)",
+				 "Reserved",		"Reserved",
+				 "Flush",		"Fence"
+	};
+#endif /* CONFIG_VERBOSE_MCHECK */
+
+#define TITAN__PCHIP_AGPERROR__LOST	(1UL << 0)
+#define TITAN__PCHIP_AGPERROR__LPQFULL	(1UL << 1)
+#define TITAN__PCHIP_AGPERROR__HPQFULL	(1UL << 2)
+#define TITAN__PCHIP_AGPERROR__RESCMD	(1UL << 3)
+#define TITAN__PCHIP_AGPERROR__IPTE	(1UL << 4)
+#define TITAN__PCHIP_AGPERROR__PTP	(1UL << 5)
+#define TITAN__PCHIP_AGPERROR__NOWINDOW	(1UL << 6)
+#define TITAN__PCHIP_AGPERROR__ERRMASK	(TITAN__PCHIP_AGPERROR__LOST |    \
+					 TITAN__PCHIP_AGPERROR__LPQFULL | \
+					 TITAN__PCHIP_AGPERROR__HPQFULL | \
+					 TITAN__PCHIP_AGPERROR__RESCMD |  \
+					 TITAN__PCHIP_AGPERROR__IPTE |    \
+					 TITAN__PCHIP_AGPERROR__PTP |     \
+					 TITAN__PCHIP_AGPERROR__NOWINDOW)
+#define TITAN__PCHIP_AGPERROR__DAC	(1UL << 48)
+#define TITAN__PCHIP_AGPERROR__MWIN	(1UL << 49)
+#define TITAN__PCHIP_AGPERROR__FENCE	(1UL << 59)
+#define TITAN__PCHIP_AGPERROR__CMD__S	(50)
+#define TITAN__PCHIP_AGPERROR__CMD__M	(0x07)
+#define TITAN__PCHIP_AGPERROR__ADDR__S	(15)
+#define TITAN__PCHIP_AGPERROR__ADDR__M  (0xffffffffUL)
+#define TITAN__PCHIP_AGPERROR__LEN__S	(53)
+#define TITAN__PCHIP_AGPERROR__LEN__M	(0x3f)
+
+	if (!(agperror & TITAN__PCHIP_AGPERROR__ERRMASK))
+		return MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+#ifdef CONFIG_VERBOSE_MCHECK
+	if (!print)
+		return status;
+
+	cmd = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__CMD);
+	addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3;
+	len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN);
+
+	printk("%s  PChip %d AGPERROR: %016lx\n", err_print_prefix,
+	       which, agperror);
+	if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW)
+		printk("%s    No Window\n", err_print_prefix);
+	if (agperror & TITAN__PCHIP_AGPERROR__PTP)
+		printk("%s    Peer-to-Peer set\n", err_print_prefix);
+	if (agperror & TITAN__PCHIP_AGPERROR__IPTE)
+		printk("%s    Invalid PTE\n", err_print_prefix);
+	if (agperror & TITAN__PCHIP_AGPERROR__RESCMD)
+		printk("%s    Reserved Command\n", err_print_prefix);
+	if (agperror & TITAN__PCHIP_AGPERROR__HPQFULL)
+		printk("%s    HP Transaction Received while Queue Full\n", 
+		       err_print_prefix);
+	if (agperror & TITAN__PCHIP_AGPERROR__LPQFULL)
+		printk("%s    LP Transaction Received while Queue Full\n", 
+		       err_print_prefix);
+	if (agperror & TITAN__PCHIP_AGPERROR__LOST)
+		printk("%s    Lost Error\n", err_print_prefix);
+	printk("%s      Command: 0x%x - %s, %d Quadwords%s\n"
+		 "      Address: 0x%lx\n",
+	       err_print_prefix, cmd, agperror_cmd[cmd], len,
+	       (agperror & TITAN__PCHIP_AGPERROR__FENCE) ? ", FENCE" : "",
+	       addr);
+	if (agperror & TITAN__PCHIP_AGPERROR__DAC)
+		printk("%s      Dual Address Cycle\n", err_print_prefix);
+	if (agperror & TITAN__PCHIP_AGPERROR__MWIN)
+		printk("%s      Hit in Monster Window\n", err_print_prefix);
+#endif /* CONFIG_VERBOSE_MCHECK */
+
+	return status;
+}	
+
+static int
+titan_parse_p_chip(int which, u64 serror, u64 gperror, 
+		   u64 aperror, u64 agperror, int print)
+{
+	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
+	status |= titan_parse_p_serror(which, serror, print);
+	status |= titan_parse_p_perror(which, 0, gperror, print);
+	status |= titan_parse_p_perror(which, 1, aperror, print);
+	status |= titan_parse_p_agperror(which, agperror, print);
+	return status;
+}
+
+int
+titan_process_logout_frame(struct el_common *mchk_header, int print)
+{
+	struct el_TITAN_sysdata_mcheck *tmchk =
+		(struct el_TITAN_sysdata_mcheck *)
+		((unsigned long)mchk_header + mchk_header->sys_offset);
+	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+	status |= titan_parse_c_misc(tmchk->c_misc, print);
+	status |= titan_parse_p_chip(0, tmchk->p0_serror, tmchk->p0_gperror,
+				     tmchk->p0_aperror, tmchk->p0_agperror, 
+				     print);
+	status |= titan_parse_p_chip(1, tmchk->p1_serror, tmchk->p1_gperror,
+				     tmchk->p1_aperror, tmchk->p1_agperror, 
+				     print);
+
+	return status;
+}
+
+void
+titan_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+{
+	struct el_common *mchk_header = (struct el_common *)la_ptr;
+	struct el_TITAN_sysdata_mcheck *tmchk =
+		(struct el_TITAN_sysdata_mcheck *)
+		((unsigned long)mchk_header + mchk_header->sys_offset);
+	u64 irqmask;
+
+	/*
+	 * Mask of Titan interrupt sources which are reported as machine checks
+	 *
+	 * 63 - CChip Error
+	 * 62 - PChip 0 H_Error
+	 * 61 - PChip 1 H_Error
+	 * 60 - PChip 0 C_Error
+	 * 59 - PChip 1 C_Error
+	 */
+#define TITAN_MCHECK_INTERRUPT_MASK	0xF800000000000000UL
+
+	/*
+	 * Sync the processor
+	 */
+	mb();
+	draina();
+	
+	/*
+	 * Only handle system errors here 
+	 */
+	if ((vector != SCB_Q_SYSMCHK) && (vector != SCB_Q_SYSERR)) 
+		return ev6_machine_check(vector, la_ptr, regs);
+
+	/* 
+	 * It's a system error, handle it here
+	 *
+	 * The PALcode has already cleared the error, so just parse it
+	 */
+	
+	/* 
+	 * Parse the logout frame without printing first. If the only error(s)
+	 * found are classified as "dismissable", then just dismiss them and
+	 * don't print any message
+	 */
+	if (titan_process_logout_frame(mchk_header, 0) != 
+	    MCHK_DISPOSITION_DISMISS) {
+		char *saved_err_prefix = err_print_prefix;
+		err_print_prefix = KERN_CRIT;
+
+		/*
+		 * Either a nondismissable error was detected or no
+		 * recognized error was detected  in the logout frame 
+		 * -- report the error in either case
+		 */
+		printk("%s"
+		       "*System %s Error (Vector 0x%x) reported on CPU %d:\n", 
+		       err_print_prefix,
+		       (vector == SCB_Q_SYSERR)?"Correctable":"Uncorrectable",
+		       (unsigned int)vector, (int)smp_processor_id());
+		
+#ifdef CONFIG_VERBOSE_MCHECK
+		titan_process_logout_frame(mchk_header, 1);
+		dik_show_regs(regs, NULL);
+#endif /* CONFIG_VERBOSE_MCHECK */
+
+		err_print_prefix = saved_err_prefix;
+
+		/*
+		 * Convert any pending interrupts which report as system
+		 * machine checks to interrupts
+		 */
+		irqmask = tmchk->c_dirx & TITAN_MCHECK_INTERRUPT_MASK;
+		titan_dispatch_irqs(irqmask, regs);
+	}	
+
+
+	/* 
+	 * Release the logout frame 
+	 */
+	wrmces(0x7);
+	mb();
+}
+
+/*
+ * Subpacket Annotations
+ */
+static char *el_titan_pchip0_extended_annotation[] = {
+	"Subpacket Header", 	"P0_SCTL",	"P0_SERREN",
+	"P0_APCTL",		"P0_APERREN",	"P0_AGPERREN",
+	"P0_ASPRST",		"P0_AWSBA0",	"P0_AWSBA1",
+	"P0_AWSBA2",		"P0_AWSBA3",	"P0_AWSM0",
+	"P0_AWSM1",		"P0_AWSM2",	"P0_AWSM3",
+	"P0_ATBA0",		"P0_ATBA1",	"P0_ATBA2",
+	"P0_ATBA3",		"P0_GPCTL",	"P0_GPERREN",
+	"P0_GSPRST",		"P0_GWSBA0",	"P0_GWSBA1",
+	"P0_GWSBA2",		"P0_GWSBA3",	"P0_GWSM0",
+	"P0_GWSM1",		"P0_GWSM2",	"P0_GWSM3",
+	"P0_GTBA0",		"P0_GTBA1",	"P0_GTBA2",
+	"P0_GTBA3",		NULL 
+};
+static char *el_titan_pchip1_extended_annotation[] = {
+	"Subpacket Header", 	"P1_SCTL",	"P1_SERREN",
+	"P1_APCTL",		"P1_APERREN",	"P1_AGPERREN",
+	"P1_ASPRST",		"P1_AWSBA0",	"P1_AWSBA1",
+	"P1_AWSBA2",		"P1_AWSBA3",	"P1_AWSM0",
+	"P1_AWSM1",		"P1_AWSM2",	"P1_AWSM3",
+	"P1_ATBA0",		"P1_ATBA1",	"P1_ATBA2",
+	"P1_ATBA3",		"P1_GPCTL",	"P1_GPERREN",
+	"P1_GSPRST",		"P1_GWSBA0",	"P1_GWSBA1",
+	"P1_GWSBA2",		"P1_GWSBA3",	"P1_GWSM0",
+	"P1_GWSM1",		"P1_GWSM2",	"P1_GWSM3",
+	"P1_GTBA0",		"P1_GTBA1",	"P1_GTBA2",
+	"P1_GTBA3",		NULL 
+};
+static char *el_titan_memory_extended_annotation[] = {
+	"Subpacket Header", 	"AAR0",		"AAR1",
+	"AAR2",			"AAR3",		"P0_SCTL",
+	"P0_GPCTL",		"P0_APCTL",	"P1_SCTL",
+	"P1_GPCTL",		"P1_SCTL",	NULL 
+};
+
+static struct el_subpacket_annotation el_titan_annotations[] = {
+	SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
+			     EL_TYPE__REGATTA__TITAN_PCHIP0_EXTENDED,
+			     1,
+			     "Titan PChip 0 Extended Frame",
+			     el_titan_pchip0_extended_annotation),
+	SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
+			     EL_TYPE__REGATTA__TITAN_PCHIP1_EXTENDED,
+			     1,
+			     "Titan PChip 1 Extended Frame",
+			     el_titan_pchip1_extended_annotation),
+	SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
+			     EL_TYPE__REGATTA__TITAN_MEMORY_EXTENDED,
+			     1,
+			     "Titan Memory Extended Frame",
+			     el_titan_memory_extended_annotation),
+	SUBPACKET_ANNOTATION(EL_CLASS__REGATTA_FAMILY,
+			     EL_TYPE__TERMINATION__TERMINATION,
+			     1,
+			     "Termination Subpacket",
+			     NULL)
+};
+
+static struct el_subpacket *
+el_process_regatta_subpacket(struct el_subpacket *header)
+{
+	int status;
+
+	if (header->class != EL_CLASS__REGATTA_FAMILY) {
+		printk("%s  ** Unexpected header CLASS %d TYPE %d, aborting\n",
+		       err_print_prefix,
+		       header->class, header->type);
+		return NULL;
+	}
+
+	switch(header->type) {
+	case EL_TYPE__REGATTA__PROCESSOR_ERROR_FRAME:
+	case EL_TYPE__REGATTA__SYSTEM_ERROR_FRAME:
+	case EL_TYPE__REGATTA__ENVIRONMENTAL_FRAME:
+	case EL_TYPE__REGATTA__PROCESSOR_DBL_ERROR_HALT:
+	case EL_TYPE__REGATTA__SYSTEM_DBL_ERROR_HALT:
+		printk("%s  ** Occurred on CPU %d:\n", 
+		       err_print_prefix,
+		       (int)header->by_type.regatta_frame.cpuid);
+		status = privateer_process_logout_frame((struct el_common *)
+			header->by_type.regatta_frame.data_start, 1);
+		break;
+	default:
+		printk("%s  ** REGATTA TYPE %d SUBPACKET\n", 
+		       err_print_prefix, header->type);
+		el_annotate_subpacket(header);
+		break;
+	}
+
+
+	return (struct el_subpacket *)((unsigned long)header + header->length);
+} 
+
+static struct el_subpacket_handler titan_subpacket_handler = 
+	SUBPACKET_HANDLER_INIT(EL_CLASS__REGATTA_FAMILY, 
+			       el_process_regatta_subpacket);
+
+void
+titan_register_error_handlers(void)
+{
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE (el_titan_annotations); i++)
+		cdl_register_subpacket_annotation(&el_titan_annotations[i]);
+
+	cdl_register_subpacket_handler(&titan_subpacket_handler);
+}
+
+
+/*
+ * Privateer
+ */
+
+static int
+privateer_process_680_frame(struct el_common *mchk_header, int print)
+{
+	struct el_PRIVATEER_envdata_mcheck *emchk =
+		(struct el_PRIVATEER_envdata_mcheck *)
+		((unsigned long)mchk_header + mchk_header->sys_offset);
+	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+	/* TODO - catagorize errors, for now, no error */
+
+#ifdef CONFIG_VERBOSE_MCHECK
+	if (!print)
+		return status;
+
+	/* TODO - decode instead of just dumping... */
+	printk("%s  Summary Flags:         %016lx\n"
+ 	         "  CChip DIRx:            %016lx\n"
+		 "  System Management IR:  %016lx\n"
+		 "  CPU IR:                %016lx\n"
+		 "  Power Supply IR:       %016lx\n"
+		 "  LM78 Fault Status:     %016lx\n"
+		 "  System Doors:          %016lx\n"
+		 "  Temperature Warning:   %016lx\n"
+		 "  Fan Control:           %016lx\n"
+		 "  Fatal Power Down Code: %016lx\n",
+	       err_print_prefix,
+	       emchk->summary,
+	       emchk->c_dirx,
+	       emchk->smir,
+	       emchk->cpuir,
+	       emchk->psir,
+	       emchk->fault,
+	       emchk->sys_doors,
+	       emchk->temp_warn,
+	       emchk->fan_ctrl,
+	       emchk->code);
+#endif /* CONFIG_VERBOSE_MCHECK */
+
+	return status;
+}
+
+int
+privateer_process_logout_frame(struct el_common *mchk_header, int print)
+{
+	struct el_common_EV6_mcheck *ev6mchk = 
+		(struct el_common_EV6_mcheck *)mchk_header;
+	int status = MCHK_DISPOSITION_UNKNOWN_ERROR;
+
+	/*
+	 * Machine check codes
+	 */
+#define PRIVATEER_MCHK__CORR_ECC		0x86	/* 630 */
+#define PRIVATEER_MCHK__DC_TAG_PERR		0x9E	/* 630 */
+#define PRIVATEER_MCHK__PAL_BUGCHECK		0x8E	/* 670 */
+#define PRIVATEER_MCHK__OS_BUGCHECK		0x90	/* 670 */
+#define PRIVATEER_MCHK__PROC_HRD_ERR		0x98	/* 670 */
+#define PRIVATEER_MCHK__ISTREAM_CMOV_PRX	0xA0	/* 670 */
+#define PRIVATEER_MCHK__ISTREAM_CMOV_FLT	0xA2	/* 670 */
+#define PRIVATEER_MCHK__SYS_HRD_ERR		0x202	/* 660 */
+#define PRIVATEER_MCHK__SYS_CORR_ERR		0x204	/* 620 */
+#define PRIVATEER_MCHK__SYS_ENVIRON		0x206	/* 680 */
+
+	switch(ev6mchk->MCHK_Code) {
+	/*
+	 * Vector 630 - Processor, Correctable
+	 */
+	case PRIVATEER_MCHK__CORR_ECC:
+	case PRIVATEER_MCHK__DC_TAG_PERR:
+		/*
+		 * Fall through to vector 670 for processing...
+		 */
+	/*
+	 * Vector 670 - Processor, Uncorrectable
+	 */
+	case PRIVATEER_MCHK__PAL_BUGCHECK:
+	case PRIVATEER_MCHK__OS_BUGCHECK:
+	case PRIVATEER_MCHK__PROC_HRD_ERR:
+	case PRIVATEER_MCHK__ISTREAM_CMOV_PRX:
+	case PRIVATEER_MCHK__ISTREAM_CMOV_FLT:
+		status |= ev6_process_logout_frame(mchk_header, print);
+		break;
+
+	/*
+	 * Vector 620 - System, Correctable
+	 */
+	case PRIVATEER_MCHK__SYS_CORR_ERR:
+		/*
+		 * Fall through to vector 660 for processing...
+		 */
+	/*
+	 * Vector 660 - System, Uncorrectable
+	 */
+	case PRIVATEER_MCHK__SYS_HRD_ERR:
+		status |= titan_process_logout_frame(mchk_header, print);
+		break;
+
+	/* 
+	 * Vector 680 - System, Environmental
+	 */
+	case PRIVATEER_MCHK__SYS_ENVIRON:	/* System, Environmental */
+		status |= privateer_process_680_frame(mchk_header, print);
+		break;
+
+	/* 
+	 * Unknown
+	 */
+	default:
+		status |= MCHK_DISPOSITION_REPORT;
+		if (print) {
+			printk("%s** Unknown Error, frame follows\n", 
+			       err_print_prefix);
+			mchk_dump_logout_frame(mchk_header);
+		}
+
+	}
+
+	return status;
+}
+
+void
+privateer_machine_check(u64 vector, u64 la_ptr, struct pt_regs *regs)
+{
+	struct el_common *mchk_header = (struct el_common *)la_ptr;
+	struct el_TITAN_sysdata_mcheck *tmchk =
+		(struct el_TITAN_sysdata_mcheck *)
+		(la_ptr + mchk_header->sys_offset);
+	u64 irqmask;
+	char *saved_err_prefix = err_print_prefix;
+
+#define PRIVATEER_680_INTERRUPT_MASK		(0xE00UL)
+#define PRIVATEER_HOTPLUG_INTERRUPT_MASK	(0xE00UL)
+
+	/*
+	 * Sync the processor.
+	 */
+	mb();
+	draina();
+
+	/* 
+	 * Only handle system events here.
+	 */
+	if (vector != SCB_Q_SYSEVENT) 
+		return titan_machine_check(vector, la_ptr, regs);
+
+	/*
+	 * Report the event - System Events should be reported even if no
+	 * error is indicated since the event could indicate the return
+	 * to normal status.
+	 */
+	err_print_prefix = KERN_CRIT;
+	printk("%s*System Event (Vector 0x%x) reported on CPU %d:\n", 
+	       err_print_prefix,
+	       (unsigned int)vector, (int)smp_processor_id());
+	privateer_process_680_frame(mchk_header, 1);
+	err_print_prefix = saved_err_prefix;
+	
+	/* 
+	 * Convert any pending interrupts which report as 680 machine
+	 * checks to interrupts.
+	 */
+	irqmask = tmchk->c_dirx & PRIVATEER_680_INTERRUPT_MASK;
+
+	/*
+	 * Dispatch the interrupt(s).
+	 */
+	titan_dispatch_irqs(irqmask, regs);
+
+	/* 
+	 * Release the logout frame.
+	 */
+	wrmces(0x7);
+	mb();
+}
diff -Nru a/arch/alpha/kernel/gct.c b/arch/alpha/kernel/gct.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/kernel/gct.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,48 @@
+/*
+ *	linux/arch/alpha/kernel/gct.c
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+
+#include <asm/hwrpb.h>
+#include <asm/gct.h>
+
+int
+gct6_find_nodes(gct6_node *node, gct6_search_struct *search)
+{
+	gct6_search_struct *wanted;
+	int status = 0;
+
+	/* First check the magic number.  */
+	if (node->magic != GCT_NODE_MAGIC) {
+		printk(KERN_ERR "GCT Node MAGIC incorrect - GCT invalid\n");
+		return -EINVAL;
+	}
+
+	/* Check against the search struct.  */
+	for (wanted = search; 
+	     wanted && (wanted->type | wanted->subtype); 
+	     wanted++) {
+		if (node->type != wanted->type)
+			continue;
+		if (node->subtype != wanted->subtype)
+			continue;
+
+		/* Found it -- call out.  */
+		if (wanted->callout)
+			wanted->callout(node);
+	}
+
+	/* Now walk the tree, siblings first.  */
+	if (node->next) 
+		status |= gct6_find_nodes(GCT_NODE_PTR(node->next), search);
+
+	/* Then the children.  */
+	if (node->child) 
+		status |= gct6_find_nodes(GCT_NODE_PTR(node->child), search);
+
+	return status;
+}
diff -Nru a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
--- a/arch/alpha/kernel/irq.c	Thu Jan 16 18:23:06 2003
+++ b/arch/alpha/kernel/irq.c	Thu Jan 16 18:23:06 2003
@@ -213,7 +213,7 @@
 static struct proc_dir_entry * root_irq_dir;
 static struct proc_dir_entry * irq_dir[NR_IRQS];
 
-#ifdef CONFIG_SMP
+#ifdef CONFIG_SMP 
 static struct proc_dir_entry * smp_affinity_entry[NR_IRQS];
 static char irq_user_affinity[NR_IRQS];
 static unsigned long irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
@@ -361,16 +361,18 @@
 	/* create /proc/irq/1234 */
 	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
 
-#ifdef CONFIG_SMP
-	/* create /proc/irq/1234/smp_affinity */
-	entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
-
-	entry->nlink = 1;
-	entry->data = (void *)(long)irq;
-	entry->read_proc = irq_affinity_read_proc;
-	entry->write_proc = irq_affinity_write_proc;
+#ifdef CONFIG_SMP 
+	if (irq_desc[irq].handler->set_affinity) {
+		/* create /proc/irq/1234/smp_affinity */
+		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
+
+		entry->nlink = 1;
+		entry->data = (void *)(long)irq;
+		entry->read_proc = irq_affinity_read_proc;
+		entry->write_proc = irq_affinity_write_proc;
 
-	smp_affinity_entry[irq] = entry;
+		smp_affinity_entry[irq] = entry;
+	}
 #endif
 }
 
@@ -387,7 +389,7 @@
 	/* create /proc/irq */
 	root_irq_dir = proc_mkdir("irq", 0);
 
-#ifdef CONFIG_SMP
+#ifdef CONFIG_SMP 
 	/* create /proc/irq/prof_cpu_mask */
 	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
 
@@ -398,12 +400,16 @@
 #endif
 
 	/*
-	 * Create entries for all existing IRQs.
+	 * Create entries for all existing IRQs. If the number of IRQs
+	 * is greater the 1/4 the total dynamic inode space for /proc,
+	 * don't pollute the inode space
 	 */
-	for (i = 0; i < NR_IRQS; i++) {
-		if (irq_desc[i].handler == &no_irq_type)
-			continue;
-		register_irq_proc(i);
+	if (ACTUAL_NR_IRQS < (PROC_NDYNAMIC / 4)) {
+		for (i = 0; i < ACTUAL_NR_IRQS; i++) {
+			if (irq_desc[i].handler == &no_irq_type)
+				continue;
+			register_irq_proc(i);
+		}
 	}
 }
 
@@ -518,7 +524,7 @@
 	seq_putc(p, '\n');
 #endif
 
-	for (i = 0; i < NR_IRQS; i++) {
+	for (i = 0; i < ACTUAL_NR_IRQS; i++) {
 		action = irq_desc[i].action;
 		if (!action) 
 			continue;
diff -Nru a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
--- a/arch/alpha/kernel/machvec_impl.h	Thu Jan 16 18:23:06 2003
+++ b/arch/alpha/kernel/machvec_impl.h	Thu Jan 16 18:23:06 2003
@@ -9,10 +9,12 @@
 #include <linux/config.h>
 #include <asm/pgalloc.h>
 
-/* Whee.  IRONGATE, POLARIS, TSUNAMI, TITAN, and WILDFIRE don't have an HAE.
+/* Whee.  These systems don't have an HAE:
+       IRONGATE, MARVEL, POLARIS, TSUNAMI, TITAN, WILDFIRE
    Fix things up for the GENERIC kernel by defining the HAE address
    to be that of the cache. Now we can read and write it as we like.  ;-)  */
 #define IRONGATE_HAE_ADDRESS	(&alpha_mv.hae_cache)
+#define MARVEL_HAE_ADDRESS	(&alpha_mv.hae_cache)
 #define POLARIS_HAE_ADDRESS	(&alpha_mv.hae_cache)
 #define TSUNAMI_HAE_ADDRESS	(&alpha_mv.hae_cache)
 #define TITAN_HAE_ADDRESS	(&alpha_mv.hae_cache)
@@ -32,7 +34,6 @@
 #define T2_IACK_SC		1
 #define WILDFIRE_IACK_SC	1 /* FIXME */
 
-
 /*
  * Some helpful macros for filling in the blanks.
  */
@@ -63,6 +64,13 @@
 	mv_flush_tlb_current:		ev5_flush_tlb_current,		\
 	mv_flush_tlb_current_page:	ev5_flush_tlb_current_page
 
+#define DO_EV7_MMU							\
+	max_asn:			EV6_MAX_ASN,			\
+	mv_switch_mm:			ev5_switch_mm,			\
+	mv_activate_mm:			ev5_activate_mm,		\
+	mv_flush_tlb_current:		ev5_flush_tlb_current,		\
+	mv_flush_tlb_current_page:	ev5_flush_tlb_current_page
+
 #define IO_LITE(UP,low)							\
 	hae_register:		(unsigned long *) CAT(UP,_HAE_ADDRESS),	\
 	iack_sc:		CAT(UP,_IACK_SC),			\
@@ -91,6 +99,7 @@
 #define DO_CIA_IO	IO(CIA,cia)
 #define DO_IRONGATE_IO	IO(IRONGATE,irongate)
 #define DO_LCA_IO	IO(LCA,lca)
+#define DO_MARVEL_IO	IO(MARVEL,marvel)
 #define DO_MCPCIA_IO	IO(MCPCIA,mcpcia)
 #define DO_POLARIS_IO	IO(POLARIS,polaris)
 #define DO_T2_IO	IO(T2,t2)
@@ -109,13 +118,13 @@
 #define DO_CIA_BUS	BUS(cia)
 #define DO_IRONGATE_BUS	BUS(irongate)
 #define DO_LCA_BUS	BUS(lca)
+#define DO_MARVEL_BUS	BUS(marvel)
 #define DO_MCPCIA_BUS	BUS(mcpcia)
 #define DO_POLARIS_BUS	BUS(polaris)
 #define DO_T2_BUS	BUS(t2)
 #define DO_TSUNAMI_BUS	BUS(tsunami)
 #define DO_TITAN_BUS	BUS(titan)
 #define DO_WILDFIRE_BUS	BUS(wildfire)
-
 
 /*
  * In a GENERIC kernel, we have lots of these vectors floating about,
diff -Nru a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
--- a/arch/alpha/kernel/osf_sys.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/osf_sys.c	Thu Jan 16 18:23:05 2003
@@ -465,18 +465,13 @@
 	unsigned long raddr;
 	long err;
 
-	lock_kernel();
 	err = sys_shmat(shmid, shmaddr, shmflg, &raddr);
-	if (err)
-		goto out;
+
 	/*
 	 * This works because all user-level addresses are
 	 * non-negative longs!
 	 */
-	err = raddr;
- out:
-	unlock_kernel();
-	return err;
+	return err ? err : (long)raddr;
 }
 
 
@@ -830,7 +825,7 @@
 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
 extern int do_getitimer(int which, struct itimerval *value);
 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
-asmlinkage int sys_utimes(char *, struct timeval *);
+extern asmlinkage int sys_utimes(char *, struct timeval *);
 extern int do_adjtimex(struct timex *);
 
 struct timeval32
diff -Nru a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
--- a/arch/alpha/kernel/pci.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/pci.c	Thu Jan 16 18:23:05 2003
@@ -42,6 +42,8 @@
 
 const char pci_hae0_name[] = "HAE0";
 
+/* Indicate whether we respect the PCI setup left by console. */
+int __initdata pci_probe_only;
 
 /*
  * The PCI controller list.
@@ -270,7 +272,11 @@
 		end = hose->mem_space->start + pci_mem_end;
 		if (hose->mem_space->end > end)
 			hose->mem_space->end = end;
-	}
+ 	} else if (pci_probe_only &&
+ 		   (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ 		pci_read_bridge_bases(bus);
+ 		pcibios_fixup_device_resources(dev, bus);
+	} 
 
 	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
 		struct pci_dev *dev = pci_dev_b(ln);
@@ -407,6 +413,30 @@
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
 }
 
+static void __init
+pcibios_claim_console_setup(void)
+{
+	struct list_head *lb;
+
+	for(lb = pci_root_buses.next; lb != &pci_root_buses; lb = lb->next) {
+		struct pci_bus *b = pci_bus_b(lb);
+		struct list_head *ld;
+
+		for (ld = b->devices.next; ld != &b->devices; ld = ld->next) {
+			struct pci_dev *dev = pci_dev_b(ld);
+			int i;
+
+			for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+				struct resource *r = &dev->resource[i];
+
+				if (r->parent || !r->start || !r->flags)
+					continue;
+				pci_claim_resource(dev, i);
+			}
+		}
+	}
+}
+
 void __init
 common_init_pci(void)
 {
@@ -424,7 +454,12 @@
 		next_busno += 1;
 	}
 
-	pci_assign_unassigned_resources();
+	if (pci_probe_only)
+		pcibios_claim_console_setup();
+	else	/* FIXME: `else' will be removed when
+		   pci_assign_unassigned_resources() is able to work
+		   correctly with [partially] allocated PCI tree. */
+		pci_assign_unassigned_resources();
 	pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
 }
 
diff -Nru a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
--- a/arch/alpha/kernel/pci_impl.h	Thu Jan 16 18:23:06 2003
+++ b/arch/alpha/kernel/pci_impl.h	Thu Jan 16 18:23:06 2003
@@ -150,11 +150,18 @@
 extern struct pci_controller *hose_head, **hose_tail;
 extern struct pci_controller *pci_isa_hose;
 
+/* Indicate that we trust the console to configure things properly.  */
+extern int pci_probe_only;
+
 extern void common_init_pci(void);
 extern u8 common_swizzle(struct pci_dev *, u8 *);
 extern struct pci_controller *alloc_pci_controller(void);
 extern struct resource *alloc_resource(void);
 
+extern struct pci_iommu_arena *iommu_arena_new_node(int,
+						    struct pci_controller *,
+					            dma_addr_t, unsigned long,
+					            unsigned long);
 extern struct pci_iommu_arena *iommu_arena_new(struct pci_controller *,
 					       dma_addr_t, unsigned long,
 					       unsigned long);
diff -Nru a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
--- a/arch/alpha/kernel/pci_iommu.c	Thu Jan 16 18:23:07 2003
+++ b/arch/alpha/kernel/pci_iommu.c	Thu Jan 16 18:23:07 2003
@@ -58,8 +58,8 @@
 }
 
 struct pci_iommu_arena *
-iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
-		unsigned long window_size, unsigned long align)
+iommu_arena_new_node(int nid, struct pci_controller *hose, dma_addr_t base,
+		     unsigned long window_size, unsigned long align)
 {
 	unsigned long mem_size;
 	struct pci_iommu_arena *arena;
@@ -73,9 +73,36 @@
 	if (align < mem_size)
 		align = mem_size;
 
+
+#ifdef CONFIG_DISCONTIGMEM
+
+        if (!NODE_DATA(nid) ||
+            (NULL == (arena = alloc_bootmem_node(NODE_DATA(nid),
+                                                 sizeof(*arena))))) {
+                printk("%s: couldn't allocate arena from node %d\n"
+                       "    falling back to system-wide allocation\n",
+                       __FUNCTION__, nid);
+                arena = alloc_bootmem(sizeof(*arena));
+        }
+
+        if (!NODE_DATA(nid) ||
+            (NULL == (arena->ptes = __alloc_bootmem_node(NODE_DATA(nid),
+                                                         mem_size,
+                                                         align,
+                                                         0)))) {
+                printk("%s: couldn't allocate arena ptes from node %d\n"
+                       "    falling back to system-wide allocation\n",
+                       __FUNCTION__, nid);
+                arena->ptes = __alloc_bootmem(mem_size, align, 0);
+        }
+
+#else /* CONFIG_DISCONTIGMEM */
+
 	arena = alloc_bootmem(sizeof(*arena));
 	arena->ptes = __alloc_bootmem(mem_size, align, 0);
 
+#endif /* CONFIG_DISCONTIGMEM */
+
 	spin_lock_init(&arena->lock);
 	arena->hose = hose;
 	arena->dma_base = base;
@@ -87,6 +114,13 @@
 	arena->align_entry = 1;
 
 	return arena;
+}
+
+struct pci_iommu_arena *
+iommu_arena_new(struct pci_controller *hose, dma_addr_t base,
+		unsigned long window_size, unsigned long align)
+{
+	return iommu_arena_new_node(0, hose, base, window_size, align);
 }
 
 /* Must be called with the arena lock held */
diff -Nru a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
--- a/arch/alpha/kernel/proto.h	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/proto.h	Thu Jan 16 18:23:05 2003
@@ -1,4 +1,6 @@
 #include <linux/config.h>
+
+
 /* Prototypes of functions used across modules here in this directory.  */
 
 #define vucp	volatile unsigned char  *
@@ -41,6 +43,22 @@
 extern void lca_machine_check(u64, u64, struct pt_regs *);
 extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
 
+/* core_marvel.c */
+extern struct pci_ops marvel_pci_ops;
+extern void marvel_init_arch(void);
+extern void marvel_kill_arch(int);
+extern void marvel_machine_check(u64, u64, struct pt_regs *);
+extern void marvel_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
+extern int marvel_pa_to_nid(unsigned long);
+extern int marvel_cpuid_to_nid(int);
+extern unsigned long marvel_node_mem_start(int);
+extern unsigned long marvel_node_mem_size(int);
+extern int marvel_srmcons_allowed(void);
+extern struct _alpha_agp_info *marvel_agp_info(void);
+struct io7 *marvel_find_io7(int pe);
+struct io7 *marvel_next_io7(struct io7 *prev);
+void io7_clear_errors(struct io7 *io7);
+
 /* core_mcpcia.c */
 extern struct pci_ops mcpcia_pci_ops;
 extern void mcpcia_init_arch(void);
@@ -68,6 +86,7 @@
 extern void titan_kill_arch(int);
 extern void titan_machine_check(u64, u64, struct pt_regs *);
 extern void titan_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
+extern struct _alpha_agp_info *titan_agp_info(void);
 
 /* core_tsunami.c */
 extern struct pci_ops tsunami_pci_ops;
@@ -82,6 +101,10 @@
 extern void wildfire_kill_arch(int);
 extern void wildfire_machine_check(u64, u64, struct pt_regs *);
 extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
+extern int wildfire_pa_to_nid(unsigned long);
+extern int wildfire_cpuid_to_nid(int);
+extern unsigned long wildfire_node_mem_start(int);
+extern unsigned long wildfire_node_mem_size(int);
 
 /* setup.c */
 extern unsigned long srm_hae;
@@ -145,9 +168,16 @@
 extern void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15);
 extern void die_if_kernel(char *, struct pt_regs *, long, unsigned long *);
 
+/* sys_titan.c */
+extern void titan_dispatch_irqs(u64, struct pt_regs *);
+
 /* ../mm/init.c */
 extern void switch_to_system_map(void);
 extern void srm_paging_stop(void);
+
+/* ../mm/remap.c */
+extern int __alpha_remap_area_pages(unsigned long, unsigned long, 
+				    unsigned long, unsigned long);
 
 /* irq.c */
 
diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
--- a/arch/alpha/kernel/setup.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/setup.c	Thu Jan 16 18:23:05 2003
@@ -155,6 +155,7 @@
 WEAK(eiger_mv);
 WEAK(jensen_mv);
 WEAK(lx164_mv);
+WEAK(marvel_ev7_mv);
 WEAK(miata_mv);
 WEAK(mikasa_mv);
 WEAK(mikasa_primo_mv);
@@ -174,6 +175,7 @@
 WEAK(shark_mv);
 WEAK(sx164_mv);
 WEAK(takara_mv);
+WEAK(titan_mv);
 WEAK(webbrick_mv);
 WEAK(wildfire_mv);
 WEAK(xl_mv);
@@ -288,7 +290,7 @@
 	  (hwrpb->mddt_offset + (unsigned long) hwrpb);
 
 	for_each_mem_cluster(memdesc, cluster, i) {
-		printk("memcluster %d, usage %01lx, start %8lu, end %8lu\n",
+		printk("memcluster %lu, usage %01lx, start %8lu, end %8lu\n",
 		       i, cluster->usage, cluster->start_pfn,
 		       cluster->start_pfn + cluster->numpages);
 
@@ -303,6 +305,24 @@
 			max_low_pfn = end;
 	}
 
+	/*
+	 * Except for the NUMA systems (wildfire, marvel) all of the 
+	 * Alpha systems we run on support 32GB of memory or less.
+	 * Since the NUMA systems introduce large holes in memory addressing,
+	 * we can get into a situation where there is not enough contiguous
+	 * memory for the memory map. 
+	 *
+	 * Limit memory to the first 32GB to limit the NUMA systems to 
+	 * memory on their first node (wildfire) or 2 (marvel) to avoid 
+	 * not being able to produce the memory map. In order to access 
+	 * all of the memory on the NUMA systems, build with discontiguous
+	 * memory support.
+	 *
+	 * If the user specified a memory limit, let that memory limit stand.
+	 */
+	if (!mem_size_limit) 
+		mem_size_limit = (32ul * 1024 * 1024 * 1024) >> PAGE_SHIFT;
+
 	if (mem_size_limit && max_low_pfn >= mem_size_limit)
 	{
 		printk("setup: forcing memory size to %ldK (from %ldK).\n",
@@ -677,7 +697,7 @@
 	"Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
 	"Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
 	"Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
-	"Tsunami", "Wildfire", "CUSCO", "Eiger", "Titan"
+	"Tsunami", "Wildfire", "CUSCO", "Eiger", "Titan", "Marvel"
 };
 
 static char unofficial_names[][8] = {"100", "Ruffian"};
@@ -696,15 +716,20 @@
 static char eb66_names[][8] = {"EB66", "EB66+"};
 static int eb66_indices[] = {0,0,1};
 
+static char marvel_names[][16] = {
+	"Marvel/EV7"
+};
+static int marvel_indices[] = { 0 };
+
 static char rawhide_names[][16] = {
 	"Dodge", "Wrangler", "Durango", "Tincup", "DaVinci"
 };
 static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4};
 
 static char titan_names[][16] = {
-	"0", "Privateer"
+	"DEFAULT", "Privateer", "Falcon", "Granite"
 };
-static int titan_indices[] = {0,1};
+static int titan_indices[] = {0,1,2,2,3};
 
 static char tsunami_names[][16] = {
 	"0", "DP264", "Warhol", "Windjammer", "Monet", "Clipper",
@@ -757,6 +782,7 @@
 		NULL,		/* CUSCO */
 		&eiger_mv,	/* Eiger */
 		NULL,		/* Titan */
+		NULL,		/* Marvel */
 	};
 
 	static struct alpha_machine_vector *unofficial_vecs[] __initdata =
@@ -794,10 +820,17 @@
 		&eb66p_mv
 	};
 
+	static struct alpha_machine_vector *marvel_vecs[] __initdata =
+	{
+		&marvel_ev7_mv,
+	};
+
 	static struct alpha_machine_vector *titan_vecs[] __initdata =
 	{
-		NULL,
+		&titan_mv,		/* default   */
 		&privateer_mv,		/* privateer */
+		&titan_mv,		/* falcon    */
+		&privateer_mv,		/* granite   */
 	};
 
 	static struct alpha_machine_vector *tsunami_vecs[]  __initdata =
@@ -862,7 +895,12 @@
 			if (member < N(eb66_indices))
 				vec = eb66_vecs[eb66_indices[member]];
 			break;
+		case ST_DEC_MARVEL:
+			if (member < N(marvel_indices))
+				vec = marvel_vecs[marvel_indices[member]];
+			break;
 		case ST_DEC_TITAN:
+			vec = titan_vecs[0];	/* default */
 			if (member < N(titan_indices))
 				vec = titan_vecs[titan_indices[member]];
 			break;
@@ -1001,11 +1039,16 @@
 		if (member < N(eb66_indices))
 			*variation_name = eb66_names[eb66_indices[member]];
 		break;
+	case ST_DEC_MARVEL:
+		if (member < N(marvel_indices))
+			*variation_name = marvel_names[marvel_indices[member]];
+		break;
 	case ST_DEC_RAWHIDE:
 		if (member < N(rawhide_indices))
 			*variation_name = rawhide_names[rawhide_indices[member]];
 		break;
 	case ST_DEC_TITAN:
+		*variation_name = titan_names[0];	/* default */
 		if (member < N(titan_indices))
 			*variation_name = titan_names[titan_indices[member]];
 		break;
diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
--- a/arch/alpha/kernel/smp.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/smp.c	Thu Jan 16 18:23:05 2003
@@ -72,37 +72,19 @@
 
 /* Which cpus ids came online.  */
 unsigned long cpu_present_mask;
+volatile unsigned long cpu_online_map;
 
 /* cpus reported in the hwrpb */
 static unsigned long hwrpb_cpu_present_mask __initdata = 0;
 
-static int max_cpus = -1;	/* Command-line limitation.  */
 int smp_num_probed;		/* Internal processor count */
 int smp_num_cpus = 1;		/* Number that came online.  */
-int smp_threads_ready;		/* True once the per process idle is forked. */
 cycles_t cacheflush_time;
 unsigned long cache_decay_ticks;
 
 extern void calibrate_delay(void);
-extern asmlinkage void entInt(void);
 
 
-static int __init nosmp(char *str)
-{
-	max_cpus = 0;
-	return 1;
-}
-
-__setup("nosmp", nosmp);
-
-static int __init maxcpus(char *str)
-{
-	get_option(&str, &max_cpus);
-	return 1;
-}
-
-__setup("maxcpus", maxcpus);
-
 
 /*
  * Called by both boot and secondaries to move global data into
@@ -151,6 +133,11 @@
 {
 	int cpuid = hard_smp_processor_id();
 
+	if (test_and_set_bit(cpuid, &cpu_online_map)) {
+		printk("??, cpu 0x%x already present??\n", cpuid);
+		BUG();
+	}
+
 	/* Turn on machine checks.  */
 	wrmces(7);
 
@@ -163,6 +150,9 @@
 	/* Get our local ticker going. */
 	smp_setup_percpu_timer(cpuid);
 
+	/* Call platform-specific callin, if specified */
+	if (alpha_mv.smp_callin) alpha_mv.smp_callin();
+
 	/* All kernel threads share the same mm context.  */
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
@@ -181,10 +171,6 @@
 	wmb();
 	smp_secondary_alive = 1;
 
-	/* Wait for the go code.  */
-	while (!smp_threads_ready)
-		barrier();
-
 	DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n",
 	      cpuid, current, current->active_mm));
 
@@ -432,7 +418,7 @@
 	/* Don't care about the contents of regs since we'll never
 	   reschedule the forked task. */
 	struct pt_regs regs;
-	return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
+	return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 }
 
 /*
@@ -542,13 +528,12 @@
 }
 
 /*
- * Called by smp_init bring all the secondaries online and hold them.
+ * Called by smp_init prepare the secondaries
  */
 void __init
-smp_boot_cpus(void)
+smp_prepare_cpus(unsigned int max_cpus)
 {
 	int cpu_count, i;
-	unsigned long bogosum;
 
 	/* Take care of some initial bookkeeping.  */
 	memset(ipi_data, 0, sizeof(ipi_data));
@@ -559,6 +544,9 @@
 	smp_tune_scheduling(boot_cpuid);
 	smp_setup_percpu_timer(boot_cpuid);
 
+	/* We have already have the boot CPU online.. */
+	set_bit(boot_cpuid, &cpu_online_map);
+
 	/* Nothing to do on a UP box, or when told not to.  */
 	if (smp_num_probed == 1 || max_cpus == 0) {
 		cpu_present_mask = 1UL << boot_cpuid;
@@ -569,44 +557,20 @@
 	printk(KERN_INFO "SMP starting up secondaries.\n");
 
 	cpu_count = 1;
-	for (i = 0; i < NR_CPUS; i++) {
+	for (i = 0; (i < NR_CPUS) && (cpu_count < max_cpus); i++) {
 		if (i == boot_cpuid)
 			continue;
 
 		if (((hwrpb_cpu_present_mask >> i) & 1) == 0)
 			continue;
 
-		if (smp_boot_one_cpu(i))
-			continue;
-
 		cpu_present_mask |= 1UL << i;
 		cpu_count++;
 	}
 
-	if (cpu_count == 1) {
-		printk(KERN_ERR "SMP: Only one lonely processor alive.\n");
-		return;
-	}
-
-	bogosum = 0;
-	for (i = 0; i < NR_CPUS; i++) {
-		if (cpu_present_mask & (1UL << i))
-			bogosum += cpu_data[i].loops_per_jiffy;
-	}
-	printk(KERN_INFO "SMP: Total of %d processors activated "
-	       "(%lu.%02lu BogoMIPS).\n",
-	       cpu_count, (bogosum + 2500) / (500000/HZ),
-	       ((bogosum + 2500) / (5000/HZ)) % 100);
-
 	smp_num_cpus = cpu_count;
 }
 
-void __init
-smp_prepare_cpus(unsigned int max_cpus)
-{
-	smp_boot_cpus();
-}
-
 void __devinit
 smp_prepare_boot_cpu(void)
 {
@@ -616,14 +580,26 @@
 int __devinit
 __cpu_up(unsigned int cpu)
 {
+	smp_boot_one_cpu(cpu);
+
 	return cpu_online(cpu) ? 0 : -ENOSYS;
 }
 
 void __init
 smp_cpus_done(unsigned int max_cpus)
 {
-	smp_threads_ready = 1;
-	mb();
+	int cpu;
+	unsigned long bogosum = 0;
+
+	for(cpu = 0; cpu < NR_CPUS; cpu++) 
+		if (cpu_online(cpu))
+			bogosum += cpu_data[cpu].loops_per_jiffy;
+	
+	printk(KERN_INFO "SMP: Total of %d processors activated "
+	       "(%lu.%02lu BogoMIPS).\n",
+	       num_online_cpus(), 
+	       (bogosum + 2500) / (500000/HZ),
+	       ((bogosum + 2500) / (5000/HZ)) % 100);
 }
 
 
@@ -865,11 +841,36 @@
 	       && time_before (jiffies, timeout))
 		barrier();
 
-	/* We either got one or timed out -- clear the lock.  */
+	/* If there's no response yet, log a message but allow a longer
+	 * timeout period -- if we get a response this time, log
+	 * a message saying when we got it.. 
+	 */
+	if (atomic_read(&data.unstarted_count) > 0) {
+		long start_time = jiffies;
+		printk(KERN_ERR "%s: initial timeout -- trying long wait\n",
+		       __FUNCTION__);
+		timeout = jiffies + 30 * HZ;
+		while (atomic_read(&data.unstarted_count) > 0
+		       && time_before(jiffies, timeout))
+			barrier();
+		if (atomic_read(&data.unstarted_count) <= 0) {
+			long delta = jiffies - start_time;
+			printk(KERN_ERR 
+			       "%s: response %ld.%ld seconds into long wait\n",
+			       __FUNCTION__, delta / HZ,
+			       (100 * (delta - ((delta / HZ) * HZ))) / HZ);
+		}
+	}
+
+	/* We either got one or timed out -- clear the lock. */
 	mb();
 	smp_call_function_data = 0;
-	if (atomic_read (&data.unstarted_count) > 0)
-		return -ETIMEDOUT;
+
+	/* 
+	 * If after both the initial and long timeout periods we still don't
+	 * have a response, something is very wrong...
+	 */
+	BUG_ON(atomic_read (&data.unstarted_count) > 0);
 
 	/* Wait for a complete response, if needed.  */
 	if (wait) {
@@ -884,7 +885,7 @@
 smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
 {
 	return smp_call_function_on_cpu (func, info, retry, wait,
-					 cpu_present_mask);
+					 cpu_online_map);
 }
 
 static void
diff -Nru a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/kernel/sys_marvel.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,500 @@
+/*
+ * linux/arch/alpha/kernel/sys_marvel.c
+ *
+ * Marvel / IO7 support
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/core_marvel.h>
+#include <asm/hwrpb.h>
+#include <asm/tlbflush.h>
+
+#include "proto.h"
+#include "err_impl.h"
+#include "irq_impl.h"
+#include "pci_impl.h"
+#include "machvec_impl.h"
+
+#if NR_IRQS < MARVEL_NR_IRQS
+# error NR_IRQS < MARVEL_NR_IRQS !!!
+#endif
+
+
+/*
+ * Interrupt handling.
+ */
+static void 
+io7_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+	unsigned int pid;
+	unsigned int irq;
+
+	/*
+	 * Vector is 0x800 + (interrupt)
+	 *
+	 * where (interrupt) is:
+	 *
+	 *	...16|15 14|13     4|3 0
+	 *	-----+-----+--------+---
+	 *	  PE |  0  |   irq  | 0
+	 *
+	 * where (irq) is 
+	 *
+	 *       0x0800 - 0x0ff0	 - 0x0800 + (LSI id << 4)
+	 *	 0x1000 - 0x2ff0	 - 0x1000 + (MSI_DAT<8:0> << 4)
+	 */
+	pid = vector >> 16;
+	irq = ((vector & 0xffff) - 0x800) >> 4;
+
+	irq += 16;				/* offset for legacy */
+	irq &= MARVEL_IRQ_VEC_IRQ_MASK;		/* not too many bits */
+	irq |= pid << MARVEL_IRQ_VEC_PE_SHIFT;	/* merge the pid     */
+
+	handle_irq(irq, regs);
+}
+
+static volatile unsigned long *
+io7_get_irq_ctl(unsigned int irq, struct io7 **pio7)
+{
+	volatile unsigned long *ctl;
+	unsigned int pid;
+	struct io7 *io7;
+
+	pid = irq >> MARVEL_IRQ_VEC_PE_SHIFT;
+
+	if (!(io7 = marvel_find_io7(pid))) {
+		printk(KERN_ERR 
+		       "%s for nonexistent io7 -- vec %x, pid %d\n",
+		       __FUNCTION__, irq, pid);
+		return NULL;
+	}
+
+	irq &= MARVEL_IRQ_VEC_IRQ_MASK;	/* isolate the vector    */
+	irq -= 16;			/* subtract legacy bias  */
+
+	if (irq >= 0x180) {
+		printk(KERN_ERR 
+		       "%s for invalid irq -- pid %d adjusted irq %x\n",
+		       __FUNCTION__, pid, irq);
+		return NULL;
+	}
+
+	ctl = &io7->csrs->PO7_LSI_CTL[irq & 0xff].csr; /* assume LSI */
+	if (irq >= 0x80)	     	/* MSI */
+		ctl = &io7->csrs->PO7_MSI_CTL[((irq - 0x80) >> 5) & 0x0f].csr;
+
+	if (pio7) *pio7 = io7;
+	return ctl;
+}
+
+static void
+io7_enable_irq(unsigned int irq)
+{
+	volatile unsigned long *ctl;
+	struct io7 *io7;
+
+	ctl = io7_get_irq_ctl(irq, &io7);
+	if (!ctl || !io7) {
+		printk(KERN_ERR "%s: get_ctl failed for irq %x\n", 
+		       __FUNCTION__, irq);
+		return;
+	}
+		
+	spin_lock(&io7->irq_lock);
+	*ctl |= 1UL << 24;
+	mb();
+	*ctl;
+	spin_unlock(&io7->irq_lock);
+}
+
+static void
+io7_disable_irq(unsigned int irq)
+{
+	volatile unsigned long *ctl;
+	struct io7 *io7;
+
+	ctl = io7_get_irq_ctl(irq, &io7);
+	if (!ctl || !io7) {
+		printk(KERN_ERR "%s: get_ctl failed for irq %x\n", 
+		       __FUNCTION__, irq);
+		return;
+	}
+		
+	spin_lock(&io7->irq_lock);
+	*ctl &= ~(1UL << 24);
+	mb();
+	*ctl;
+	spin_unlock(&io7->irq_lock);
+}
+
+static unsigned int
+io7_startup_irq(unsigned int irq)
+{
+	io7_enable_irq(irq);
+	return 0;	/* never anything pending */
+}
+
+static void
+io7_end_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		io7_enable_irq(irq);
+}
+
+static void
+marvel_irq_noop(unsigned int irq) 
+{ 
+	return; 
+}
+
+static unsigned int
+marvel_irq_noop_return(unsigned int irq) 
+{ 
+	return 0; 
+}
+
+static struct hw_interrupt_type marvel_legacy_irq_type = {
+	.typename	= "LEGACY",
+	.startup	= marvel_irq_noop_return,
+	.shutdown	= marvel_irq_noop,
+	.enable		= marvel_irq_noop,
+	.disable	= marvel_irq_noop,
+	.ack		= marvel_irq_noop,
+	.end		= marvel_irq_noop,
+};
+
+static struct hw_interrupt_type io7_lsi_irq_type = {
+	.typename	= "LSI",
+	.startup	= io7_startup_irq,
+	.shutdown	= io7_disable_irq,
+	.enable		= io7_enable_irq,
+	.disable	= io7_disable_irq,
+	.ack		= io7_disable_irq,
+	.end		= io7_end_irq,
+};
+
+static struct hw_interrupt_type io7_msi_irq_type = {
+	.typename	= "MSI",
+	.startup	= io7_startup_irq,
+	.shutdown	= io7_disable_irq,
+	.enable		= io7_enable_irq,
+	.disable	= io7_disable_irq,
+	.ack		= marvel_irq_noop,
+	.end		= io7_end_irq,
+};
+
+static void
+io7_redirect_irq(struct io7 *io7, 
+		 volatile unsigned long *csr, 
+		 unsigned int where)
+{
+	unsigned long val;
+	
+	val = *csr;
+	val &= ~(0x1ffUL << 24);		/* clear the target pid   */
+	val |= ((unsigned long)where << 24);	/* set the new target pid */
+	
+	*csr = val;
+	mb();
+	*csr;
+}
+
+static void 
+io7_redirect_one_lsi(struct io7 *io7, unsigned int which, unsigned int where)
+{
+	unsigned long val;
+
+	/*
+	 * LSI_CTL has target PID @ 14
+	 */
+	val = io7->csrs->PO7_LSI_CTL[which].csr;
+	val &= ~(0x1ffUL << 14);		/* clear the target pid */
+	val |= ((unsigned long)where << 14);	/* set teh new target pid */
+
+	io7->csrs->PO7_LSI_CTL[which].csr = val;
+	mb();
+	io7->csrs->PO7_LSI_CTL[which].csr;
+}
+
+static void 
+io7_redirect_one_msi(struct io7 *io7, unsigned int which, unsigned int where)
+{
+	unsigned long val;
+
+	/*
+	 * MSI_CTL has target PID @ 14
+	 */
+	val = io7->csrs->PO7_MSI_CTL[which].csr;
+	val &= ~(0x1ffUL << 14);		/* clear the target pid */
+	val |= ((unsigned long)where << 14);	/* set teh new target pid */
+
+	io7->csrs->PO7_MSI_CTL[which].csr = val;
+	mb();
+	io7->csrs->PO7_MSI_CTL[which].csr;
+}
+
+static void __init
+init_one_io7_lsi(struct io7 *io7, unsigned int which, unsigned int where)
+{
+	/*
+	 * LSI_CTL has target PID @ 14
+	 */
+	io7->csrs->PO7_LSI_CTL[which].csr = ((unsigned long)where << 14);
+	mb();
+	io7->csrs->PO7_LSI_CTL[which].csr;
+}
+
+static void __init
+init_one_io7_msi(struct io7 *io7, unsigned int which, unsigned int where)
+{
+	/*
+	 * MSI_CTL has target PID @ 14
+	 */
+	io7->csrs->PO7_MSI_CTL[which].csr = ((unsigned long)where << 14);
+	mb();
+	io7->csrs->PO7_MSI_CTL[which].csr;
+}
+
+static void __init
+init_io7_irqs(struct io7 *io7, 
+	      struct hw_interrupt_type *lsi_ops,
+	      struct hw_interrupt_type *msi_ops)
+{
+	long base = (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT) + 16;
+	long i;
+
+	printk("Initializing interrupts for IO7 at PE %u - base %lx\n",
+		io7->pe, base);
+
+	/*
+	 * Where should interrupts from this IO7 go?
+	 *
+	 * They really should be sent to the local CPU to avoid having to
+	 * traverse the mesh, but if it's not an SMP kernel, they have to
+	 * go to the boot CPU. Send them all to the boot CPU for now,
+	 * as each secondary starts, it can redirect it's local device 
+	 * interrupts.
+	 */
+	printk("  Interrupts reported to CPU at PE %u\n", boot_cpuid);
+
+	spin_lock(&io7->irq_lock);
+
+	/* set up the error irqs */
+	io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr, boot_cpuid);
+	io7_redirect_irq(io7, &io7->csrs->HPI_CTL.csr, boot_cpuid);
+	io7_redirect_irq(io7, &io7->csrs->CRD_CTL.csr, boot_cpuid);
+	io7_redirect_irq(io7, &io7->csrs->STV_CTL.csr, boot_cpuid);
+	io7_redirect_irq(io7, &io7->csrs->HEI_CTL.csr, boot_cpuid);
+
+	/* Set up the lsi irqs.  */
+	for (i = 0; i < 128; ++i) {
+		irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL;
+		irq_desc[base + i].handler = lsi_ops;
+	}
+
+	/* Disable the implemented irqs in hardware.  */
+	for (i = 0; i < 0x60; ++i) 
+		init_one_io7_lsi(io7, i, boot_cpuid);
+
+	init_one_io7_lsi(io7, 0x74, boot_cpuid);
+	init_one_io7_lsi(io7, 0x75, boot_cpuid);
+
+
+	/* Set up the msi irqs.  */
+	for (i = 128; i < (128 + 512); ++i) {
+		irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL;
+		irq_desc[base + i].handler = msi_ops;
+	}
+
+	for (i = 0; i < 16; ++i)
+		init_one_io7_msi(io7, i, boot_cpuid);
+
+	spin_unlock(&io7->irq_lock);
+}
+
+static void __init
+marvel_init_irq(void)
+{
+	int i;
+	struct io7 *io7 = NULL;
+
+	/* Reserve the legacy irqs.  */
+	for (i = 0; i < 16; ++i) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].handler = &marvel_legacy_irq_type;
+	}
+
+	/* Init the io7 irqs.  */
+	for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; )
+		init_io7_irqs(io7, &io7_lsi_irq_type, &io7_msi_irq_type);
+}
+
+static int 
+marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct pci_controller *hose = dev->sysdata;
+	struct io7_port *io7_port = hose->sysdata;
+	struct io7 *io7 = io7_port->io7;
+	int msi_loc, msi_data_off;
+	u16 msg_ctl;
+	u16 msg_dat;
+	u8 intline; 
+	int irq;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline);
+	irq = intline;
+
+	msi_loc = pci_find_capability(dev, PCI_CAP_ID_MSI);
+	msg_ctl = 0;
+	if (msi_loc) 
+		pci_read_config_word(dev, msi_loc + PCI_MSI_FLAGS, &msg_ctl);
+
+	if (msg_ctl & PCI_MSI_FLAGS_ENABLE) {
+ 		msi_data_off = PCI_MSI_DATA_32;
+		if (msg_ctl & PCI_MSI_FLAGS_64BIT) 
+			msi_data_off = PCI_MSI_DATA_64;
+		pci_read_config_word(dev, msi_loc + msi_data_off, &msg_dat);
+
+		irq = msg_dat & 0x1ff;		/* we use msg_data<8:0> */
+		irq += 0x80;			/* offset for lsi       */
+
+#if 1
+		printk("PCI:%d:%d:%d (hose %d) [%s] is using MSI\n",
+		       dev->bus->number, 
+		       PCI_SLOT(dev->devfn), 
+		       PCI_FUNC(dev->devfn),
+		       hose->index,
+		       dev->dev.name);
+		printk("  %d message(s) from 0x%04x\n", 
+		       1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4),
+		       msg_dat);
+		printk("  reporting on %d IRQ(s) from %d (0x%x)\n", 
+		       1 << ((msg_ctl & PCI_MSI_FLAGS_QSIZE) >> 4),
+		       (irq + 16) | (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT),
+		       (irq + 16) | (io7->pe << MARVEL_IRQ_VEC_PE_SHIFT));
+#endif
+
+#if 0
+		pci_write_config_word(dev, msi_loc + PCI_MSI_FLAGS,
+				      msg_ctl & ~PCI_MSI_FLAGS_ENABLE);
+		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline);
+		irq = intline;
+
+		printk("  forcing LSI interrupt on irq %d [0x%x]\n", irq, irq);
+#endif
+	}
+
+	irq += 16;					/* offset for legacy */
+	irq |= io7->pe << MARVEL_IRQ_VEC_PE_SHIFT;	/* merge the pid     */
+
+	return irq; 
+}
+
+static void __init
+marvel_init_pci(void)
+{
+	struct io7 *io7;
+
+	marvel_register_error_handlers();
+
+	pci_probe_only = 1;
+	common_init_pci();
+
+#ifdef CONFIG_VGA_HOSE
+	locate_and_init_vga(NULL);
+#endif
+
+	/* Clear any io7 errors.  */
+	for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) 
+		io7_clear_errors(io7);
+}
+
+static void
+marvel_init_rtc(void)
+{
+	init_rtc_irq();
+}
+
+static void
+marvel_smp_callin(void)
+{
+	int cpuid = hard_smp_processor_id();
+	struct io7 *io7 = marvel_find_io7(cpuid);
+	unsigned int i;
+
+	if (!io7)
+		return;
+
+	/* 
+	 * There is a local IO7 - redirect all of it's interrupts here.
+	 */
+	printk("Redirecting IO7 interrupts to local CPU at PE %u\n", cpuid);
+
+	/* Redirect the error IRQS here.  */
+	io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr, cpuid);
+	io7_redirect_irq(io7, &io7->csrs->HPI_CTL.csr, cpuid);
+	io7_redirect_irq(io7, &io7->csrs->CRD_CTL.csr, cpuid);
+	io7_redirect_irq(io7, &io7->csrs->STV_CTL.csr, cpuid);
+	io7_redirect_irq(io7, &io7->csrs->HEI_CTL.csr, cpuid);
+
+	/* Redirect the implemented LSIs here.  */
+	for (i = 0; i < 0x60; ++i) 
+		io7_redirect_one_lsi(io7, i, cpuid);
+
+	io7_redirect_one_lsi(io7, 0x74, cpuid);
+	io7_redirect_one_lsi(io7, 0x75, cpuid);
+
+	/* Redirect the MSIs here.  */
+	for (i = 0; i < 16; ++i)
+		io7_redirect_one_msi(io7, i, cpuid);
+}
+
+/*
+ * System Vectors
+ */
+struct alpha_machine_vector marvel_ev7_mv __initmv = {
+	.vector_name		= "MARVEL/EV7",
+	DO_EV7_MMU,
+	DO_DEFAULT_RTC,
+	DO_MARVEL_IO,
+	DO_MARVEL_BUS,
+	.machine_check		= marvel_machine_check,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
+	.min_io_address		= DEFAULT_IO_BASE,
+	.min_mem_address	= DEFAULT_MEM_BASE,
+	.pci_dac_offset		= IO7_DAC_OFFSET,
+
+	.nr_irqs		= MARVEL_NR_IRQS,
+	.device_interrupt	= io7_device_interrupt,
+
+	.agp_info		= marvel_agp_info,
+
+	.smp_callin		= marvel_smp_callin,
+	.init_arch		= marvel_init_arch,
+	.init_irq		= marvel_init_irq,
+	.init_rtc		= marvel_init_rtc,
+	.init_pci		= marvel_init_pci,
+	.kill_arch		= marvel_kill_arch,
+	.pci_map_irq		= marvel_map_irq,
+	.pci_swizzle		= common_swizzle,
+
+	.pa_to_nid		= marvel_pa_to_nid,
+	.cpuid_to_nid		= marvel_cpuid_to_nid,
+	.node_mem_start		= marvel_node_mem_start,
+	.node_mem_size		= marvel_node_mem_size,
+};
+ALIAS_MV(marvel_ev7)
diff -Nru a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
--- a/arch/alpha/kernel/sys_titan.c	Thu Jan 16 18:23:07 2003
+++ b/arch/alpha/kernel/sys_titan.c	Thu Jan 16 18:23:07 2003
@@ -8,6 +8,8 @@
  *
  * Code supporting TITAN systems (EV6+TITAN), currently:
  *      Privateer
+ *	Falcon
+ *	Granite
  */
 
 #include <linux/config.h>
@@ -34,12 +36,26 @@
 #include "irq_impl.h"
 #include "pci_impl.h"
 #include "machvec_impl.h"
+#include "err_impl.h"
 
-/* Note mask bit is true for ENABLED irqs. */
-static unsigned long cached_irq_mask;
-/* Titan boards handle at most four CPUs.  */
-static unsigned long cpu_irq_affinity[4] = { ~0UL, ~0UL, ~0UL, ~0UL };
+
+/*
+ * Titan generic
+ */
+
+/*
+ * Titan supports up to 4 CPUs
+ */
+static unsigned long titan_cpu_irq_affinity[4] = { ~0UL, ~0UL, ~0UL, ~0UL };
+
+/*
+ * Mask is set (1) if enabled
+ */
+static unsigned long titan_cached_irq_mask;
 
+/*
+ * Need SMP-safe access to interrupt CSRs
+ */
 spinlock_t titan_irq_lock = SPIN_LOCK_UNLOCKED;
 
 static void
@@ -55,10 +71,10 @@
 	unsigned long mask0, mask1, mask2, mask3, dummy;
 
 	mask &= ~isa_enable;
-	mask0 = mask & cpu_irq_affinity[0];
-	mask1 = mask & cpu_irq_affinity[1];
-	mask2 = mask & cpu_irq_affinity[2];
-	mask3 = mask & cpu_irq_affinity[3];
+	mask0 = mask & titan_cpu_irq_affinity[0];
+	mask1 = mask & titan_cpu_irq_affinity[1];
+	mask2 = mask & titan_cpu_irq_affinity[2];
+	mask3 = mask & titan_cpu_irq_affinity[3];
 
 	if (bcpu == 0) mask0 |= isa_enable;
 	else if (bcpu == 1) mask1 |= isa_enable;
@@ -97,79 +113,68 @@
 }
 
 static inline void
-privateer_enable_irq(unsigned int irq)
+titan_enable_irq(unsigned int irq)
 {
 	spin_lock(&titan_irq_lock);
-	cached_irq_mask |= 1UL << (irq - 16);
-	titan_update_irq_hw(cached_irq_mask);
+	titan_cached_irq_mask |= 1UL << (irq - 16);
+	titan_update_irq_hw(titan_cached_irq_mask);
 	spin_unlock(&titan_irq_lock);
 }
 
 static inline void
-privateer_disable_irq(unsigned int irq)
+titan_disable_irq(unsigned int irq)
 {
 	spin_lock(&titan_irq_lock);
-	cached_irq_mask &= ~(1UL << (irq - 16));
-	titan_update_irq_hw(cached_irq_mask);
+	titan_cached_irq_mask &= ~(1UL << (irq - 16));
+	titan_update_irq_hw(titan_cached_irq_mask);
 	spin_unlock(&titan_irq_lock);
 }
 
 static unsigned int
-privateer_startup_irq(unsigned int irq)
+titan_startup_irq(unsigned int irq)
 {
-	privateer_enable_irq(irq);
+	titan_enable_irq(irq);
 	return 0;	/* never anything pending */
 }
 
 static void
-privateer_end_irq(unsigned int irq)
+titan_end_irq(unsigned int irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		privateer_enable_irq(irq);
+		titan_enable_irq(irq);
 }
 
 static void
-cpu_set_irq_affinity(unsigned int irq, unsigned long affinity)
+titan_cpu_set_irq_affinity(unsigned int irq, unsigned long affinity)
 {
 	int cpu;
 
 	for (cpu = 0; cpu < 4; cpu++) {
 		if (affinity & (1UL << cpu))
-			cpu_irq_affinity[cpu] |= 1UL << irq;
+			titan_cpu_irq_affinity[cpu] |= 1UL << irq;
 		else
-			cpu_irq_affinity[cpu] &= ~(1UL << irq);
+			titan_cpu_irq_affinity[cpu] &= ~(1UL << irq);
 	}
 
 }
 
 static void
-privateer_set_affinity(unsigned int irq, unsigned long affinity)
+titan_set_irq_affinity(unsigned int irq, unsigned long affinity)
 { 
 	spin_lock(&titan_irq_lock);
-	cpu_set_irq_affinity(irq - 16, affinity);
-	titan_update_irq_hw(cached_irq_mask);
+	titan_cpu_set_irq_affinity(irq - 16, affinity);
+	titan_update_irq_hw(titan_cached_irq_mask);
 	spin_unlock(&titan_irq_lock);
 }
 
-static struct hw_interrupt_type privateer_irq_type = {
-	.typename	= "PRIVATEER",
-	.startup	= privateer_startup_irq,
-	.shutdown	= privateer_disable_irq,
-	.enable		= privateer_enable_irq,
-	.disable	= privateer_disable_irq,
-	.ack		= privateer_disable_irq,
-	.end		= privateer_end_irq,
-	.set_affinity	= privateer_set_affinity,
-};
-
 static void
-privateer_device_interrupt(unsigned long vector, struct pt_regs * regs)
+titan_device_interrupt(unsigned long vector, struct pt_regs * regs)
 {
-	printk("privateer_device_interrupt: NOT IMPLEMENTED YET!! \n");
+	printk("titan_device_interrupt: NOT IMPLEMENTED YET!! \n");
 }
 
 static void 
-privateer_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+titan_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
 {
 	int irq;
 
@@ -182,186 +187,209 @@
 init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax)
 {
 	long i;
-	for(i = imin; i <= imax; ++i) {
+	for (i = imin; i <= imax; ++i) {
 		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
 		irq_desc[i].handler = ops;
 	}
 }
 
+static struct hw_interrupt_type titan_irq_type = {
+       .typename       = "TITAN",
+       .startup        = titan_startup_irq,
+       .shutdown       = titan_disable_irq,
+       .enable         = titan_enable_irq,
+       .disable        = titan_disable_irq,
+       .ack            = titan_disable_irq,
+       .end            = titan_end_irq,
+       .set_affinity   = titan_set_irq_affinity,
+};
+
+static void
+titan_intr_nop(int irq, void *dev_id, struct pt_regs *regs)                    
+{
+      /*
+       * This is a NOP interrupt handler for the purposes of
+       * event counting -- just return.
+       */                                                                     
+}
+
+static void __init
+titan_init_irq(void)
+{
+	if (alpha_using_srm && !alpha_mv.device_interrupt)
+		alpha_mv.device_interrupt = titan_srm_device_interrupt;
+	if (!alpha_mv.device_interrupt)
+		alpha_mv.device_interrupt = titan_device_interrupt;
+
+	titan_update_irq_hw(0);
+
+	init_titan_irqs(&titan_irq_type, 16, 63 + 16);
+}
+  
 static void __init
-privateer_init_irq(void)
+titan_legacy_init_irq(void)
 {
+	/* init the legacy dma controller */
 	outb(0, DMA1_RESET_REG);
 	outb(0, DMA2_RESET_REG);
 	outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
 	outb(0, DMA2_MASK_REG);
 
-	if (alpha_using_srm)
-		alpha_mv.device_interrupt = privateer_srm_device_interrupt;
-
-	titan_update_irq_hw(0UL);
-
+	/* init the legacy irq controller */
 	init_i8259a_irqs();
-	init_titan_irqs(&privateer_irq_type, 16, 63 + 16);
+
+	/* init the titan irqs */
+	titan_init_irq();
 }
 
+void
+titan_dispatch_irqs(u64 mask, struct pt_regs *regs)
+{
+	unsigned long vector;
+
+	/*
+	 * Mask down to those interrupts which are enable on this processor
+	 */
+	mask &= titan_cpu_irq_affinity[smp_processor_id()];
+
+	/*
+	 * Dispatch all requested interrupts 
+	 */
+	while (mask) {
+		/* convert to SRM vector... priority is <63> -> <0> */
+		__asm__("ctlz %1, %0" : "=r"(vector) : "r"(mask));
+		vector = 63 - vector;
+		mask &= ~(1UL << vector);	/* clear it out 	 */
+		vector = 0x900 + (vector << 4);	/* convert to SRM vector */
+		
+		/* dispatch it */
+		alpha_mv.device_interrupt(vector, regs);
+	}
+}
+  
+
 /*
- * Privateer PCI Fixup configuration.
- *
- * PCHIP 0 BUS 0 (Hose 0)
- *
- *     IDSEL	Dev	What
- *     -----	---	----
- *	18	 7	Embedded Southbridge
- *	19	 8	Slot 0 
- *	20	 9	Slot 1
- *	21	10	Slot 2 
- *	22	11	Slot 3
- *	23	12	Embedded HotPlug controller
- *	27	16	Embedded Southbridge IDE
- *	29	18     	Embedded Southbridge PMU
- *	31	20	Embedded Southbridge USB
- *
- * PCHIP 1 BUS 0 (Hose 1)
- *
- *     IDSEL	Dev	What
- *     -----	---	----
- *	12	 1	Slot 0
- * 	13	 2	Slot 1
- *	17	 6	Embedded hotPlug controller
- *
- * PCHIP 0 BUS 1 (Hose 2)
- *
- *     IDSEL	What
- *     -----	----
- *	NONE	AGP
- *
- * PCHIP 1 BUS 1 (Hose 3)
- *
- *     IDSEL	Dev	What
- *     -----	---	----
- *	12	 1	Slot 0
- * 	13	 2	Slot 1
- *	17	 6	Embedded hotPlug controller
- *
- * Summary @ TITAN_CSR_DIM0:
- * Bit      Meaning
- *  0-7     Unused
- *  8       PCHIP 0 BUS 1 YUKON (if present)
- *  9       PCHIP 1 BUS 1 YUKON
- * 10       PCHIP 1 BUS 0 YUKON
- * 11       PCHIP 0 BUS 0 YUKON
- * 12       PCHIP 0 BUS 0 SLOT 2 INT A
- * 13       PCHIP 0 BUS 0 SLOT 2 INT B
- * 14       PCHIP 0 BUS 0 SLOT 2 INT C
- * 15       PCHIP 0 BUS 0 SLOT 2 INT D
- * 16       PCHIP 0 BUS 0 SLOT 3 INT A
- * 17       PCHIP 0 BUS 0 SLOT 3 INT B
- * 18       PCHIP 0 BUS 0 SLOT 3 INT C
- * 19       PCHIP 0 BUS 0 SLOT 3 INT D
- * 20       PCHIP 0 BUS 0 SLOT 0 INT A
- * 21       PCHIP 0 BUS 0 SLOT 0 INT B
- * 22       PCHIP 0 BUS 0 SLOT 0 INT C
- * 23       PCHIP 0 BUS 0 SLOT 0 INT D
- * 24       PCHIP 0 BUS 0 SLOT 1 INT A
- * 25       PCHIP 0 BUS 0 SLOT 1 INT B
- * 26       PCHIP 0 BUS 0 SLOT 1 INT C
- * 27       PCHIP 0 BUS 0 SLOT 1 INT D
- * 28       PCHIP 1 BUS 0 SLOT 0 INT A
- * 29       PCHIP 1 BUS 0 SLOT 0 INT B
- * 30       PCHIP 1 BUS 0 SLOT 0 INT C
- * 31       PCHIP 1 BUS 0 SLOT 0 INT D
- * 32       PCHIP 1 BUS 0 SLOT 1 INT A
- * 33       PCHIP 1 BUS 0 SLOT 1 INT B
- * 34       PCHIP 1 BUS 0 SLOT 1 INT C
- * 35       PCHIP 1 BUS 0 SLOT 1 INT D
- * 36       PCHIP 1 BUS 1 SLOT 0 INT A
- * 37       PCHIP 1 BUS 1 SLOT 0 INT B
- * 38       PCHIP 1 BUS 1 SLOT 0 INT C
- * 39       PCHIP 1 BUS 1 SLOT 0 INT D
- * 40       PCHIP 1 BUS 1 SLOT 1 INT A
- * 41       PCHIP 1 BUS 1 SLOT 1 INT B
- * 42       PCHIP 1 BUS 1 SLOT 1 INT C
- * 43       PCHIP 1 BUS 1 SLOT 1 INT D
- * 44       AGP INT A
- * 45       AGP INT B
- * 46-47    Unused
- * 49       Reserved for Sleep mode
- * 50       Temperature Warning (optional)
- * 51       Power Warning (optional)
- * 52       Reserved
- * 53       South Bridge NMI
- * 54       South Bridge SMI INT
- * 55       South Bridge ISA Interrupt
- * 56-58    Unused
- * 59       PCHIP1_C_ERROR
- * 60       PCHIP0_C_ERROR 
- * 61       PCHIP1_H_ERROR
- * 62       PCHIP0_H_ERROR
- * 63       Reserved
- *
+ * Titan Family
  */
-static int __init
-privateer_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+static void __init
+titan_late_init(void)
 {
-	u8 irq;
-	
-	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
-
-	/* is it routed through ISA? */
-	if ((irq & 0xF0) == 0xE0)
-		return (int)irq;
+	/*
+	 * Enable the system error interrupts. These interrupts are 
+	 * all reported to the kernel as machine checks, so the handler
+	 * is a nop so it can be called to count the individual events.
+	 */
+	request_irq(63+16, titan_intr_nop, SA_INTERRUPT, 
+		    "CChip Error", NULL);
+	request_irq(62+16, titan_intr_nop, SA_INTERRUPT, 
+		    "PChip 0 H_Error", NULL);
+	request_irq(61+16, titan_intr_nop, SA_INTERRUPT, 
+		    "PChip 1 H_Error", NULL);
+	request_irq(60+16, titan_intr_nop, SA_INTERRUPT, 
+		    "PChip 0 C_Error", NULL);
+	request_irq(59+16, titan_intr_nop, SA_INTERRUPT, 
+		    "PChip 1 C_Error", NULL);
+
+	/* 
+	 * Register our error handlers.
+	 */
+	titan_register_error_handlers();
+
+	/*
+	 * Check if the console left us any error logs.
+	 */
+	cdl_check_console_data_log();
 
-	return (int)irq + 16;	/* HACK -- this better only be called once */
 }
 
-#ifdef CONFIG_VGA_HOSE
-static struct pci_controller * __init
-privateer_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2)
+static int __devinit
+titan_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
-	struct pci_controller *hose = h1;
-	int agp1, agp2;
-
-	/* which hose(s) are agp? */
-	agp1 = (0 != (TITAN_agp & (1 << h1->index)));
-	agp2 = (0 != (TITAN_agp & (1 << h2->index)));
-       
-	hose = h1;			/* default to h1 */
-	if (agp1 ^ agp2) {
-		if (agp2) hose = h2;	/* take agp if only one */
-	} else if (h2->index < h1->index)
-		hose = h2;		/* first hose if 2xpci or 2xagp */
+	u8 intline;
+	int irq;
 
-	return hose;
+ 	/* Get the current intline.  */
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline);
+	irq = intline;
+
+ 	/* Is it explicitly routed through ISA?  */
+ 	if ((irq & 0xF0) == 0xE0)
+ 		return irq;
+ 
+ 	/* Offset by 16 to make room for ISA interrupts 0 - 15.  */
+ 	return irq + 16;
 }
-#endif
 
 static void __init
-privateer_init_pci(void)
+titan_init_pci(void)
 {
+ 	/*
+ 	 * This isn't really the right place, but there's some init
+ 	 * that needs to be done after everything is basically up.
+ 	 */
+ 	titan_late_init();
+ 
+	pci_probe_only = 1;
 	common_init_pci();
 	SMC669_Init(0);
 #ifdef CONFIG_VGA_HOSE
-	locate_and_init_vga(privateer_vga_hose_select);
+	locate_and_init_vga(NULL);
 #endif
 }
 
-void
-privateer_machine_check(unsigned long vector, unsigned long la_ptr,
-			struct pt_regs * regs)
+
+/*
+ * Privateer
+ */
+static void __init
+privateer_init_pci(void)
 {
-	/* only handle system events here */
-	if (vector != SCB_Q_SYSEVENT) 
-		return titan_machine_check(vector, la_ptr, regs);
-
-	/* it's a system event, handle it here */
-	printk("PRIVATEER 680 Machine Check on CPU %d\n", smp_processor_id());
+	/*
+	 * Hook a couple of extra err interrupts that the
+	 * common titan code won't.
+	 */
+	request_irq(53+16, titan_intr_nop, SA_INTERRUPT, 
+		    "NMI", NULL);
+	request_irq(50+16, titan_intr_nop, SA_INTERRUPT, 
+		    "Temperature Warning", NULL);
+
+	/*
+	 * Finish with the common version.
+	 */
+	return titan_init_pci();
 }
 
-
+
 /*
- * The System Vectors
+ * The System Vectors.
  */
+struct alpha_machine_vector titan_mv __initmv = {
+	.vector_name		= "TITAN",
+	DO_EV6_MMU,
+	DO_DEFAULT_RTC,
+	DO_TITAN_IO,
+	DO_TITAN_BUS,
+	.machine_check		= titan_machine_check,
+	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
+	.min_io_address		= DEFAULT_IO_BASE,
+	.min_mem_address	= DEFAULT_MEM_BASE,
+	.pci_dac_offset		= TITAN_DAC_OFFSET,
+
+	.nr_irqs		= 80,	/* 64 + 16 */
+	/* device_interrupt will be filled in by titan_init_irq */
+
+	.agp_info		= titan_agp_info,
+
+	.init_arch		= titan_init_arch,
+	.init_irq		= titan_legacy_init_irq,
+	.init_rtc		= common_init_rtc,
+	.init_pci		= titan_init_pci,
+
+	.kill_arch		= titan_kill_arch,
+	.pci_map_irq		= titan_map_irq,
+	.pci_swizzle		= common_swizzle,
+};
+ALIAS_MV(titan)
 
 struct alpha_machine_vector privateer_mv __initmv = {
 	.vector_name		= "PRIVATEER",
@@ -376,14 +404,18 @@
 	.pci_dac_offset		= TITAN_DAC_OFFSET,
 
 	.nr_irqs		= 80,	/* 64 + 16 */
-	.device_interrupt	= privateer_device_interrupt,
+	/* device_interrupt will be filled in by titan_init_irq */
+
+	.agp_info		= titan_agp_info,
 
 	.init_arch		= titan_init_arch,
-	.init_irq		= privateer_init_irq,
+	.init_irq		= titan_legacy_init_irq,
 	.init_rtc		= common_init_rtc,
 	.init_pci		= privateer_init_pci,
+
 	.kill_arch		= titan_kill_arch,
-	.pci_map_irq		= privateer_map_irq,
+	.pci_map_irq		= titan_map_irq,
 	.pci_swizzle		= common_swizzle,
 };
-ALIAS_MV(privateer)
+/* No alpha_mv alias for privateer since we compile it 
+   in unconditionally with titan; setup_arch knows how to cope. */
diff -Nru a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
--- a/arch/alpha/kernel/sys_wildfire.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/kernel/sys_wildfire.c	Thu Jan 16 18:23:05 2003
@@ -353,5 +353,10 @@
 	.kill_arch		= wildfire_kill_arch,
 	.pci_map_irq		= wildfire_map_irq,
 	.pci_swizzle		= common_swizzle,
+
+	.pa_to_nid		= wildfire_pa_to_nid,
+	.cpuid_to_nid		= wildfire_cpuid_to_nid,
+	.node_mem_start		= wildfire_node_mem_start,
+	.node_mem_size		= wildfire_node_mem_size,
 };
 ALIAS_MV(wildfire)
diff -Nru a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
--- a/arch/alpha/kernel/traps.c	Thu Jan 16 18:23:06 2003
+++ b/arch/alpha/kernel/traps.c	Thu Jan 16 18:23:06 2003
@@ -118,7 +118,7 @@
 	long i = 0;
 	printk("Trace:");
 	while (0x1ff8 & (unsigned long) sp) {
-		extern unsigned long _stext, _etext;
+		extern char _stext[], _etext[];
 		unsigned long tmp = *sp;
 		sp++;
 		if (tmp < (unsigned long) &_stext)
diff -Nru a/arch/alpha/lib/callback_srm.S b/arch/alpha/lib/callback_srm.S
--- a/arch/alpha/lib/callback_srm.S	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/lib/callback_srm.S	Thu Jan 16 18:23:05 2003
@@ -78,6 +78,8 @@
 CALLBACK(open, CCB_OPEN, 3)
 CALLBACK(close, CCB_CLOSE, 2)
 CALLBACK(read, CCB_READ, 5)
+CALLBACK(open_console, CCB_OPEN_CONSOLE, 1)
+CALLBACK(close_console, CCB_CLOSE_CONSOLE, 1)
 CALLBACK(getenv, CCB_GET_ENV, 4)
 CALLBACK(setenv, CCB_SET_ENV, 4)
 CALLBACK(getc, CCB_GETC, 2)
diff -Nru a/arch/alpha/mm/Makefile b/arch/alpha/mm/Makefile
--- a/arch/alpha/mm/Makefile	Thu Jan 16 18:23:07 2003
+++ b/arch/alpha/mm/Makefile	Thu Jan 16 18:23:07 2003
@@ -2,6 +2,6 @@
 # Makefile for the linux alpha-specific parts of the memory manager.
 #
 
-obj-y	:= init.o fault.o extable.o
+obj-y	:= init.o fault.o extable.o remap.o
 
 obj-$(CONFIG_DISCONTIGMEM) += numa.o
diff -Nru a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
--- a/arch/alpha/mm/numa.c	Thu Jan 16 18:23:05 2003
+++ b/arch/alpha/mm/numa.c	Thu Jan 16 18:23:05 2003
@@ -19,8 +19,8 @@
 #include <asm/hwrpb.h>
 #include <asm/pgalloc.h>
 
-plat_pg_data_t *plat_node_data[MAX_NUMNODES];
-bootmem_data_t plat_node_bdata[MAX_NUMNODES];
+pg_data_t node_data[MAX_NUMNODES];
+bootmem_data_t node_bdata[MAX_NUMNODES];
 
 #undef DEBUG_DISCONTIG
 #ifdef DEBUG_DISCONTIG
@@ -65,12 +65,12 @@
 	unsigned long start, end;
 	unsigned long node_pfn_start, node_pfn_end;
 	int i;
-	unsigned long node_datasz = PFN_UP(sizeof(plat_pg_data_t));
+	unsigned long node_datasz = PFN_UP(sizeof(pg_data_t));
 	int show_init = 0;
 
 	/* Find the bounds of current node */
-	node_pfn_start = (nid * NODE_MAX_MEM_SIZE) >> PAGE_SHIFT;
-	node_pfn_end = node_pfn_start + (NODE_MAX_MEM_SIZE >> PAGE_SHIFT);
+	node_pfn_start = (node_mem_start(nid)) >> PAGE_SHIFT;
+	node_pfn_end = node_pfn_start + (node_mem_size(nid) >> PAGE_SHIFT);
 	
 	/* Find free clusters, and init and free the bootmem accordingly.  */
 	memdesc = (struct memdesc_struct *)
@@ -93,7 +93,7 @@
 
 		if (!show_init) {
 			show_init = 1;
-			printk("Initialing bootmem allocator on Node ID %d\n", nid);
+			printk("Initializing bootmem allocator on Node ID %d\n", nid);
 		}
 		printk(" memcluster %2d, usage %1lx, start %8lu, end %8lu\n",
 		       i, cluster->usage, cluster->start_pfn,
@@ -107,13 +107,17 @@
 		if (start < min_low_pfn)
 			min_low_pfn = start;
 		if (end > max_low_pfn)
-			max_low_pfn = end;
+			max_pfn = max_low_pfn = end;
 	}
 
-	if (mem_size_limit && max_low_pfn >= mem_size_limit) {
-		printk("setup: forcing memory size to %ldK (from %ldK).\n",
-		       mem_size_limit << (PAGE_SHIFT - 10),
-		       max_low_pfn    << (PAGE_SHIFT - 10));
+	if (mem_size_limit && max_low_pfn > mem_size_limit) {
+		static int msg_shown = 0;
+		if (!msg_shown) {
+			msg_shown = 1;
+			printk("setup: forcing memory size to %ldK (from %ldK).\n",
+			       mem_size_limit << (PAGE_SHIFT - 10),
+			       max_low_pfn    << (PAGE_SHIFT - 10));
+		}
 		max_low_pfn = mem_size_limit;
 	}
 
@@ -122,20 +126,22 @@
 
 	num_physpages += max_low_pfn - min_low_pfn;
 
+#if 0 /* we'll try this one again in a little while */
 	/* Cute trick to make sure our local node data is on local memory */
-	PLAT_NODE_DATA(nid) = (plat_pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT));
-	/* Quasi-mark the plat_pg_data_t as in-use */
+	node_data[nid] = (pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT));
+#endif
+	/* Quasi-mark the pg_data_t as in-use */
 	min_low_pfn += node_datasz;
 	if (min_low_pfn >= max_low_pfn) {
-		printk(" not enough mem to reserve PLAT_NODE_DATA");
+		printk(" not enough mem to reserve NODE_DATA");
 		return;
 	}
-	NODE_DATA(nid)->bdata = &plat_node_bdata[nid];
+	NODE_DATA(nid)->bdata = &node_bdata[nid];
 
 	printk(" Detected node memory:   start %8lu, end %8lu\n",
 	       min_low_pfn, max_low_pfn);
 
-	DBGDCONT(" DISCONTIG: plat_node_data[%d]   is at 0x%p\n", nid, PLAT_NODE_DATA(nid));
+	DBGDCONT(" DISCONTIG: node_data[%d]   is at 0x%p\n", nid, NODE_DATA(nid));
 	DBGDCONT(" DISCONTIG: NODE_DATA(%d)->bdata is at 0x%p\n", nid, NODE_DATA(nid)->bdata);
 
 	/* Find the bounds of kernel memory.  */
@@ -286,8 +292,8 @@
 	dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 
 	for (nid = 0; nid < numnodes; nid++) {
-		unsigned long start_pfn = plat_node_bdata[nid].node_boot_start >> PAGE_SHIFT;
-		unsigned long end_pfn = plat_node_bdata[nid].node_low_pfn;
+		unsigned long start_pfn = node_bdata[nid].node_boot_start >> PAGE_SHIFT;
+		unsigned long end_pfn = node_bdata[nid].node_low_pfn;
 
 		if (dma_local_pfn >= end_pfn - start_pfn)
 			zones_size[ZONE_DMA] = end_pfn - start_pfn;
@@ -302,52 +308,6 @@
 	memset((void *)ZERO_PGE, 0, PAGE_SIZE);
 }
 
-#define printkdot()					\
-do {							\
-	if (!(i++ % ((100UL*1024*1024)>>PAGE_SHIFT)))	\
-		printk(".");				\
-} while(0)
-
-#define clobber(p, size) memset((p)->virtual, 0xaa, (size))
-
-void __init mem_stress(void)
-{
-	LIST_HEAD(x);
-	LIST_HEAD(xx);
-	struct page * p;
-	unsigned long i = 0;
-
-	printk("starting memstress");
-	while ((p = alloc_pages(GFP_ATOMIC, 1))) {
-		clobber(p, PAGE_SIZE*2);
-		list_add(&p->list, &x);
-		printkdot();
-	}
-	while ((p = alloc_page(GFP_ATOMIC))) {
-		clobber(p, PAGE_SIZE);
-		list_add(&p->list, &xx);
-		printkdot();
-	}
-	while (!list_empty(&x)) {
-		p = list_entry(x.next, struct page, list);
-		clobber(p, PAGE_SIZE*2);
-		list_del(x.next);
-		__free_pages(p, 1);
-		printkdot();
-	}
-	while (!list_empty(&xx)) {
-		p = list_entry(xx.next, struct page, list);
-		clobber(p, PAGE_SIZE);
-		list_del(xx.next);
-		__free_pages(p, 0);
-		printkdot();
-	}
-	printk("I'm still alive duh!\n");
-}
-
-#undef printkdot
-#undef clobber
-
 void __init mem_init(void)
 {
 	unsigned long codesize, reservedpages, datasize, initsize, pfn;
@@ -355,9 +315,9 @@
 	extern char _text, _etext, _data, _edata;
 	extern char __init_begin, __init_end;
 	unsigned long nid, i;
-	mem_map_t * lmem_map;
+	struct page * lmem_map;
 
-	high_memory = (void *) __va(max_mapnr <<PAGE_SHIFT);
+	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 
 	reservedpages = 0;
 	for (nid = 0; nid < numnodes; nid++) {
@@ -366,9 +326,9 @@
 		 */
 		totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
 
-		lmem_map = NODE_MEM_MAP(nid);
+		lmem_map = node_mem_map(nid);
 		pfn = NODE_DATA(nid)->node_start_pfn;
-		for (i = 0; i < PLAT_NODE_DATA_SIZE(nid); i++, pfn++)
+		for (i = 0; i < node_size(nid); i++, pfn++)
 			if (page_is_ram(pfn) && PageReserved(lmem_map+i))
 				reservedpages++;
 	}
@@ -401,8 +361,8 @@
 	show_free_areas();
 	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
 	for (nid = 0; nid < numnodes; nid++) {
-		mem_map_t * lmem_map = NODE_MEM_MAP(nid);
-		i = PLAT_NODE_DATA_SIZE(nid);
+		struct page * lmem_map = node_mem_map(nid);
+		i = node_size(nid);
 		while (i-- > 0) {
 			total++;
 			if (PageReserved(lmem_map+i))
@@ -420,5 +380,4 @@
 	printk("%ld reserved pages\n",reserved);
 	printk("%ld pages shared\n",shared);
 	printk("%ld pages swap cached\n",cached);
-	printk("%ld pages in page table cache\n",pgtable_cache_size);
 }
diff -Nru a/arch/alpha/mm/remap.c b/arch/alpha/mm/remap.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/alpha/mm/remap.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,90 @@
+#include <linux/vmalloc.h>
+#include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
+
+/* called with the page_table_lock held */
+static inline void 
+remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, 
+	       unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+	unsigned long pfn;
+
+	address &= ~PMD_MASK;
+	end = address + size;
+	if (end > PMD_SIZE)
+		end = PMD_SIZE;
+	if (address >= end)
+		BUG();
+	pfn = phys_addr >> PAGE_SHIFT;
+	do {
+		if (!pte_none(*pte)) {
+			printk("remap_area_pte: page already exists\n");
+			BUG();
+		}
+		set_pte(pte, pfn_pte(pfn, 
+				     __pgprot(_PAGE_VALID | _PAGE_ASM | 
+				              _PAGE_KRE | _PAGE_KWE | flags)));
+		address += PAGE_SIZE;
+		pfn++;
+		pte++;
+	} while (address && (address < end));
+}
+
+/* called with the page_table_lock held */
+static inline int 
+remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, 
+	       unsigned long phys_addr, unsigned long flags)
+{
+	unsigned long end;
+
+	address &= ~PGDIR_MASK;
+	end = address + size;
+	if (end > PGDIR_SIZE)
+		end = PGDIR_SIZE;
+	phys_addr -= address;
+	if (address >= end)
+		BUG();
+	do {
+		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
+		if (!pte)
+			return -ENOMEM;
+		remap_area_pte(pte, address, end - address, 
+				     address + phys_addr, flags);
+		address = (address + PMD_SIZE) & PMD_MASK;
+		pmd++;
+	} while (address && (address < end));
+	return 0;
+}
+
+int
+__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr,
+			 unsigned long size, unsigned long flags)
+{
+	pgd_t * dir;
+	int error = 0;
+	unsigned long end = address + size;
+
+	phys_addr -= address;
+	dir = pgd_offset(&init_mm, address);
+	flush_cache_all();
+	if (address >= end)
+		BUG();
+	spin_lock(&init_mm.page_table_lock);
+	do {
+		pmd_t *pmd;
+		pmd = pmd_alloc(&init_mm, dir, address);
+		error = -ENOMEM;
+		if (!pmd)
+			break;
+		if (remap_area_pmd(pmd, address, end - address,
+			           phys_addr + address, flags))
+			break;
+		error = 0;
+		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+		dir++;
+	} while (address && (address < end));
+	spin_unlock(&init_mm.page_table_lock);
+	return error;
+}
+
diff -Nru a/arch/alpha/vmlinux.lds.S b/arch/alpha/vmlinux.lds.S
--- a/arch/alpha/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
+++ b/arch/alpha/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
@@ -1,6 +1,8 @@
 #include <linux/config.h>
+#include <asm-generic/vmlinux.lds.h>
 
 OUTPUT_FORMAT("elf64-alpha")
+OUTPUT_ARCH(alpha)
 ENTRY(__start)
 PHDRS { kernel PT_LOAD ; }
 jiffies = jiffies_64;
@@ -9,67 +11,43 @@
 #ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
   . = 0xfffffc0000310000;
 #else
-  . = 0xfffffc0000810000;
+  . = 0xfffffc0001010000;
 #endif
 
-  .text : {
-	_text = .;
-	*(.text)
-	_etext = .;
+  _text = .;					/* Text and read-only data */
+  .text : { 
+	*(.text) 
+	*(.fixup)
+	*(.gnu.warning)
   } :kernel
+  _etext = .;					/* End of text section */
 
-  /* Exception table */
-  __ex_table ALIGN(16) : {
-	__start___ex_table = .;
-	*(__ex_table)
-	__stop___ex_table = .;
-  }
-
-  /* Kernel symbol table */
-  __ksymtab ALIGN(8) : {
-	__start___ksymtab = .;
-	*(__ksymtab)
-	__stop___ksymtab = .;
-  }
-
-  /* Kernel symbol table: GPL only */
-  __gpl_ksymtab ALIGN(8) : {
-	__start___gpl_ksymtab = .;
-	*(__gpl_ksymtab)
-	__stop___gpl_ksymtab = .;
-  }
-
-  /* All kernel symbols */
-  __kallsyms ALIGN(8) : {
-	__start___kallsyms = .;
-	*(__kallsyms)
-	__stop___kallsyms = .;
-  }
-
-  .kstrtab : { *(.kstrtab) }
-  .rodata : { *(.rodata) *(.rodata.*) }
-
-  /* Startup code */
-  .init.text ALIGN(8192) : {
-	__init_begin = .;
-	*(.init.text)
-  }
+  . = ALIGN(16);
+  __start___ex_table = .;			/* Exception table */
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  RODATA
+
+  /* Will be freed after init */
+  . = ALIGN(8192);				/* Init code and data */
+  __init_begin = .;
+  .init.text : { *(.init.text) }
   .init.data : { *(.init.data) }
 
-  .init.setup ALIGN(16): {
-	__setup_start = .;
-	*(.init.setup)
-	__setup_end = .;
-  }
-
-  __param ALIGN(8): {
-	__start___param = .;
-	*(__param)
-	__stop___param = .;
-  }
-
-  .initcall.init ALIGN(8): {
-	__initcall_start = .;
+  . = ALIGN(16);
+  __setup_start = .;
+  .init.setup : { *(.init.setup) }
+  __setup_end = .;
+
+  . = ALIGN(8);
+  __start___param = .;
+  __param : { *(__param) }
+  __stop___param = .;
+
+  . = ALIGN(8);
+  __initcall_start = .;
+  .initcall.init : {
 	*(.initcall1.init) 
 	*(.initcall2.init) 
 	*(.initcall3.init) 
@@ -77,54 +55,64 @@
 	*(.initcall5.init) 
 	*(.initcall6.init) 
 	*(.initcall7.init)
-	__initcall_end = .;
   }
+  __initcall_end = .;
 
-  .init.ramfs ALIGN(8192): {
-	__initramfs_start = .;
-	*(.init.ramfs)
-	__initramfs_end = .;
-  }
+  . = ALIGN(8192);
+  __initramfs_start = .;
+  .init.ramfs : { *(.init.ramfs) }
+  __initramfs_end = .;
 
-  .data.percpu ALIGN(64): {
-	__per_cpu_start = .;
-	*(.data.percpu)
-	__per_cpu_end = .;
-  }
+  . = ALIGN(64);
+  __per_cpu_start = .;
+  .data.percpu : { *(.data.percpu) }
+  __per_cpu_end = .;
 
-  /* The initial task and kernel stack */
-  .data.init_thread ALIGN(2*8192) : {
-	__init_end = .;
-	*(.data.init_thread)
-  }
+  . = ALIGN(2*8192);
+  __init_end = .;
+  /* Freed after init ends here */
 
-  /* Global data */
-  .data.page_aligned ALIGN(8192) : {
-	_data = .;
-	*(.data.page_aligned) 
-  }
+  /* Note 2 page alignment above.  */
+  .data.init_thread : { *(.data.init_thread) }
+
+  . = ALIGN(8192);
+  .data.page_aligned : { *(.data.page_aligned) }
+
+  . = ALIGN(64);
   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-  .data : { *(.data) CONSTRUCTORS }
-  .got : { *(.got) }
-  .sdata : {
-	*(.sdata)
-	_edata = .;
-  }
 
-  .sbss : {
-	__bss_start = .;
-	*(.sbss) *(.scommon)
-  }
-  .bss : {
-	*(.bss) *(COMMON)
-	__bss_stop = .;
-	_end = .;
+  _data = .;
+  .data : {					/* Data */
+	*(.data)
+	CONSTRUCTORS
   }
 
+  .got : { *(.got) }
+  .sdata : { *(.sdata) }
+
+  _edata = .;					/* End of data section */
+
+  __bss_start = .;
+  .sbss : { *(.sbss) *(.scommon) }
+  .bss : { *(.bss) *(COMMON) }
+  __bss_stop = .;
+
+  _end = .;
+
+  /* Sections to be discarded */
+  /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) }
+
   .mdebug 0 : { *(.mdebug) }
   .note 0 : { *(.note) }
   .comment 0 : { *(.comment) }
 
+  /* Stabs debugging sections */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
   /* DWARF 1 */
   .debug          0 : { *(.debug) }
   .line           0 : { *(.line) }
@@ -147,6 +135,4 @@
   .debug_funcnames 0 : { *(.debug_funcnames) }
   .debug_typenames 0 : { *(.debug_typenames) }
   .debug_varnames  0 : { *(.debug_varnames) }
-
-  /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) }
 }
diff -Nru a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
--- a/arch/arm/kernel/bios32.c	Thu Jan 16 18:23:05 2003
+++ b/arch/arm/kernel/bios32.c	Thu Jan 16 18:23:05 2003
@@ -11,7 +11,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 
-#include <asm/page.h> /* for BUG() */
+#include <asm/bug.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
diff -Nru a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
--- a/arch/arm/kernel/calls.S	Thu Jan 16 18:23:07 2003
+++ b/arch/arm/kernel/calls.S	Thu Jan 16 18:23:07 2003
@@ -10,7 +10,7 @@
  *  This file is included twice in entry-common.S
  */
 #ifndef NR_syscalls
-#define NR_syscalls 256
+#define NR_syscalls 288
 #else
 
 __syscall_start:
@@ -253,6 +253,24 @@
 		.long	sys_lremovexattr
 		.long	sys_fremovexattr
 		.long	sys_tkill
+		.long	sys_sendfile64
+/* 240 */	.long	sys_futex
+		.long	sys_sched_setaffinity
+		.long	sys_sched_getaffinity
+		.long	sys_io_setup
+		.long	sys_io_destroy
+/* 245 */	.long	sys_io_getevents
+		.long	sys_io_submit
+		.long	sys_io_cancel
+		.long	sys_exit_group
+		.long	sys_lookup_dcookie
+/* 250 */	.long	sys_epoll_create
+		.long	sys_epoll_ctl
+		.long	sys_epoll_wait
+	 	.long	sys_remap_file_pages
+		.long	sys_ni_syscall	/* sys_set_thread_area */
+/* 255 */	.long	sys_ni_syscall	/* sys_get_thread_area */
+ 		.long	sys_ni_syscall	/* sys_set_tid_address */
 __syscall_end:
 
 		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
diff -Nru a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
--- a/arch/arm/kernel/process.c	Thu Jan 16 18:23:06 2003
+++ b/arch/arm/kernel/process.c	Thu Jan 16 18:23:06 2003
@@ -91,15 +91,16 @@
 void cpu_idle(void)
 {
 	/* endless idle loop with no priority at all */
-	preempt_disable();
 	while (1) {
 		void (*idle)(void) = pm_idle;
 		if (!idle)
 			idle = default_idle;
+		preempt_disable();
 		leds_event(led_idle_start);
 		while (!need_resched())
 			idle();
 		leds_event(led_idle_end);
+		preempt_enable();
 		schedule();
 	}
 }
diff -Nru a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
--- a/arch/arm/mach-integrator/cpu.c	Thu Jan 16 18:23:05 2003
+++ b/arch/arm/mach-integrator/cpu.c	Thu Jan 16 18:23:05 2003
@@ -228,4 +228,4 @@
 	return 0;
 }
 
-core_initcall(integrator_cpu_init);
+arch_initcall(integrator_cpu_init);
diff -Nru a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
--- a/arch/arm/mach-sa1100/cpu-sa1100.c	Thu Jan 16 18:23:05 2003
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c	Thu Jan 16 18:23:05 2003
@@ -232,4 +232,4 @@
 	return ret;
 }
 
-core_initcall(sa1100_dram_init);
+arch_initcall(sa1100_dram_init);
diff -Nru a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
--- a/arch/arm/mach-sa1100/cpu-sa1110.c	Thu Jan 16 18:23:05 2003
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c	Thu Jan 16 18:23:05 2003
@@ -345,4 +345,4 @@
 	return 0;
 }
 
-core_initcall(sa1110_clk_init);
+arch_initcall(sa1110_clk_init);
diff -Nru a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
--- a/arch/arm/tools/mach-types	Thu Jan 16 18:23:05 2003
+++ b/arch/arm/tools/mach-types	Thu Jan 16 18:23:05 2003
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Mon Dec 23 18:49:04 2002
+# Last update: Mon Jan 13 22:55:16 2003
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -198,7 +198,7 @@
 ta7			ARCH_TA7		TA7			187
 nova			SA1100_NOVA		NOVA			188
 hmk			ARCH_HMK		HMK			189
-inphinity		ARCH_INPHINITY		INPHINITY		190
+karo			ARCH_KARO		KARO			190
 fester			SA1100_FESTER		FESTER			191
 gpi			ARCH_GPI		GPI			192
 smdk2410		ARCH_SMDK2410		SMDK2410		193
@@ -273,3 +273,11 @@
 at91rm9200dk		ARCH_AT91RM9200DK	AT91RM9200DK		262
 armstick		ARCH_ARMSTICK		ARMSTICK		263
 armonie			ARCH_ARMONIE		ARMONIE			264
+mport1			ARCH_MPORT1		MPORT1			265
+s3c5410			ARCH_S3C5410		S3C5410			266
+zcp320a			ARCH_ZCP320A		ZCP320A			267
+i_box			ARCH_I_BOX		I_BOX			268
+stlc1502		ARCH_STLC1502		STLC1502		269
+siren			ARCH_SIREN		SIREN			270
+greenlake		ARCH_GREENLAKE		GREENLAKE		271
+argus			ARCH_ARGUS		ARGUS			272
diff -Nru a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in
--- a/arch/arm/vmlinux-armo.lds.in	Thu Jan 16 18:23:07 2003
+++ b/arch/arm/vmlinux-armo.lds.in	Thu Jan 16 18:23:07 2003
@@ -2,6 +2,9 @@
  * taken from the i386 version by Russell King
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  */
+
+#include <asm-generic/vmlinux.lds.h>
+	
 OUTPUT_ARCH(arm)
 ENTRY(stext)
 jiffies = jiffies_64;
@@ -63,8 +66,6 @@
 		_etext = .;		/* End of text section		*/
 	}
 
-	.kstrtab : { *(.kstrtab) }
-
 	. = ALIGN(16);
 	__ex_table : {			/* Exception table		*/
 		__start___ex_table = .;
@@ -72,17 +73,7 @@
 		__stop___ex_table = .;
 	}
 
-	__ksymtab : {			/* Kernel symbol table		*/
-		__start___ksymtab = .;
-			*(__ksymtab)
-		__stop___ksymtab = .;
-	}
-
-	__gpl_ksymtab : {		/* Kernel symbol table: GPL-only */
-		__start___gpl_ksymtab = .;
-			*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-	}
+	RODATA
 
 	.data : {
 		/*
diff -Nru a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in
--- a/arch/arm/vmlinux-armv.lds.in	Thu Jan 16 18:23:05 2003
+++ b/arch/arm/vmlinux-armv.lds.in	Thu Jan 16 18:23:05 2003
@@ -2,6 +2,9 @@
  * taken from the i386 version by Russell King
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  */
+
+#include <asm-generic/vmlinux.lds.h>
+	
 OUTPUT_ARCH(arm)
 ENTRY(stext)
 jiffies = jiffies_64;
@@ -66,8 +69,6 @@
 		_etext = .;		/* End of text section		*/
 	}
 
-	.kstrtab : { *(.kstrtab) }
-
 	. = ALIGN(16);
 	__ex_table : {			/* Exception table		*/
 		__start___ex_table = .;
@@ -75,23 +76,7 @@
 		__stop___ex_table = .;
 	}
 
-	__gpl_ksymtab : {		/* GPL Kernel symbol table	*/
-		__start___gpl_ksymtab = .;
-			*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-	}
-
-	__ksymtab : {			/* Kernel symbol table		*/
-		__start___ksymtab = .;
-			*(__ksymtab)
-		__stop___ksymtab = .;
-	}
-
-	__kallsyms : {			/* All kernel symbols		*/
-		__start___kallsyms = .;
-			*(__kallsyms)
-		__stop___kallsyms = .;
-	}
+	RODATA
 
 	. = ALIGN(8192);
 
diff -Nru a/arch/cris/vmlinux.lds.S b/arch/cris/vmlinux.lds.S
--- a/arch/cris/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/cris/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -9,7 +9,8 @@
  */	
 
 #include <linux/config.h>
-	
+#include <asm-generic/vmlinux.lds.h>
+
 jiffies = jiffies_64;
 SECTIONS
 {
@@ -31,21 +32,12 @@
 	_etext = . ;                  /* End of text section */ 
 	__etext = .;
 
-	.rodata : { *(.rodata) *(.rodata.__*) }
-	.kstrtab : { *(.kstrtab) }
-
 	. = ALIGN(4);                /* Exception table */
   	__start___ex_table = .;
   	__ex_table : { *(__ex_table) }
   	__stop___ex_table = .;
 
-  	__start___ksymtab = .;        /* Kernel symbol table */
-  	__ksymtab : { *(__ksymtab) }
-  	__stop___ksymtab = .;
-
-	__start___gpl_ksymtab = .;    /* Kernel symbol table: GPL-only */
-	__gpl_ksymtab : { *(__gpl_ksymtab) }
-	__stop___gpl_ksymtab = .;
+	RODATA
 
 	. = ALIGN (4);
 	___data_start = . ;
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Thu Jan 16 18:23:05 2003
+++ b/arch/i386/Kconfig	Thu Jan 16 18:23:05 2003
@@ -1181,6 +1181,8 @@
 
 	  Otherwise, say N.
 
+source "drivers/eisa/Kconfig"
+
 config MCA
 	bool "MCA support"
 	depends on !(X86_VISWS || X86_VOYAGER)
diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/i386/Makefile	Thu Jan 16 18:23:05 2003
@@ -69,6 +69,10 @@
 mflags-$(CONFIG_X86_BIGSMP)	:= -Iinclude/asm-i386/mach-bigsmp
 mcore-$(CONFIG_X86_BIGSMP)	:= mach-default
 
+#Summit subarch support
+mflags-$(CONFIG_X86_SUMMIT) := -Iinclude/asm-i386/mach-summit
+mcore-$(CONFIG_X86_SUMMIT)  := mach-default
+
 # default subarch .h files
 mflags-y += -Iinclude/asm-i386/mach-default
 
diff -Nru a/arch/i386/defconfig b/arch/i386/defconfig
--- a/arch/i386/defconfig	Thu Jan 16 18:23:06 2003
+++ b/arch/i386/defconfig	Thu Jan 16 18:23:06 2003
@@ -839,11 +839,6 @@
 CONFIG_SOUND=y
 
 #
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
 # Advanced Linux Sound Architecture
 #
 CONFIG_SND=y
@@ -922,6 +917,11 @@
 # ALSA USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
 
 #
 # USB support
diff -Nru a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c
--- a/arch/i386/kernel/acpi.c	Thu Jan 16 18:23:06 2003
+++ b/arch/i386/kernel/acpi.c	Thu Jan 16 18:23:06 2003
@@ -44,6 +44,8 @@
 #include <asm/io_apic.h>
 #include <asm/tlbflush.h>
 
+#include <mach_apic.h>
+#include <mach_mpparse.h>
 
 #define PREFIX			"ACPI: "
 
@@ -126,6 +128,8 @@
 	printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n",
 		madt->lapic_address);
 
+	acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
+	
 	return 0;
 }
 
@@ -430,8 +434,10 @@
 #endif /*CONFIG_X86_IO_APIC*/
 
 #ifdef CONFIG_X86_LOCAL_APIC
-	if (acpi_lapic && acpi_ioapic)
+	if (acpi_lapic && acpi_ioapic) {
 		smp_found_config = 1;
+		clustered_apic_check();
+	}
 #endif
 
 	return 0;
diff -Nru a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
--- a/arch/i386/kernel/cpu/amd.c	Thu Jan 16 18:23:07 2003
+++ b/arch/i386/kernel/cpu/amd.c	Thu Jan 16 18:23:07 2003
@@ -56,7 +56,7 @@
 				if (inl (CBAR) & CBAR_ENB)
 					outl (0 | CBAR_KEY, CBAR);
 			}
-
+			break;
 		case 5:
 			if( c->x86_model < 6 )
 			{
diff -Nru a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	Thu Jan 16 18:23:05 2003
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	Thu Jan 16 18:23:05 2003
@@ -482,6 +482,7 @@
 	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 	driver->verify = &cpufreq_gx_verify;
 	driver->setpolicy = &cpufreq_gx_setpolicy;
+	strncpy(driver->name, "gx-suspmod", CPUFREQ_NAME_LEN);
 
 	gx_driver = driver;
 
diff -Nru a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
--- a/arch/i386/kernel/cpu/proc.c	Thu Jan 16 18:23:06 2003
+++ b/arch/i386/kernel/cpu/proc.c	Thu Jan 16 18:23:06 2003
@@ -22,7 +22,7 @@
 	        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
 	        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
 	        "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-	        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
+	        "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
 
 		/* AMD-defined */
 		NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	Thu Jan 16 18:23:05 2003
+++ b/arch/i386/kernel/entry.S	Thu Jan 16 18:23:05 2003
@@ -126,7 +126,8 @@
 	addl $4, %esp;	\
 1:	iret;		\
 .section .fixup,"ax";   \
-2:	movl $(__USER_DS), %edx; \
+2:	sti;		\
+	movl $(__USER_DS), %edx; \
 	movl %edx, %ds; \
 	movl %edx, %es; \
 	pushl $11;	\
@@ -154,17 +155,6 @@
 	movl %eax,EFLAGS(%ebp)	#
 	movl %edx,EIP(%ebp)	# Now we move them to their "normal" places
 	movl %ecx,CS(%ebp)	#
-
-	#
-	# Call gates don't clear TF and NT in eflags like
-	# traps do, so we need to do it ourselves.
-	# %eax already contains eflags (but it may have
-	# DF set, clear that also)
-	#
-	andl $~(DF_MASK | TF_MASK | NT_MASK),%eax
-	pushl %eax
-	popfl
-
 	andl $-8192, %ebp	# GET_THREAD_INFO
 	movl TI_EXEC_DOMAIN(%ebp), %edx	# Get the execution domain
 	call *4(%edx)		# Call the lcall7 handler for the domain
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Thu Jan 16 18:23:05 2003
+++ b/arch/i386/kernel/io_apic.c	Thu Jan 16 18:23:05 2003
@@ -278,7 +278,7 @@
 		new_cpu = move(entry->cpu, allowed_mask, now, random_number);
 		if (entry->cpu != new_cpu) {
 			entry->cpu = new_cpu;
-			set_ioapic_affinity(irq, 1 << new_cpu);
+			set_ioapic_affinity(irq, cpu_to_logical_apicid(new_cpu));
 		}
 	}
 }
@@ -719,8 +719,8 @@
 		 */
 		memset(&entry,0,sizeof(entry));
 
-		entry.delivery_mode = dest_LowestPrio;
-		entry.dest_mode = INT_DELIVERY_MODE;
+		entry.delivery_mode = INT_DELIVERY_MODE;
+		entry.dest_mode = INT_DEST_MODE;
 		entry.mask = 0;				/* enable IRQ */
 		entry.dest.logical.logical_dest = TARGET_CPUS;
 
@@ -799,10 +799,10 @@
 	 * We use logical delivery to get the timer IRQ
 	 * to the first CPU.
 	 */
-	entry.dest_mode = INT_DELIVERY_MODE;
+	entry.dest_mode = INT_DEST_MODE;
 	entry.mask = 0;					/* unmask IRQ now */
 	entry.dest.logical.logical_dest = TARGET_CPUS;
-	entry.delivery_mode = dest_LowestPrio;
+	entry.delivery_mode = INT_DELIVERY_MODE;
 	entry.polarity = 0;
 	entry.trigger = 0;
 	entry.vector = vector;
@@ -1763,7 +1763,7 @@
 
 #ifdef CONFIG_ACPI_BOOT
 
-#define IO_APIC_MAX_ID		15
+#define IO_APIC_MAX_ID APIC_BROADCAST_ID
 
 int __init io_apic_get_unique_id (int ioapic, int apic_id)
 {
@@ -1880,8 +1880,8 @@
 
 	memset(&entry,0,sizeof(entry));
 
-	entry.delivery_mode = dest_LowestPrio;
-	entry.dest_mode = INT_DELIVERY_MODE;
+	entry.delivery_mode = INT_DELIVERY_MODE;
+	entry.dest_mode = INT_DEST_MODE;
 	entry.dest.logical.logical_dest = TARGET_CPUS;
 	entry.mask = 1;					 /* Disabled (masked) */
 	entry.trigger = 1;				   /* Level sensitive */
diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c	Thu Jan 16 18:23:05 2003
+++ b/arch/i386/kernel/mpparse.c	Thu Jan 16 18:23:05 2003
@@ -72,8 +72,8 @@
 /* Bitmask of physically existing CPUs */
 unsigned long phys_cpu_present_map;
 
-int summit_x86 = 0;
-u8 raw_phys_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+int x86_summit = 0;
+u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
 
 /*
  * Intel MP BIOS table parsing routines:
@@ -186,7 +186,7 @@
 		ver = 0x10;
 	}
 	apic_version[m->mpc_apicid] = ver;
-	raw_phys_apicid[num_processors - 1] = m->mpc_apicid;
+	bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
 }
 
 static void __init MP_bus_info (struct mpc_config_bus *m)
diff -Nru a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
--- a/arch/i386/kernel/smp.c	Thu Jan 16 18:23:05 2003
+++ b/arch/i386/kernel/smp.c	Thu Jan 16 18:23:05 2003
@@ -24,6 +24,7 @@
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <mach_ipi.h>
+#include <mach_apic.h>
 
 /*
  *	Some notes on x86 processor bugs affecting SMP operation:
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Thu Jan 16 18:23:05 2003
+++ b/arch/i386/kernel/smpboot.c	Thu Jan 16 18:23:05 2003
@@ -1045,10 +1045,10 @@
 		/*
 		 * Don't even attempt to start the boot CPU!
 		 */
-		if (apicid == boot_cpu_apicid)
+		if ((apicid == boot_cpu_apicid) || (apicid == BAD_APICID))
 			continue;
 
-		if (!(phys_cpu_present_map & (1 << bit)))
+		if (!check_apicid_present(bit))
 			continue;
 		if (max_cpus <= cpucount+1)
 			continue;
diff -Nru a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S
--- a/arch/i386/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/i386/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -1,6 +1,9 @@
 /* ld script to make i386 Linux kernel
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
  */
+
+#include <asm-generic/vmlinux.lds.h>
+	
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
 ENTRY(_start)
@@ -18,26 +21,12 @@
 
   _etext = .;			/* End of text section */
 
-  .rodata : { *(.rodata) *(.rodata.*) }
-  .kstrtab : { *(.kstrtab) }
-
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  . = ALIGN(64);
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-
-  __start___kallsyms = .;       /* All kernel symbols */
-  __kallsyms : { *(__kallsyms) }
-  __stop___kallsyms = .;
+  RODATA
 
   /* writeable */
   .data : {			/* Data */
diff -Nru a/arch/ia64/defconfig b/arch/ia64/defconfig
--- a/arch/ia64/defconfig	Thu Jan 16 18:23:05 2003
+++ b/arch/ia64/defconfig	Thu Jan 16 18:23:05 2003
@@ -657,6 +657,11 @@
 CONFIG_SOUND=y
 
 #
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=y
@@ -679,11 +684,6 @@
 # CONFIG_SOUND_VIA82CXXX is not set
 # CONFIG_SOUND_OSS is not set
 # CONFIG_SOUND_TVMIXER is not set
-
-#
-# Advanced Linux Sound Architecture
-#
-# CONFIG_SND is not set
 
 #
 # USB support
diff -Nru a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S
--- a/arch/ia64/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
+++ b/arch/ia64/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
@@ -4,6 +4,9 @@
 #include <asm/ptrace.h>
 #include <asm/system.h>
 
+#define LOAD_OFFSET PAGE_OFFSET
+#include <asm-generic/vmlinux.lds.h>
+	
 OUTPUT_FORMAT("elf64-ia64-little")
 OUTPUT_ARCH(ia64)
 ENTRY(phys_start)
@@ -60,23 +63,6 @@
   machvec_end = .;
 #endif
 
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : AT(ADDR(__ksymtab) - PAGE_OFFSET)
-	{ *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL only */
-  __gpl_ksymtab : AT(ADDR(__gpl_ksymtab) - PAGE_OFFSET)
-	{ *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-
-  __kallsyms : AT(ADDR(__kallsyms) - PAGE_OFFSET)
-	{
-	  __start___kallsyms = .;	/* All kernel symbols */
-	  *(__kallsyms)
-	  __stop___kallsyms = .;
-	}
-
   /* Unwind info & table: */
   . = ALIGN(8);
   .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET)
@@ -86,10 +72,8 @@
 	{ *(.IA_64.unwind*) }
   ia64_unw_end = .;
 
-  .rodata : AT(ADDR(.rodata) - PAGE_OFFSET)
-	{ *(.rodata) *(.rodata.*) }
-  .kstrtab : AT(ADDR(.kstrtab) - PAGE_OFFSET)
-	{ *(.kstrtab) }
+  RODATA
+
   .opd : AT(ADDR(.opd) - PAGE_OFFSET)
 	{ *(.opd) }
 
diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig	Thu Jan 16 18:23:06 2003
+++ b/arch/m68k/Kconfig	Thu Jan 16 18:23:06 2003
@@ -1720,6 +1720,31 @@
 	tristate "Generic /dev/rtc emulation" if !SUN3
 	depends on !ATARI
 	default y if SUN3
+	---help---
+	  If you say Y here and create a character special file /dev/rtc with
+	  major number 10 and minor number 135 using mknod ("man mknod"), you
+	  will get access to the real time clock (or hardware clock) built
+	  into your computer.
+
+	  It reports status information via the file /proc/driver/rtc and its
+	  behaviour is set by various ioctls on /dev/rtc. If you enable the
+	  "extended RTC operation" below it will also provide an emulation
+	  for RTC_UIE which is required by some programs and may improve
+	  precision in some cases.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module is called genrtc.o. If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>. To load the
+	  module automatically add 'alias char-major-10-135 genrtc' to your
+	  /etc/modules.conf
+
+config GEN_RTC_X
+	bool "Extended RTC operation"
+	depends on GEN_RTC
+	help
+	  Provides an emulation for RTC_UIE which is required by some programs
+	  and may improve precision of the generic RTC support in some cases.
 
 config UNIX98_PTYS
 	bool "Unix98 PTY support"
diff -Nru a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
--- a/arch/m68k/atari/stram.c	Thu Jan 16 18:23:06 2003
+++ b/arch/m68k/atari/stram.c	Thu Jan 16 18:23:06 2003
@@ -540,7 +540,6 @@
 	p->flags        = SWP_USED;
 	p->swap_file    = &fake_dentry;
 	p->swap_vfsmnt  = &fake_vfsmnt;
-	p->swap_device  = 0;
 	p->swap_map	= swap_data;
 	p->cluster_nr   = 0;
 	p->next         = -1;
@@ -549,8 +548,7 @@
 
 	/* call stram_open() directly, avoids at least the overhead in
 	 * constructing a dummy file structure... */
-	p->swap_device = MKDEV( STRAM_MAJOR, STRAM_MINOR );
-	swap_inode.i_rdev = p->swap_device;
+	swap_inode.i_rdev = MKDEV( STRAM_MAJOR, STRAM_MINOR );
 	stram_open( &swap_inode, MAGIC_FILE_P );
 	p->max = SWAP_NR(swap_end);
 
diff -Nru a/arch/m68k/kernel/m68k_defs.c b/arch/m68k/kernel/m68k_defs.c
--- a/arch/m68k/kernel/m68k_defs.c	Thu Jan 16 18:23:05 2003
+++ b/arch/m68k/kernel/m68k_defs.c	Thu Jan 16 18:23:05 2003
@@ -14,7 +14,7 @@
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
 #include <asm/amigahw.h>
-#include <video/font.h>
+#include <linux/font.h>
 
 #define DEFINE(sym, val) \
 	asm volatile("\n#define " #sym " %c0" : : "i" (val))
diff -Nru a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
--- a/arch/m68k/kernel/m68k_ksyms.c	Thu Jan 16 18:23:06 2003
+++ b/arch/m68k/kernel/m68k_ksyms.c	Thu Jan 16 18:23:06 2003
@@ -50,6 +50,9 @@
 #endif /* !CONFIG_SUN3 */
 EXPORT_SYMBOL(m68k_debug_device);
 EXPORT_SYMBOL(mach_hwclk);
+EXPORT_SYMBOL(mach_get_ss);
+EXPORT_SYMBOL(mach_get_rtc_pll);
+EXPORT_SYMBOL(mach_set_rtc_pll);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(dump_thread);
 EXPORT_SYMBOL(strnlen);
diff -Nru a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
--- a/arch/m68k/kernel/setup.c	Thu Jan 16 18:23:07 2003
+++ b/arch/m68k/kernel/setup.c	Thu Jan 16 18:23:07 2003
@@ -82,6 +82,7 @@
 unsigned long (*mach_gettimeoffset) (void);
 int (*mach_hwclk) (int, struct rtc_time*) = NULL;
 int (*mach_set_clock_mmss) (unsigned long) = NULL;
+unsigned int (*mach_get_ss)(void) = NULL;
 int (*mach_get_rtc_pll)(struct rtc_pll_info *) = NULL;
 int (*mach_set_rtc_pll)(struct rtc_pll_info *) = NULL;
 void (*mach_reset)( void );
diff -Nru a/arch/m68k/mm/extable.c b/arch/m68k/mm/extable.c
--- a/arch/m68k/mm/extable.c	Thu Jan 16 18:23:07 2003
+++ b/arch/m68k/mm/extable.c	Thu Jan 16 18:23:07 2003
@@ -9,10 +9,11 @@
 extern const struct exception_table_entry __start___ex_table[];
 extern const struct exception_table_entry __stop___ex_table[];
 
-static inline unsigned long
-search_one_table(const struct exception_table_entry *first,
-		 const struct exception_table_entry *last,
-		 unsigned long value)
+/* Simple binary search */
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+	       const struct exception_table_entry *last,
+	       unsigned long value)
 {
         while (first <= last) {
 		const struct exception_table_entry *mid;
@@ -21,41 +22,12 @@
 		mid = (last - first) / 2 + first;
 		diff = value - mid->insn;
 		if (diff >= 0 && diff <= 2)
-			return mid->fixup;
+			return mid;
 		else if (diff > 0)
 			first = mid+1;
 		else
 			last = mid-1;
 	}
-	return 0;
+	return NULL;
 }
 
-unsigned long
-search_exception_table(unsigned long addr)
-{
-	unsigned long ret = 0;
-
-#ifndef CONFIG_MODULES
-	/* There is only the kernel to search.  */
-	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
-	return ret;
-#else
-	unsigned long flags;
-	struct list_head *i;
-
-	/* The kernel is the last "module" -- no need to treat it special.  */
-	spin_lock_irqsave(&modlist_lock, flags);
-	list_for_each(i, &extables) {
-		struct exception_table *ex
-			= list_entry(i, struct exception_table, list);
-		if (ex->num_entries == 0)
-			continue;
-		ret = search_one_table(ex->entry,
-				       ex->entry + ex->num_entries - 1, addr);
-		if (ret)
-			break;
-	}
-	spin_unlock_irqrestore(&modlist_lock, flags);
-	return ret;
-#endif
-}
diff -Nru a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
--- a/arch/m68k/mm/fault.c	Thu Jan 16 18:23:05 2003
+++ b/arch/m68k/mm/fault.c	Thu Jan 16 18:23:05 2003
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 
 #include <asm/setup.h>
 #include <asm/traps.h>
@@ -34,10 +35,10 @@
 		force_sig_info(siginfo.si_signo,
 			       &siginfo, current);
 	} else {
-		unsigned long fixup;
+		const struct exception_table_entry *fixup;
 
 		/* Are we prepared to handle this kernel fault? */
-		if ((fixup = search_exception_table(regs->pc))) {
+		if ((fixup = search_exception_tables(regs->pc))) {
 			struct pt_regs *tregs;
 			/* Create a new four word stack frame, discarding the old
 			   one.  */
@@ -45,7 +46,7 @@
 			tregs =	(struct pt_regs *)((ulong)regs + regs->stkadj);
 			tregs->vector = regs->vector;
 			tregs->format = 0;
-			tregs->pc = fixup;
+			tregs->pc = fixup->fixup;
 			tregs->sr = regs->sr;
 			return -1;
 		}
diff -Nru a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
--- a/arch/m68k/q40/config.c	Thu Jan 16 18:23:06 2003
+++ b/arch/m68k/q40/config.c	Thu Jan 16 18:23:06 2003
@@ -53,7 +53,10 @@
 
 extern unsigned long q40_gettimeoffset (void);
 extern int q40_hwclk (int, struct rtc_time *);
+extern unsigned int q40_get_ss (void);
 extern int q40_set_clock_mmss (unsigned long);
+static int q40_get_rtc_pll(struct rtc_pll_info *pll);
+static int q40_set_rtc_pll(struct rtc_pll_info *pll);
 extern void q40_reset (void);
 void q40_halt(void);
 extern void q40_waitbut(void);
@@ -170,6 +173,9 @@
     mach_init_IRQ        = q40_init_IRQ;   
     mach_gettimeoffset   = q40_gettimeoffset; 
     mach_hwclk           = q40_hwclk; 
+    mach_get_ss          = q40_get_ss;
+    mach_get_rtc_pll     = q40_get_rtc_pll;
+    mach_set_rtc_pll     = q40_set_rtc_pll;
     mach_set_clock_mmss	 = q40_set_clock_mmss;
 
     mach_reset		 = q40_reset;
@@ -290,6 +296,11 @@
 	return 0;
 }
 
+unsigned int q40_get_ss()
+{
+	return bcd2bin(Q40_RTC_SECS);
+}
+
 /*
  * Set the minutes and seconds from seconds value 'nowtime'.  Fail if
  * clock is out by > 30 minutes.  Logic lifted from atari code.
@@ -321,3 +332,36 @@
 	return retval;
 }
 
+
+/* get and set PLL calibration of RTC clock */
+#define Q40_RTC_PLL_MASK ((1<<5)-1)
+#define Q40_RTC_PLL_SIGN (1<<5)
+
+static int q40_get_rtc_pll(struct rtc_pll_info *pll)
+{
+	int tmp=Q40_RTC_CTRL;
+	pll->pll_value = tmp & Q40_RTC_PLL_MASK;
+	if (tmp & Q40_RTC_PLL_SIGN)
+		pll->pll_value = -pll->pll_value;
+	pll->pll_max=31;
+	pll->pll_min=-31;
+	pll->pll_posmult=512;
+	pll->pll_negmult=256;
+	pll->pll_clock=125829120;
+	return 0;
+}
+
+static int q40_set_rtc_pll(struct rtc_pll_info *pll)
+{
+	if (!pll->pll_ctrl){
+		/* the docs are a bit unclear so I am doublesetting */
+		/* RTC_WRITE here ... */
+		int tmp = (pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) |
+			  Q40_RTC_WRITE;
+		Q40_RTC_CTRL |= Q40_RTC_WRITE;
+		Q40_RTC_CTRL = tmp;
+		Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
+		return 0;
+	} else
+		return -EINVAL;
+}
diff -Nru a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
--- a/arch/m68k/q40/q40ints.c	Thu Jan 16 18:23:06 2003
+++ b/arch/m68k/q40/q40ints.c	Thu Jan 16 18:23:06 2003
@@ -207,7 +207,6 @@
 
 int ql_ticks;              /* 200Hz ticks since last jiffie */
 static int sound_ticks;
-short q40rtc_oldsecs;
 
 #define SVOL 45
 
@@ -234,7 +233,6 @@
 
 static void q40_timer_int (int irq, void * dev, struct pt_regs * regs)
 {
-#if (HZ==100)
     ql_ticks = ql_ticks ? 0 : 1;
     if (sound_ticks)
       {
@@ -243,16 +241,9 @@
 	*DAC_LEFT=sval;
 	*DAC_RIGHT=sval;
       }
-#if defined(CONFIG_Q40RTC) || defined(CONFIG_GEN_RTC)
-    if (gen_rtc_irq_ctrl && (q40rtc_oldsecs != Q40_RTC_SECS))
-      {
-	q40rtc_oldsecs = Q40_RTC_SECS;
-	gen_rtc_irq_flags = RTC_UIE;
-	gen_rtc_interrupt(0);
-      }
-#endif
+
     if (ql_ticks) return;
-#endif
+
     q40_timer_routine(irq, dev, regs);
 }
 
@@ -261,30 +252,14 @@
     int timer_irq;
 
     q40_timer_routine = timer_routine;
-
-#if (HZ==10000)
-    timer_irq=Q40_IRQ_SAMPLE;
-#else
     timer_irq=Q40_IRQ_FRAME;
-#endif
-
-    /*printk("registering sched/timer IRQ %d, handler %p\n", timer_irq,q40_timer_int);*/
-    /*printk("timer routine %p\n",q40_timer_routine);*/
 
     if (request_irq(timer_irq, q40_timer_int, 0,
 				"timer", q40_timer_int))
 	panic ("Couldn't register timer int");
 
-#if (HZ==10000)
-    master_outb(SAMPLE_LOW,SAMPLE_RATE_REG);
-    master_outb(-1,SAMPLE_CLEAR_REG);
-    master_outb(1,SAMPLE_ENABLE_REG);
-#else
-    master_outb(-1,FRAME_CLEAR_REG);   /* not necessary ? */
-#if (HZ==100)
+    master_outb(-1,FRAME_CLEAR_REG);
     master_outb( 1,FRAME_RATE_REG);
-#endif
-#endif
 }
 
 
@@ -297,20 +272,20 @@
 struct IRQ_TABLE{ unsigned mask; int irq ;};
 #if 0
 static struct IRQ_TABLE iirqs[]={
-  {IRQ_FRAME_MASK,Q40_IRQ_FRAME},
-  {IRQ_KEYB_MASK,Q40_IRQ_KEYBOARD},
+  {Q40_IRQ_FRAME_MASK,Q40_IRQ_FRAME},
+  {Q40_IRQ_KEYB_MASK,Q40_IRQ_KEYBOARD},
   {0,0}};
 #endif
 static struct IRQ_TABLE eirqs[]={
-  {IRQ3_MASK,3},                   /* ser 1 */
-  {IRQ4_MASK,4},                   /* ser 2 */
-  {IRQ14_MASK,14},                 /* IDE 1 */
-  {IRQ15_MASK,15},                 /* IDE 2 */
-  {IRQ6_MASK,6},                   /* floppy */
-  {IRQ7_MASK,7},                   /* par */
+  {Q40_IRQ3_MASK,3},                   /* ser 1 */
+  {Q40_IRQ4_MASK,4},                   /* ser 2 */
+  {Q40_IRQ14_MASK,14},                 /* IDE 1 */
+  {Q40_IRQ15_MASK,15},                 /* IDE 2 */
+  {Q40_IRQ6_MASK,6},                   /* floppy, handled elsewhere */
+  {Q40_IRQ7_MASK,7},                   /* par */
 
-  {IRQ5_MASK,5},
-  {IRQ10_MASK,10},
+  {Q40_IRQ5_MASK,5},
+  {Q40_IRQ10_MASK,10},
 
 
 
@@ -325,7 +300,7 @@
 
 #define IRQ_INPROGRESS 1
 /*static unsigned short saved_mask;*/
-static int do_tint=0;
+//static int do_tint=0;
 
 #define DEBUG_Q40INT
 /*#define IP_USE_DISABLE *//* would be nice, but crashes ???? */
@@ -337,101 +312,82 @@
 /* got level 2 interrupt, dispatch to ISA or keyboard/timer IRQs */
 void q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
 {
-  unsigned mir;
-	unsigned mer;
-	int irq,i;
+  unsigned mir, mer;
+  int irq,i;
 
  repeat:
   mir=master_inb(IIRQ_REG);
-  if (mir&IRQ_FRAME_MASK) 
-    { /* dont loose  ticks */
-      do_tint++;
-      master_outb(-1,FRAME_CLEAR_REG);
-    }
-	if ((mir&IRQ_SER_MASK) || (mir&IRQ_EXT_MASK)) 
-	  {
-	    /* some ISA dev caused the int */
-	    mer=master_inb(EIRQ_REG);
-	    for (i=0; eirqs[i].mask; i++)
-	      {
-		if (mer&(eirqs[i].mask)) 
-		  {
-		    irq=eirqs[i].irq;
+  if (mir&Q40_IRQ_FRAME_MASK) {
+	  irq_tab[Q40_IRQ_FRAME].count++;
+	  irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp);   
+	  master_outb(-1,FRAME_CLEAR_REG);
+  }
+  if ((mir&Q40_IRQ_SER_MASK) || (mir&Q40_IRQ_EXT_MASK)) {
+	  mer=master_inb(EIRQ_REG);
+	  for (i=0; eirqs[i].mask; i++) {
+		  if (mer&(eirqs[i].mask)) {
+			  irq=eirqs[i].irq;
 /*
  * There is a little mess wrt which IRQ really caused this irq request. The
  * main problem is that IIRQ_REG and EIRQ_REG reflect the state when they
  * are read - which is long after the request came in. In theory IRQs should
  * not just go away but they occassionally do
  */
-	      if (irq>4 && irq<=15 && mext_disabled) 
-		{
-		  /*aliased_irq++;*/
-		  goto iirq;
-		}
-		    if (irq_tab[irq].handler == q40_defhand )
-		      {
-			printk("handler for IRQ %d not defined\n",irq);
-			continue; /* ignore uninited INTs :-( */
-		      }
-		    if ( irq_tab[irq].state & IRQ_INPROGRESS )
-		      {
-		  /* some handlers do local_irq_enable() for irq latency reasons, */
-		  /* however reentering an active irq handler is not permitted */
+			  if (irq>4 && irq<=15 && mext_disabled) {
+				  /*aliased_irq++;*/
+				  goto iirq;
+			  }
+			  if (irq_tab[irq].handler == q40_defhand ) {
+				  printk("handler for IRQ %d not defined\n",irq);
+				  continue; /* ignore uninited INTs :-( */
+			  }
+			  if ( irq_tab[irq].state & IRQ_INPROGRESS ) {
+				  /* some handlers do sti() for irq latency reasons, */
+				  /* however reentering an active irq handler is not permitted */
 #ifdef IP_USE_DISABLE
-		  /* in theory this is the better way to do it because it still */
-		  /* lets through eg the serial irqs, unfortunately it crashes */
-		  disable_irq(irq);
-		  disabled=1;
+				  /* in theory this is the better way to do it because it still */
+				  /* lets through eg the serial irqs, unfortunately it crashes */
+				  disable_irq(irq);
+				  disabled=1;
 #else
-			/*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",irq,disabled ? "already" : "not yet"); */
-		  fp->sr = (((fp->sr) & (~0x700))+0x200);
-			disabled=1;
-#endif
-		  goto iirq;
-		      }
-	      irq_tab[irq].count++; 
-		    irq_tab[irq].state |= IRQ_INPROGRESS;
-		    irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
-	      irq_tab[irq].state &= ~IRQ_INPROGRESS;
-
-		    /* naively enable everything, if that fails than    */
-		    /* this function will be reentered immediately thus */
-		    /* getting another chance to disable the IRQ        */
-
-		    if ( disabled ) 
-		      {
+				  /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",irq,disabled ? "already" : "not yet"); */
+				  fp->sr = (((fp->sr) & (~0x700))+0x200);
+				  disabled=1;
+#endif
+				  goto iirq;
+			  }
+			  irq_tab[irq].count++; 
+			  irq_tab[irq].state |= IRQ_INPROGRESS;
+			  irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
+			  irq_tab[irq].state &= ~IRQ_INPROGRESS;
+			  
+			  /* naively enable everything, if that fails than    */
+			  /* this function will be reentered immediately thus */
+			  /* getting another chance to disable the IRQ        */
+			  
+			  if ( disabled ) {
 #ifdef IP_USE_DISABLE
-			if (irq>4){
-			  disabled=0;
-			  enable_irq(irq);}
+				  if (irq>4){
+					  disabled=0;
+					  enable_irq(irq);}
 #else
-			disabled=0;
-			/*printk("reenabling irq %d\n",irq); */
+				  disabled=0;
+				  /*printk("reenabling irq %d\n",irq); */
 #endif
-		      }
-	      goto repeat;  /* return;  */
+			  }
+// used to do 'goto repeat;' her, this delayed bh processing too long
+			  return;
 		  }
-	      }
-	    if (mer && ccleirq>0 && !aliased_irq) 
-	      printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--;
-	  } 
- iirq:
-	mir=master_inb(IIRQ_REG);
-	if (mir&IRQ_FRAME_MASK) 
-	  {
-	    do_tint++;
-	    master_outb(-1,FRAME_CLEAR_REG);
-	  }
-	for(;do_tint>0;do_tint--) 
-	  {
-	    irq_tab[Q40_IRQ_FRAME].count++;
-	    irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp);    
-	  }
-	if (mir&IRQ_KEYB_MASK) /* may handle it even if actually disabled*/
-	  {
-	    irq_tab[Q40_IRQ_KEYBOARD].count++;
-	    irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
 	  }
+	  if (mer && ccleirq>0 && !aliased_irq) 
+		  printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--;
+  } 
+ iirq:
+  mir=master_inb(IIRQ_REG);
+  if (mir&Q40_IRQ_KEYB_MASK) {
+	  irq_tab[Q40_IRQ_KEYBOARD].count++;
+	  irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
+  }
 }
 
 int show_q40_interrupts (struct seq_file *p, void *v)
@@ -453,25 +409,16 @@
 
 static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp)
 {
-#if 0
 	printk ("Unknown q40 interrupt 0x%02x\n", irq);
-#endif
 }
 static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs)
 {
-#if 0
-        if (ints_inited)
-#endif
-	  printk ("Uninitialised interrupt level %d\n", lev);
-#if 0
-	else
-	  printk ("Interrupt before interrupt initialisation\n");
-#endif
+	printk ("Uninitialised interrupt level %d\n", lev);
 }
 
  void (*q40_sys_default_handler[SYS_IRQS]) (int, void *, struct pt_regs *) = {
-   sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler,
-   sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler
+	 sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler,
+	 sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler
  };
 
 
@@ -491,16 +438,15 @@
 void q40_disable_irq (unsigned int irq)
 {
   /* disable ISA iqs : only do something if the driver has been
-  * verified to be Q40 "compatible" - right now IDE, NE2K
-  * Any driver should not attempt to sleep accross disable_irq !!
-  */
+   * verified to be Q40 "compatible" - right now IDE, NE2K
+   * Any driver should not attempt to sleep accross disable_irq !!
+   */
 
-  if ( irq>=5 && irq<=15 ) 
-    {
+  if ( irq>=5 && irq<=15 ) {
     master_outb(0,EXT_ENABLE_REG);
-      mext_disabled++;
-      if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled);
-    }
+    mext_disabled++;
+    if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled);
+  }
 }
 
 unsigned long q40_probe_irq_on (void)
@@ -515,4 +461,5 @@
 /*
  * Local variables:
  * compile-command: "m68k-linux-gcc -D__KERNEL__ -I/home/rz/lx/linux-2.2.6/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -ffixed-a2 -m68040   -c -o q40ints.o q40ints.c"
+ * End:
  */
diff -Nru a/arch/m68k/vmlinux-std.lds b/arch/m68k/vmlinux-std.lds
--- a/arch/m68k/vmlinux-std.lds	Thu Jan 16 18:23:06 2003
+++ b/arch/m68k/vmlinux-std.lds	Thu Jan 16 18:23:06 2003
@@ -1,4 +1,7 @@
 /* ld script to make m68k Linux kernel */
+
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
 OUTPUT_ARCH(m68k)
 ENTRY(_start)
@@ -12,21 +15,13 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x4e75
-  .rodata : { *(.rodata) *(.rodata.*) }
-  .kstrtab : { *(.kstrtab) }
 
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table: GPL only */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
+  RODATA
 
   _etext = .;			/* End of text section */
 
diff -Nru a/arch/m68k/vmlinux-sun3.lds b/arch/m68k/vmlinux-sun3.lds
--- a/arch/m68k/vmlinux-sun3.lds	Thu Jan 16 18:23:05 2003
+++ b/arch/m68k/vmlinux-sun3.lds	Thu Jan 16 18:23:05 2003
@@ -1,4 +1,7 @@
 /* ld script to make m68k Linux kernel */
+
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
 OUTPUT_ARCH(m68k)
 ENTRY(_start)
@@ -13,26 +16,16 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x4e75
-  .kstrtab : { *(.kstrtab) }
-
 
   _etext = .;			/* End of text section */
 
   .data : {			/* Data */
-	*(.rodata)
-	*(.rodata.*)
-	*(.data)
+	RODATA
 	CONSTRUCTORS
   	. = ALIGN(16);		/* Exception table */
   	__start___ex_table = .;
   	*(__ex_table) 
   	__stop___ex_table = .;
-  	__start___ksymtab = .;	/* Kernel symbol table */
-  	*(__ksymtab) 
-  	__stop___ksymtab = .;
-	__start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-	__gpl_ksymtab : { *(__gpl_ksymtab) }
-	__stop___gpl_ksymtab = .;
 	}
   /* End of data goes *here* so that freeing init code works properly. */
   _edata = .;
diff -Nru a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile
--- a/arch/m68knommu/kernel/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/m68knommu/kernel/Makefile	Thu Jan 16 18:23:05 2003
@@ -4,7 +4,8 @@
 
 export-objs := m68k_ksyms.o
 
-obj-y += init_task.o ints.o m68k_ksyms.o process.o ptrace.o semaphore.o \
-	 setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o
+obj-y += entry.o init_task.o ints.o m68k_ksyms.o process.o ptrace.o \
+	 semaphore.o setup.o signal.o syscalltable.o sys_m68k.o time.o \
+	 traps.o
 
 obj-$(CONFIG_COMEMPCI)	+= comempci.o
diff -Nru a/arch/m68knommu/platform/5307/entry.S b/arch/m68knommu/platform/5307/entry.S
--- a/arch/m68knommu/platform/5307/entry.S	Thu Jan 16 18:23:07 2003
+++ b/arch/m68knommu/platform/5307/entry.S	Thu Jan 16 18:23:07 2003
@@ -1,5 +1,4 @@
-/* -*- mode: asm -*-
- *
+/*
  *  linux/arch/m68knommu/platform/5307/entry.S
  *
  *  Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
@@ -25,34 +24,6 @@
  * linux 2.4 support David McCullough <davidm@snapgear.com>
  */
 
-/*
- * entry.S  contains the system-call and fault low-level handling routines.
- * This also contains the timer-interrupt handler, as well as all interrupts
- * and faults that can result in a task-switch.
- *
- * NOTE: This code handles signal-recognition, which happens every time
- * after a timer-interrupt and after each system call.
- *
- * Stack layout in 'ret_from_exception':
- *
- *	This allows access to the syscall arguments in registers d1-d5
- *
- *	 0(sp) - d1
- *	 4(sp) - d2
- *	 8(sp) - d3
- *	 C(sp) - d4
- *	10(sp) - d5
- *	14(sp) - a0
- *	18(sp) - a1
- *	1C(sp) - a2
- *	20(sp) - d0
- *	24(sp) - orig_d0
- *	28(sp) - stack adjustment
- *	2C(sp) - format & vector      }
- *	2E(sp) - sr                   } different to m68k
- *	30(sp) - pc                   }
- */
-
 #include <linux/config.h>
 #include <linux/sys.h>
 #include <linux/linkage.h>
@@ -61,118 +32,7 @@
 #include <asm/setup.h>
 #include <asm/segment.h>
 #include <asm/asm-offsets.h>
-
-LENOSYS = 38
-
-/* the following macro is used when enabling interrupts */
-#define ALLOWINT 0xf8ff
-#define	MAX_NOINT_IPL	0
-
-
-LD0		= 0x20
-LORIG_D0	= 0x24
-LFORMATVEC	= 0x2c
-LSR		= 0x2e
-LPC		= 0x30
-
-/*
- * This defines the normal kernel pt-regs layout.
- *
- * regs are a2-a6 and d6-d7 preserved by C code
- * the kernel doesn't mess with usp unless it needs to
- *
- *	This is made a little more tricky on the ColdFire. There is no
- *	separate kernel and user stack pointers. Need to artificially
- *	construct a usp in software... When doing this we need to disable
- *	interrupts, otherwise bad things could happen.
- */
-#define SAVE_ALL						\
-	move	#0x2700,%sr;		/* disable intrs */	\
-	btst	#5,%sp@(2);		/* from user? */	\
-	bnes	6f;			/* no, skip */		\
-	movel	%sp,sw_usp;		/* save user sp */	\
-	addql	#8,sw_usp;		/* remove exception */	\
-	movel	sw_ksp,%sp;		/* kernel sp */		\
-	subql	#8,%sp;			/* room for exception */\
-	clrl	%sp@-;			/* stk_adj */		\
-	movel	%d0,%sp@-;		/* orig d0 */		\
-	movel	%d0,%sp@-;		/* d0 */		\
-	subl	#32,%sp;		/* space for 8 regs */	\
-	moveml	%d1-%d5/%a0-%a2,%sp@;				\
-	movel	sw_usp,%a0;		/* get usp */		\
-	moveml	%a0@(-8),%d1-%d2;	/* get exception */	\
-	moveml	%d1-%d2,%sp@(LFORMATVEC); /* copy exception */	\
-	bra	7f;						\
-	6:							\
-	clrl	%sp@-;			/* stk_adj */		\
-	movel	%d0,%sp@-;		/* orig d0 */		\
-	movel	%d0,%sp@-;		/* d0 */		\
-	subl	#32,%sp;		/* space for 7 regs */	\
-	moveml	%d1-%d5/%a0-%a2,%sp@;				\
-	7:
-
-#define RESTORE_ALL						\
-	btst	#5,%sp@(LSR);		/* going user? */	\
-	bnes	8f;			/* no, skip */		\
-	move	#0x2700,%sr;		/* disable intrs */	\
-	movel	sw_usp,%a0;		/* get usp */		\
-	moveml	%sp@(LFORMATVEC),%d1-%d2; /* copy exception */	\
-	moveml	%d1-%d2,%a0@(-8);				\
-	moveml	%sp@,%d1-%d5/%a0-%a2;				\
-	addl	#32,%sp;		/* space for 8 regs */	\
-	movel	%sp@+,%d0;					\
-	addql	#4,%sp;			/* orig d0 */		\
-	addl	%sp@+,%sp;		/* stk adj */		\
-	addql	#8,%sp;			/* remove exception */	\
-	movel	%sp,sw_ksp;		/* save ksp */		\
-	subql	#8,sw_usp;		/* set exception */	\
-	movel	sw_usp,%sp;		/* restore usp */	\
-	rte;							\
-	8:							\
-	moveml	%sp@,%d1-%d5/%a0-%a2;				\
-	addl	#32,%sp;		/* space for 8 regs */	\
-	movel	%sp@+,%d0;					\
-	addql	#4,%sp;			/* orig d0 */		\
-	addl	%sp@+,%sp;		/* stk adj */		\
-	rte
-
-/*
- *	Quick exception save, use current stack only.
- */
-#define SAVE_LOCAL						\
-	move	#0x2700,%sr;		/* disable intrs */	\
-	clrl	%sp@-;			/* stk_adj */		\
-	movel	%d0,%sp@-;		/* orig d0 */		\
-	movel	%d0,%sp@-;		/* d0 */		\
-	subl	#32,%sp;		/* space for 8 regs */	\
-	moveml	%d1-%d5/%a0-%a2,%sp@;
-
-#define RESTORE_LOCAL						\
-	moveml	%sp@,%d1-%d5/%a0-%a2;				\
-	addl	#32,%sp;		/* space for 8 regs */	\
-	movel	%sp@+,%d0;					\
-	addql	#4,%sp;			/* orig d0 */		\
-	addl	%sp@+,%sp;		/* stk adj */		\
-	rte
-
-
-#define SWITCH_STACK_SIZE (6*4+4)	/* includes return address */
-
-#define SAVE_SWITCH_STACK		\
-	subl    #24,%sp; /* 6 regs */	\
-	moveml	%a3-%a6/%d6-%d7,%sp@
-
-#define RESTORE_SWITCH_STACK		\
-	moveml	%sp@,%a3-%a6/%d6-%d7;	\
-	addl	#24,%sp /* 6 regs */
-
-/*
- *	Software copy of the user and kernel stack pointers... Ugh...
- *	Need these to get around ColdFire not having separate kernel
- *	and user stack pointers.
- */
-.globl sw_usp
-.globl sw_ksp
+#include <asm/entry.h>
 
 .data
 
@@ -184,85 +44,25 @@
 
 .text
 
-
-.globl buserr
-.globl trap
 .globl system_call
-.globl resume, ret_from_exception
+.globl resume
+.globl ret_from_exception
 .globl ret_from_signal
 .globl sys_call_table
-.globl sys_fork, sys_clone, sys_vfork
 .globl ret_from_interrupt
 .globl inthandler
 .globl fasthandler
 
-#ifdef TRAP_DBG_INTERRUPT
-.globl dbginterrupt
-#endif
-
-/*--------------------------------------------------------------------------*/
-
-.text
-
-ENTRY(buserr)
-	SAVE_ALL
-	moveq	#-1,%d0
-	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
-					| signifies that the stack frame
-					| is NOT for syscall
-
-	movel	%sp,%sp@- 		| stack frame pointer argument
-	jsr	buserr_c
-	addql	#4,%sp
-	jra	ret_from_exception
-
-
-#ifdef TRAP_DBG_INTERRUPT
-ENTRY(dbginterrupt)
-	SAVE_ALL
-	moveq	#-1,%d0
-	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
-					| signifies that the stack frame
-					| is NOT for syscall
-
-	movel	%sp,%sp@- 		| stack frame pointer argument
-	jsr	dbginterrupt_c
-	addql	#4,%sp
-	jra	ret_from_exception
-#endif
-
-
-ENTRY(reschedule)
-	| save top of frame
-	pea	%sp@
-	jbsr	set_esp0
-	addql	#4,%sp
-
-	pea	ret_from_exception
-	jmp	schedule
-
-	| After a fork we jump here directly from resume,
-	| so that %d1 contains the previous task
-	| Theoretically only needed on SMP, but lets watch
-	| what happens in schedule_tail() in future...
-ENTRY(ret_from_fork)
-#ifdef CONFIG_SMP
-	movel	%d1,%sp@-
-	jsr	schedule_tail
-	addql	#4,%sp
-#endif
-	jra	ret_from_exception
-
 ENTRY(system_call)
 	SAVE_ALL
-	move	#0x2000,%sr;		| enable intrs again
+	move	#0x2000,%sr		/* enable intrs again */
 
 	movel	#-LENOSYS,%d2
-	movel	%d2,LD0(%sp)		| default return value in d0
-					| original D0 is in orig_d0
+	movel	%d2,LD0(%sp)		/* default return value in d0 */
+					/* original D0 is in orig_d0 */
 	movel	%d0,%d2
 
-	| save top of frame
+	/* save top of frame */
 	pea	%sp@
 	jbsr	set_esp0
 	addql	#4,%sp
@@ -270,20 +70,20 @@
 	cmpl	#NR_syscalls,%d2
 	jcc	ret_from_exception
 	lea	sys_call_table,%a0
-	lsll	#2,%d2			| movel	%a0@(%d2:l:4),%d3
+	lsll	#2,%d2			/* movel %a0@(%d2:l:4),%d3 */
 	movel	%a0@(%d2),%d3
 	jeq	ret_from_exception
 	lsrl	#2,%d2
 
-	movel	%sp,%d2			| get thread_info pointer
-	andl	#0xffffe000,%d2		| at start of 8k kernel stack
+	movel	%sp,%d2			/* get thread_info pointer */
+	andl	#0xffffe000,%d2		/* at start of 8k kernel stack */
 	movel	%d2,%a0
 	btst	#TIF_SYSCALL_TRACE,%a0@(TI_FLAGS)
 	bnes	1f
 
 	movel	%d3,%a0
 	jbsr	%a0@
-	movel	%d0,%sp@(LD0)		| save the return value
+	movel	%d0,%sp@(LD0)		/* save the return value */
 	jra	ret_from_exception
 1:
 	subql	#4,%sp
@@ -293,8 +93,8 @@
 	addql	#4,%sp
 	movel	%d3,%a0
 	jbsr	%a0@
-	movel	%d0,%sp@(LD0)		| save the return value
-	subql	#4,%sp			| dummy return address
+	movel	%d0,%sp@(LD0)		/* save the return value */
+	subql	#4,%sp			/* dummy return address */
 	SAVE_SWITCH_STACK
 	jbsr	syscall_trace
 
@@ -303,58 +103,60 @@
 	addql	#4,%sp
 
 ret_from_exception:
-	btst	#5,%sp@(LSR)		| check if returning to kernel
-	jeq	Luser_return		| if so, skip resched, signals
+	btst	#5,%sp@(LSR)		/* check if returning to kernel */
+	jeq	Luser_return		/* if so, skip resched, signals */
 
 Lkernel_return:
 	moveml  %sp@,%d1-%d5/%a0-%a2
-	addl    #32,%sp			| space for 8 regs
+	addl    #32,%sp			/* space for 8 regs */
 	movel   %sp@+,%d0
-	addql   #4,%sp			| orig d0
-	addl    %sp@+,%sp		| stk adj
+	addql   #4,%sp			/* orig d0 */
+	addl    %sp@+,%sp		/* stk adj */
 	rte
 
 Luser_return:
-	movel	%sp,%d1			| get thread_info pointer
-	andl	#0xffffe000,%d1		| at base of 8k kernel stack
+	movel	%sp,%d1			/* get thread_info pointer */
+	andl	#0xffffe000,%d1		/* at base of 8k kernel stack */
 	movel	%d1,%a0
-	movel	%a0@(TI_FLAGS),%d1	| get thread_info->flags
+	movel	%a0@(TI_FLAGS),%d1	/* get thread_info->flags */
 	andl	#_TIF_WORK_MASK,%d1
-	jne	Lwork_to_do		| still work to do
+	jne	Lwork_to_do		/* still work to do */
 
 Lreturn:
-	move    #0x2700,%sr		| disable intrs
-	movel   sw_usp,%a0		| get usp
-	moveml  %sp@(LFORMATVEC),%d1-%d2 | copy exception
+	move    #0x2700,%sr		/* disable intrs */
+	movel   sw_usp,%a0		/* get usp */
+	moveml  %sp@(LFORMATVEC),%d1-%d2 /* copy exception */
 	moveml  %d1-%d2,%a0@(-8)
-	bclr    #5,%a0@(-8)		| clear format byte, bit 5 to make
-					| stack appear modulo 4 which it WILL
-					| be when we do the rte because it was
-					| generated in setup_frame
-	bclr    #4,%a0@(-8)		| clear format byte, bit 4 to make 
-					| stack appear modulo 4 which it WILL
-					| be when we do the rte because it was
-					| generated in setup_frame
+	bclr    #5,%a0@(-8)		/* clear format byte, bit 5 to make
+					 * stack appear modulo 4 which it WILL
+					 * be when we do the rte because it was
+					 * generated in setup_frame
+					 */
+	bclr    #4,%a0@(-8)		/* clear format byte, bit 4 to make 
+					 * stack appear modulo 4 which it WILL
+					 * be when we do the rte because it was
+					 * generated in setup_frame
+					 */
 	moveml  %sp@,%d1-%d5/%a0-%a2
-	addl    #32,%sp			| space for 8 regs
+	addl    #32,%sp			/* space for 8 regs */
 	movel   %sp@+,%d0                  
-	addql   #4,%sp			| orig d0
-	addl    %sp@+,%sp		| stk adj
-	addql   #8,%sp			| remove exception
-	movel   %sp,sw_ksp		| save ksp
-	movel   sw_usp,%sp		| restore usp
-	subql   #8,%sp			| set exception
+	addql   #4,%sp			/* orig d0 */
+	addl    %sp@+,%sp		/* stk adj */
+	addql   #8,%sp			/* remove exception */
+	movel   %sp,sw_ksp		/* save ksp */
+	movel   sw_usp,%sp		/* restore usp */
+	subql   #8,%sp			/* set exception */
 	rte
 
 Lwork_to_do:
-	movel	%a0@(TI_FLAGS),%d1	| get thread_info->flags
+	movel	%a0@(TI_FLAGS),%d1	/* get thread_info->flags */
 	btst	#TIF_NEED_RESCHED,%d1
 	jne	reschedule
 
 	/* GERG: do we need something here for TRACEing?? */
 
 Lsignal_return:
-	subql	#4,%sp			| dummy return address
+	subql	#4,%sp			/* dummy return address */
 	SAVE_SWITCH_STACK
 	pea	%sp@(SWITCH_STACK_SIZE)
 	clr	%d1
@@ -365,91 +167,68 @@
 	addql	#4,%sp
 	jmp	Lreturn
 
-/*--------------------------------------------------------------------------*/
-
-/*
- *	Common ColdFire trap handler. Most traps come through here first.
- */
-ENTRY(trap)
-	SAVE_ALL
-	moveq	#-1,%d0
-	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
-					| signifies that the stack frame
-					| is NOT for syscall
-	movel	%sp,%sp@- 		| stack frame pointer argument
-	jsr	trap_c
-	addql	#4,%sp
-	jra	ret_from_exception
-
 /*
- *	This is the generic interrupt handler (for all hardware interrupt
- *	sources). It figures out the vector number and calls the appropriate
- *	interrupt service routine directly.
+ * This is the generic interrupt handler (for all hardware interrupt
+ * sources). It figures out the vector number and calls the appropriate
+ * interrupt service routine directly.
  */
 ENTRY(inthandler)
 	SAVE_ALL
 	moveq	#-1,%d0
-	movel	%d0,%sp@(LORIG_D0)	| a -1 in the ORIG_D0 field
-					| signifies that the stack frame
-					| is NOT for syscall
+	movel	%d0,%sp@(LORIG_D0)
 	addql	#1,local_irq_count
-					| put exception # in d0
-	movew   %sp@(LFORMATVEC),%d0
-	andl	#0x03fc,%d0		| mask out vector only
 
-	movel	mach_kstat_irqs,%a0
-					| get addr of kstat struct
-	addql	#1,%a0@(%d0)		| incr irq intr count
+	movew   %sp@(LFORMATVEC),%d0	/* put exception # in d0 */
+	andl	#0x03fc,%d0		/* mask out vector only */
+
+	leal	kstat__per_cpu+STAT_IRQ,%a0
+	addql	#1,%a0@(%d0)
 
-	lsrl	#2,%d0			| calculate real vector #
-	movel	%d0,%d1			| calculate array offset
+	lsrl	#2,%d0			/* calculate real vector # */
+	movel	%d0,%d1			/* calculate array offset */
 	lsll	#4,%d1
 	lea	irq_list,%a0
-	addl	%d1,%a0			| pointer to array struct
-
-	movel	%sp,%sp@-		| push regs arg onto stack
-	movel	%a0@(8),%sp@-		| push devid arg
-	movel	%d0,%sp@- 		| push vector # on stack
+	addl	%d1,%a0			/* pointer to array struct */
 
-	movel	%a0@,%a0		| get function to call
-	jbsr	%a0@			| call vector handler
-	addl	#12,%sp			| pop parameters off stack
+	movel	%sp,%sp@-		/* push regs arg onto stack */
+	movel	%a0@(8),%sp@-		/* push devid arg */
+	movel	%d0,%sp@- 		/* push vector # on stack */
 
-	bra	ret_from_interrupt	| this was fallthrough
+	movel	%a0@,%a0		/* get function to call */
+	jbsr	%a0@			/* call vector handler */
+	addl	#12,%sp			/* pop parameters off stack */
 
+	bra	ret_from_interrupt	/* this was fallthrough */
 
 /*
- *	This is the fast interrupt handler (for certain hardware interrupt
- *	sources). Unlike the normal interrupt handler it just uses the
- *	current stack (doesn't care if it is user or kernel). It also
- *	doesn't bother doing the bottom half handlers.
+ * This is the fast interrupt handler (for certain hardware interrupt
+ * sources). Unlike the normal interrupt handler it just uses the
+ * current stack (doesn't care if it is user or kernel). It also
+ * doesn't bother doing the bottom half handlers.
  */
 ENTRY(fasthandler)
 	SAVE_LOCAL
 
 	movew   %sp@(LFORMATVEC),%d0
-	andl	#0x03fc,%d0		| mask out vector only
+	andl	#0x03fc,%d0		/* mask out vector only */
 
-	movel	mach_kstat_irqs,%a0
-					| get addr of kstat struct
-	addql	#1,%a0@(%d0)		| incr irq intr count
+	leal	kstat__per_cpu+STAT_IRQ,%a0
+	addql	#1,%a0@(%d0)
 
-	movel	%sp,%sp@-		| push regs arg onto stack
+	movel	%sp,%sp@-		/* push regs arg onto stack */
 	clrl	%d1
-	movel	%d1,%sp@- 		| push devid arg
-	lsrl	#2,%d0			| calculate real vector #
-	movel	%d0,%sp@- 		| push vector # on stack
+	movel	%d1,%sp@- 		/* push devid arg */
+	lsrl	#2,%d0			/* calculate real vector # */
+	movel	%d0,%sp@- 		/* push vector # on stack */
 
-	lsll	#4,%d0			| adjust for array offset
+	lsll	#4,%d0			/* adjust for array offset */
 	lea	irq_list,%a0
-	movel	%a0@(%d0),%a0		| get function to call
-	jbsr	%a0@			| call vector handler
-	addl	#12,%sp			| pop parameters off stack
+	movel	%a0@(%d0),%a0		/* get function to call */
+	jbsr	%a0@			/* call vector handler */
+	addl	#12,%sp			/* pop parameters off stack */
 
 	RESTORE_LOCAL
 
-/*--------------------------------------------------------------------------*/
-
 ENTRY(ret_from_interrupt)
 	subql	#1,local_irq_count
 	jeq	2f
@@ -458,9 +237,6 @@
 2:
 	moveb	%sp@(LSR),%d0
 	andl	#0x7,%d0
-#if MAX_NOINT_IPL > 0
-	cmpiw	#MAX_NOINT_IPL,%d0
-#endif
 	jhi	1b
 
 	/* check if we need to do software interrupts */
@@ -470,88 +246,32 @@
 	pea	ret_from_exception
 	jmp	do_softirq
 
-ENTRY(sys_fork)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	m68k_fork
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_vfork)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	m68k_vfork
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_clone)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	m68k_clone
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_sigsuspend)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	do_sigsuspend
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_rt_sigsuspend)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	do_rt_sigsuspend
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_sigreturn)
-	SAVE_SWITCH_STACK
-	jbsr	do_sigreturn
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_rt_sigreturn)
-	SAVE_SWITCH_STACK
-	jbsr	do_rt_sigreturn
-	RESTORE_SWITCH_STACK
-	rts
-
-/*--------------------------------------------------------------------------*/
-
 /*
- *	Beware - when entering resume, prev (the current task) is
- *	in a0, next (the new task) is in a1,so don't change these
- *	registers until their contents are no longer needed.
+ * Beware - when entering resume, prev (the current task) is
+ * in a0, next (the new task) is in a1,so don't change these
+ * registers until their contents are no longer needed.
  */
 ENTRY(resume)
+	movel	%a0, %d1			/* get prev thread in d1 */
 
-	movel	%a0, %d1			| get prev thread in d1
-
-	movew	%sr,%d0				| save thread status reg
+	movew	%sr,%d0				/* save thread status reg */
 	movew	%d0,%a0@(TASK_THREAD+THREAD_SR)
 
-	oril	#0x700,%d0			| disable interrupts
+	oril	#0x700,%d0			/* disable interrupts */
 	move	%d0,%sr
 
-	movel	sw_usp,%d0			| save usp
+	movel	sw_usp,%d0			/* save usp */
 	movel	%d0,%a0@(TASK_THREAD+THREAD_USP)
 
 	SAVE_SWITCH_STACK
-	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP) | save kernel stack pointer
-	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp | restore new thread stack
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack pointer */
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
 	RESTORE_SWITCH_STACK
 
-	movel	%a1@(TASK_THREAD+THREAD_USP),%a0 | restore thread user stack
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0 /* restore thread user stack */
 	movel	%a0, sw_usp
 
-	movew	%a1@(TASK_THREAD+THREAD_SR),%d0	| restore thread status reg
+	movew	%a1@(TASK_THREAD+THREAD_SR),%d0	/* restore thread status reg */
 	movew	%d0, %sr
 	rts
 
-/*--------------------------------------------------------------------------*/
diff -Nru a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S
--- a/arch/m68knommu/platform/68328/entry.S	Thu Jan 16 18:23:05 2003
+++ b/arch/m68knommu/platform/68328/entry.S	Thu Jan 16 18:23:05 2003
@@ -1,6 +1,5 @@
-/* -*- mode: asm -*-
- *
- *  linux/arch/m68k/kernel/entry.S
+/*
+ *  linux/arch/m68knommu/platform/68328/entry.S
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *
@@ -9,87 +8,35 @@
  * for more details.
  *
  * Linux/m68k support by Hamish Macdonald
- *
- */
-
-/*
- * entry.S  contains the system-call and fault low-level handling routines.
- * This also contains the timer-interrupt handler, as well as all interrupts
- * and faults that can result in a task-switch.
- *
- * NOTE: This code handles signal-recognition, which happens every time
- * after a timer-interrupt and after each system call.
- *
- */
-
-/*
- * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
- *               all pointers that used to be 'current' are now entry
- *               number 0 in the 'current_set' list.
  */
 
 #include <linux/config.h>
 #include <linux/sys.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
-#include <asm/entry.h>
 #include <asm/errno.h>
 #include <asm/setup.h>
 #include <asm/segment.h>
 #include <asm/traps.h>
 #include <asm/asm-offsets.h>
+#include <asm/entry.h>
 
-#define IMMED #
-#define DBG_PUTC(x)	moveb IMMED x,0xfffff907; \
-			moveb IMMED '\r',0xfffff907; \
-			moveb IMMED '\n',0xfffff907
+.text
 
-.globl system_call, buserr, trap
-.globl resume, ret_from_exception
+.globl system_call
+.globl resume
+.globl ret_from_exception
 .globl ret_from_signal
 .globl sys_call_table
-.globl sys_fork, sys_clone, sys_vfork
-.globl ret_from_interrupt, bad_interrupt
-.globl inthandler1, inthandler2, inthandler3, inthandler4
-.globl inthandler5, inthandler6, inthandler7
-
-.text
-ENTRY(buserr)
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
-	movel	%sp,%sp@- 		/* stack frame pointer argument*/
-	bsrw	buserr_c
-	addql	#4,%sp
-	jra	ret_from_exception
-
-ENTRY(trap)
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
-	movel	%sp,%sp@- 		/* stack frame pointer argument*/
-	bsrw	trap_c
-	addql	#4,%sp
-	jra	ret_from_exception
-
-ENTRY(reschedule)
-	/* save top of frame*/
-	pea     %sp@
-	jbsr    set_esp0
-	addql   #4,%sp
-
-	pea	ret_from_exception
-	jmp	schedule
-
-	/* After a fork we jump here directly from resume,*/
-	/* so that %d1 contains the previous task*/
-	/* Theoretically only needed on SMP, but let's watch*/
-	/* what happens in schedule_tail() in future...*/
-ENTRY(ret_from_fork)
-#ifdef CONFIG_SMP
-	movel	%d1,%sp@-
-	jsr	schedule_tail
-	addql	#4,%sp
-#endif
-	jra	ret_from_exception
+.globl ret_from_interrupt
+.globl bad_interrupt
+.globl inthandler1
+.globl inthandler2
+.globl inthandler3
+.globl inthandler4
+.globl inthandler5
+.globl inthandler6
+.globl inthandler7
 
 badsys:
 	movel	#-ENOSYS,%sp@(PT_D0)
@@ -110,8 +57,8 @@
 	lea	sys_call_table, %a0
 	jbsr	%a0@(%d1)
 
-1:	movel	%d0,%sp@(PT_D0)		/* save the return value*/
-	subql	#4,%sp			/* dummy return address*/
+1:	movel	%d0,%sp@(PT_D0)		/* save the return value */
+	subql	#4,%sp			/* dummy return address */
 	SAVE_SWITCH_STACK
 	jbsr	syscall_trace
 
@@ -121,9 +68,8 @@
 	jra	ret_from_exception
 
 ENTRY(system_call)
-	SAVE_ALL_SYS
+	SAVE_ALL
 
-	GET_CURRENT(%d1)
 	/* save top of frame*/
 	pea     %sp@
 	jbsr    set_esp0
@@ -178,13 +124,11 @@
 	RESTORE_ALL
 
 /*
-** This is the main interrupt handler, responsible for calling process_int()
-*/
+ * This is the main interrupt handler, responsible for calling process_int()
+ */
 inthandler1:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
+	SAVE_ALL
 	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
 	movew	%sp@(PT_VECTOR), %d0
 	and	#0x3ff, %d0
 
@@ -195,10 +139,8 @@
 	bra	ret_from_interrupt
 
 inthandler2:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
+	SAVE_ALL
 	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
 	movew	%sp@(PT_VECTOR), %d0
 	and	#0x3ff, %d0
 
@@ -209,10 +151,8 @@
 	bra	ret_from_interrupt
 
 inthandler3:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
+	SAVE_ALL
 	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
 	movew	%sp@(PT_VECTOR), %d0
 	and	#0x3ff, %d0
 
@@ -223,10 +163,8 @@
 	bra	ret_from_interrupt
 
 inthandler4:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
+	SAVE_ALL
 	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
 	movew	%sp@(PT_VECTOR), %d0
 	and	#0x3ff, %d0
 
@@ -237,10 +175,8 @@
 	bra	ret_from_interrupt
 
 inthandler5:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
+	SAVE_ALL
 	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
 	movew	%sp@(PT_VECTOR), %d0
 	and	#0x3ff, %d0
 
@@ -251,10 +187,8 @@
 	bra	ret_from_interrupt
 
 inthandler6:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
+	SAVE_ALL
 	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
 	movew	%sp@(PT_VECTOR), %d0
 	and	#0x3ff, %d0
 
@@ -265,10 +199,8 @@
 	bra	ret_from_interrupt
 
 inthandler7:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
+	SAVE_ALL
 	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
 	movew	%sp@(PT_VECTOR), %d0
 	and	#0x3ff, %d0
 
@@ -278,67 +210,9 @@
 3:     	addql	#8,%sp			/*  pop parameters off stack*/
 	bra	ret_from_interrupt
 
-inthandler8:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
-	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
-	movew	%sp@(PT_VECTOR), %d0
-	and	#0x3ff, %d0
-
-	movel	%sp,%sp@-
-	movel	#72,%sp@- 		/*  put vector # on stack*/
-	jbsr	process_int		/*  process the IRQ*/
-3:     	addql	#8,%sp			/*  pop parameters off stack*/
-	bra	ret_from_interrupt
-
-timerhandler:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
-	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
-	movew	%sp@(PT_VECTOR), %d0
-	and	#0x3ff, %d0
-
-	movel	%sp,%sp@-
-	movel	#0x40,%sp@- 		/*  put vector # on stack*/
-	jbsr	process_int		/*  process the IRQ*/
-3:     	addql	#8,%sp			/*  pop parameters off stack*/
-	bra	ret_from_interrupt
-
-serialhandler:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
-	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
-	movew	%sp@(PT_VECTOR), %d0
-	and	#0x3ff, %d0
-
-	movel	%sp,%sp@-
-	movel	#0x42,%sp@- 		/*  put vector # on stack*/
-	jbsr	process_int		/*  process the IRQ*/
-3:     	addql	#8,%sp			/*  pop parameters off stack*/
-	bra	ret_from_interrupt
-
-inthandler_wrap:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
-	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
-	movew	%sp@(PT_VECTOR), %d0
-	and	#0x3ff, %d0
-
-	movel	%sp,%sp@-
-	movel	%d0,%sp@- 		/*  put vector # on stack*/
-	jbsr	process_int		/*  process the IRQ*/
-3:     	addql	#8,%sp			/*  pop parameters off stack*/
-	bra	ret_from_interrupt
-
 inthandler:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
+	SAVE_ALL
 	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
 	movew	%sp@(PT_VECTOR), %d0
 	and	#0x3ff, %d0
 
@@ -354,18 +228,11 @@
 2:
 	RESTORE_ALL
 1:
-#if 1
-/*	bfextu  %sp@(PT_SR){#5,#3},%d0 */	/* Check for nested interrupt.*/
 	moveb	%sp@(PT_SR), %d0
 	and	#7, %d0
-
-#if MAX_NOINT_IPL > 0
-	cmpiw	#MAX_NOINT_IPL,%d0
-#endif
 	jhi	2b
-#endif
-	/* check if we need to do software interrupts */
 
+	/* check if we need to do software interrupts */
 	movel	local_irq_count,%d0
 	jeq	ret_from_exception
 
@@ -373,111 +240,31 @@
 	jra	do_softirq
 
 
-/* Handler for uninitialized and spurious interrupts */
-
-bad_interrupt:
+/*
+ * Handler for uninitialized and spurious interrupts.
+ */
+ENTRY(bad_interrupt)
 	addql	#1,num_spurious
 	rte
 
-ENTRY(sys_fork)
-	SAVE_SWITCH_STACK	
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	m68k_fork
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_clone)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	m68k_clone
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_vfork)
-	SAVE_SWITCH_STACK	
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	m68k_vfork
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_sigsuspend)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	do_sigsuspend
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_rt_sigsuspend)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	do_rt_sigsuspend
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_sigreturn)
-	SAVE_SWITCH_STACK
-	jbsr	do_sigreturn
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_rt_sigreturn)
-	SAVE_SWITCH_STACK
-	jbsr	do_rt_sigreturn
-	RESTORE_SWITCH_STACK
-	rts
-
-resume:
-	/*
-	 * Beware - when entering resume, prev (the current task) is
-	 * in a0, next (the new task) is in a1,so don't change these
-	 * registers until their contents are no longer needed.
-	 */
-
-	/* save prev thread in d1 */
-	movel	%a0,%d1
-
-	/* save sr */
-	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)
-#ifdef USE_SFC_DFC
-	/* save fs (sfc,%dfc) (may be pointing to kernel memory) */
-	movec	%sfc,%d0
-	movew	%d0,%a0@(TASK_THREAD+THREAD_FS)
-#endif
-
-	/* save non-scratch registers on stack */
-	SAVE_SWITCH_STACK
-
-	/* save usp */
-	/* it is better to use a movel here instead of a movew 8*) */
-	movel	%usp,%a2
+/*
+ * Beware - when entering resume, prev (the current task) is
+ * in a0, next (the new task) is in a1,so don't change these
+ * registers until their contents are no longer needed.
+ */
+ENTRY(resume)
+	movel	%a0,%d1				/* save prev thread in d1 */
+	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)	/* save sr */
+	movel	%usp,%a2			/* save usp */
 	movel	%a2,%a0@(TASK_THREAD+THREAD_USP)
 
-	/* save current kernel stack pointer */
-	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP)
-
-	/* restore the kernel stack pointer */
-	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp
-
-	/* restore non-scratch registers */
+	SAVE_SWITCH_STACK
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
 	RESTORE_SWITCH_STACK
 
-	/* restore user stack pointer */
-	movel	%a1@(TASK_THREAD+THREAD_USP),%a0
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0 /* restore user stack */
 	movel	%a0,%usp
-
-#ifdef USE_SFC_DFC
-	/* restore fs (sfc,%dfc) */
-	movew	%a1@(TASK_THREAD+THREAD_FS),%a0
-	movec	%a0,%sfc
-	movec	%a0,%dfc
-#endif
-	/* restore status register */
-	movew	%a1@(TASK_THREAD+THREAD_SR),%sr
-
+	movew	%a1@(TASK_THREAD+THREAD_SR),%sr	/* restore thread status reg */
 	rts
 
diff -Nru a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S
--- a/arch/m68knommu/platform/68360/entry.S	Thu Jan 16 18:23:06 2003
+++ b/arch/m68knommu/platform/68360/entry.S	Thu Jan 16 18:23:06 2003
@@ -1,5 +1,4 @@
-/* -*- mode: asm -*-
- *
+/*
  *  linux/arch/m68knommu/platform/68360/entry.S
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
@@ -11,99 +10,30 @@
  *
  * Linux/m68k support by Hamish Macdonald
  * M68360 Port by SED Systems, and Lineo.
- *
- */
-
-/*
- * entry.S  contains the system-call and fault low-level handling routines.
- * This also contains the timer-interrupt handler, as well as all interrupts
- * and faults that can result in a task-switch.
- *
- * NOTE: This code handles signal-recognition, which happens every time
- * after a timer-interrupt and after each system call.
- *
- */
-
-/*
- * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
- *               all pointers that used to be 'current' are now entry
- *               number 0 in the 'current_set' list.
  */
 
 #include <linux/config.h>
 #include <linux/sys.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
+#include <asm/errno.h>
 #include <asm/setup.h>
 #include <asm/segment.h>
-#include <asm/entry.h>
-#include <asm/errno.h>
 #include <asm/traps.h>
 #include <asm/asm-offsets.h>
+#include <asm/entry.h>
 
-#define IMMED #
-#define DBG_PUTC(x)	moveb IMMED x,0xfffff907; \
-			moveb IMMED '\r',0xfffff907; \
-			moveb IMMED '\n',0xfffff907
-LD0         =   0x20
-LORIG_D0    =   0x24
+.text
 
 .globl system_call
-.globl buserr
-.globl trap
 .globl resume
 .globl ret_from_exception
 .globl ret_from_signal
 .globl sys_call_table
-.globl sys_fork
-.globl sys_clone
-.globl sys_vfork
 .globl ret_from_interrupt
 .globl bad_interrupt
 .globl inthandler
 
-.text
-ENTRY(buserr)
-	SAVE_ALL_INT
-	/* GET_CURRENT(%d0) */
-	movel	%sp,%sp@- 		/* stack frame pointer argument*/
-	bsrw	buserr_c
-	addql	#4,%sp
-	jra	ret_from_exception
-
-ENTRY(trap)
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
-    moveq.l #-1,%d0
-    move.l  %d0,%sp@(LORIG_D0)
-/* may have to test for LFORMATVEC here as was done in teh 2.0 module */
-	movel	%sp,%sp@- 		/* stack frame pointer argument*/
-	bsrw	trap_c
-	addql	#4,%sp
-	jra	ret_from_exception
-
-
-ENTRY(reschedule)
-	/* save top of frame*/
-	pea	%sp@
-	jbsr	set_esp0
-	addql	#4,%sp
-
-	pea	ret_from_exception
-	jmp	schedule
-
-	/* After a fork we jump here directly from resume,*/
-	/* so that %d1 contains the previous task*/
-	/* Theoretically only needed on SMP, but let's watch*/
-	/* what happens in schedule_tail() in future...*/
-ENTRY(ret_from_fork)
-#ifdef CONFIG_SMP
-	movel	%d1,%sp@-
-	jsr	schedule_tail
-	addql	#4,%sp
-#endif
-	jra	ret_from_exception
-
 badsys:
 	movel	#-ENOSYS,%sp@(PT_D0)
 	jra	ret_from_exception
@@ -123,8 +53,8 @@
 	lea	sys_call_table, %a0
 	jbsr	%a0@(%d1)
 
-1:	movel	%d0,%sp@(PT_D0)		/* save the return value*/
-	subql	#4,%sp			/* dummy return address*/
+1:	movel	%d0,%sp@(PT_D0)		/* save the return value */
+	subql	#4,%sp			/* dummy return address */
 	SAVE_SWITCH_STACK
 	jbsr	syscall_trace
 
@@ -134,9 +64,8 @@
 	jra	ret_from_exception
 
 ENTRY(system_call)
-	SAVE_ALL_SYS
+	SAVE_ALL
 
-	GET_CURRENT(%d1)
 	/* save top of frame*/
 	pea	%sp@
 	jbsr	set_esp0
@@ -191,14 +120,11 @@
 	RESTORE_ALL
 
 /*
-** This is the main interrupt handler, responsible for calling process_int()
-*/
-
+ * This is the main interrupt handler, responsible for calling process_int()
+ */
 inthandler:
-	SAVE_ALL_INT
-	GET_CURRENT(%d0)
+	SAVE_ALL
 	addql	#1,local_irq_count	/*  put exception # in d0*/
-/*	bfextu %sp@(PT_VECTOR){#4,#10},%d0 */
 	movew	%sp@(PT_VECTOR), %d0
 	and.l	#0x3ff, %d0
 	lsr.l   #0x02,  %d0
@@ -215,16 +141,9 @@
 2:
 	RESTORE_ALL
 1:
-#if 1
-/*	bfextu  %sp@(PT_SR){#5,#3},%d0 */	/* Check for nested interrupt.*/
 	moveb	%sp@(PT_SR), %d0
 	and	#7, %d0
-
-#if MAX_NOINT_IPL > 0
-	cmpiw	#MAX_NOINT_IPL,%d0
-#endif
 	jhi	2b
-#endif
 	/* check if we need to do software interrupts */
 
 	movel	irq_stat+CPUSTAT_SOFTIRQ_PENDING,%d0
@@ -234,111 +153,31 @@
 	jra	do_softirq
 
 
-/* Handler for uninitialized and spurious interrupts */
-
+/*
+ * Handler for uninitialized and spurious interrupts.
+ */
 bad_interrupt:
 	addql	#1,num_spurious
 	rte
 
-ENTRY(sys_fork)
-	SAVE_SWITCH_STACK	
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	m68k_fork
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_clone)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	m68k_clone
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_vfork)
-	SAVE_SWITCH_STACK	
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	m68k_vfork
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_sigsuspend)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	do_sigsuspend
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_rt_sigsuspend)
-	SAVE_SWITCH_STACK
-	pea	%sp@(SWITCH_STACK_SIZE)
-	jbsr	do_rt_sigsuspend
-	addql	#4,%sp
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_sigreturn)
-	SAVE_SWITCH_STACK
-	jbsr	do_sigreturn
-	RESTORE_SWITCH_STACK
-	rts
-
-ENTRY(sys_rt_sigreturn)
-	SAVE_SWITCH_STACK
-	jbsr	do_rt_sigreturn
-	RESTORE_SWITCH_STACK
-	rts
-
-resume:
-	/*
-	 * Beware - when entering resume, prev (the current task) is
-	 * in a0, next (the new task) is in a1,so don't change these
-	 * registers until their contents are no longer needed.
-	 */
-
-	/* save prev thread in d1 */
-	movel	%a0,%d1
-
-	/* save sr */
-	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)
-#ifdef USE_SFC_DFC
-	/* save fs (sfc,%dfc) (may be pointing to kernel memory) */
-	movec	%sfc,%d0
-	movew	%d0,%a0@(TASK_THREAD+THREAD_FS)
-#endif
-
-	/* save non-scratch registers on stack */
-	SAVE_SWITCH_STACK
-
-	/* save usp */
-	/* it is better to use a movel here instead of a movew 8*) */
-	movel	%usp,%a2
+/*
+ * Beware - when entering resume, prev (the current task) is
+ * in a0, next (the new task) is in a1,so don't change these
+ * registers until their contents are no longer needed.
+ */
+ENTRY(resume)
+	movel	%a0,%d1				/* save prev thread in d1 */
+	movew	%sr,%a0@(TASK_THREAD+THREAD_SR)	/* save sr */
+	movel	%usp,%a2			/* save usp */
 	movel	%a2,%a0@(TASK_THREAD+THREAD_USP)
 
-	/* save current kernel stack pointer */
-	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP)
-
-	/* restore the kernel stack pointer */
-	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp
-
-	/* restore non-scratch registers */
+	SAVE_SWITCH_STACK
+	movel	%sp,%a0@(TASK_THREAD+THREAD_KSP) /* save kernel stack */
+	movel	%a1@(TASK_THREAD+THREAD_KSP),%sp /* restore new thread stack */
 	RESTORE_SWITCH_STACK
 
-	/* restore user stack pointer */
-	movel	%a1@(TASK_THREAD+THREAD_USP),%a0
+	movel	%a1@(TASK_THREAD+THREAD_USP),%a0 /* restore user stack */
 	movel	%a0,%usp
-
-#ifdef USE_SFC_DFC
-	/* restore fs (sfc,%dfc) */
-	movew	%a1@(TASK_THREAD+THREAD_FS),%a0
-	movec	%a0,%sfc
-	movec	%a0,%dfc
-#endif
-	/* restore status register */
-	movew	%a1@(TASK_THREAD+THREAD_SR),%sr
-
+	movew	%a1@(TASK_THREAD+THREAD_SR),%sr	/* restore thread status reg */
 	rts
 
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S
--- a/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S	Thu Jan 16 18:23:06 2003
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_ram.S	Thu Jan 16 18:23:06 2003
@@ -1,13 +1,8 @@
-	.global __text_start
 	.global __main
-	.global __bss_start
-	.global __bss_end
 	.global __ram_start
 	.global __ram_end
 	.global __rom_start
 	.global __rom_end
-	.global __data_start
-	.global __data_end
 
         .global _rambase
         .global _ramstart
@@ -75,7 +70,7 @@
 	/* Copy me to RAM */
 	moveal	#__rom_start, %a0
 	moveal	#__ram_start, %a1
-	moveal	#__data_end, %a2
+	moveal	#_edata, %a2
 
 	/* Copy %a0 to %a1 until %a1 == %a2 */
 LD1:
@@ -107,8 +102,8 @@
 	beq	pclp3
 #endif /* DEBUG */
 	moveal	#0x007ffff0, %ssp
-	moveal	#__bss_start, %a0
-	moveal	#__bss_end, %a1
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
 
 	/* Copy 0 to %a0 until %a0 >= %a1 */
 L1:
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/himem.ld b/arch/m68knommu/platform/68VZ328/de2/himem.ld
--- a/arch/m68knommu/platform/68VZ328/de2/himem.ld	Thu Jan 16 18:23:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,11 +0,0 @@
-MEMORY 
-	{
-        romvec : ORIGIN = 0x01e00000, LENGTH = 1k
-        flash  : ORIGIN = 0x01e00400, LENGTH = 2M - 1k
-        eflash : ORIGIN = 0x02000000, LENGTH = 0
-        ramvec : ORIGIN = 0x00000000, LENGTH = 1k
-        ram    : ORIGIN = 0x00010000, LENGTH = 30M - 64k
-        eram   : ORIGIN = 0x01e00000, LENGTH = 0
-	}
-
-INCLUDE arch/m68knommu/platform/68VZ328/de2/fixed.ld
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S
--- a/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S	Thu Jan 16 18:23:05 2003
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_ram.S	Thu Jan 16 18:23:05 2003
@@ -1,15 +1,10 @@
 #include <linux/config.h>
 
-	.global __text_start
 	.global __main
-	.global __bss_start
-	.global __bss_end
 	.global __ram_start
 	.global __ram_end
 	.global __rom_start
 	.global __rom_end
-	.global __data_start
-	.global __data_end
 
         .global _rambase
         .global _ramstart
@@ -79,7 +74,7 @@
 	/* Copy me to RAM */
 	moveal	#__rom_start, %a0
 	moveal	#__ram_start, %a1
-	moveal	#__data_end, %a2
+	moveal	#_edata, %a2
 
 	/* Copy %a0 to %a1 until %a1 == %a2 */
 LD1:
@@ -111,8 +106,8 @@
 	beq	pclp3
 #endif /* DEBUG */
 	moveal	#0x007ffff0, %ssp
-	moveal	#__bss_start, %a0
-	moveal	#__bss_end, %a1
+	moveal	#_sbss, %a0
+	moveal	#_ebss, %a1
 
 	/* Copy 0 to %a0 until %a0 >= %a1 */
 L1:
diff -Nru a/arch/m68knommu/vmlinux.lds.S b/arch/m68knommu/vmlinux.lds.S
--- a/arch/m68knommu/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/m68knommu/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -10,6 +10,7 @@
  */
 
 #include <linux/config.h>
+#include <asm-generic/vmlinux.lds.h>
 
 /*
  *	Original Palm pilot (same for Xcopilot).
@@ -219,20 +220,13 @@
 		_stext = . ;
         	*(.text)
         	*(.text.lock)
-		*(.rodata)
-		*(.rodata.*)
-
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
 
 		. = ALIGN(16);          /* Exception table              */
 		__start___ex_table = .;
 		*(__ex_table)
 		__stop___ex_table = .;
 
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
+		RODATA
 
 		. = ALIGN(4) ;
 		_etext = . ;
diff -Nru a/arch/mips/vmlinux.lds.S b/arch/mips/vmlinux.lds.S
--- a/arch/mips/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/mips/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -1,3 +1,5 @@
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_ARCH(mips)
 ENTRY(kernel_entry)
 SECTIONS
@@ -9,12 +11,9 @@
   {
     _ftext = . ;
     *(.text)
-    *(.rodata)
-    *(.rodata1)
     /* .gnu.warning sections are handled specially by elf32.em.  */
     *(.gnu.warning)
   } =0
-  .kstrtab : { *(.kstrtab) }
 
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
@@ -25,14 +24,8 @@
   __dbe_table : { *(__dbe_table) }
   __stop___dbe_table = .;
 
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-
+  RODATA
+	
   _etext = .;
 
   . = ALIGN(8192);
diff -Nru a/arch/mips64/ld.script.elf64 b/arch/mips64/ld.script.elf64
--- a/arch/mips64/ld.script.elf64	Thu Jan 16 18:23:06 2003
+++ b/arch/mips64/ld.script.elf64	Thu Jan 16 18:23:06 2003
@@ -25,6 +25,7 @@
     *(.gnu.warning)
   } = 0
   .kstrtab : { *(.kstrtab) }
+  __vermagic : { *(__vermagic) }
 
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
diff -Nru a/arch/mips64/vmlinux.lds.S b/arch/mips64/vmlinux.lds.S
--- a/arch/mips64/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/mips64/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -1,3 +1,5 @@
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_ARCH(mips)
 ENTRY(kernel_entry)
 SECTIONS
@@ -7,13 +9,9 @@
   .text      :
   {
     *(.text)
-    *(.rodata)
-    *(.rodata.*)
-    *(.rodata1)
     /* .gnu.warning sections are handled specially by elf32.em.  */
     *(.gnu.warning)
   } =0
-  .kstrtab : { *(.kstrtab) }
 
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
@@ -24,6 +22,8 @@
   __dbe_table : { *(__dbe_table) }
   __stop___dbe_table = .;
 
+  RODATA
+	
   _etext = .;
 
   . = ALIGN(16384);
diff -Nru a/arch/parisc/defconfig b/arch/parisc/defconfig
--- a/arch/parisc/defconfig	Thu Jan 16 18:23:05 2003
+++ b/arch/parisc/defconfig	Thu Jan 16 18:23:05 2003
@@ -643,14 +643,14 @@
 CONFIG_SOUND=y
 
 #
-# Open Sound System
+# Advanced Linux Sound Architecture
 #
-# CONFIG_SOUND_PRIME is not set
+# CONFIG_SND is not set
 
 #
-# Advanced Linux Sound Architecture
+# Open Sound System
 #
-# CONFIG_SND is not set
+# CONFIG_SOUND_PRIME is not set
 
 #
 # USB support
diff -Nru a/arch/parisc/vmlinux.lds.S b/arch/parisc/vmlinux.lds.S
--- a/arch/parisc/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/parisc/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -1,5 +1,6 @@
 #include <linux/config.h>
-
+#include <asm-generic/vmlinux.lds.h>
+	
 /* ld script to make hppa Linux kernel */
 #ifndef CONFIG_PARISC64
 OUTPUT_FORMAT("elf32-hppa-linux")
@@ -31,31 +32,17 @@
 
   _etext = .;			/* End of text section */
 
-  . = ALIGN(16);
-  .rodata : { *(.rodata) *(.rodata.*) }
-  .kstrtab : { *(.kstrtab) }
-
-  .data BLOCK(8192) : {			/* Data without special */
-	data_start = .;
-	*(.data)
-	}
-
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-
-  __start___kallsyms = .;       /* All kernel symbols */
-  __kallsyms : { *(__kallsyms) }
-  __stop___kallsyms = .;
+  RODATA
+
+  .data BLOCK(8192) : {			/* Data without special */
+	data_start = .;
+	*(.data)
+	}
 
 #ifdef CONFIG_PARISC64
   . = ALIGN(16);               /* Linkage tables */
diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile
--- a/arch/ppc/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/Makefile	Thu Jan 16 18:23:05 2003
@@ -55,6 +55,7 @@
 drivers-$(CONFIG_8xx)		+= arch/ppc/8xx_io/
 drivers-$(CONFIG_4xx)		+= arch/ppc/4xx_io/
 drivers-$(CONFIG_8260)		+= arch/ppc/8260_io/
+drivers-$(CONFIG_OCP)		+= arch/ppc/ocp/
 
 BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd pImage vmlinux.sm
 
diff -Nru a/arch/ppc/boot/common/cpc700_memory.c b/arch/ppc/boot/common/cpc700_memory.c
--- a/arch/ppc/boot/common/cpc700_memory.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/boot/common/cpc700_memory.c	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Dan Cox
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <asm/types.h>
diff -Nru a/arch/ppc/boot/common/misc-common.c b/arch/ppc/boot/common/misc-common.c
--- a/arch/ppc/boot/common/misc-common.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/boot/common/misc-common.c	Thu Jan 16 18:23:05 2003
@@ -8,27 +8,10 @@
  *
  * Derived from arch/ppc/boot/prep/misc.c
  *
- * Copyright 2000-2001 MontaVista Software Inc.
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <stdarg.h>	/* for va_ bits */
diff -Nru a/arch/ppc/boot/common/mpc10x_memory.c b/arch/ppc/boot/common/mpc10x_memory.c
--- a/arch/ppc/boot/common/mpc10x_memory.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/boot/common/mpc10x_memory.c	Thu Jan 16 18:23:05 2003
@@ -9,12 +9,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/pci.h>
diff -Nru a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S
--- a/arch/ppc/boot/common/util.S	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/boot/common/util.S	Thu Jan 16 18:23:07 2003
@@ -14,12 +14,10 @@
  *	   trini@mvista.com
  * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <asm/processor.h>
diff -Nru a/arch/ppc/boot/include/mpc10x.h b/arch/ppc/boot/include/mpc10x.h
--- a/arch/ppc/boot/include/mpc10x.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/boot/include/mpc10x.h	Thu Jan 16 18:23:05 2003
@@ -12,12 +12,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #ifndef __BOOT_MPC10X_H__
 #define __BOOT_MPC10X_H__
diff -Nru a/arch/ppc/boot/ld.script b/arch/ppc/boot/ld.script
--- a/arch/ppc/boot/ld.script	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/boot/ld.script	Thu Jan 16 18:23:06 2003
@@ -39,7 +39,7 @@
   PROVIDE (etext = .);
 
   /* Read-write section, merged into data segment: */
-  . = ALIGN(8);
+  . = ALIGN(4096);
   .data    :
   {
     *(.data)
diff -Nru a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
--- a/arch/ppc/boot/simple/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/boot/simple/Makefile	Thu Jan 16 18:23:05 2003
@@ -3,7 +3,10 @@
 #
 # Author: Tom Rini <trini@mvista.com>
 #
-# Copyright 2001-2002 MontaVista Software Inc.
+# 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+# the terms of the GNU General Public License version 2.1.  This program
+# is licensed "as is" without any warranty of any kind, whether express
+# or implied.
 #
 # Notes:
 # (1) For machine targets which produce more than one image, define
@@ -18,11 +21,6 @@
 # (4) It is advisable to pass in the memory size using BI_MEMSIZE and
 # get_mem_size(), which is memory controller dependant.  Add in the correct
 # XXX_memory.o file for this to work, as well as editing the $(MISC) file.
-#
-# 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.
 
 boot: zImage
 
diff -Nru a/arch/ppc/boot/simple/gt64260_tty.c b/arch/ppc/boot/simple/gt64260_tty.c
--- a/arch/ppc/boot/simple/gt64260_tty.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/boot/simple/gt64260_tty.c	Thu Jan 16 18:23:05 2003
@@ -6,12 +6,10 @@
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /* This code assumes that the data cache has been disabled (L1, L2, L3). */
diff -Nru a/arch/ppc/boot/simple/head.S b/arch/ppc/boot/simple/head.S
--- a/arch/ppc/boot/simple/head.S	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/boot/simple/head.S	Thu Jan 16 18:23:06 2003
@@ -7,12 +7,10 @@
  *	   trini@mvista.com
  * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/boot/simple/misc-ev64260.S b/arch/ppc/boot/simple/misc-ev64260.S
--- a/arch/ppc/boot/simple/misc-ev64260.S	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/boot/simple/misc-ev64260.S	Thu Jan 16 18:23:07 2003
@@ -6,12 +6,10 @@
  *
  * Author: Mark Greer <mgreer@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <asm/ppc_asm.h>
diff -Nru a/arch/ppc/boot/simple/misc-spruce.c b/arch/ppc/boot/simple/misc-spruce.c
--- a/arch/ppc/boot/simple/misc-spruce.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/boot/simple/misc-spruce.c	Thu Jan 16 18:23:06 2003
@@ -8,27 +8,10 @@
  *
  * Derived from arch/ppc/boot/prep/misc.c
  *
- * Copyright 2000-2001 MontaVista Software Inc.
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/types.h>
diff -Nru a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
--- a/arch/ppc/boot/simple/misc.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/boot/simple/misc.c	Thu Jan 16 18:23:06 2003
@@ -10,12 +10,10 @@
  * Author: Matt Porter <mporter@mvista.com>
  * Derived from arch/ppc/boot/prep/misc.c
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/types.h>
diff -Nru a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S
--- a/arch/ppc/boot/simple/relocate.S	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/boot/simple/relocate.S	Thu Jan 16 18:23:05 2003
@@ -9,12 +9,10 @@
  *	   trini@mvista.com
  * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c
--- a/arch/ppc/boot/utils/mkbugboot.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/boot/utils/mkbugboot.c	Thu Jan 16 18:23:06 2003
@@ -6,12 +6,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #define ELF_HEADER_SIZE	65536
diff -Nru a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c
--- a/arch/ppc/kernel/asm-offsets.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/kernel/asm-offsets.c	Thu Jan 16 18:23:06 2003
@@ -36,6 +36,7 @@
 	DEFINE(THREAD, offsetof(struct task_struct, thread));
 	DEFINE(THREAD_INFO, offsetof(struct task_struct, thread_info));
 	DEFINE(MM, offsetof(struct task_struct, mm));
+	DEFINE(PTRACE, offsetof(struct task_struct, ptrace));
 	DEFINE(KSP, offsetof(struct thread_struct, ksp));
 	DEFINE(PGDIR, offsetof(struct thread_struct, pgdir));
 	DEFINE(LAST_SYSCALL, offsetof(struct thread_struct, last_syscall));
@@ -43,6 +44,10 @@
 	DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
 	DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
 	DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
+#ifdef CONFIG_4xx
+	DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
+	DEFINE(PT_PTRACED, PT_PTRACED);
+#endif
 #ifdef CONFIG_ALTIVEC
 	DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
 	DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
diff -Nru a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
--- a/arch/ppc/kernel/entry.S	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/kernel/entry.S	Thu Jan 16 18:23:06 2003
@@ -35,6 +35,25 @@
 #undef SHOW_SYSCALLS_TASK
 
 /*
+ * MSR_KERNEL is > 0x10000 on 4xx since it include MSR_CE.
+ */
+#if MSR_KERNEL >= 0x10000
+#define LOAD_MSR_KERNEL(r, x)	lis r,(x)@h; ori r,r,(x)@l
+#else
+#define LOAD_MSR_KERNEL(r, x)	li r,(x)
+#endif
+
+#ifdef CONFIG_4xx
+	.globl	crit_transfer_to_handler
+crit_transfer_to_handler:
+	lwz	r0,crit_r10@l(0)
+	stw	r0,GPR10(r11)
+	lwz	r0,crit_r11@l(0)
+	stw	r0,GPR11(r11)
+	/* fall through */
+#endif
+
+/*
  * This code finishes saving the registers to the exception frame
  * and jumps to the appropriate handler for the exception, turning
  * on address translation.
@@ -51,6 +70,7 @@
 	stw	r2,GPR2(r11)
 	stw	r12,_NIP(r11)
 	stw	r9,_MSR(r11)
+	andi.	r2,r9,MSR_PR
 	mfctr	r12
 	mfspr	r2,XER
 	stw	r12,_CTR(r11)
@@ -61,6 +81,22 @@
 	beq	2f			/* if from user, fix up THREAD.regs */
 	addi	r11,r1,STACK_FRAME_OVERHEAD
 	stw	r11,PT_REGS(r12)
+#ifdef CONFIG_4xx
+	lwz	r12,PTRACE-THREAD(r12)
+	andi.	r12,r12,PT_PTRACED
+	beq+	3f
+	/* From user and task is ptraced - load up global dbcr0 */
+	li	r12,-1			/* clear all pending debug events */
+	mtspr	SPRN_DBSR,r12
+	lis	r11,global_dbcr0@ha
+	tophys(r11,r11)
+	addi	r11,r11,global_dbcr0@l
+	lwz	r12,0(r11)
+	mtspr	SPRN_DBCR0,r12
+	lwz	r12,4(r11)
+	addi	r12,r12,-1
+	stw	r12,4(r11)
+#endif
 	b	3f
 2:	/* if from kernel, check interrupted DOZE/NAP mode and
          * check for stack overflow
@@ -96,15 +132,19 @@
  * and call StackOverflow(regs), which should not return.
  */
 stack_ovf:
+	/* sometimes we use a statically-allocated stack, which is OK. */
+	lis	r11,_end@h
+	ori	r11,r11,_end@l
+	cmplw	r1,r11
+	ble	3b			/* r1 <= &_end is OK */
 	SAVE_NVGPRS(r11)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	tovirt(r2,r2)			/* set r2 to current */
 	lis	r1,init_thread_union@ha
 	addi	r1,r1,init_thread_union@l
 	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
 	lis	r9,StackOverflow@ha
 	addi	r9,r9,StackOverflow@l
-	li	r10,MSR_KERNEL
+	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
 	FIX_SRR1(r10,r12)
 	mtspr	SRR0,r9
 	mtspr	SRR1,r10
@@ -161,7 +201,7 @@
 	stw	r10,_CCR(r1)
 
 	/* disable interrupts so current_thread_info()->flags can't change */
-30:	li	r10,MSR_KERNEL	/* doesn't include MSR_EE */
+30:	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
 	SYNC
 	MTMSRD(r10)
 	rlwinm	r12,r1,0,0,18	/* current_thread_info() */
@@ -169,6 +209,12 @@
 	andi.	r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
 	bne-	syscall_exit_work
 syscall_exit_cont:
+#ifdef CONFIG_4xx
+	/* If the process has its own DBCR0 value, load it up */
+	lwz	r0,PTRACE(r2)
+	andi.	r0,r0,PT_PTRACED
+	bnel-	load_4xx_dbcr0
+#endif
 	stwcx.	r0,0,r1			/* to clear the reservation */
 	lwz	r4,_LINK(r1)
 	lwz	r5,_CCR(r1)
@@ -215,7 +261,6 @@
 	stw	r3,GPR3(r1)	/* Update return value */
 	andi.	r0,r9,_TIF_SYSCALL_TRACE
 	beq	5f
-	stw	r6,GPR0(r1)	/* temporary gross hack to make strace work */
 	ori	r10,r10,MSR_EE
 	SYNC
 	MTMSRD(r10)		/* re-enable interrupts */
@@ -230,7 +275,7 @@
 	REST_NVGPRS(r1)
 2:
 	lwz	r3,GPR3(r1)
-	li	r10,MSR_KERNEL	/* doesn't include MSR_EE */
+	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
 	SYNC
 	MTMSRD(r10)		/* disable interrupts again */
 	rlwinm	r12,r1,0,0,18	/* current_thread_info() */
@@ -243,10 +288,7 @@
 	beq	syscall_exit_cont
 	andi.	r0,r9,_TIF_SIGPENDING
 	beq	syscall_exit_cont
-	ori	r10,r10,MSR_EE
-	SYNC
-	MTMSRD(r10)		/* re-enable interrupts */
-	b	syscall_do_signal
+	b	do_user_signal
 1:
 	ori	r10,r10,MSR_EE
 	SYNC
@@ -459,7 +501,7 @@
 	/* Hard-disable interrupts so that current_thread_info()->flags
 	 * can't change between when we test it and when we return
 	 * from the interrupt. */
-	li	r10,MSR_KERNEL	/* doesn't include EE */
+	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
 	SYNC			/* Some chip revs have problems here... */
 	MTMSRD(r10)		/* disable interrupts */
 
@@ -467,23 +509,33 @@
 	andi.	r3,r3,MSR_PR
 	beq	resume_kernel
 
+user_exc_return:		/* r10 contains MSR_KERNEL here */
 	/* Check current_thread_info()->flags */
 	rlwinm	r9,r1,0,0,18
 	lwz	r9,TI_FLAGS(r9)
 	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED)
 	bne	do_work
 
+restore_user:
+#ifdef CONFIG_4xx
+	/* Check whether this process has its own DBCR0 value */
+	lwz	r0,PTRACE(r2)
+	andi.	r0,r0,PT_PTRACED
+	bnel-	load_4xx_dbcr0
+#endif
+
 #ifdef CONFIG_PREEMPT
 	b	restore
 
 resume_kernel:
-	rlwinm	r9,r1,0,0,18	/* check current_thread_info->preempt_count */
+	/* check current_thread_info->preempt_count */
+	rlwinm	r9,r1,0,0,18
 	lwz	r3,TI_PREEMPT(r9)
-	cmpwi	0,r0,0		/* if non-zero, just restore regs and return */
+	cmpwi	0,r3,0		/* if non-zero, just restore regs and return */
 	bne	restore
 	lwz	r9,TI_FLAGS(r9)
 	andi.	r0,r9,_TIF_NEED_RESCHED
-	bne	do_work
+	bne	do_resched
 #else
 resume_kernel:
 #endif /* CONFIG_PREEMPT */
@@ -522,7 +574,7 @@
 	 * can restart the exception exit path at the label
 	 * exc_exit_restart below.  -- paulus
 	 */
-	li	r10,MSR_KERNEL & ~MSR_RI
+	LOAD_MSR_KERNEL(r10,MSR_KERNEL & ~MSR_RI)
 	SYNC
 	MTMSRD(r10)		/* clear the RI bit */
 	.globl exc_exit_restart
@@ -542,18 +594,14 @@
 #else /* CONFIG_4xx */
 	/*
 	 * This is a bit different on 4xx because 4xx doesn't have
-	 * the RI bit in the MSR, and because we have critical
-	 * exceptions, for which we need to restore SRR0 and SRR1
-	 * and then use SRR2/SRR3 to return from the exception.
+	 * the RI bit in the MSR.
 	 * The TLB miss handler checks if we have interrupted
-	 * the exception exit path and restarts it if so.
+	 * the exception exit path and restarts it if so
+	 * (well maybe one day it will... :).
 	 */
-	lwz	r10,TRAP(r1)		/* check for critical exception */
 	lwz	r11,_LINK(r1)
-	andi.	r10,r10,2
 	mtlr	r11
 	lwz	r10,_CCR(r1)
-	bne	crit_exc_exit
 	mtcrf	0xff,r10
 	REST_2GPRS(9, r1)
 	.globl exc_exit_restart
@@ -570,7 +618,43 @@
 	PPC405_ERR77_SYNC
 	rfi
 	b	.			/* prevent prefetch past rfi */
-crit_exc_exit:
+
+/*
+ * Returning from a critical interrupt in user mode doesn't need
+ * to be any different from a normal exception.  For a critical
+ * interrupt in the kernel, we just return (without checking for
+ * preemption) since the interrupt may have happened at some crucial
+ * place (e.g. inside the TLB miss handler), and because we will be
+ * running with r1 pointing into critical_stack, not the current
+ * process's kernel stack (and therefore current_thread_info() will
+ * give the wrong answer).
+ * We have to restore various SPRs that may have been in use at the
+ * time of the critical interrupt.
+ */
+	.globl	ret_from_crit_exc
+ret_from_crit_exc:
+	REST_NVGPRS(r1)
+	lwz	r3,_MSR(r1)
+	andi.	r3,r3,MSR_PR
+	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+	bne	user_exc_return
+
+	lwz	r0,GPR0(r1)
+	lwz	r2,GPR2(r1)
+	REST_4GPRS(3, r1)
+	REST_2GPRS(7, r1)
+
+	lwz	r10,_XER(r1)
+	lwz	r11,_CTR(r1)
+	mtspr	XER,r10
+	mtctr	r11
+
+	PPC405_ERR77(0,r1)
+	stwcx.	r0,0,r1			/* to clear the reservation */
+
+	lwz	r11,_LINK(r1)
+	mtlr	r11
+	lwz	r10,_CCR(r1)
 	mtcrf	0xff,r10
 	/* avoid any possible TLB misses here by turning off MSR.DR, we
 	 * assume the instructions here are mapped by a pinned TLB entry */
@@ -606,40 +690,68 @@
 	mtspr	SRR1,r10
 	lwz	r10,crit_pid@l(0)
 	mtspr	SPRN_PID,r10
-	lwz	r10,crit_r10@l(0)
-	lwz	r11,crit_r11@l(0)
+	lwz	r10,GPR10(r1)
+	lwz	r11,GPR11(r1)
 	lwz	r1,GPR1(r1)
 	PPC405_ERR77_SYNC
 	rfci
 	b	.		/* prevent prefetch past rfci */
+
+/*
+ * Load the DBCR0 value for a task that is being ptraced,
+ * having first saved away the global DBCR0.
+ */
+load_4xx_dbcr0:
+	mfmsr	r0		/* first disable debug exceptions */
+	rlwinm	r0,r0,0,~MSR_DE
+	mtmsr	r0
+	isync
+	mfspr	r10,SPRN_DBCR0
+	lis	r11,global_dbcr0@ha
+	addi	r11,r11,global_dbcr0@l
+	lwz	r0,THREAD+THREAD_DBCR0(r2)
+	stw	r10,0(r11)
+	mtspr	SPRN_DBCR0,r0
+	lwz	r10,4(r11)
+	addi	r10,r10,1
+	stw	r10,4(r11)
+	li	r11,-1
+	mtspr	SPRN_DBSR,r11	/* clear all pending debug events */
+	blr
+
+	.comm	global_dbcr0,8
 #endif /* CONFIG_4xx */
 
+do_work:			/* r10 contains MSR_KERNEL here */
+	andi.	r0,r9,_TIF_NEED_RESCHED
+	beq	do_user_signal
+
+do_resched:			/* r10 contains MSR_KERNEL here */
+	ori	r10,r10,MSR_EE
+	SYNC
+	MTMSRD(r10)		/* hard-enable interrupts */
+	bl	schedule
 recheck:
-	li	r10,MSR_KERNEL
+	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
 	SYNC
 	MTMSRD(r10)		/* disable interrupts */
 	rlwinm	r9,r1,0,0,18
 	lwz	r9,TI_FLAGS(r9)
+	andi.	r0,r9,_TIF_NEED_RESCHED
+	bne-	do_resched
+
 #ifdef CONFIG_PREEMPT
 	lwz	r0,_MSR(r1)
-	li	r11,_TIF_NEED_RESCHED
-	/* move MSR_PR bit down to TIF_SIGPENDING (0x4) bit */
-	rlwimi	r11,r0,18+TIF_SIGPENDING,31-TIF_SIGPENDING,31-TIF_SIGPENDING
-	and.	r0,r9,r11
-#else /* CONFIG_PREEMPT */
-	andi.	r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED)
-#endif /* CONFIG_PREEMPT */
+	andi.	r0,r0,MSR_PR
 	beq	restore
-do_work:
+#endif
+
+	andi.	r0,r9,_TIF_SIGPENDING
+	beq	restore_user
+do_user_signal:			/* r10 contains MSR_KERNEL here */
 	ori	r10,r10,MSR_EE
 	SYNC
 	MTMSRD(r10)		/* hard-enable interrupts */
-	andi.	r0,r9,_TIF_NEED_RESCHED
-	beq	1f
-	bl	schedule
-	b	recheck
-1:
-syscall_do_signal:
 	/* save r13-r31 in the exception frame, if not already done */
 	lwz	r3,TRAP(r1)
 	andi.	r0,r3,1
@@ -715,7 +827,7 @@
 	lwz	r8,rtas_entry@l(r8)
 	mfmsr	r9
 	stw	r9,8(r1)
-	li	r0,MSR_KERNEL
+	LOAD_MSR_KERNEL(r0,MSR_KERNEL)
 	SYNC			/* disable interrupts so SRR0/1 */
 	MTMSRD(r0)		/* don't get trashed */
 	li	r9,MSR_
diff -Nru a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
--- a/arch/ppc/kernel/head.S	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/kernel/head.S	Thu Jan 16 18:23:06 2003
@@ -401,7 +401,6 @@
 	mfspr	r4,DAR
 	stw	r4,_DAR(r11)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	andi.	r0,r9,MSR_PR		/* set cr0.eq if from kernel */
 	EXC_XFER_EE_LITE(0x300, do_page_fault)
 
 #ifdef CONFIG_PPC64BRIDGE
@@ -427,7 +426,6 @@
 1:	addi	r3,r1,STACK_FRAME_OVERHEAD
 	mr	r4,r12
 	mr	r5,r9
-	andi.	r0,r9,MSR_PR		/* set cr0.eq if from kernel */
 	EXC_XFER_EE_LITE(0x400, do_page_fault)
 
 #ifdef CONFIG_PPC64BRIDGE
diff -Nru a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
--- a/arch/ppc/kernel/head_4xx.S	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/kernel/head_4xx.S	Thu Jan 16 18:23:07 2003
@@ -75,7 +75,8 @@
  * ready to work.
  */
 turn_on_mmu:
-	li	r0,MSR_KERNEL
+	lis	r0,MSR_KERNEL@h
+	ori	r0,r0,MSR_KERNEL@l
 	mtspr	SRR1,r0
 	lis	r0,start_here@h
 	ori	r0,r0,start_here@l
@@ -213,42 +214,21 @@
 	SAVE_4GPRS(3, r11);						     \
 	SAVE_2GPRS(7, r11)
 
-#if 0
-#define CRITICAL_EXCEPTION_PROLOG					     \
-	stw	r10,crit_save@l(0);	/* save two registers to work with */\
-	stw	r11,4+crit_save@l(0);					     \
-	mfcr	r10;			/* save CR in r10 for now	   */\
-	mfspr	r11,SPRN_SRR3;		/* check whether user or kernel    */\
-	andi.	r11,r11,MSR_PR;						     \
-	mr	r11,r1;							     \
-	beq	1f;							     \
-	mfspr	r11,SPRG3;		/* if from user, start at top of   */\
-	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
-	addi	r11,r11,THREAD_SIZE;					     \
-1:	subi	r11,r11,INT_FRAME_SIZE;	/* Allocate an exception frame     */\
-	tophys(r11,r11);						     \
-	stw	r10,_CCR(r11);          /* save various registers	   */\
-	stw	r12,GPR12(r11);						     \
-	stw	r9,GPR9(r11);						     \
-	lwz	r10,crit_save@l(0);					     \
-	stw	r10,GPR10(r11);						     \
-	lwz	r12,4+crit_save@l(0);					     \
-	stw	r12,GPR11(r11);						     \
-	mflr	r10;							     \
-	stw	r10,_LINK(r11);						     \
-	mfspr	r12,SRR0;		/* save SRR0 and SRR1 in the frame */\
-	stw	r12,_SRR0(r11);		/* since they may have had stuff   */\
-	mfspr	r9,SRR1;		/* in them at the point where the  */\
-	stw	r9,_SRR1(r11);		/* exception was taken		   */\
-	mfspr	r12,SRR2;						     \
-	stw	r1,GPR1(r11);						     \
-	mfspr	r9,SRR3;						     \
-	stw	r1,0(r11);						     \
-	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
-	stw	r0,GPR0(r11);						     \
-	SAVE_4GPRS(3, r11);						     \
-	SAVE_2GPRS(7, r11)
-#endif
+	/*
+	 * State at this point:
+	 * r9 saved in stack frame, now saved SRR3 & ~MSR_WE
+	 * r10 saved in crit_r10 and in stack frame, trashed
+	 * r11 saved in crit_r11 and in stack frame,
+	 *	now phys stack/exception frame pointer
+	 * r12 saved in stack frame, now saved SRR2
+	 * SPRG0,1,4,5,6,7 saved in crit_sprg0,1,4,5,6,7
+	 * PID saved in crit_pid
+	 * SRR0,1 saved in crit_srr0,1
+	 * CR saved in stack frame, CR0.EQ = !SRR3.PR
+	 * LR, DEAR, ESR in stack frame
+	 * r1 saved in stack frame, now virt stack/excframe pointer
+	 * r0, r3-r8 saved in stack frame
+	 */
 
 /*
  * Exception vectors.
@@ -257,12 +237,6 @@
 	. = n;								     \
 label:
 
-#define FINISH_EXCEPTION(func)					\
-	bl	transfer_to_handler_full;			\
-	.long	func;						\
-	.long	ret_from_except_full
-
-
 #define EXCEPTION(n, label, hdlr, xfer)				\
 	START_EXCEPTION(n, label);				\
 	NORMAL_EXCEPTION_PROLOG;				\
@@ -274,13 +248,14 @@
 	CRITICAL_EXCEPTION_PROLOG;				\
 	addi	r3,r1,STACK_FRAME_OVERHEAD;			\
 	EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
-			  NOCOPY, transfer_to_handler_full, \
-			  ret_from_except_full)
+			  NOCOPY, crit_transfer_to_handler,	\
+			  ret_from_crit_exc)
 
 #define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret)	\
 	li	r10,trap;					\
 	stw	r10,TRAP(r11);					\
-	li	r10,msr;					\
+	lis	r10,msr@h;					\
+	ori	r10,r10,msr@l;					\
 	copyee(r10, r9);					\
 	bl	tfer;		 				\
 	.long	hdlr;						\
@@ -732,7 +707,47 @@
 
 /* 0x2000 - Debug Exception
 */
-	CRITICAL_EXCEPTION(0x2000, DebugTrap, DebugException)
+	START_EXCEPTION(0x2000, DebugTrap)
+	CRITICAL_EXCEPTION_PROLOG
+
+	/*
+	 * If this is a single step or branch-taken exception in an
+	 * exception entry sequence, it was probably meant to apply to
+	 * the code where the exception occurred (since exception entry
+	 * doesn't turn off DE automatically).  We simulate the effect
+	 * of turning off DE on entry to an exception handler by turning
+	 * off DE in the SRR3 value and clearing the debug status.
+	 */
+	mfspr	r10,SPRN_DBSR		/* check single-step/branch taken */
+	andis.	r10,r10,(DBSR_IC|DBSR_BT)@h
+	beq+	1f
+	andi.	r0,r9,MSR_IR|MSR_PR	/* check supervisor + MMU off */
+	beq	2f			/* branch if we need to fix it up... */
+
+	/* continue normal handling for a critical exception... */
+1:	mfspr	r4,SPRN_DBSR
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	EXC_XFER_TEMPLATE(DebugException, 0x2002, \
+		(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+		NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
+
+	/* here it looks like we got an inappropriate debug exception. */
+2:	rlwinm	r9,r9,0,~MSR_DE		/* clear DE in the SRR3 value */
+	mtspr	SPRN_DBSR,r10		/* clear the IC/BT debug intr status */
+	/* restore state and get out */
+	lwz	r10,_CCR(r11)
+	lwz	r0,GPR0(r11)
+	lwz	r1,GPR1(r11)
+	mtcrf	0x80,r10
+	mtspr	SRR2,r12
+	mtspr	SRR3,r9
+	lwz	r9,GPR9(r11)
+	lwz	r12,GPR12(r11)
+	lwz	r10,crit_r10@l(0)
+	lwz	r11,crit_r11@l(0)
+	PPC405_ERR77_SYNC
+	rfci
+	b	.
 
 /*
  * The other Data TLB exceptions bail out to this point
@@ -747,60 +762,6 @@
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	EXC_XFER_EE_LITE(0x300, do_page_fault)
 
-#if 0
-/* Check for a single step debug exception while in an exception
- * handler before state has been saved.  This is to catch the case
- * where an instruction that we are trying to single step causes
- * an exception (eg ITLB miss) and thus the first instruction of
- * the exception handler generates a single step debug exception.
- *
- * If we get a debug trap on the first instruction of an exception handler,
- * we reset the MSR_DE in the _exception handlers_ MSR (the debug trap is
- * a critical exception, so we are using SPRN_SRR3 to manipulate the MSR).
- * The exception handler was handling a non-critical interrupt, so it will
- * save (and later restore) the MSR via SPRN_SRR1, which will still have
- * the MSR_DE bit set.
- */
-check_single_step_in_exception:
-
-	/* This first instruction was already executed by the exception
-	 * handler and must be the first instruction of every exception
-	 * handler.
-	 */
-	mtspr	SPRN_SPRG0,r10		/* Save some working registers... */
-	mtspr	SPRN_SPRG1,r11
-	mfcr	r10			/* ..and the cr because we change it */
-
-	mfspr   r11,SPRN_SRR3		/* MSR at the time of fault */
-	andi.   r11,r11,MSR_PR
-	bne+    2f			/* trapped from problem state */
-
-	mfspr   r11,SPRN_SRR2		/* Faulting instruction address */
-	cmplwi  r11,0x2100
-	bgt+    2f			/* address above exception vectors */
-
-	lis     r11,DBSR_IC@h           /* Remove the trap status */
-	mtspr   SPRN_DBSR,r11
-
-	mfspr	r11,SPRN_SRR3
-	rlwinm	r11,r11,0,23,21		/* clear MSR_DE */
-	mtspr	SPRN_SRR3, r11		/* restore MSR at rcfi without DE */
-
-	mtcrf   0xff,r10                /* restore registers */
-	mfspr   r11,SPRN_SPRG1
-	mfspr   r10,SPRN_SPRG0
-
-	sync
-	rfci                            /* return to the exception handler  */
-	b	.			/* prevent prefetch past rfi */
-
-2:
-	mtcrf   0xff,r10                /* restore registers */
-	mfspr   r11,SPRN_SPRG1
-	mfspr   r10,SPRN_SPRG0
-	b       ret_to_debug_exception
-#endif 0
-
 /* Other PowerPC processors, namely those derived from the 6xx-series
  * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
  * However, for the 4xx-series processors these are neither defined nor
@@ -911,7 +872,8 @@
 	lis	r4,2f@h
 	ori	r4,r4,2f@l
 	tophys(r4,r4)
-	li	r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+	lis	r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
+	ori	r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
 	mtspr	SRR0,r4
 	mtspr	SRR1,r3
 	rfi
@@ -934,7 +896,8 @@
 	stw	r6, 0(r5)
 
 /* Now turn on the MMU for real! */
-	li	r4,MSR_KERNEL
+	lis	r4,MSR_KERNEL@h
+	ori	r4,r4,MSR_KERNEL@l
 	lis	r3,start_kernel@h
 	ori	r3,r3,start_kernel@l
 	mtspr	SRR0,r3
diff -Nru a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
--- a/arch/ppc/kernel/ptrace.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/kernel/ptrace.c	Thu Jan 16 18:23:05 2003
@@ -35,7 +35,11 @@
 /*
  * Set of msr bits that gdb can change on behalf of a process.
  */
-#define MSR_DEBUGCHANGE	(MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
+#ifdef CONFIG_4xx
+#define MSR_DEBUGCHANGE	0
+#else
+#define MSR_DEBUGCHANGE	(MSR_SE | MSR_BE)
+#endif
 
 /*
  * does not yet catch signals sent when the child dies.
@@ -132,8 +136,14 @@
 {
 	struct pt_regs *regs = task->thread.regs;
 
-	if (regs != NULL)
+	if (regs != NULL) {
+#ifdef CONFIG_4xx
+		task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
+		/* MSR.DE should already be set */
+#else
 		regs->msr |= MSR_SE;
+#endif
+	}
 }
 
 static inline void
@@ -141,8 +151,13 @@
 {
 	struct pt_regs *regs = task->thread.regs;
 
-	if (regs != NULL)
+	if (regs != NULL) {
+#ifdef CONFIG_4xx
+		task->thread.dbcr0 = 0;
+#else
 		regs->msr &= ~MSR_SE;
+#endif
+	}
 }
 
 /*
diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
--- a/arch/ppc/kernel/smp.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/kernel/smp.c	Thu Jan 16 18:23:07 2003
@@ -44,8 +44,8 @@
 struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 };
 atomic_t ipi_recv;
 atomic_t ipi_sent;
-unsigned int prof_multiplier[NR_CPUS] = { [1 ... NR_CPUS-1] = 1 };
-unsigned int prof_counter[NR_CPUS] = { [1 ... NR_CPUS-1] = 1 };
+DEFINE_PER_CPU(unsigned int, prof_multiplier);
+DEFINE_PER_CPU(unsigned int, prof_counter);
 unsigned long cache_decay_ticks = HZ/100;
 unsigned long cpu_online_map = 1UL;
 unsigned long cpu_possible_map = 1UL;
@@ -90,9 +90,9 @@
 {
 	int cpu = smp_processor_id();
 
-	if (!--prof_counter[cpu]) {
+	if (!--per_cpu(prof_counter, cpu)) {
 		update_process_times(user_mode(regs));
-		prof_counter[cpu]=prof_multiplier[cpu];
+		per_cpu(prof_counter, cpu) = per_cpu(prof_multiplier, cpu);
 	}
 }
 
@@ -327,6 +327,8 @@
 	/* assume bogomips are same for everything */
         c->loops_per_jiffy = loops_per_jiffy;
         c->pvr = mfspr(PVR);
+	per_cpu(prof_counter, id) = 1;
+	per_cpu(prof_multiplier, id) = 1;
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
diff -Nru a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
--- a/arch/ppc/kernel/traps.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/kernel/traps.c	Thu Jan 16 18:23:05 2003
@@ -313,8 +313,6 @@
 	int isbpt = esr & ESR_PTR;
 	extern int do_mathemu(struct pt_regs *regs);
 
-	if (isbpt)
-		mtspr(SPRN_DBSR, DBSR_TIE);
 #ifdef CONFIG_MATH_EMULATION
 	if (!isbpt && do_mathemu(regs) == 0)
 		return;
@@ -436,28 +434,20 @@
 
 #if defined(CONFIG_4xx)
 
-void DebugException(struct pt_regs *regs)
+void DebugException(struct pt_regs *regs, unsigned long debug_status)
 {
-	unsigned long debug_status;
-
-	debug_status = mfspr(SPRN_DBSR);
-
-	regs->msr &= ~MSR_DE;  /* Turn off 'debug' bit */
+#if 0
 	if (debug_status & DBSR_TIE) {		/* trap instruction*/
-
-		mtspr(SPRN_DBSR, DBSR_TIE);
-
 		if (!user_mode(regs) && debugger_bpt(regs))
 			return;
 		_exception(SIGTRAP, regs);
 
-	} else if (debug_status & DBSR_IC) {	/* instruction completion */
-
-		mtspr(SPRN_DBSR, DBSR_IC);
-		mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC);
-
+	}
+#endif
+	if (debug_status & DBSR_IC) {	/* instruction completion */
 		if (!user_mode(regs) && debugger_sstep(regs))
 			return;
+		current->thread.dbcr0 &= ~DBCR0_IC;
 		_exception(SIGTRAP, regs);
 	}
 }
diff -Nru a/arch/ppc/ocp/Makefile b/arch/ppc/ocp/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/ocp/Makefile	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+#
+# NB: cribbed from the drivers/sbus/Makefile -- PMM
+
+export-objs := ocp.o ocp-driver.o ocp-probe.o
+obj-y   	+= ocp.o ocp-driver.o ocp-probe.o
+
diff -Nru a/arch/ppc/ocp/ocp-driver.c b/arch/ppc/ocp/ocp-driver.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/ocp/ocp-driver.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,195 @@
+/*
+ * FILE NAME: ocp-driver.c
+ *
+ * BRIEF MODULE DESCRIPTION: 
+ * driver callback, id matching and registration
+ * Based on drivers/pci/pci-driver, Copyright (c) 1997--1999 Martin Mares
+ *
+ * Maintained by: Armin <akuster@mvista.com>
+ *
+ *
+ *  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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/ocp.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+/*
+ *  Registration of OCP drivers and handling of hot-pluggable devices.
+ */
+
+static int
+ocp_device_probe(struct device *dev)
+{
+	int error = 0;
+	struct ocp_driver *drv;
+	struct ocp_device *ocp_dev;
+
+	drv = to_ocp_driver(dev->driver);
+	ocp_dev = to_ocp_dev(dev);
+
+	if (drv->probe) {
+		error = drv->probe(ocp_dev);
+		DBG("probe return code %d\n", error);
+		if (error >= 0) {
+			ocp_dev->driver = drv;
+			error = 0;
+		}
+	}
+	return error;
+}
+
+static int
+ocp_device_remove(struct device *dev)
+{
+	struct ocp_device *ocp_dev = to_ocp_dev(dev);
+
+	if (ocp_dev->driver) {
+		if (ocp_dev->driver->remove)
+			ocp_dev->driver->remove(ocp_dev);
+		ocp_dev->driver = NULL;
+	}
+	return 0;
+}
+
+static int
+ocp_device_suspend(struct device *dev, u32 state, u32 level)
+{
+	struct ocp_device *ocp_dev = to_ocp_dev(dev);
+
+	int error = 0;
+
+	if (ocp_dev->driver) {
+		if (level == SUSPEND_SAVE_STATE && ocp_dev->driver->save_state)
+			error = ocp_dev->driver->save_state(ocp_dev, state);
+		else if (level == SUSPEND_POWER_DOWN
+			 && ocp_dev->driver->suspend)
+			error = ocp_dev->driver->suspend(ocp_dev, state);
+	}
+	return error;
+}
+
+static int
+ocp_device_resume(struct device *dev, u32 level)
+{
+	struct ocp_device *ocp_dev = to_ocp_dev(dev);
+
+	if (ocp_dev->driver) {
+		if (level == RESUME_POWER_ON && ocp_dev->driver->resume)
+			ocp_dev->driver->resume(ocp_dev);
+	}
+	return 0;
+}
+
+/**
+ * ocp_bus_match - Works out whether an OCP device matches any
+ * of the IDs listed for a given OCP driver.
+ * @dev: the generic device struct for the OCP device
+ * @drv: the generic driver struct for the OCP driver
+ * 
+ * Used by a driver to check whether a OCP device present in the
+ * system is in its list of supported devices.  Returns 1 for a
+ * match, or 0 if there is no match.
+ */
+static int
+ocp_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct ocp_device *ocp_dev = to_ocp_dev(dev);
+	struct ocp_driver *ocp_drv = to_ocp_driver(drv);
+	const struct ocp_device_id *ids = ocp_drv->id_table;
+
+	if (!ids)
+		return 0;
+
+	while (ids->vendor || ids->device) {
+		if ((ids->vendor == OCP_ANY_ID
+		     || ids->vendor == ocp_dev->vendor)
+		    && (ids->device == OCP_ANY_ID
+			|| ids->device == ocp_dev->device)) {
+			DBG("Bus match -vendor:%x device:%x\n", ids->vendor,
+			    ids->device);
+			return 1;
+		}
+		ids++;
+	}
+	return 0;
+}
+
+struct bus_type ocp_bus_type = {
+	.name = "ocp",
+	.match = ocp_bus_match,
+};
+
+static int __init
+ocp_driver_init(void)
+{
+	return bus_register(&ocp_bus_type);
+}
+
+postcore_initcall(ocp_driver_init);
+
+/**
+ * ocp_register_driver - register a new ocp driver
+ * @drv: the driver structure to register
+ * 
+ * Adds the driver structure to the list of registered drivers
+ * Returns the number of ocp devices which were claimed by the driver
+ * during registration.  The driver remains registered even if the
+ * return value is zero.
+ */
+int
+ocp_register_driver(struct ocp_driver *drv)
+{
+	int count = 0;
+
+	/* initialize common driver fields */
+	drv->driver.name = drv->name;
+	drv->driver.bus = &ocp_bus_type;
+	drv->driver.probe = ocp_device_probe;
+	drv->driver.resume = ocp_device_resume;
+	drv->driver.suspend = ocp_device_suspend;
+	drv->driver.remove = ocp_device_remove;
+
+	/* register with core */
+	count = driver_register(&drv->driver);
+	return count ? count : 1;
+}
+
+/**
+ * ocp_unregister_driver - unregister a ocp driver
+ * @drv: the driver structure to unregister
+ * 
+ * Deletes the driver structure from the list of registered OCP drivers,
+ * gives it a chance to clean up by calling its remove() function for
+ * each device it was responsible for, and marks those devices as
+ * driverless.
+ */
+
+void
+ocp_unregister_driver(struct ocp_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+
+EXPORT_SYMBOL(ocp_register_driver);
+EXPORT_SYMBOL(ocp_unregister_driver);
+EXPORT_SYMBOL(ocp_bus_type);
diff -Nru a/arch/ppc/ocp/ocp-probe.c b/arch/ppc/ocp/ocp-probe.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/ocp/ocp-probe.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,114 @@
+/*
+ * FILE NAME: ocp-probe.c
+ *
+ * BRIEF MODULE DESCRIPTION: 
+ * Device scanning & bus set routines
+ * Based on drivers/pci/probe, Copyright (c) 1997--1999 Martin Mares
+ *
+ * Maintained by: Armin <akuster@mvista.com>
+ *
+ *
+ *  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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <asm/ocp.h>
+
+LIST_HEAD(ocp_devices);
+struct device *ocp_bus;
+
+static struct ocp_device * __devinit
+ocp_setup_dev(struct ocp_def *odef, unsigned int index)
+{
+	struct ocp_device *dev;
+
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+	memset(dev, 0, sizeof(*dev));
+
+	dev->vendor = odef->vendor;
+	dev->device = odef->device;
+	dev->num = ocp_get_num(dev->device);
+	dev->paddr = odef->paddr;
+	dev->irq = odef->irq;
+	dev->pm = odef->pm;
+	dev->current_state = 4;
+
+	sprintf(dev->name, "OCP device %04x:%04x", dev->vendor, dev->device);
+	
+	DBG("%s %s 0x%lx irq:%d pm:0x%lx \n", dev->slot_name, dev->name,
+	    (unsigned long) dev->paddr, dev->irq, dev->pm);
+
+	/* now put in global tree */
+	strcpy(dev->dev.name, dev->name);
+	sprintf(dev->dev.bus_id, "%d", index);
+	dev->dev.parent = ocp_bus;
+	dev->dev.bus = &ocp_bus_type;
+	device_register(&dev->dev);
+
+	return dev;
+}
+
+static struct device * __devinit ocp_alloc_primary_bus(void)
+{
+	struct device *b;
+
+	b = kmalloc(sizeof(struct device), GFP_KERNEL);
+	if (b == NULL)
+		return NULL;
+	memset(b, 0, sizeof(struct device));
+	strcpy(b->bus_id, "ocp");
+	strcpy(b->name, "Host/OCP Bridge");
+	device_register(b);
+
+	return b;
+}
+
+void __devinit ocp_setup_devices(struct ocp_def *odef)
+{
+	int index;
+	struct ocp_device *dev;
+
+	if (ocp_bus == NULL)
+		ocp_bus = ocp_alloc_primary_bus();
+	for (index = 0; odef->vendor != OCP_VENDOR_INVALID; ++index, ++odef) {
+		dev = ocp_setup_dev(odef, index);
+		if (dev != NULL)
+			list_add_tail(&dev->global_list, &ocp_devices);
+	}
+}
+
+extern struct ocp_def core_ocp[];
+
+static int __init
+ocparch_init(void)
+{
+	ocp_setup_devices(core_ocp);
+	return 0;
+}
+
+subsys_initcall(ocparch_init);
+
+EXPORT_SYMBOL(ocp_devices);
diff -Nru a/arch/ppc/ocp/ocp.c b/arch/ppc/ocp/ocp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/ocp/ocp.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,109 @@
+/*
+ * ocp.c
+ *
+ *	The is drived from pci.c
+ *
+ * 	Current Maintainer
+ *      Armin Kuster akuster@dslextreme.com
+ *      Jan, 2002
+ *
+ *
+ *
+ * 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.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/ocp.h>
+#include <asm/errno.h>
+
+/**
+ * ocp_get_num - This determines how many OCP devices of a given
+ * device are registered
+ * @device: OCP device such as HOST, PCI, GPT, UART, OPB, IIC, GPIO, EMAC, ZMII,
+ *  
+ * The routine returns the number that devices which is registered
+ */
+unsigned int ocp_get_num(unsigned int device)
+{
+	unsigned int count = 0;
+	struct ocp_device *ocp;
+	struct list_head *ocp_l;
+
+	list_for_each(ocp_l, &ocp_devices) {
+		ocp = list_entry(ocp_l, struct ocp_device, global_list);
+		if (device == ocp->device)
+			count++;
+	}
+	return count;
+}
+
+/**
+ * ocp_get_dev - get ocp driver pointer for ocp device and instance of it 
+ * @device: OCP device such as PCI, GPT, UART, OPB, IIC, GPIO, EMAC, ZMII
+ * @dev_num: ocp device number whos paddr you want
+ *  
+ * The routine returns ocp device pointer 
+ * in list based on device and instance of that device
+ *
+ */
+struct ocp_device *
+ocp_get_dev(unsigned int device, int dev_num)
+{
+	struct ocp_device *ocp;
+	struct list_head *ocp_l;
+	int count = 0;
+
+	list_for_each(ocp_l, &ocp_devices) {
+		ocp = list_entry(ocp_l, struct ocp_device, global_list);
+		if (device == ocp->device) {
+			if (dev_num == count)
+				return ocp;
+			count++;
+		}
+	}
+	return NULL;
+}
+
+EXPORT_SYMBOL(ocp_get_dev);
+EXPORT_SYMBOL(ocp_get_num);
+
+#ifdef CONFIG_PM
+int ocp_generic_suspend(struct ocp_device *pdev, u32 state)
+{
+	ocp_force_power_off(pdev);
+	return 0;
+}
+
+int ocp_generic_resume(struct ocp_device *pdev)
+{
+	ocp_force_power_on(pdev);
+}
+
+EXPORT_SYMBOL(ocp_generic_suspend);
+EXPORT_SYMBOL(ocp_generic_resume);
+#endif /* CONFIG_PM */
diff -Nru a/arch/ppc/platforms/4xx/ash.c b/arch/ppc/platforms/4xx/ash.c
--- a/arch/ppc/platforms/4xx/ash.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ash.c	Thu Jan 16 18:23:05 2003
@@ -1,8 +1,14 @@
 /*
+ * arch/ppc/platforms/4xx/ash.c
+ * 
+ * Support for the IBM NP405H ash eval board
+ * 
+ * Author: Armin Kuster <akuster@mvista.com>
  *
- *    Copyright 2001-2002 MontaVista Software Inc.
- *        <akuster@mvista.com>
- *	IBM NP405H ash eval board
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/config.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/4xx/ash.h b/arch/ppc/platforms/4xx/ash.h
--- a/arch/ppc/platforms/4xx/ash.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ash.h	Thu Jan 16 18:23:05 2003
@@ -1,17 +1,15 @@
 /*
+ * arch/ppc/platforms/4xx/ash.h
  *
+ * Macros, definitions, and data structures specific to the IBM PowerPC
+ * Ash eval board.
  *
- *    Copyright 2000-2002  MontaVista Software Inc.
- * 	Author: MontaVista Software, Inc.
- *         	akuster@mvista.com or source@mvista.com
- *
- *    Module name: ash.h
- *
- *    Description:
- *      Macros, definitions, and data structures specific to the IBM PowerPC
- *      Ash eval board.
- *
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/cedar.c b/arch/ppc/platforms/4xx/cedar.c
--- a/arch/ppc/platforms/4xx/cedar.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/cedar.c	Thu Jan 16 18:23:06 2003
@@ -1,9 +1,14 @@
 /*
+ * arch/ppc/platforms/4xx/cedar.c
+ * 
+ * Support for the IBM NP405L ceder eval board
  *
- *    Copyright 2001 MontaVista Software Inc.
- *        <akuster@mvista.com>
- *	IBM NP405L ceder eval board
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/config.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/4xx/cedar.h b/arch/ppc/platforms/4xx/cedar.h
--- a/arch/ppc/platforms/4xx/cedar.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/cedar.h	Thu Jan 16 18:23:06 2003
@@ -1,17 +1,15 @@
 /*
+ * arch/ppc/platforms/4xx/cedar.h
  *
+ * Macros, definitions, and data structures specific to the IBM PowerPC
+ * Cedar eval board.
  *
- *    Copyright 2000 MontaVista Software Inc.
- * 	Author: MontaVista Software, Inc.
- *         	akuster@mvista.com or source@mvista.com
- *
- *    Module name: cedar.h
- *
- *    Description:
- *      Macros, definitions, and data structures specific to the IBM PowerPC
- *      Cedar eval board.
- *
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/ep405.c b/arch/ppc/platforms/4xx/ep405.c
--- a/arch/ppc/platforms/4xx/ep405.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ep405.c	Thu Jan 16 18:23:05 2003
@@ -1,9 +1,15 @@
 /*
- *    Copyright 2001 MontaVista Software Inc.
- *        <mlocke@mvista.com>
+ * arch/ppc/platforms/4xx/ep405.c
  *
- * 	Not much needed for the Embedded Planet 405gp board
+ * Embedded Planet 405GP board
+ * http://www.embeddedplanet.com
  *
+ * Author: Matthew Locke <mlocke@mvista.com>
+ * 
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/config.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/4xx/ep405.h b/arch/ppc/platforms/4xx/ep405.h
--- a/arch/ppc/platforms/4xx/ep405.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ep405.h	Thu Jan 16 18:23:05 2003
@@ -1,11 +1,15 @@
 /*
- *    Copyright 2000 MontaVista Software Inc.
- *    	http://www.mvista.com
- *	<mlocke@mvista.com>
+ * arch/ppc/platforms/4xx/ep405.h
  *
- *         Embedded Planet 405GP board
- *         http://www.embeddedplanet.com
+ * Embedded Planet 405GP board
+ * http://www.embeddedplanet.com
  *
+ * Author: Matthew Locke <mlocke@mvista.com>
+ *
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/ibm405gp.c b/arch/ppc/platforms/4xx/ibm405gp.c
--- a/arch/ppc/platforms/4xx/ibm405gp.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/ibm405gp.c	Thu Jan 16 18:23:06 2003
@@ -1,33 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/ibm405gp.c
  *
- *    Copyright 2000-2001 MontaVista Software Inc.
- *      Completed implementation.
- *	Current maintainer
- *      Armin Kuster akuster@mvista.com
- *
- *    Module name: ibm405gp.c
- *
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/ibm405gp.h b/arch/ppc/platforms/4xx/ibm405gp.h
--- a/arch/ppc/platforms/4xx/ibm405gp.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ibm405gp.h	Thu Jan 16 18:23:05 2003
@@ -1,35 +1,12 @@
 /*
- * ibm405gp.h
+ * arch/ppc/platforms/4xx/ibm405gp.h
  *
- *	This was derived from the ppc4xx.h and all 405GP specific
- *	definition and board inclusions were moved here.
- *
- *      Armin Kuster akuster@mvista.com
- *      Oct, 2001
- *
- *
- * Copyright 2001 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster akuster@mvista.com
  *
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/ibm405gpr.c b/arch/ppc/platforms/4xx/ibm405gpr.c
--- a/arch/ppc/platforms/4xx/ibm405gpr.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/ibm405gpr.c	Thu Jan 16 18:23:06 2003
@@ -1,32 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/ibm405gpr.c
  *
- *    Copyright 2000-2002 MontaVista Software Inc.
- *	Current maintainer
- *      Armin Kuster akuster@mvista.com
- *
- *    Module name: ibm405gpr.c
- *
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/ibm405gpr.h b/arch/ppc/platforms/4xx/ibm405gpr.h
--- a/arch/ppc/platforms/4xx/ibm405gpr.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/ibm405gpr.h	Thu Jan 16 18:23:06 2003
@@ -1,33 +1,12 @@
 /*
- * ibm405gpr.h
+ * arch/ppc/platforms/4xx/ibm405gpr.h
  *
+ * Author: Armin Kuster <akuster@mvista.com>
  *
- *      Armin Kuster akuster@mvista.com
- *      Aug, 2002
- *
- *
- * Copyright 2002 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/ibmnp405h.c b/arch/ppc/platforms/4xx/ibmnp405h.c
--- a/arch/ppc/platforms/4xx/ibmnp405h.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/4xx/ibmnp405h.c	Thu Jan 16 18:23:07 2003
@@ -1,33 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/ibmnp405h.c
  *
- *    Copyright 2000-2002 MontaVista Software Inc.
- *      Completed implementation.
- *	Current maintainer
- *      Armin Kuster akuster@mvista.com
- *
- *    Module name: ibmnp405h.c
- *
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/ibmnp405h.h b/arch/ppc/platforms/4xx/ibmnp405h.h
--- a/arch/ppc/platforms/4xx/ibmnp405h.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/ibmnp405h.h	Thu Jan 16 18:23:06 2003
@@ -1,35 +1,12 @@
 /*
- * ibmnp405h.h
+ * arch/ppc/platforms/4xx/ibmnp405h.h
  *
- *	This was dirived from the ibm405gp.h and other previus works in ppc4xx.h
- *
- *      Current maintainer
- *      Armin Kuster akuster@mvista.com
- *      Jan, 2002
- *
- *
- * Copyright 2002 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/ibmnp405l.c b/arch/ppc/platforms/4xx/ibmnp405l.c
--- a/arch/ppc/platforms/4xx/ibmnp405l.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ibmnp405l.c	Thu Jan 16 18:23:05 2003
@@ -1,33 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/ibmnp405l.c
  *
- *    Copyright 2000-2001 MontaVista Software Inc.
- *      Completed implementation.
- *	Current maintainer
- *      Armin Kuster akuster@mvista.com
- *
- *    Module name: ibmnp405l.c
- *
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/ibmnp405l.h b/arch/ppc/platforms/4xx/ibmnp405l.h
--- a/arch/ppc/platforms/4xx/ibmnp405l.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ibmnp405l.h	Thu Jan 16 18:23:05 2003
@@ -1,35 +1,12 @@
 /*
- * ibmnp405l.h
+ * arch/ppc/platforms/4xx/ibmnp405l.h
  *
- *	This was dirived from the ibm405gp.h and other previus works in ppc4xx.h
- *
- *      Current maintainer
- *      Armin Kuster akuster@mvista.com
- *      Oct, 2001
- *
- *
- * Copyright 2001 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/ibmnp4gs.c b/arch/ppc/platforms/4xx/ibmnp4gs.c
--- a/arch/ppc/platforms/4xx/ibmnp4gs.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ibmnp4gs.c	Thu Jan 16 18:23:05 2003
@@ -1,33 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/ibmnp4gs.c
  *
- *    Copyright 2000-2002 MontaVista Software Inc.
- *      Completed implementation.
- *	Current maintainer
- *      Armin Kuster akuster@mvista.com
- *
- *    Module name: ibmnp4gs.c
- *
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/4xx/ibmnp4gs.h b/arch/ppc/platforms/4xx/ibmnp4gs.h
--- a/arch/ppc/platforms/4xx/ibmnp4gs.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/ibmnp4gs.h	Thu Jan 16 18:23:06 2003
@@ -1,31 +1,12 @@
 /*
- * ibmnp405gs.h
+ * arch/ppc/platforms/4xx/ibmnp4gs.h
  *
- *      Armin Kuster akuster@mvista.com
- *
- *
- * Copyright 2002 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/ibmstb3.c b/arch/ppc/platforms/4xx/ibmstb3.c
--- a/arch/ppc/platforms/4xx/ibmstb3.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ibmstb3.c	Thu Jan 16 18:23:05 2003
@@ -1,33 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/ibmstb3.c
  *
- *    Copyright 2000-2001 MontaVista Software Inc.
- *      Completed implementation.
- *	Current maintainer
- *      Armin Kuster akuster@mvista.com
- *
- *    Module name: ibmstb3.c
- *
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/ibmstb3.h b/arch/ppc/platforms/4xx/ibmstb3.h
--- a/arch/ppc/platforms/4xx/ibmstb3.h	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/4xx/ibmstb3.h	Thu Jan 16 18:23:07 2003
@@ -1,37 +1,12 @@
 /*
- * ibmstbx.h
+ * arch/ppc/platforms/4xx/ibmstb3.h
  *
- *	This was dirived from the ppc4xx.h and all stbx specific definitions
- *	are located here.
- *
- *      Armin Kuster <akuster@mvista.com>
- *      Tom Rini <trini@mvista.com>
- *      Oct, 2001
- *
- *
- *
- * Copyright 2001 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Authors: Armin Kuster <akuster@mvista.com>, Tom Rini <trini@mvista.com>
  *
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/ibmstb4.c b/arch/ppc/platforms/4xx/ibmstb4.c
--- a/arch/ppc/platforms/4xx/ibmstb4.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ibmstb4.c	Thu Jan 16 18:23:05 2003
@@ -1,33 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/ibmstb4.c
  *
- *    Copyright 2000-2001 MontaVista Software Inc.
- *      Completed implementation.
- *	Current maintainer
- *      Armin Kuster akuster@mvista.com
- *
- *    Module name: ibmstb4.c
- *
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/ibmstb4.h b/arch/ppc/platforms/4xx/ibmstb4.h
--- a/arch/ppc/platforms/4xx/ibmstb4.h	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/4xx/ibmstb4.h	Thu Jan 16 18:23:07 2003
@@ -1,35 +1,12 @@
 /*
- * ibmstb4.h
+ * arch/ppc/platforms/4xx/ibmstb4.h
  *
- *	This was dirived from the ibm405gp.h and other previus works in ppc4xx.h
- *
- *      Current maintainer
- *      Armin Kuster akuster@mvista.com
- *      DEC, 2001
- *
- *
- * Copyright 2001 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/ibmstbx25.c b/arch/ppc/platforms/4xx/ibmstbx25.c
--- a/arch/ppc/platforms/4xx/ibmstbx25.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ibmstbx25.c	Thu Jan 16 18:23:05 2003
@@ -1,33 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/ibmstbx25.c
  *
- *    Copyright 2000-2002 MontaVista Software Inc.
- *      Completed implementation.
- *	Current maintainer
- *      Armin Kuster akuster@mvista.com
- *
- *    Module name: ibmstbx25.c
- *
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/ibmstbx25.h b/arch/ppc/platforms/4xx/ibmstbx25.h
--- a/arch/ppc/platforms/4xx/ibmstbx25.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/ibmstbx25.h	Thu Jan 16 18:23:05 2003
@@ -1,33 +1,12 @@
 /*
- * ibmstbx25.h
+ * arch/ppc/platforms/4xx/ibmstbx25.h
  *
- *      Current maintainer
- *      Armin Kuster akuster@mvista.com
- *      July, 2002
- *
- *
- * Copyright 2002 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/redwood.c b/arch/ppc/platforms/4xx/redwood.c
--- a/arch/ppc/platforms/4xx/redwood.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/redwood.c	Thu Jan 16 18:23:06 2003
@@ -1,12 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/redwood.c
  *
- *    Copyright 2000-2001 MontaVista Software Inc.
- *      Completed implementation.
- *      Author: MontaVista Software, Inc.  <source@mvista.com>
- *              Frank Rowand <frank_rowand@mvista.com>
- *
- *    Module name: redwood.c
+ * Author: Frank Rowand <frank_rowand@mvista.com>, or source@mvista.com
  *
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/redwood.h b/arch/ppc/platforms/4xx/redwood.h
--- a/arch/ppc/platforms/4xx/redwood.h	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/4xx/redwood.h	Thu Jan 16 18:23:07 2003
@@ -1,14 +1,15 @@
 /*
- *    Copyright 2001 MontaVista Software Inc.
- *	PPC405 modifications
- * 	Author: MontaVista Software, Inc.
- *         	frank_rowand@mvista.com or source@mvista.com
+ * arch/ppc/platforms/4xx/redwood.h
  *
- *    Module name: redwood.h
+ * Macros, definitions, and data structures specific to the IBM PowerPC
+ * STB03xxx "Redwood" evaluation board.
  *
- *    Description:
- *      Macros, definitions, and data structures specific to the IBM PowerPC
- *      STB03xxx "Redwood" evaluation board.
+ * Author: Frank Rowand <frank_rowand@mvista.com>, or source@mvista.com
+ * 
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/redwood5.c b/arch/ppc/platforms/4xx/redwood5.c
--- a/arch/ppc/platforms/4xx/redwood5.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/redwood5.c	Thu Jan 16 18:23:05 2003
@@ -1,14 +1,14 @@
 /*
+ * arch/ppc/platforms/4xx/redwood5.c
  *
- *    Copyright 2000-2001 MontaVista Software Inc.
- *      Completed implementation.
- *      Author: Armin Kuster
+ * Support for the IBM redwood5 eval board file
  *
- *    Module name: redwood5.c
- *
- *    Description:
- *    	IBM redwood5 eval board file
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/redwood5.h b/arch/ppc/platforms/4xx/redwood5.h
--- a/arch/ppc/platforms/4xx/redwood5.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/redwood5.h	Thu Jan 16 18:23:05 2003
@@ -1,14 +1,15 @@
 /*
- *    Copyright 2001 MontaVista Software Inc.
- *	PPC405 modifications
- * 	Author: MontaVista Software, Inc.
- *          Armin Kuster
+ * arch/ppc/platforms/4xx/redwood5.h
  *
- *    Module name: redwood5.h
+ * Macros, definitions, and data structures specific to the IBM PowerPC
+ * STB03xxx "Redwood" evaluation board.
  *
- *    Description:
- *      Macros, definitions, and data structures specific to the IBM PowerPC
- *      STB03xxx "Redwood" evaluation board.
+ * Author: Armin Kuster <akuster@mvista.com>
+ *
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/redwood6.c b/arch/ppc/platforms/4xx/redwood6.c
--- a/arch/ppc/platforms/4xx/redwood6.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/4xx/redwood6.c	Thu Jan 16 18:23:07 2003
@@ -1,33 +1,12 @@
 /*
+ * arch/ppc/platforms/4xx/redwood6.c
  *
- *    Module name: redwood6.c
- *
- *    Description:
- *    	IBM redwood6 eval board file
- *
- *    Author: Armin Kuster
- *    Copyright 2002 MontaVista Software Inc.
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/4xx/redwood6.h b/arch/ppc/platforms/4xx/redwood6.h
--- a/arch/ppc/platforms/4xx/redwood6.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/redwood6.h	Thu Jan 16 18:23:05 2003
@@ -1,37 +1,15 @@
 /*
- * 	Author: MontaVista Software, Inc.
- *          Armin Kuster
+ * arch/ppc/platforms/4xx/redwood6.h
  *
- *    Module name: redwood6.h
+ * Macros, definitions, and data structures specific to the IBM PowerPC
+ * STBx25xx "Redwood6" evaluation board.
  *
- *    Description:
- *      Macros, definitions, and data structures specific to the IBM PowerPC
- *      STBx25xx "Redwood6" evaluation board.
- *
- *    Copyright 2002 MontaVista Software Inc.
- * 	Author: MontaVista Software, Inc.
- *          Armin Kuster
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/sycamore.c b/arch/ppc/platforms/4xx/sycamore.c
--- a/arch/ppc/platforms/4xx/sycamore.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/sycamore.c	Thu Jan 16 18:23:06 2003
@@ -1,15 +1,15 @@
 /*
+ * arch/ppc/platforms/4xx/sycamore.c
  *
- *    Copyright 2000-2002 MontaVista Software Inc.
- *      Author: Armin Kuster <akuster@mvista.com>
- *      MontaVista Software, Inc.  <source@mvista.com>
+ * Architecture- / platform-specific boot-time initialization code for
+ * IBM PowerPC 4xx based boards. 
  *
- *    Module name: sycamore.c
- *
- *    Description:
- *      Architecture- / platform-specific boot-time initialization code for
- *      IBM PowerPC 4xx based boards. 
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/config.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/4xx/sycamore.h b/arch/ppc/platforms/4xx/sycamore.h
--- a/arch/ppc/platforms/4xx/sycamore.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/sycamore.h	Thu Jan 16 18:23:06 2003
@@ -1,19 +1,15 @@
 /*
+ * arch/ppc/platforms/4xx/sycamore.h
  *
- *    Copyright 2000 MontaVista Software Inc.
- * 	Author: Armin Kuster <akuster@mvista.com>
- * 		MontaVista Software, Inc.
+ * Macros, definitions, and data structures specific to the IBM PowerPC
+ * 405GPr "Sycamore" evaluation board.
  *
- *    Module name: sycamore.h
- *
- *    Description:
- *      Macros, definitions, and data structures specific to the IBM PowerPC
- *      based boards.
- *
- *      This includes:
- *
- *         405GP "Sycamore" evaluation board
+ * Author: Armin Kuster <akuster@mvista.com>
  *
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/4xx/walnut.c b/arch/ppc/platforms/4xx/walnut.c
--- a/arch/ppc/platforms/4xx/walnut.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/4xx/walnut.c	Thu Jan 16 18:23:06 2003
@@ -1,19 +1,17 @@
 /*
+ * arch/ppc/platforms/4xx/walnut.c
  *
- *    Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
+ * Architecture- / platform-specific boot-time initialization code for
+ * IBM PowerPC 4xx based boards. Adapted from original
+ * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
+ * <dan@net4x.com>.
  *
- *    Copyright 2000-2002 MontaVista Software Inc.
- *      Completed implementation.
- *      Author: MontaVista Software, Inc.  <source@mvista.com>
- *
- *    Module name: walnut.c
- *
- *    Description:
- *      Architecture- / platform-specific boot-time initialization code for
- *      IBM PowerPC 4xx based boards. Adapted from original
- *      code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
- *      <dan@net4x.com>.
+ * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
  *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/config.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/4xx/walnut.h b/arch/ppc/platforms/4xx/walnut.h
--- a/arch/ppc/platforms/4xx/walnut.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/4xx/walnut.h	Thu Jan 16 18:23:05 2003
@@ -1,23 +1,19 @@
 /*
+ * arch/ppc/platforms/4xx/walnut.h
  *
- *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Macros, definitions, and data structures specific to the IBM PowerPC
+ * 405GP "Walnut" evaluation board.
  *
- *    Copyright 2000 MontaVista Software Inc.
- *	PPC405 modifications
- * 	Author: MontaVista Software, Inc.
- *         	frank_rowand@mvista.com or source@mvista.com
- * 	   	debbie_chu@mvista.com
+ * Authors: Grant Erickson <grant@lcse.umn.edu>, Frank Rowand
+ * <frank_rowand@mvista.com>, Debbie Chu <debbie_chu@mvista.com> or
+ * source@mvista.com
  *
- *    Module name: ppc405.h
- *
- *    Description:
- *      Macros, definitions, and data structures specific to the IBM PowerPC
- *      based boards.
- *
- *      This includes:
- *
- *         405GP "Walnut" evaluation board
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
  *
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/ev64260.h b/arch/ppc/platforms/ev64260.h
--- a/arch/ppc/platforms/ev64260.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/ev64260.h	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/platforms/ev64260_setup.c b/arch/ppc/platforms/ev64260_setup.c
--- a/arch/ppc/platforms/ev64260_setup.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/ev64260_setup.c	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/platforms/k2.h b/arch/ppc/platforms/k2.h
--- a/arch/ppc/platforms/k2.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/k2.h	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __PPC_PLATFORMS_K2_H
diff -Nru a/arch/ppc/platforms/k2_pci.c b/arch/ppc/platforms/k2_pci.c
--- a/arch/ppc/platforms/k2_pci.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/k2_pci.c	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/kernel.h>
diff -Nru a/arch/ppc/platforms/k2_setup.c b/arch/ppc/platforms/k2_setup.c
--- a/arch/ppc/platforms/k2_setup.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/k2_setup.c	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/lopec_pci.c b/arch/ppc/platforms/lopec_pci.c
--- a/arch/ppc/platforms/lopec_pci.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/lopec_pci.c	Thu Jan 16 18:23:06 2003
@@ -6,12 +6,10 @@
  * Author: Dan Cox
  *         danc@mvista.com (or, alternately, source@mvista.com)
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/lopec_serial.h b/arch/ppc/platforms/lopec_serial.h
--- a/arch/ppc/platforms/lopec_serial.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/lopec_serial.h	Thu Jan 16 18:23:06 2003
@@ -6,12 +6,10 @@
  * Author: Dan Cox
  *         danc@mvista.com (or, alternately, source@mvista.com)
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __H_LOPEC_SERIAL
diff -Nru a/arch/ppc/platforms/lopec_setup.c b/arch/ppc/platforms/lopec_setup.c
--- a/arch/ppc/platforms/lopec_setup.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/lopec_setup.c	Thu Jan 16 18:23:06 2003
@@ -6,12 +6,10 @@
  * Author: Dan Cox
  *         danc@mvista.com
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/mcpn765.h b/arch/ppc/platforms/mcpn765.h
--- a/arch/ppc/platforms/mcpn765.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/mcpn765.h	Thu Jan 16 18:23:05 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/platforms/mcpn765_pci.c b/arch/ppc/platforms/mcpn765_pci.c
--- a/arch/ppc/platforms/mcpn765_pci.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/mcpn765_pci.c	Thu Jan 16 18:23:06 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/mcpn765_serial.h b/arch/ppc/platforms/mcpn765_serial.h
--- a/arch/ppc/platforms/mcpn765_serial.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/mcpn765_serial.h	Thu Jan 16 18:23:06 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __ASMPPC_MCPN765_SERIAL_H
diff -Nru a/arch/ppc/platforms/mcpn765_setup.c b/arch/ppc/platforms/mcpn765_setup.c
--- a/arch/ppc/platforms/mcpn765_setup.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/mcpn765_setup.c	Thu Jan 16 18:23:06 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/platforms/menf1.h b/arch/ppc/platforms/menf1.h
--- a/arch/ppc/platforms/menf1.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/menf1.h	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __PPC_PLATFORMS_MENF1_H
diff -Nru a/arch/ppc/platforms/menf1_pci.c b/arch/ppc/platforms/menf1_pci.c
--- a/arch/ppc/platforms/menf1_pci.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/menf1_pci.c	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/kernel.h>
diff -Nru a/arch/ppc/platforms/menf1_setup.c b/arch/ppc/platforms/menf1_setup.c
--- a/arch/ppc/platforms/menf1_setup.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/menf1_setup.c	Thu Jan 16 18:23:06 2003
@@ -1,16 +1,14 @@
 /*
  * arch/ppc/platforms/menf1_setup.c
- 
+ *
  * Board setup routines for MEN F1
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/mvme5100.h b/arch/ppc/platforms/mvme5100.h
--- a/arch/ppc/platforms/mvme5100.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/mvme5100.h	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/mvme5100_pci.c b/arch/ppc/platforms/mvme5100_pci.c
--- a/arch/ppc/platforms/mvme5100_pci.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/mvme5100_pci.c	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/mvme5100_serial.h b/arch/ppc/platforms/mvme5100_serial.h
--- a/arch/ppc/platforms/mvme5100_serial.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/mvme5100_serial.h	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/mvme5100_setup.c b/arch/ppc/platforms/mvme5100_setup.c
--- a/arch/ppc/platforms/mvme5100_setup.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/mvme5100_setup.c	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/pal4.h b/arch/ppc/platforms/pal4.h
--- a/arch/ppc/platforms/pal4.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/pal4.h	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Dan Cox
  *
- * Copyright 2002 MontaVista Software Inc.
- *
- * 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.
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __PPC_PLATFORMS_PAL4_H
diff -Nru a/arch/ppc/platforms/pal4_pci.c b/arch/ppc/platforms/pal4_pci.c
--- a/arch/ppc/platforms/pal4_pci.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/pal4_pci.c	Thu Jan 16 18:23:07 2003
@@ -5,12 +5,10 @@
  *
  * Author: Dan Cox 
  *
- * Copyright 2002 MontaVista Software Inc.
- *
- * 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.
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/kernel.h>
diff -Nru a/arch/ppc/platforms/pal4_serial.h b/arch/ppc/platforms/pal4_serial.h
--- a/arch/ppc/platforms/pal4_serial.h	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/pal4_serial.h	Thu Jan 16 18:23:07 2003
@@ -5,12 +5,10 @@
  *
  * Author: Dan Cox
  *
- * Copyright 2002 MontaVista Software Inc.
- *
- * 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.
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __PPC_PAL4_SERIAL_H
diff -Nru a/arch/ppc/platforms/pal4_setup.c b/arch/ppc/platforms/pal4_setup.c
--- a/arch/ppc/platforms/pal4_setup.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/pal4_setup.c	Thu Jan 16 18:23:07 2003
@@ -5,12 +5,10 @@
  *
  * Author: Dan Cox
  *
- * Copyright 2002 MontaVista Software Inc.
- *
- * 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.
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/pcore.h b/arch/ppc/platforms/pcore.h
--- a/arch/ppc/platforms/pcore.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/pcore.h	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __PPC_PLATFORMS_PCORE_H
diff -Nru a/arch/ppc/platforms/pcore_pci.c b/arch/ppc/platforms/pcore_pci.c
--- a/arch/ppc/platforms/pcore_pci.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/pcore_pci.c	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/kernel.h>
diff -Nru a/arch/ppc/platforms/pcore_setup.c b/arch/ppc/platforms/pcore_setup.c
--- a/arch/ppc/platforms/pcore_setup.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/pcore_setup.c	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/powerpmc250.c b/arch/ppc/platforms/powerpmc250.c
--- a/arch/ppc/platforms/powerpmc250.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/powerpmc250.c	Thu Jan 16 18:23:05 2003
@@ -7,12 +7,10 @@
  * Borrowed heavily from prpmc750_*.c by
  * 	Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/powerpmc250.h b/arch/ppc/platforms/powerpmc250.h
--- a/arch/ppc/platforms/powerpmc250.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/powerpmc250.h	Thu Jan 16 18:23:06 2003
@@ -7,12 +7,10 @@
  * 
  * Borrowed heavily from prpmc750.h by Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __ASMPPC_POWERPMC250_H
diff -Nru a/arch/ppc/platforms/powerpmc250_serial.h b/arch/ppc/platforms/powerpmc250_serial.h
--- a/arch/ppc/platforms/powerpmc250_serial.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/powerpmc250_serial.h	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Troy Benjegerdes <tbenjegerdes@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/pplus_pci.c b/arch/ppc/platforms/pplus_pci.c
--- a/arch/ppc/platforms/pplus_pci.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/pplus_pci.c	Thu Jan 16 18:23:07 2003
@@ -9,16 +9,10 @@
  * Cort Dougan, Johnnie Peters, Matt Porter, and
  * Troy Benjegerdes.
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/pplus_setup.c b/arch/ppc/platforms/pplus_setup.c
--- a/arch/ppc/platforms/pplus_setup.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/pplus_setup.c	Thu Jan 16 18:23:07 2003
@@ -9,16 +9,10 @@
  * Cort Dougan, Johnnie Peters, Matt Porter, and
  * Troy Benjegerdes.
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/prpmc750_pci.c b/arch/ppc/platforms/prpmc750_pci.c
--- a/arch/ppc/platforms/prpmc750_pci.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/prpmc750_pci.c	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/kernel.h>
diff -Nru a/arch/ppc/platforms/prpmc750_serial.h b/arch/ppc/platforms/prpmc750_serial.h
--- a/arch/ppc/platforms/prpmc750_serial.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/prpmc750_serial.h	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/prpmc750_setup.c b/arch/ppc/platforms/prpmc750_setup.c
--- a/arch/ppc/platforms/prpmc750_setup.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/prpmc750_setup.c	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/prpmc800.h b/arch/ppc/platforms/prpmc800.h
--- a/arch/ppc/platforms/prpmc800.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/prpmc800.h	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Dale Farnsworth <dale.farnsworth@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
  /*
  * From Processor to PCI:
diff -Nru a/arch/ppc/platforms/prpmc800_pci.c b/arch/ppc/platforms/prpmc800_pci.c
--- a/arch/ppc/platforms/prpmc800_pci.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/prpmc800_pci.c	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Dale Farnsworth <dale.farnsworth@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/kernel.h>
diff -Nru a/arch/ppc/platforms/prpmc800_serial.h b/arch/ppc/platforms/prpmc800_serial.h
--- a/arch/ppc/platforms/prpmc800_serial.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/prpmc800_serial.h	Thu Jan 16 18:23:06 2003
@@ -1,16 +1,14 @@
 /*
- * include/asm-ppc/platforms/prpmc800_serial.h
+ * arch/ppc/platforms/prpmc800_serial.h
  * 
  * Definitions for Motorola MCG PRPMC800 cPCI board support
  *
  * Author: Dale Farnsworth	dale.farnsworth@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __ASMPPC_PRPMC800_SERIAL_H
diff -Nru a/arch/ppc/platforms/prpmc800_setup.c b/arch/ppc/platforms/prpmc800_setup.c
--- a/arch/ppc/platforms/prpmc800_setup.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/prpmc800_setup.c	Thu Jan 16 18:23:06 2003
@@ -2,12 +2,10 @@
  *
  * Author: Dale Farnsworth <dale.farnsworth@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/sandpoint.h b/arch/ppc/platforms/sandpoint.h
--- a/arch/ppc/platforms/sandpoint.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/sandpoint.h	Thu Jan 16 18:23:05 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2000, 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/platforms/sandpoint_pci.c b/arch/ppc/platforms/sandpoint_pci.c
--- a/arch/ppc/platforms/sandpoint_pci.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/sandpoint_pci.c	Thu Jan 16 18:23:05 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2000, 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/sandpoint_serial.h b/arch/ppc/platforms/sandpoint_serial.h
--- a/arch/ppc/platforms/sandpoint_serial.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/sandpoint_serial.h	Thu Jan 16 18:23:05 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __ASMPPC_SANDPOINT_SERIAL_H
diff -Nru a/arch/ppc/platforms/sandpoint_setup.c b/arch/ppc/platforms/sandpoint_setup.c
--- a/arch/ppc/platforms/sandpoint_setup.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/sandpoint_setup.c	Thu Jan 16 18:23:07 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2000-2002 MontaVista Software Inc.
- *
- * 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.
+ * 2000-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/platforms/spruce.h b/arch/ppc/platforms/spruce.h
--- a/arch/ppc/platforms/spruce.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/spruce.h	Thu Jan 16 18:23:05 2003
@@ -7,27 +7,10 @@
  *          mporter@mvista.com
  *          jpeters@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/arch/ppc/platforms/spruce_pci.c b/arch/ppc/platforms/spruce_pci.c
--- a/arch/ppc/platforms/spruce_pci.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/spruce_pci.c	Thu Jan 16 18:23:06 2003
@@ -6,27 +6,10 @@
  * Author: Johnnie Peters
  *         jpeters@mvista.com
  *
- * Copyright 2000 MontaVista Software Inc.
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/kernel.h>
diff -Nru a/arch/ppc/platforms/spruce_serial.h b/arch/ppc/platforms/spruce_serial.h
--- a/arch/ppc/platforms/spruce_serial.h	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/spruce_serial.h	Thu Jan 16 18:23:07 2003
@@ -7,27 +7,10 @@
  *          mporter@mvista.com
  *          jpeters@mvista.com
  *
- * Copyright 2000 MontaVista Software Inc.
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __ASMPPC_SPRUCE_SERIAL_H
diff -Nru a/arch/ppc/platforms/spruce_setup.c b/arch/ppc/platforms/spruce_setup.c
--- a/arch/ppc/platforms/spruce_setup.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/spruce_setup.c	Thu Jan 16 18:23:05 2003
@@ -6,27 +6,10 @@
  * Authors: Johnnie Peters <jpeters@mvista.com>
  *          Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/platforms/zx4500.h b/arch/ppc/platforms/zx4500.h
--- a/arch/ppc/platforms/zx4500.h	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/platforms/zx4500.h	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2000, 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #ifndef	__PPC_PLATFORMS_ZX4500_H_
 #define	__PPC_PLATFORMS_ZX4500_H_
diff -Nru a/arch/ppc/platforms/zx4500_pci.c b/arch/ppc/platforms/zx4500_pci.c
--- a/arch/ppc/platforms/zx4500_pci.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/zx4500_pci.c	Thu Jan 16 18:23:07 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2000, 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/platforms/zx4500_serial.h b/arch/ppc/platforms/zx4500_serial.h
--- a/arch/ppc/platforms/zx4500_serial.h	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/platforms/zx4500_serial.h	Thu Jan 16 18:23:07 2003
@@ -1,17 +1,15 @@
 /*
- * include/asm-ppc/zx4500_serial.h
+ * arch/ppc/platforms/zx4500_serial.h
  * 
  * Definitions for Znyx ZX4500 board support
  *
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2000, 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __ASMPPC_ZX4500_SERIAL_H
diff -Nru a/arch/ppc/platforms/zx4500_setup.c b/arch/ppc/platforms/zx4500_setup.c
--- a/arch/ppc/platforms/zx4500_setup.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/platforms/zx4500_setup.c	Thu Jan 16 18:23:05 2003
@@ -6,12 +6,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2000, 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2000-2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/syslib/cpc700.h b/arch/ppc/syslib/cpc700.h
--- a/arch/ppc/syslib/cpc700.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/syslib/cpc700.h	Thu Jan 16 18:23:05 2003
@@ -1,32 +1,15 @@
 /*
- * include/asm-ppc/cpc700.h
+ * arch/ppc/syslib/cpc700.h
  * 
  * Header file for IBM CPC700 Host Bridge, et. al.
  *
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2000-2002 MontaVista Software Inc.
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2000-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/syslib/cpc700_pic.c b/arch/ppc/syslib/cpc700_pic.c
--- a/arch/ppc/syslib/cpc700_pic.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/syslib/cpc700_pic.c	Thu Jan 16 18:23:05 2003
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/platforms/cpc700_pic.c
+ * arch/ppc/syslib/cpc700_pic.c
  * 
  * Interrupt controller support for IBM Spruce
  *
@@ -8,27 +8,10 @@
  *          mporter@mvista.com
  *          jpeters@mvista.com
  *
- * Copyright 2001-2002 MontaVista Software Inc.
- *
- * 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.
- *
- * THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/stddef.h>
diff -Nru a/arch/ppc/syslib/cpc710.h b/arch/ppc/syslib/cpc710.h
--- a/arch/ppc/syslib/cpc710.h	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/syslib/cpc710.h	Thu Jan 16 18:23:05 2003
@@ -1,16 +1,14 @@
 /*
- * arch/ppc/platforms/cpc710.h
+ * arch/ppc/syslib/cpc710.h
  * 
  * Definitions for the IBM CPC710 PCI Host Bridge
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __PPC_PLATFORMS_CPC710_H
diff -Nru a/arch/ppc/syslib/gt64260_common.c b/arch/ppc/syslib/gt64260_common.c
--- a/arch/ppc/syslib/gt64260_common.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/syslib/gt64260_common.c	Thu Jan 16 18:23:05 2003
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/kernel/gt64260_common.c
+ * arch/ppc/syslib/gt64260_common.c
  * 
  * Common routines for the Marvell/Galileo GT64260 (Discovery) host bridge,
  * interrupt controller, memory controller, serial controller, enet controller,
@@ -7,12 +7,10 @@
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c
--- a/arch/ppc/syslib/gt64260_pic.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/syslib/gt64260_pic.c	Thu Jan 16 18:23:06 2003
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/kernel/gt64260_pic.c
+ * arch/ppc/syslib/gt64260_pic.c
  * 
  * Interrupt controller support for Galileo's GT64260.
  *
@@ -8,12 +8,10 @@
  *
  * Based on sources from Rabeeh Khoury / Galileo Technology
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/syslib/harrier.c b/arch/ppc/syslib/harrier.c
--- a/arch/ppc/syslib/harrier.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/syslib/harrier.c	Thu Jan 16 18:23:05 2003
@@ -1,17 +1,15 @@
 /*
- * arch/ppc/kernel/harrier.c
+ * arch/ppc/syslib/harrier.c
  * 
  * Motorola MCG Harrier northbridge/memory controller support
  *
  * Author: Dale Farnsworth
  *         dale.farnsworth@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c
--- a/arch/ppc/syslib/mpc10x_common.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/syslib/mpc10x_common.c	Thu Jan 16 18:23:05 2003
@@ -1,6 +1,5 @@
-
 /*
- * arch/ppc/kernel/mpc10x_common.c
+ * arch/ppc/syslib/mpc10x_common.c
  * 
  * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
  * Mem ctlr, EPIC, etc.
@@ -8,12 +7,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/syslib/pci_auto.c b/arch/ppc/syslib/pci_auto.c
--- a/arch/ppc/syslib/pci_auto.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/syslib/pci_auto.c	Thu Jan 16 18:23:06 2003
@@ -1,16 +1,14 @@
 /*
- * arch/ppc/kernel/pci_auto.c
+ * arch/ppc/syslib/pci_auto.c
  * 
  * PCI autoconfiguration library
  *
  * Author: Matt Porter <mporter@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/arch/ppc/syslib/ppc405_pci.c b/arch/ppc/syslib/ppc405_pci.c
--- a/arch/ppc/syslib/ppc405_pci.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/syslib/ppc405_pci.c	Thu Jan 16 18:23:06 2003
@@ -1,35 +1,14 @@
 /*
- * FILE NAME: ppc405_pci.c
+ * Authors: Frank Rowand <frank_rowand@mvista.com>,
+ * Debbie Chu <debbie_chu@mvista.com>, or source@mvista.com
+ * Further modifications by Armin Kuster <akuster@mvista.com>
+ *
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  *
- * BRIEF MODULE DESCRIPTION: 
  * Based on arch/ppc/kernel/indirect.c, Copyright (C) 1998 Gabriel Paubert.
- *
- * Author: MontaVista Software, Inc.  <source@mvista.com>
- *         Frank Rowand <frank_rowand@mvista.com>
- *         Debbie Chu   <debbie_chu@mvista.com>
- * Further modifications by Armin Kuster.
- *
- * Copyright 2000 MontaVista Software Inc.
- *
- *  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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/pci.h>
diff -Nru a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c
--- a/arch/ppc/syslib/ppc4xx_dma.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/syslib/ppc4xx_dma.c	Thu Jan 16 18:23:07 2003
@@ -1,33 +1,14 @@
 /*
- * linux/arch/ppc/kernel/ppc405_dma.c
+ * Author: Pete Popov <ppopov@mvista.com> or source@mvista.com
  *
- * BRIEF MODULE DESCRIPTION
- *	IBM 405 DMA Controller Functions
+ * arch/ppc/kernel/ppc405_dma.c
  *
- * Copyright 2000 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  *
- *
- *  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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * IBM 405 DMA Controller Functions
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/syslib/ppc4xx_pm.c b/arch/ppc/syslib/ppc4xx_pm.c
--- a/arch/ppc/syslib/ppc4xx_pm.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/syslib/ppc4xx_pm.c	Thu Jan 16 18:23:05 2003
@@ -1,41 +1,13 @@
 /*
- *	file: ppc4xx_pm.c
+ * Author: Armin Kuster <akuster@mvista.com>
  *
- *	This an attempt to get Power Management going for the IBM 4xx processor.
- *	This was derived from the ppc4xx._setup.c file
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  *
- *      Armin Kuster akuster@mvista.com
- *      Jan  2002
- *
- *
- * Copyright 2002 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *	Version 1.0 (02/14/01) - A. Kuster
- *	Initial version	 - moved pm code from ppc4xx_setup.c
- *
- *	1.1 02/21/01 - A. Kuster
- *		minor fixes, init value to 0 & += to &=
- *		added stb03 ifdef for 2nd i2c device
+ * This an attempt to get Power Management going for the IBM 4xx processor.
+ * This was derived from the ppc4xx._setup.c file
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/syslib/ppc4xx_serial.c b/arch/ppc/syslib/ppc4xx_serial.c
--- a/arch/ppc/syslib/ppc4xx_serial.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc/syslib/ppc4xx_serial.c	Thu Jan 16 18:23:05 2003
@@ -1,38 +1,19 @@
-
 /*
- * linux/arch/ppc/kernel/ppc405_serial.c
+ * arch/ppc/syslib/ppc405_serial.c
  *
- * This is a fairly standard 165xx type device that will eventually
- * be merged with other similar processor/boards.	-- Dan
- *
- * BRIEF MODULE DESCRIPTION
- *	Console I/O support for Early kernel bringup. 
- *
- * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
  *         	frank_rowand@mvista.com or source@mvista.com
  * 	   	debbie_chu@mvista.com
  *
+ * This is a fairly standard 165xx type device that will eventually
+ * be merged with other similar processor/boards.	-- Dan
  *
- *  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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * Console I/O support for Early kernel bringup. 
  */
 
 #include <linux/config.h>
diff -Nru a/arch/ppc/syslib/pplus_common.c b/arch/ppc/syslib/pplus_common.c
--- a/arch/ppc/syslib/pplus_common.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/syslib/pplus_common.c	Thu Jan 16 18:23:06 2003
@@ -1,17 +1,15 @@
 /*
- * arch/ppc/kernel/pplus_common.c
+ * arch/ppc/syslib/pplus_common.c
  * 
  * Common Motorola PowerPlus Platform--really Falcon/Raven or HAWK.
  *
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/syslib/todc_time.c b/arch/ppc/syslib/todc_time.c
--- a/arch/ppc/syslib/todc_time.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc/syslib/todc_time.c	Thu Jan 16 18:23:06 2003
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/kernel/todc_time.c
+ * arch/ppc/syslib/todc_time.c
  * 
  * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818
  * Real Time Clocks/Timekeepers.
@@ -7,12 +7,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/errno.h>
 #include <linux/init.h>
diff -Nru a/arch/ppc/vmlinux.lds.S b/arch/ppc/vmlinux.lds.S
--- a/arch/ppc/vmlinux.lds.S	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc/vmlinux.lds.S	Thu Jan 16 18:23:07 2003
@@ -1,3 +1,5 @@
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_ARCH(powerpc)
 SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
 /* Do we need any of these for elf?
@@ -40,13 +42,8 @@
   }
   _etext = .;
   PROVIDE (etext = .);
-  .rodata    :
-  {
-    *(.rodata)
-    *(.rodata.*)
-    *(.rodata1)
-  }
-  .kstrtab   : { *(.kstrtab) }
+
+  RODATA
   .fini      : { *(.fini)    } =0
   .ctors     : { *(.ctors)   }
   .dtors     : { *(.dtors)   }
@@ -56,18 +53,6 @@
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
-
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-
-  __start___kallsyms = .;     /* All kernel symbols */
-  __kallsyms : { *(__kallsyms) }
-  __stop___kallsyms = .;
 
   /* Read-write section, merged into data segment: */
   . = ALIGN(4096);
diff -Nru a/arch/ppc64/boot/zImage.lds b/arch/ppc64/boot/zImage.lds
--- a/arch/ppc64/boot/zImage.lds	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc64/boot/zImage.lds	Thu Jan 16 18:23:05 2003
@@ -42,6 +42,7 @@
     *(.rodata1)
   }
   .kstrtab   : { *(.kstrtab) }
+  __vermagic : { *(__vermagic) }
   .fini      : { *(.fini)    } =0
   .ctors     : { *(.ctors)   }
   .dtors     : { *(.dtors)   }
diff -Nru a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc64/kernel/Makefile	Thu Jan 16 18:23:07 2003
@@ -6,7 +6,7 @@
 EXTRA_TARGETS	:= head.o
 export-objs	:= ppc_ksyms.o
 
-obj-y               :=	ppc_ksyms.o setup.o entry.o traps.o irq.o idle.o \
+obj-y               :=	setup.o entry.o traps.o irq.o idle.o \
 			time.o process.o signal.o syscalls.o misc.o ptrace.o \
 			align.o semaphore.o bitops.o stab.o htab.o pacaData.o \
 			udbg.o binfmt_elf32.o sys_ppc32.o sys32.o ioctl32.o \
@@ -30,3 +30,4 @@
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_PROFILING)		+= profile.o
+obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
diff -Nru a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S
--- a/arch/ppc64/kernel/entry.S	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc64/kernel/entry.S	Thu Jan 16 18:23:05 2003
@@ -106,9 +106,8 @@
 	beq-	15f
 	ld	r10,.SYS_CALL_TABLE32@toc(2)
 /*
- * Now mung the first 4 parameters into shape, by making certain that
- * the high bits (most significant 32 bits in 64 bit reg) are 0
- * for the first 4 parameter regs(3-6).
+ * We now zero extend all six arguments (r3 - r8), the compatibility
+ * layer assumes this.
  */
 	clrldi	r3,r3,32
 	clrldi	r4,r4,32
@@ -178,9 +177,8 @@
 	beq-	55f
 	ld	r10,.SYS_CALL_TABLE32@toc(2)
 /*
- * Now mung the first 4 parameters into shape, by making certain that
- * the high bits (most significant 32 bits in 64 bit reg) are 0
- * for the first 4 parameter regs(3-6).
+ * We now zero extend all six arguments (r3 - r8), the compatibility
+ * layer assumes this.
  */
 	clrldi	r3,r3,32
 	clrldi	r4,r4,32
@@ -200,7 +198,6 @@
 	blrl			/* Call handler */
 _GLOBAL(ret_from_syscall_2)
 	std	r3,RESULT(r1)	/* Save result */	
-	std	r3,GPR0(r1)	/* temporary gross hack to make strace work */
 	li	r10,-_LAST_ERRNO
 	cmpl	0,r3,r10
 	blt	60f
@@ -229,10 +226,6 @@
 
 _GLOBAL(ppc32_rt_sigreturn)
 	bl	.sys32_rt_sigreturn
-	b	80f
-
-_GLOBAL(ppc64_sigreturn)
-	bl	.sys_sigreturn
 	b	80f
 
 _GLOBAL(ppc64_rt_sigreturn)
diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
--- a/arch/ppc64/kernel/ioctl32.c	Thu Jan 16 18:23:07 2003
+++ b/arch/ppc64/kernel/ioctl32.c	Thu Jan 16 18:23:07 2003
@@ -4495,10 +4495,9 @@
 {
 	int i;
 	if (!additional_ioctls) {
-		additional_ioctls = module_map(PAGE_SIZE);
+		additional_ioctls = get_zeroed_page(GFP_KERNEL);
 		if (!additional_ioctls)
 			return -ENOMEM;
-		memset(additional_ioctls, 0, PAGE_SIZE);
 	}
 	for (i = 0; i < PAGE_SIZE/sizeof(struct ioctl_trans); i++) {
 		if (!additional_ioctls[i].cmd)
diff -Nru a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc64/kernel/misc.S	Thu Jan 16 18:23:06 2003
@@ -487,7 +487,7 @@
 	.llong .sys_lchown
 	.llong .sys_ni_syscall		/* old break syscall */
 	.llong .sys_ni_syscall		/* old stat syscall */
-	.llong .sys32_lseek
+	.llong .ppc32_lseek
 	.llong .sys_getpid              /* 20 */
 	.llong .sys32_mount
 	.llong .sys_oldumount
@@ -540,7 +540,7 @@
 	.llong .sys32_ssetmask
 	.llong .sys_setreuid	        /* 70 */
 	.llong .sys_setregid
-	.llong .sys_sigsuspend
+	.llong .sys32_sigsuspend
 	.llong .sys32_sigpending
 	.llong .sys32_sethostname
 	.llong .sys32_setrlimit	        /* 75 */
@@ -558,7 +558,7 @@
 	.llong .sys_swapon
 	.llong .sys_reboot
 	.llong .old32_readdir
-	.llong .sys32_mmap		/* 90 */
+	.llong .sys_mmap		/* 90 */
 	.llong .sys_munmap
 	.llong .sys_truncate
 	.llong .sys_ftruncate
@@ -660,7 +660,7 @@
 	.llong .sys_vfork
 	.llong .sys32_getrlimit	        /* 190 */
 	.llong .sys32_readahead
-	.llong .ppc32_mmap2
+	.llong .sys32_mmap2
 	.llong .sys32_truncate64
 	.llong .sys32_ftruncate64
 	.llong .sys_stat64      	/* 195 */
@@ -707,7 +707,7 @@
 	.llong .sys_epoll_create
 	.llong .sys_epoll_ctl
 	.llong .sys_epoll_wait
-	.llong .ppc32_remap_file_pages
+	.llong .sys_remap_file_pages
 
 	.rept NR_syscalls-239
 		.llong .sys_ni_syscall
@@ -783,13 +783,13 @@
 	.llong .sys_getppid
 	.llong .sys_getpgrp		/* 65 */
 	.llong .sys_setsid
-	.llong .sys_sigaction
+	.llong .sys_ni_syscall		/* 32 bit only sigaction */
 	.llong .sys_sgetmask
 	.llong .sys_ssetmask
 	.llong .sys_setreuid		/* 70 */
 	.llong .sys_setregid
-	.llong .sys_sigsuspend
-	.llong .sys_sigpending
+	.llong .sys_ni_syscall		/* 32bit only sigsuspend */
+	.llong .sys_ni_syscall		/* 32bit only sigpending */
 	.llong .sys_sethostname
 	.llong .sys_setrlimit		/* 75 */
 	.llong .sys_ni_syscall		/* old getrlimit syscall */
@@ -835,14 +835,14 @@
 	.llong .sys_sysinfo
 	.llong .sys_ipc
 	.llong .sys_fsync
-	.llong .ppc64_sigreturn
+	.llong .sys_ni_syscall		/* 32bit only sigreturn */
 	.llong .sys_clone		/* 120 */
 	.llong .sys_setdomainname
 	.llong .ppc64_newuname
 	.llong .sys_ni_syscall		/* old modify_ldt syscall */
 	.llong .sys_adjtimex
 	.llong .sys_mprotect		/* 125 */
-	.llong .sys_sigprocmask
+	.llong .sys_ni_syscall		/* 32bit only sigprocmask */
 	.llong .sys_ni_syscall		/* old create_module syscall */
 	.llong .sys_init_module
 	.llong .sys_delete_module
@@ -948,10 +948,10 @@
 	.llong .sys_io_getevents
 	.llong .sys_io_submit		/* 230 */
 	.llong .sys_io_cancel
-	.llong .sys_ni_syscall		/* reserved for alloc_hugepages */
-	.llong .sys_ni_syscall		/* reserved for free_hugepages */
+	.llong .sys_ni_syscall
+	.llong .sys_ni_syscall
 	.llong .sys_exit_group
-	.llong .sys_lookup_dcookie	/* 245 */
+	.llong .sys_lookup_dcookie	/* 235 */
 	.llong .sys_epoll_create
 	.llong .sys_epoll_ctl
 	.llong .sys_epoll_wait
diff -Nru a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc64/kernel/module.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,464 @@
+/*  Kernel module help for PPC64.
+    Copyright (C) 2001, 2003 Rusty Russell IBM Corporation.
+
+    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.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <linux/module.h>
+#include <linux/elf.h>
+#include <linux/moduleloader.h>
+#include <linux/err.h>
+#include <linux/vmalloc.h>
+
+/* FIXME: We don't do .init separately.  To do this, we'd need to have
+   a separate r2 value in the init and core section, and stub between
+   them, too.
+
+   Using a magic allocator which places modules within 32MB solves
+   this, and makes other things simpler.  Anton?
+   --RR.  */
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt , ...)
+#endif
+
+/* There's actually a third entry here, but it's unused */
+struct ppc64_opd_entry
+{
+	unsigned long funcaddr;
+	unsigned long r2;
+};
+
+/* Like PPC32, we need little trampolines to do > 24-bit jumps (into
+   the kernel itself).  But on PPC64, these need to be used for every
+   jump, actually, to reset r2 (TOC+0x8000). */
+struct ppc64_stub_entry
+{
+	/* 28 byte jump instruction sequence (7 instructions) */
+	unsigned char jump[28];
+	unsigned char unused[4];
+	/* Data for the above code */
+	struct ppc64_opd_entry opd;
+};
+
+/* We use a stub to fix up r2 (TOC ptr) and to jump to the (external)
+   function which may be more than 24-bits away.  We could simply
+   patch the new r2 value and function pointer into the stub, but it's
+   significantly shorter to put these values at the end of the stub
+   code, and patch the stub address (32-bits relative to the TOC ptr,
+   r2) into the stub. */
+static struct ppc64_stub_entry ppc64_stub =
+{ .jump = {
+	0x3d, 0x82, 0x00, 0x00, /* addis   r12,r2, <high> */
+	0x39, 0x8c, 0x00, 0x00, /* addi    r12,r12, <low> */
+	/* Save current r2 value in magic place on the stack. */
+	0xf8, 0x41, 0x00, 0x28, /* std     r2,40(r1) */
+	0xe9, 0x6c, 0x00, 0x20, /* ld      r11,32(r12) */
+	0xe8, 0x4c, 0x00, 0x28, /* ld      r2,40(r12) */
+	0x7d, 0x69, 0x03, 0xa6, /* mtctr   r11 */
+	0x4e, 0x80, 0x04, 0x20  /* bctr */
+} };
+
+/* Count how many different 24-bit relocations (different symbol,
+   different addend) */
+static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num)
+{
+	unsigned int i, j, ret = 0;
+
+	/* FIXME: Only count external ones --RR */
+	/* Sure, this is order(n^2), but it's usually short, and not
+           time critical */
+	for (i = 0; i < num; i++) {
+		/* Only count 24-bit relocs, others don't need stubs */
+		if (ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24)
+			continue;
+		for (j = 0; j < i; j++) {
+			/* If this addend appeared before, it's
+                           already been counted */
+			if (rela[i].r_info == rela[j].r_info
+			    && rela[i].r_addend == rela[j].r_addend)
+				break;
+		}
+		if (j == i) ret++;
+	}
+	return ret;
+}
+
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+	return vmalloc(size);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
+/* Get size of potential trampolines required. */
+static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
+				    const Elf64_Shdr *sechdrs)
+{
+	/* One extra reloc so it's always 0-funcaddr terminated */
+	unsigned long relocs = 1;
+	unsigned i;
+
+	/* Every relocated section... */
+	for (i = 1; i < hdr->e_shnum; i++) {
+		if (sechdrs[i].sh_type == SHT_RELA) {
+			DEBUGP("Found relocations in section %u\n", i);
+			DEBUGP("Ptr: %p.  Number: %lu\n",
+			       (void *)sechdrs[i].sh_addr,
+			       sechdrs[i].sh_size / sizeof(Elf64_Rela));
+			relocs += count_relocs((void *)sechdrs[i].sh_addr,
+					       sechdrs[i].sh_size
+					       / sizeof(Elf64_Rela));
+		}
+	}
+
+	DEBUGP("Looks like a total of %lu stubs, max\n", relocs);
+	return relocs * sizeof(struct ppc64_stub_entry);
+}
+
+int module_frob_arch_sections(Elf64_Ehdr *hdr,
+			      Elf64_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *me)
+{
+	unsigned int i;
+
+	/* Find .toc and .stubs sections */
+	for (i = 1; i < hdr->e_shnum; i++) {
+		char *p;
+		if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0)
+			me->arch.stubs_section = i;
+		else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0)
+			me->arch.toc_section = i;
+
+		/* We don't handle .init for the moment: rename to _init */
+		while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))
+			p[0] = '_';
+	}
+	if (!me->arch.stubs_section || !me->arch.toc_section) {
+		printk("%s: doesn't contain .toc or .stubs.\n", me->name);
+		return -ENOEXEC;
+	}
+
+	/* Override the stubs size */
+	sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
+	return 0;
+}
+
+int apply_relocate(Elf64_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	printk(KERN_ERR "%s: Non-ADD RELOCATION unsupported\n", me->name);
+	return -ENOEXEC;
+}
+
+/* Both low and high 16 bits are added as SIGNED additions, so if low
+   16 bits has high bit set, high 16 bits must be adjusted.  These
+   macros do that (stolen from binutils). */
+#define PPC_LO(v) ((v) & 0xffff)
+#define PPC_HI(v) (((v) >> 16) & 0xffff)
+#define PPC_HA(v) PPC_HI ((v) + 0x8000)
+
+/* Patch stub to reference function and correct r2 value. */
+static inline int create_stub(struct ppc64_stub_entry *entry,
+			      unsigned long my_r2,
+			      unsigned long func,
+			      unsigned long r2)
+{
+	Elf64_Half *loc1, *loc2;
+	long reladdr;
+
+	*entry = ppc64_stub;
+
+	loc1 = (Elf64_Half *)&entry->jump[2];
+	loc2 = (Elf64_Half *)&entry->jump[6];
+
+	/* Stub uses address relative to r2, which is set to the TOC +
+           0x8000. */
+	reladdr = (unsigned long)entry - my_r2;
+	if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
+		printk("Address %p of stub out of range of %p.\n",
+		       (void *)reladdr, (void *)my_r2);
+		return 0;
+	}
+	DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr);
+
+	*loc1 = PPC_HA(reladdr);
+	*loc2 = PPC_LO(reladdr);
+	entry->opd.funcaddr = func;
+	entry->opd.r2 = r2;
+
+	DEBUGP("Stub: %08X %08X %08X %08X %08X %08X %08X: %p %p\n",
+	       ((unsigned int *)entry->jump)[0],
+	       ((unsigned int *)entry->jump)[1],
+	       ((unsigned int *)entry->jump)[2],
+	       ((unsigned int *)entry->jump)[3],
+	       ((unsigned int *)entry->jump)[4],
+	       ((unsigned int *)entry->jump)[5],
+	       ((unsigned int *)entry->jump)[6],
+	       (void *)entry->opd.funcaddr,
+	       (void *)entry->opd.r2);
+	return 1;
+}
+
+/* Given ".function" reference, return address of "function" opd entry */
+static struct ppc64_opd_entry *find_function(const char *name,
+					     Elf64_Shdr *sechdrs,
+					     unsigned int symindex,
+					     const char *strtab,
+					     struct module *me,
+					     struct kernel_symbol_group **ksg)
+{
+	unsigned long val;
+
+	if (name[0] != '.')
+		return 0;
+
+	val = find_symbol_internal(sechdrs, symindex, strtab, name+1, me, ksg);
+
+	DEBUGP("Function %s is at %p\n", name+1, (void *)val);
+	return (void *)val;
+}
+
+/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
+   gives the value maximum span in an instruction which uses a signed
+   offset) */
+static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me)
+{
+	return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
+}
+
+/* Create stub for this OPD address */
+static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
+				   unsigned long addr,
+				   unsigned long r2,
+				   struct module *me)
+{
+	struct ppc64_stub_entry *stubs;
+	unsigned int i, num_stubs;
+
+	DEBUGP("Looking for stub for %p\n", (void *)addr);
+
+	num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs);
+
+	/* Find this stub, or if that fails, the next avail. entry */
+	stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr;
+	for (i = 0; stubs[i].opd.funcaddr; i++) {
+		BUG_ON(i >= num_stubs);
+
+		if (stubs[i].opd.funcaddr == addr) {
+			DEBUGP("Reusing stub %u (%p) for %p\n",
+			       i, &stubs[i], (void *)addr);
+			return (unsigned long)&stubs[i];
+		}
+	}
+	DEBUGP("Here for %p\n", (void *)addr);
+
+	if (!create_stub(&stubs[i], my_r2(sechdrs, me), addr, r2))
+		return (unsigned long)-EINVAL;
+
+	DEBUGP("CREATED stub %u for %p\n", i, (void *)addr);
+
+	return (unsigned long)&stubs[i];
+}
+
+/* We need a stub to set the toc ptr when we make external calls. */
+static unsigned long do_stub_call(Elf64_Shdr *sechdrs,
+				  const char *strtab,
+				  unsigned int symindex,
+				  void *location,
+				  const char *funcname,
+				  struct module *me)
+{
+	struct ppc64_opd_entry *opd;
+	struct kernel_symbol_group *ksg;
+
+	DEBUGP("Doing stub for %lu (%s)\n",
+	       (unsigned long)location, funcname);
+	opd = find_function(funcname, sechdrs, symindex, strtab, me, &ksg);
+	if (!opd) {
+		printk("%s: Can't find function `%s'\n", me->name, funcname);
+		return (unsigned long)-ENOENT;
+	}
+
+	return stub_for_addr(sechdrs, opd->funcaddr, opd->r2, me);
+}
+
+/* We expect a noop next: if it is, replace it with instruction to
+   restore r2. */
+static int restore_r2(u32 *instruction)
+{
+	if (*instruction != 0x60000000) {
+		printk("Expect noop after relocate, got %08x\n", *instruction);
+		return 0;
+	}
+	*instruction = 0xe8410028;	/* ld r2,40(r1) */
+	return 1;
+}
+
+int apply_relocate_add(Elf64_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	unsigned int i;
+	Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+	Elf64_Sym *sym;
+	unsigned long *location;
+	unsigned long value;
+
+	DEBUGP("Applying ADD relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rela[i].r_offset;
+		/* This is the symbol it is referring to */
+		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
+			+ ELF64_R_SYM(rela[i].r_info);
+
+		DEBUGP("RELOC at %p: %li-type as %s (%lu) + %li\n",
+		       location, (long)ELF64_R_TYPE(rela[i].r_info),
+		       strtab + sym->st_name, (unsigned long)sym->st_value,
+		       (long)rela[i].r_addend);
+
+		/* REL24 references to (external) .function won't
+                   resolve; deal with that below */
+		if (!sym->st_value
+		    && ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24) {
+			printk("%s: Unknown symbol %s (index %u)\n",
+			       me->name, strtab + sym->st_name,
+			       sym->st_shndx);
+			return -ENOENT;
+		}
+		/* `Everything is relative'. */
+		value = sym->st_value + rela[i].r_addend;
+
+		switch (ELF64_R_TYPE(rela[i].r_info)) {
+		case R_PPC64_ADDR32:
+			/* Simply set it */
+			DEBUGP("Setting location %p to 32-bit value %u\n",
+			       location, (unsigned int)value);
+			*(u32 *)location = value;
+			break;
+			
+		case R_PPC64_ADDR64:
+			/* Simply set it */
+			*(unsigned long *)location = value;
+			DEBUGP("Setting location %p to 64-bit value %p\n",
+			       location, (void *)value);
+			break;
+
+		case R_PPC64_TOC:
+			*(unsigned long *)location = my_r2(sechdrs, me);
+			break;
+
+		case R_PPC64_TOC16_DS:
+			/* Subtact TOC pointer */
+			value -= my_r2(sechdrs, me);
+			if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
+				DEBUGP("%s: bad TOC16_DS relocation (%lu)\n",
+				       me->name, value);
+				return -ENOEXEC;
+			}
+			*((uint16_t *) location)
+				= (*((uint16_t *) location) & ~0xfffc)
+				| (value & 0xfffc);
+			DEBUGP("Modifying location %p by TOC (%p) => %i\n",
+			       location, 
+			       (void *)my_r2(sechdrs, me),
+			       *(uint16_t *)location);
+			break;
+
+		case R_PPC_REL24:
+			/* FIXME: Handle weak symbols here --RR */
+			if (sym->st_shndx == SHN_UNDEF) {
+				value = do_stub_call(sechdrs, strtab,
+						     symindex, location,
+						     strtab+sym->st_name, me);
+				if (IS_ERR((void *)value))
+					return value;
+				value += rela[i].r_addend;
+				if (!restore_r2((u32 *)location + 1))
+					return -ENOEXEC;
+			}
+
+			/* Convert value to relative */
+			value -= (unsigned long)location;
+			if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){
+				printk("REL24 relocation %li out of range!\n",
+				       (long int)value);
+				return -ENOEXEC;
+			}
+
+			/* Only replace bits 2 through 26 */
+			*(uint32_t *)location 
+				= (*(uint32_t *)location & ~0x03fffffc)
+				| (value & 0x03fffffc);
+			break;
+
+		default:
+			printk("Unknown ADD relocation: %lu\n",
+			       (unsigned long)ELF64_R_TYPE(rela[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+
+	return 0;
+}
+
+/* In arch/ppc64/mm/extable.c */
+extern void sort_ex_table(struct exception_table_entry *start,
+			  struct exception_table_entry *finish);
+
+int module_finalize(const Elf_Ehdr *hdr,
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+	struct ppc64_stub_entry *stubs;
+	unsigned int i;
+
+	/* Here is where we copy the OPD entry into the stub: we don't
+           do it ealier in case it's actually in the same module, and
+           hasn't been relocated yet. */
+	stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr;
+	for (i = 0; stubs[i].opd.funcaddr; i++) {
+		struct ppc64_opd_entry *opd;
+
+		/* We mark opd pointers by setting r2 to 0: otherwise
+                   it's a function pointer already. */
+		if (stubs[i].opd.r2 == 0) {
+			/* We put the opd entry ptr in the funcaddr member. */
+			opd = (void *)stubs[i].opd.funcaddr;
+			stubs[i].opd = *opd;
+		}
+	}
+
+	sort_ex_table(me->extable.entry,
+		      me->extable.entry + me->extable.num_entries);
+	return 0;
+}
diff -Nru a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
--- a/arch/ppc64/kernel/ppc_ksyms.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc64/kernel/ppc_ksyms.c	Thu Jan 16 18:23:05 2003
@@ -47,18 +47,11 @@
 #include <asm/iSeries/HvLpConfig.h>
 #endif
 
-/* Tell string.h we don't want memcpy etc. as cpp defines */
-#define EXPORT_SYMTAB_STROPS
-
 extern int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
-extern int sys_sigreturn(struct pt_regs *regs);
 extern int do_signal(sigset_t *, struct pt_regs *);
 extern int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *));
 extern int unregister_ioctl32_conversion(unsigned int cmd);
 
-long long __ashrdi3(long long, int);
-long long __ashldi3(long long, int);
-long long __lshrdi3(long long, int);
 int abs(int);
 
 extern struct pci_dev * iSeries_veth_dev;
@@ -66,7 +59,6 @@
 
 EXPORT_SYMBOL(do_signal);
 EXPORT_SYMBOL(sys_ioctl);
-EXPORT_SYMBOL(sys_sigreturn);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(disable_irq_nosync);
@@ -81,6 +73,7 @@
 EXPORT_SYMBOL(pci_io_base);
 
 EXPORT_SYMBOL(find_next_zero_bit);
+EXPORT_SYMBOL(find_next_zero_le_bit);
 
 EXPORT_SYMBOL(strcpy);
 EXPORT_SYMBOL(strncpy);
@@ -184,7 +177,6 @@
 EXPORT_SYMBOL(enable_kernel_fp);
 EXPORT_SYMBOL(flush_icache_range);
 EXPORT_SYMBOL(flush_icache_user_range);
-EXPORT_SYMBOL(flush_icache_page);
 EXPORT_SYMBOL(flush_dcache_page);
 #ifdef CONFIG_SMP
 #ifdef CONFIG_PPC_ISERIES
@@ -207,9 +199,6 @@
 EXPORT_SYMBOL(get_property);
 
 
-EXPORT_SYMBOL_NOVERS(__ashrdi3);
-EXPORT_SYMBOL_NOVERS(__ashldi3);
-EXPORT_SYMBOL_NOVERS(__lshrdi3);
 EXPORT_SYMBOL_NOVERS(memcpy);
 EXPORT_SYMBOL_NOVERS(memset);
 EXPORT_SYMBOL_NOVERS(memmove);
diff -Nru a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
--- a/arch/ppc64/kernel/process.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc64/kernel/process.c	Thu Jan 16 18:23:06 2003
@@ -69,6 +69,12 @@
 int
 dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
 {
+	/*
+	 * XXX temporary workaround until threaded coredumps for ppc64
+	 * are implemented - Anton
+	 */
+	if (!regs)
+		return 0;
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
 	memcpy(fpregs, &current->thread.fpr[0], sizeof(*fpregs));
diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
--- a/arch/ppc64/kernel/signal.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc64/kernel/signal.c	Thu Jan 16 18:23:05 2003
@@ -99,40 +99,6 @@
 
 extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
 
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
-	       struct pt_regs *regs)
-{
-	sigset_t saveset;
-
-	mask &= _BLOCKABLE;
-	spin_lock_irq(&current->sig->siglock);
-	saveset = current->blocked;
-	siginitset(&current->blocked, mask);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
-
-	regs->result = -EINTR;
-	regs->gpr[3] = EINTR;
-	regs->ccr |= 0x10000000;
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs))
-			/*
-			 * If a signal handler needs to be called,
-			 * do_signal() has set R3 to the signal number (the
-			 * first argument of the signal handler), so don't
-			 * overwrite that with EINTR !
-			 * In the other cases, do_signal() doesn't touch 
-			 * R3, so it's still set to -EINTR (see above).
-			 */
-			return regs->gpr[3];
-	}
-}
-
 long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
 		  int p7, struct pt_regs *regs)
 {
@@ -170,37 +136,6 @@
 	return do_sigaltstack(uss, uoss, regs->gpr[1]);
 }
 
-long sys_sigaction(int sig, const struct old_sigaction *act,
-	      struct old_sigaction *oact)
-{
-	struct k_sigaction new_ka, old_ka;
-	int ret;
-
-	if (act) {
-		old_sigset_t mask;
-
-		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
-		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
-			return -EFAULT;
-		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		__get_user(mask, &act->sa_mask);
-		siginitset(&new_ka.sa.sa_mask, mask);
-	}
-
-	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-	if (!ret && oact) {
-		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
-		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
-			return -EFAULT;
-		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
-	}
-
-	return ret;
-}
-
 /*
  *  When we have rt signals to deliver, we set up on the
  *  user stack, going down from the original stack pointer:
@@ -329,116 +264,6 @@
 }
 
 /*
- * Do a signal return; undo the signal stack.
- */
-long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
-		   unsigned long r6, unsigned long r7, unsigned long r8,
-		   struct pt_regs *regs)
-{
-	struct sigcontext *sc, sigctx;
-	struct sigregs *sr;
-	elf_gregset_t saved_regs;  /* an array of ELF_NGREG unsigned longs */
-	sigset_t set;
-
-	sc = (struct sigcontext *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
-	if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
-		goto badframe;
-
-	set.sig[0] = sigctx.oldmask;
-#if _NSIG_WORDS > 1
-	set.sig[1] = sigctx._unused[3];
-#endif
-	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sig->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sig->siglock);
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
-
-	/* restore registers */
-	sr = (struct sigregs *)sigctx.regs;
-	if (copy_from_user(saved_regs, &sr->gp_regs, sizeof(sr->gp_regs)))
-		goto badframe;
-	saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
-		| (saved_regs[PT_MSR] & MSR_USERCHANGE);
-	saved_regs[PT_SOFTE] = regs->softe;
-	memcpy(regs, saved_regs, GP_REGS_SIZE);
-
-	if (copy_from_user(current->thread.fpr, &sr->fp_regs,
-			   sizeof(sr->fp_regs)))
-		goto badframe;
-
-	return regs->result;
-
-badframe:
-	do_exit(SIGSEGV);
-}	
-
-/*
- * Set up a signal frame.
- */
-static void setup_frame(struct pt_regs *regs, struct sigregs *frame,
-	    unsigned long newsp)
-{
-
-	/* Handler is *really* a pointer to the function descriptor for
-	 * the signal routine.  The first entry in the function
-	 * descriptor is the entry address of signal and the second
-	 * entry is the TOC value we need to use.
-	 */
-	struct funct_descr_entry {
-		unsigned long entry;
-		unsigned long toc;
-	};
-  
-	struct funct_descr_entry * funct_desc_ptr;
-	unsigned long temp_ptr;
-
-	struct sigcontext *sc = (struct sigcontext *)newsp;
-  
-	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
-		goto badframe;
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
-	if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
-	    || __copy_to_user(&frame->fp_regs, current->thread.fpr,
-			      ELF_NFPREG * sizeof(double))
-	    /* li r0, __NR_sigreturn */
-	    || __put_user(0x38000000UL + __NR_sigreturn, &frame->tramp[0])
-	    /* sc */
-	    || __put_user(0x44000002UL, &frame->tramp[1]))
-		goto badframe;
-	flush_icache_range((unsigned long)&frame->tramp[0],
-			   (unsigned long)&frame->tramp[2]);
-	current->thread.fpscr = 0;	/* turn off all fp exceptions */
-
-	newsp -= __SIGNAL_FRAMESIZE;
-	if (get_user(temp_ptr, &sc->handler))
-		goto badframe;
-  
-	funct_desc_ptr = (struct funct_descr_entry *)temp_ptr;
-
-	if (put_user(regs->gpr[1], (unsigned long *)newsp)
-	    || get_user(regs->nip, &funct_desc_ptr ->entry)
-	    || get_user(regs->gpr[2],&funct_desc_ptr->toc)
-	    || get_user(regs->gpr[3], &sc->signal))
-		goto badframe;
-	regs->gpr[1] = newsp;
-	regs->gpr[4] = (unsigned long)sc;
-	regs->link = (unsigned long)frame->tramp;
-
-	return;
-
-badframe:
-#if DEBUG_SIG
-	printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
-	       regs, frame, newsp);
-#endif
-	do_exit(SIGSEGV);
-}
-
-/*
  * OK, we're invoking a handler
  */
 static void handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
@@ -582,10 +407,7 @@
 	if (newsp == frame)
 		return 0;		/* no signals delivered */
 
-	/* Invoke correct stack setup routine */
-	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(regs, (struct sigregs *)frame, newsp);
-	else
-		setup_frame(regs, (struct sigregs *)frame, newsp);
+	setup_rt_frame(regs, (struct sigregs *)frame, newsp);
+
 	return 1;
 }
diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
--- a/arch/ppc64/kernel/signal32.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc64/kernel/signal32.c	Thu Jan 16 18:23:06 2003
@@ -114,6 +114,43 @@
  *        setup_frame32
  */
 
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+
+extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6,
+		      int p7, struct pt_regs *regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sig->siglock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sig->siglock);
+
+	regs->result = -EINTR;
+	regs->gpr[3] = EINTR;
+	regs->ccr |= 0x10000000;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			/*
+			 * If a signal handler needs to be called,
+			 * do_signal() has set R3 to the signal number (the
+			 * first argument of the signal handler), so don't
+			 * overwrite that with EINTR !
+			 * In the other cases, do_signal() doesn't touch 
+			 * R3, so it's still set to -EINTR (see above).
+			 */
+			return regs->gpr[3];
+	}
+}
+
 long sys32_sigaction(int sig, struct old_sigaction32 *act,
 		struct old_sigaction32 *oact)
 {
@@ -799,9 +836,6 @@
 	set_fs (old_fs);
 	return ret;
 }
-
-
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
 
 int sys32_rt_sigsuspend(sigset32_t* unewset, size_t sigsetsize, int p3,
 		int p4, int p6, int p7, struct pt_regs *regs)
diff -Nru a/arch/ppc64/kernel/sys32.S b/arch/ppc64/kernel/sys32.S
--- a/arch/ppc64/kernel/sys32.S	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc64/kernel/sys32.S	Thu Jan 16 18:23:06 2003
@@ -21,34 +21,10 @@
 
 	.text
 
-_GLOBAL(sys32_mmap)
-	clrldi		r7, r7, 32	/* int fd parm */
-	clrldi		r8, r8, 32	/* off_t offset parm */
-	b		.sys_mmap
-
-_GLOBAL(sys32_lseek)
+_GLOBAL(ppc32_lseek)
 	extsw		r4,r4		/* sign extend off_t offset parm */
 	b		.sys_lseek
 
-_GLOBAL(sys32_sendto)
-	clrldi		r7, r7, 32	/* struct sockaddr *addr parm */
-	clrldi		r8, r8, 32	/* int addr_len parm */
-	b		.sys_sendto
-
-_GLOBAL(sys32_recvfrom)
-	clrldi		r7, r7, 32	/* struct sockaddr *addr parm */
-	clrldi		r8, r8, 32	/* int *addr_len parm */
-	b		.sys_recvfrom
-
-_GLOBAL(ppc32_mmap2)
-	clrldi		r7, r7, 32	/* unsigned long fd parm */
-	clrldi		r8, r8, 32	/* unsigned long pgoff */
-	b		.sys32_mmap2
-
-_GLOBAL(ppc32_remap_file_pages)
-	clrldi		r7, r7, 32
-	b		.sys_remap_file_pages
-
 _GLOBAL(sys32_socketcall)	/* r3=call, r4=args */
 	cmpwi		r3, 1
 	blt-		.do_einval
@@ -64,140 +40,254 @@
 /* Socket function vectored fix ups for 32 bit */
 _STATIC(do_sys_socket) /* sys_socket(int, int, int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwa		r4,4(r10)
-	lwa		r5,8(r10)
+1:	lwa		r3,0(r10)
+2:	lwa		r4,4(r10)
+3:	lwa		r5,8(r10)
 	b		.sys_socket
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.previous
 
 _STATIC(do_sys_bind) /* sys_bind(int fd, struct sockaddr *, int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwa		r5,8(r10)
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwa		r5,8(r10)
 	b		.sys_bind
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.previous
 
 _STATIC(do_sys_connect) /* sys_connect(int, struct sockaddr *, int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwa		r5,8(r10)
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwa		r5,8(r10)
 	b		.sys_connect
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.previous
 
 _STATIC(do_sys_listen) /* sys_listen(int, int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwa		r4,4(r10)
+1:	lwa		r3,0(r10)
+2:	lwa		r4,4(r10)
 	b		.sys_listen
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.previous
 
 _STATIC(do_sys_accept) /* sys_accept(int, struct sockaddr *, int *) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwz		r5,8(r10)
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwz		r5,8(r10)
 	b		.sys_accept
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.previous
 
 _STATIC(do_sys_getsockname) /* sys_getsockname(int, struct sockaddr *, int *) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwz		r5,8(r10)
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwz		r5,8(r10)
 	b		.sys_getsockname
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.previous
 
 _STATIC(do_sys_getpeername) /* sys_getpeername(int, struct sockaddr *, int *) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwz		r5,8(r10)
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwz		r5,8(r10)
 	b		.sys_getpeername
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.previous
 
 _STATIC(do_sys_socketpair) /* sys_socketpair(int, int, int, int *) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwa		r4,4(r10)
-	lwa		r5,8(r10)
-	lwz		r6,12(r10)
+1:	lwa		r3,0(r10)
+2:	lwa		r4,4(r10)
+3:	lwa		r5,8(r10)
+4:	lwz		r6,12(r10)
 	b		.sys_socketpair
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.llong		4b,.do_efault
+	.previous
 
 _STATIC(do_sys_send) /* sys_send(int, void *, size_t, unsigned int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwz		r5,8(r10)
-	lwz		r6,12(r10)
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwz		r5,8(r10)
+4:	lwz		r6,12(r10)
 	b		.sys_send
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.llong		4b,.do_efault
+	.previous
 
 _STATIC(do_sys_recv) /* sys_recv(int, void *, size_t, unsigned int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwz		r5,8(r10)
-	lwz		r6,12(r10)
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwz		r5,8(r10)
+4:	lwz		r6,12(r10)
 	b		.sys_recv
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.llong		4b,.do_efault
+	.previous
 
 _STATIC(do_sys_sendto) /* sys32_sendto(int, u32, compat_size_t, unsigned int, u32, int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwz		r5,8(r10)
-	lwz		r6,12(r10)
-	lwz		r7,16(r10)
-	lwa		r8,20(r10)
-	b		.sys32_sendto
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwz		r5,8(r10)
+4:	lwz		r6,12(r10)
+5:	lwz		r7,16(r10)
+6:	lwz		r8,20(r10)
+	b		.sys_sendto
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.llong		4b,.do_efault
+	.llong		5b,.do_efault
+	.llong		6b,.do_efault
+	.previous
 
 _STATIC(do_sys_recvfrom) /* sys32_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwz		r5,8(r10)
-	lwz		r6,12(r10)
-	lwz		r7,16(r10)
-	lwz		r8,20(r10)
-	b		.sys32_recvfrom
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwz		r5,8(r10)
+4:	lwz		r6,12(r10)
+5:	lwz		r7,16(r10)
+6:	lwz		r8,20(r10)
+	b		.sys_recvfrom
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.llong		4b,.do_efault
+	.llong		5b,.do_efault
+	.llong		6b,.do_efault
+	.previous
 
 _STATIC(do_sys_shutdown) /* sys_shutdown(int, int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwa		r4,4(r10)
+1:	lwa		r3,0(r10)
+2:	lwa		r4,4(r10)
 	b		.sys_shutdown
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.previous
 
 _STATIC(do_sys_setsockopt) /* sys32_setsockopt(int, int, int, char *, int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwa		r4,4(r10)
-	lwa		r5,8(r10)
-	lwz		r6,12(r10)
-	lwa		r7,16(r10)
+1:	lwa		r3,0(r10)
+2:	lwa		r4,4(r10)
+3:	lwa		r5,8(r10)
+4:	lwz		r6,12(r10)
+5:	lwa		r7,16(r10)
 	b		.sys32_setsockopt
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.llong		4b,.do_efault
+	.llong		5b,.do_efault
+	.previous
 
 _STATIC(do_sys_getsockopt) /* sys32_getsockopt(int, int, int, u32, u32) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwa		r4,4(r10)
-	lwa		r5,8(r10)
-	lwz		r6,12(r10)
-	lwz		r7,16(r10)
+1:	lwa		r3,0(r10)
+2:	lwa		r4,4(r10)
+3:	lwa		r5,8(r10)
+4:	lwz		r6,12(r10)
+5:	lwz		r7,16(r10)
 	b		.sys32_getsockopt
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.llong		4b,.do_efault
+	.llong		5b,.do_efault
+	.previous
 
 _STATIC(do_sys_sendmsg) /* sys32_sendmsg(int, struct msghdr32 *, unsigned int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwa		r5,8(r10)
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwa		r5,8(r10)
 	b		.sys32_sendmsg
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.previous
 
 _STATIC(do_sys_recvmsg) /* sys32_recvmsg(int, struct msghdr32 *, unsigned int) */
 	mr		r10,r4
-	lwa		r3,0(r10)
-	lwz		r4,4(r10)
-	lwa		r5,8(r10)
+1:	lwa		r3,0(r10)
+2:	lwz		r4,4(r10)
+3:	lwa		r5,8(r10)
 	b		.sys32_recvmsg
+	.section	__ex_table,"a"
+	.align		3
+	.llong		1b,.do_efault
+	.llong		2b,.do_efault
+	.llong		3b,.do_efault
+	.previous
 
 _STATIC(do_einval)
 	li	r3,-EINVAL
-	b	.ret_from_syscall_1
+	blr
+
 _STATIC(do_efault)
 	li	r3,-EFAULT
-	b	.ret_from_syscall_1
+	blr
 
 	.data
 	.align	8
@@ -220,10 +310,3 @@
 	.llong		.do_sys_sendmsg
 	.llong		.do_sys_recvmsg
 _GLOBAL(socketcall_table_end)
-	.section	__ex_table,"a"
-	.align		3
-	.llong		.socketcall_table_begin
-	.llong		0
-	.llong		.socketcall_table_end
-	.llong		.do_efault
-	.previous
diff -Nru a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc64/kernel/sys_ppc32.c	Thu Jan 16 18:23:06 2003
@@ -934,430 +934,37 @@
 	return ret;
 }
 
-
-
 #ifdef CONFIG_MODULES
 
-extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
-
-asmlinkage unsigned long sys32_create_module(const char *name_user, compat_size_t size)
-{
-	return sys_create_module(name_user, (size_t)size);
-}
-
-
-
-extern asmlinkage long sys_init_module(const char *name_user, struct module *mod_user);
-
-asmlinkage long sys32_init_module(const char *name_user, struct module *mod_user)
-{
-	return sys_init_module(name_user, mod_user);
-}
-
-
-
-extern asmlinkage long sys_delete_module(const char *name_user);
-
-asmlinkage long sys32_delete_module(const char *name_user)
-{
-	return sys_delete_module(name_user);
-}
-
-
-
-struct module_info32 {
-	u32 addr;
-	u32 size;
-	u32 flags;
-	s32 usecount;
-};
-
-/* Query various bits about modules.  */
-
-static inline long
-get_mod_name(const char *user_name, char **buf)
-{
-	unsigned long page;
-	long retval;
-
-	if ((unsigned long)user_name >= TASK_SIZE
-	    && !segment_eq(get_fs (), KERNEL_DS))
-		return -EFAULT;
-
-	page = __get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
-	retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
-	if (retval > 0) {
-		if (retval < PAGE_SIZE) {
-			*buf = (char *)page;
-			return retval;
-		}
-		retval = -ENAMETOOLONG;
-	} else if (!retval)
-		retval = -EINVAL;
-
-	free_page(page);
-	return retval;
-}
-
-static inline void
-put_mod_name(char *buf)
-{
-	free_page((unsigned long)buf);
-}
-
-static __inline__ struct module *find_module(const char *name)
-{
-	struct module *mod;
-
-	for (mod = module_list; mod ; mod = mod->next) {
-		if (mod->flags & MOD_DELETED)
-			continue;
-		if (!strcmp(mod->name, name))
-			break;
-	}
-
-	return mod;
-}
-
-static int
-qm_modules(char *buf, size_t bufsize, compat_size_t *ret)
-{
-	struct module *mod;
-	size_t nmod, space, len;
-
-	nmod = space = 0;
-
-	for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
-		len = strlen(mod->name)+1;
-		if (len > bufsize)
-			goto calc_space_needed;
-		if (copy_to_user(buf, mod->name, len))
-			return -EFAULT;
-		buf += len;
-		bufsize -= len;
-		space += len;
-	}
-
-	if (put_user(nmod, ret))
-		return -EFAULT;
-	else
-		return 0;
-
-calc_space_needed:
-	space += len;
-	while ((mod = mod->next)->next != NULL)
-		space += strlen(mod->name)+1;
-
-	if (put_user(space, ret))
-		return -EFAULT;
-	else
-		return -ENOSPC;
-}
-
-static int
-qm_deps(struct module *mod, char *buf, size_t bufsize, compat_size_t *ret)
-{
-	size_t i, space, len;
-
-	if (mod->next == NULL)
-		return -EINVAL;
-	if (!MOD_CAN_QUERY(mod))
-		return put_user(0, ret);
-
-	space = 0;
-	for (i = 0; i < mod->ndeps; ++i) {
-		const char *dep_name = mod->deps[i].dep->name;
-
-		len = strlen(dep_name)+1;
-		if (len > bufsize)
-			goto calc_space_needed;
-		if (copy_to_user(buf, dep_name, len))
-			return -EFAULT;
-		buf += len;
-		bufsize -= len;
-		space += len;
-	}
-
-	return put_user(i, ret);
-
-calc_space_needed:
-	space += len;
-	while (++i < mod->ndeps)
-		space += strlen(mod->deps[i].dep->name)+1;
-
-	if (put_user(space, ret))
-		return -EFAULT;
-	else
-		return -ENOSPC;
-}
-
-static int
-qm_refs(struct module *mod, char *buf, size_t bufsize, compat_size_t *ret)
-{
-	size_t nrefs, space, len;
-	struct module_ref *ref;
-
-	if (mod->next == NULL)
-		return -EINVAL;
-	if (!MOD_CAN_QUERY(mod))
-		if (put_user(0, ret))
-			return -EFAULT;
-		else
-			return 0;
-
-	space = 0;
-	for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
-		const char *ref_name = ref->ref->name;
-
-		len = strlen(ref_name)+1;
-		if (len > bufsize)
-			goto calc_space_needed;
-		if (copy_to_user(buf, ref_name, len))
-			return -EFAULT;
-		buf += len;
-		bufsize -= len;
-		space += len;
-	}
-
-	if (put_user(nrefs, ret))
-		return -EFAULT;
-	else
-		return 0;
-
-calc_space_needed:
-	space += len;
-	while ((ref = ref->next_ref) != NULL)
-		space += strlen(ref->ref->name)+1;
-
-	if (put_user(space, ret))
-		return -EFAULT;
-	else
-		return -ENOSPC;
-}
-
-static inline int
-qm_symbols(struct module *mod, char *buf, size_t bufsize, compat_size_t *ret)
-{
-	size_t i, space, len;
-	struct module_symbol *s;
-	char *strings;
-	unsigned *vals;
-
-	if (!MOD_CAN_QUERY(mod))
-		if (put_user(0, ret))
-			return -EFAULT;
-		else
-			return 0;
-
-	space = mod->nsyms * 2*sizeof(u32);
-
-	i = len = 0;
-	s = mod->syms;
-
-	if (space > bufsize)
-		goto calc_space_needed;
-
-	if (!access_ok(VERIFY_WRITE, buf, space))
-		return -EFAULT;
-
-	bufsize -= space;
-	vals = (unsigned *)buf;
-	strings = buf+space;
-
-	for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
-		len = strlen(s->name)+1;
-		if (len > bufsize)
-			goto calc_space_needed;
-
-		if (copy_to_user(strings, s->name, len)
-		    || __put_user(s->value, vals+0)
-		    || __put_user(space, vals+1))
-			return -EFAULT;
-
-		strings += len;
-		bufsize -= len;
-		space += len;
-	}
-
-	if (put_user(i, ret))
-		return -EFAULT;
-	else
-		return 0;
-
-calc_space_needed:
-	for (; i < mod->nsyms; ++i, ++s)
-		space += strlen(s->name)+1;
-
-	if (put_user(space, ret))
-		return -EFAULT;
-	else
-		return -ENOSPC;
-}
-
-static inline int
-qm_info(struct module *mod, char *buf, size_t bufsize, compat_size_t *ret)
-{
-	int error = 0;
-
-	if (mod->next == NULL)
-		return -EINVAL;
-
-	if (sizeof(struct module_info32) <= bufsize) {
-		struct module_info32 info;
-		info.addr = (unsigned long)mod;
-		info.size = mod->size;
-		info.flags = mod->flags;
-		info.usecount =
-			((mod_member_present(mod, can_unload)
-			  && mod->can_unload)
-			 ? -1 : atomic_read(&mod->uc.usecount));
-
-		if (copy_to_user(buf, &info, sizeof(struct module_info32)))
-			return -EFAULT;
-	} else
-		error = -ENOSPC;
-
-	if (put_user(sizeof(struct module_info32), ret))
-		return -EFAULT;
-
-	return error;
-}
+extern asmlinkage long sys_init_module(void *, unsigned long, const char *);
 
-/* Note: it is necessary to treat which as an unsigned int, 
- * with the corresponding cast to a signed int to insure that the 
- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
- * and the register representation of a signed int (msr in 64-bit mode) is performed.
- */
-asmlinkage long sys32_query_module(char *name_user, u32 which, char *buf, compat_size_t bufsize, u32 ret)
+asmlinkage int sys32_init_module(void *umod, u32 len, const char *uargs)
 {
-	struct module *mod;
-	int err;
-	
-	lock_kernel();
-	if (name_user == 0) {
-		/* This finds "kernel_module" which is not exported. */
-		for(mod = module_list; mod->next != NULL; mod = mod->next)
-			;
-	} else {
-		long namelen;
-		char *name;
-
-		if ((namelen = get_mod_name(name_user, &name)) < 0) {
-			err = namelen;
-			goto out;
-		}
-		err = -ENOENT;
-		if (namelen == 0) {
-			/* This finds "kernel_module" which is not exported. */
-			for(mod = module_list; mod->next != NULL; mod = mod->next)
-				;
-		} else if ((mod = find_module(name)) == NULL) {
-			put_mod_name(name);
-			goto out;
-		}
-		put_mod_name(name);
-	}
-
-	switch ((int)which)
-	{
-	case 0:
-		err = 0;
-		break;
-	case QM_MODULES:
-		err = qm_modules(buf, bufsize, (compat_size_t *)AA(ret));
-		break;
-	case QM_DEPS:
-		err = qm_deps(mod, buf, bufsize, (compat_size_t *)AA(ret));
-		break;
-	case QM_REFS:
-		err = qm_refs(mod, buf, bufsize, (compat_size_t *)AA(ret));
-		break;
-	case QM_SYMBOLS:
-		err = qm_symbols(mod, buf, bufsize, (compat_size_t *)AA(ret));
-		break;
-	case QM_INFO:
-		err = qm_info(mod, buf, bufsize, (compat_size_t *)AA(ret));
-		break;
-	default:
-		err = -EINVAL;
-		break;
-	}
-out:
-	unlock_kernel();
-	
-	return err;
+	return sys_init_module(umod, len, uargs);
 }
 
+extern asmlinkage long sys_delete_module(const char *, unsigned int);
 
-
-struct kernel_sym32 {
-	u32 value;
-	char name[60];
-};
-		 
-extern asmlinkage long sys_get_kernel_syms(struct kernel_sym *table);
-
-asmlinkage long sys32_get_kernel_syms(struct kernel_sym32 *table)
+asmlinkage int sys32_delete_module(const char *name_user, unsigned int flags)
 {
-	int len, i;
-	struct kernel_sym *tbl;
-	mm_segment_t old_fs;
-	
-	len = sys_get_kernel_syms(NULL);
-	if (!table) return len;
-	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
-	if (!tbl) return -ENOMEM;
-	old_fs = get_fs();
-	set_fs (KERNEL_DS);
-	sys_get_kernel_syms(tbl);
-	set_fs (old_fs);
-	for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
-		if (put_user (tbl[i].value, &table->value) ||
-		    copy_to_user (table->name, tbl[i].name, 60))
-			break;
-	}
-	kfree (tbl);
-	
-	return i;
+	return sys_delete_module(name_user, flags);
 }
 
 #else /* CONFIG_MODULES */
 
-asmlinkage unsigned long sys32_create_module(const char *name_user, size_t size)
-{
-	return -ENOSYS;
-}
-
-asmlinkage long sys32_init_module(const char *name_user, struct module *mod_user)
+asmlinkage int
+sys32_init_module(const char *name_user, struct module *mod_user)
 {
 	return -ENOSYS;
 }
 
-asmlinkage long sys32_delete_module(const char *name_user)
-{
-	return -ENOSYS;
-}
-
-asmlinkage long sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize, size_t *ret)
-{
-	/* Let the program know about the new interface.  Not that it'll do them much good. */
-	if (which == 0)
-		return 0;
-
-	return -ENOSYS;
-}
-
-asmlinkage long sys32_get_kernel_syms(struct kernel_sym *table)
+asmlinkage int
+sys32_delete_module(const char *name_user)
 {
 	return -ENOSYS;
 }
 
 #endif  /* CONFIG_MODULES */
-
-
 
 /* Stuff for NFS server syscalls... */
 struct nfsctl_svc32 {
diff -Nru a/arch/ppc64/mm/extable.c b/arch/ppc64/mm/extable.c
--- a/arch/ppc64/mm/extable.c	Thu Jan 16 18:23:05 2003
+++ b/arch/ppc64/mm/extable.c	Thu Jan 16 18:23:05 2003
@@ -21,10 +21,11 @@
  * The exception table needs to be sorted because we use the macros
  * which put things into the exception table in a variety of segments
  * as well as the init segment and the main kernel text segment.
+ *
+ * Also used for modules.
  */
-static inline void
-sort_ex_table(struct exception_table_entry *start,
-	      struct exception_table_entry *finish)
+void __init_or_module sort_ex_table(struct exception_table_entry *start,
+				    struct exception_table_entry *finish)
 {
 	struct exception_table_entry el, *p, *q;
 
diff -Nru a/arch/ppc64/vmlinux.lds.S b/arch/ppc64/vmlinux.lds.S
--- a/arch/ppc64/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
+++ b/arch/ppc64/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
@@ -1,3 +1,5 @@
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_ARCH(powerpc:common64)
 /* Do we need any of these for elf?
    __DYNAMIC = 0;    */
@@ -37,11 +39,9 @@
   . = ALIGN(4096);
   _etext = .;
   PROVIDE (etext = .);
-  .rodata    :
-  {
-    *(.rodata)
-    *(.rodata1)
-  }
+
+  RODATA
+
   .fini      : { *(.fini)    } =0
   .ctors     : { *(.ctors)   }
   .dtors     : { *(.dtors)   }
@@ -64,18 +64,6 @@
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
-
-  __start___ksymtab = .;        /* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-
-  __start___kallsyms = .;	/* All kernel symbols */
-  __kallsyms : { *(__kallsyms) }
-  __stop___kallsyms = .;
 
   . = ALIGN(16384);		/* init_task */
   .data.init_task : { *(.data.init_task) }
diff -Nru a/arch/s390/vmlinux.lds.S b/arch/s390/vmlinux.lds.S
--- a/arch/s390/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/s390/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -1,6 +1,9 @@
 /* ld script to make s390 Linux kernel
  * Written by Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
+
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
 OUTPUT_ARCH(s390)
 ENTRY(_start)
@@ -17,22 +20,12 @@
 
   _etext = .;			/* End of text section */
 
-  .rodata : { *(.rodata) *(.rodata.*) }
-  .kstrtab : { *(.kstrtab) }
-
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  . = ALIGN(64);
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
+  RODATA
 
 #ifdef CONFIG_SHARED_KERNEL
   . = ALIGN(1048576);		/* VM shared segments are 1MB aligned */
diff -Nru a/arch/s390x/kernel/entry.S b/arch/s390x/kernel/entry.S
--- a/arch/s390x/kernel/entry.S	Thu Jan 16 18:23:05 2003
+++ b/arch/s390x/kernel/entry.S	Thu Jan 16 18:23:05 2003
@@ -464,7 +464,7 @@
         .long  SYSCALL(sys_ni_syscall,sys32_setreuid16_wrapper) /* old setreuid16 syscall */
         .long  SYSCALL(sys_ni_syscall,sys32_setregid16_wrapper) /* old setregid16 syscall */
         .long  SYSCALL(sys_sigsuspend_glue,sys32_sigsuspend_glue)
-        .long  SYSCALL(sys_sigpending,sys32_sigpending_wrapper)
+        .long  SYSCALL(sys_sigpending,compat_sys_sigpending_wrapper)
         .long  SYSCALL(sys_sethostname,sys32_sethostname_wrapper)
         .long  SYSCALL(sys_setrlimit,sys32_setrlimit_wrapper)   /* 75 */
         .long  SYSCALL(sys_getrlimit,sys32_old_getrlimit_wrapper) 
@@ -517,7 +517,7 @@
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* modify_ldt for i386 */
         .long  SYSCALL(sys_adjtimex,sys32_adjtimex_wrapper)
         .long  SYSCALL(sys_mprotect,sys32_mprotect_wrapper) /* 125 */
-        .long  SYSCALL(sys_sigprocmask,sys32_sigprocmask_wrapper)
+        .long  SYSCALL(sys_sigprocmask,compat_sys_sigprocmask_wrapper)
         .long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* old "create module" */
         .long  SYSCALL(sys_init_module,sys32_init_module_wrapper)
         .long  SYSCALL(sys_delete_module,sys32_delete_module_wrapper)
diff -Nru a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c
--- a/arch/s390x/kernel/linux32.c	Thu Jan 16 18:23:06 2003
+++ b/arch/s390x/kernel/linux32.c	Thu Jan 16 18:23:06 2003
@@ -1621,34 +1621,17 @@
 	return ret;
 }
 
-extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
-
-asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
-{
-	old_sigset_t s;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-	
-	if (set && get_user (s, set)) return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
-	set_fs (old_fs);
-	if (ret) return ret;
-	if (oset && put_user (s, oset)) return -EFAULT;
-	return 0;
-}
-
 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
 
-asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, compat_size_t sigsetsize)
+asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset, compat_size_t sigsetsize)
 {
 	sigset_t s;
-	sigset_t32 s32;
+	compat_sigset_t s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	
 	if (set) {
-		if (copy_from_user (&s32, set, sizeof(sigset_t32)))
+		if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
 			return -EFAULT;
 		switch (_NSIG_WORDS) {
 		case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
@@ -1668,33 +1651,18 @@
 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
 		}
-		if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
+		if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
 			return -EFAULT;
 	}
 	return 0;
 }
 
-extern asmlinkage int sys_sigpending(old_sigset_t *set);
-
-asmlinkage int sys32_sigpending(old_sigset_t32 *set)
-{
-	old_sigset_t s;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-		
-	set_fs (KERNEL_DS);
-	ret = sys_sigpending(&s);
-	set_fs (old_fs);
-	if (put_user (s, set)) return -EFAULT;
-	return ret;
-}
-
 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
-asmlinkage int sys32_rt_sigpending(sigset_t32 *set, compat_size_t sigsetsize)
+asmlinkage int sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize)
 {
 	sigset_t s;
-	sigset_t32 s32;
+	compat_sigset_t s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 		
@@ -1708,7 +1676,7 @@
 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
 		}
-		if (copy_to_user (set, &s32, sizeof(sigset_t32)))
+		if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
 			return -EFAULT;
 	}
 	return ret;
@@ -1718,12 +1686,12 @@
 copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from);
 
 asmlinkage int
-sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
+sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
 		      struct compat_timespec *uts, compat_size_t sigsetsize)
 {
 	int ret, sig;
 	sigset_t these;
-	sigset_t32 these32;
+	compat_sigset_t these32;
 	struct timespec ts;
 	siginfo_t info;
 	long timeout = 0;
@@ -1732,7 +1700,7 @@
 	if (sigsetsize != sizeof(sigset_t))
 		return -EINVAL;
 
-	if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
+	if (copy_from_user (&these32, uthese, sizeof(compat_sigset_t)))
 		return -EFAULT;
 
 	switch (_NSIG_WORDS) {
diff -Nru a/arch/s390x/kernel/linux32.h b/arch/s390x/kernel/linux32.h
--- a/arch/s390x/kernel/linux32.h	Thu Jan 16 18:23:07 2003
+++ b/arch/s390x/kernel/linux32.h	Thu Jan 16 18:23:07 2003
@@ -25,20 +25,13 @@
 #define F_SETLK64       13
 #define F_SETLKW64      14    
 
-typedef __u32 old_sigset_t32;       /* at least 32 bits */ 
-
 struct old_sigaction32 {
        __u32			sa_handler;	/* Really a pointer, but need to deal with 32 bits */
-       old_sigset_t32		sa_mask;	/* A 32 bit mask */
+       compat_old_sigset_t	sa_mask;	/* A 32 bit mask */
        __u32			sa_flags;
        __u32			sa_restorer;	/* Another 32 bit pointer */
 };
  
-#define _SIGCONTEXT_NSIG_WORDS32    2 
-typedef struct {
-        __u32   sig[_SIGCONTEXT_NSIG_WORDS32];
-} sigset_t32;  
-
 typedef union sigval32 {
         int     sival_int;
         __u32   sival_ptr;
@@ -174,7 +167,7 @@
 
 struct sigcontext32
 {
-	__u32	oldmask[_SIGCONTEXT_NSIG_WORDS32];
+	__u32	oldmask[_COMPAT_NSIG_WORDS];
 	__u32	sregs;				/* pointer */
 };
 
@@ -183,7 +176,7 @@
 	__u32		sa_handler;		/* pointer */
 	__u32		sa_flags;
         __u32		sa_restorer;		/* pointer */
-	sigset_t32	sa_mask;        /* mask last for extensibility */
+	compat_sigset_t	sa_mask;        /* mask last for extensibility */
 };
 
 typedef struct {
@@ -198,7 +191,7 @@
 	__u32			uc_link;	/* pointer */	
 	stack_t32		uc_stack;
 	_sigregs32		uc_mcontext;
-	sigset_t32		uc_sigmask;	/* mask last for extensibility */
+	compat_sigset_t		uc_sigmask;	/* mask last for extensibility */
 };
 
 #endif /* _ASM_S390X_S390_H */
diff -Nru a/arch/s390x/kernel/signal32.c b/arch/s390x/kernel/signal32.c
--- a/arch/s390x/kernel/signal32.c	Thu Jan 16 18:23:05 2003
+++ b/arch/s390x/kernel/signal32.c	Thu Jan 16 18:23:05 2003
@@ -12,6 +12,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/compat.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -127,10 +128,10 @@
 }
 
 asmlinkage int
-sys32_rt_sigsuspend(struct pt_regs * regs,sigset_t32 *unewset, size_t sigsetsize)
+sys32_rt_sigsuspend(struct pt_regs * regs,compat_sigset_t *unewset, size_t sigsetsize)
 {
 	sigset_t saveset, newset;
-	sigset_t32 set32;
+	compat_sigset_t set32;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
 	if (sigsetsize != sizeof(sigset_t))
@@ -169,7 +170,7 @@
         int ret;
 
         if (act) {
-		old_sigset_t32 mask;
+		compat_old_sigset_t mask;
 		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
 		    __get_user((unsigned long)new_ka.sa.sa_handler, &act->sa_handler) ||
 		    __get_user((unsigned long)new_ka.sa.sa_restorer, &act->sa_restorer))
@@ -202,16 +203,16 @@
 {
 	struct k_sigaction new_ka, old_ka;
 	int ret;
-	sigset_t32 set32;
+	compat_sigset_t set32;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t32))
+	if (sigsetsize != sizeof(compat_sigset_t))
 		return -EINVAL;
 
 	if (act) {
 		ret = get_user((unsigned long)new_ka.sa.sa_handler, &act->sa_handler);
 		ret |= __copy_from_user(&set32, &act->sa_mask,
-					sizeof(sigset_t32));
+					sizeof(compat_sigset_t));
 		switch (_NSIG_WORDS) {
 		case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
 				| (((long)set32.sig[7]) << 32);
@@ -247,7 +248,7 @@
 		}
 		ret = put_user((unsigned long)old_ka.sa.sa_handler, &oact->sa_handler);
 		ret |= __copy_to_user(&oact->sa_mask, &set32,
-				      sizeof(sigset_t32));
+				      sizeof(compat_sigset_t));
 		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 	}
 
diff -Nru a/arch/s390x/kernel/wrapper32.S b/arch/s390x/kernel/wrapper32.S
--- a/arch/s390x/kernel/wrapper32.S	Thu Jan 16 18:23:07 2003
+++ b/arch/s390x/kernel/wrapper32.S	Thu Jan 16 18:23:07 2003
@@ -288,10 +288,10 @@
 
 #sys32_sigsuspend_wrapper		# done in sigsuspend_glue 
 
-	.globl  sys32_sigpending_wrapper 
-sys32_sigpending_wrapper:
-	llgtr	%r2,%r2			# old_sigset_emu31_t *
-	jg	sys32_sigpending	# branch to system call
+	.globl  compat_sys_sigpending_wrapper 
+compat_sys_sigpending_wrapper:
+	llgtr	%r2,%r2			# compat_old_sigset_t *
+	jg	compat_sys_sigpending	# branch to system call
 
 	.globl  sys32_sethostname_wrapper 
 sys32_sethostname_wrapper:
@@ -557,12 +557,12 @@
 	llgfr	%r4,%r4			# unsigned long
 	jg	sys_mprotect		# branch to system call
 
-	.globl  sys32_sigprocmask_wrapper 
-sys32_sigprocmask_wrapper:
+	.globl  compat_sys_sigprocmask_wrapper 
+compat_sys_sigprocmask_wrapper:
 	lgfr	%r2,%r2			# int
-	llgtr	%r3,%r3			# old_sigset_emu31 *
-	llgtr	%r4,%r4			# old_sigset_emu31 *
-	jg	sys32_sigprocmask		# branch to system call
+	llgtr	%r3,%r3			# compat_old_sigset_t *
+	llgtr	%r4,%r4			# compat_old_sigset_t *
+	jg	compat_sys_sigprocmask		# branch to system call
 
 	.globl  sys32_init_module_wrapper 
 sys32_init_module_wrapper:
diff -Nru a/arch/s390x/vmlinux.lds.S b/arch/s390x/vmlinux.lds.S
--- a/arch/s390x/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/s390x/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -1,6 +1,9 @@
 /*	
  * Written by Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
+
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
 OUTPUT_ARCH(s390:64-bit)
 ENTRY(_start)
@@ -17,22 +20,12 @@
 
   _etext = .;			/* End of text section */
 
-  .rodata : { *(.rodata) *(.rodata.*) }
-  .kstrtab : { *(.kstrtab) }
-
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  . = ALIGN(64);
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
+  RODATA
 	
 #ifdef CONFIG_SHARED_KERNEL
   . = ALIGN(1048576);		/* VM shared segments are 1MB aligned */
diff -Nru a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S
--- a/arch/sh/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/sh/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -3,6 +3,8 @@
  * Written by Niibe Yutaka
  */
 #include <linux/config.h>
+#include <asm-generic/vmlinux.lds.h>
+
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
 OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
 jiffies = jiffies_64;        
@@ -25,25 +27,13 @@
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x0009
-  .rodata : { *(.rodata) *(.rodata.*) }
-  .kstrtab : { *(.kstrtab) }
 
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-
-  __start___kallsyms = .;	/* All kernel symbols */
-  __kallsyms : { *(__kallsyms) }
-  __stop___kallsyms = .;
+  RODATA
 
   _etext = .;			/* End of text section */
 
diff -Nru a/arch/sparc/vmlinux.lds.S b/arch/sparc/vmlinux.lds.S
--- a/arch/sparc/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/sparc/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -1,4 +1,7 @@
 /* ld script to make SparcLinux kernel */
+
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
 OUTPUT_ARCH(sparc)
 ENTRY(_start)
@@ -13,8 +16,7 @@
   } =0
   _etext = .;
   PROVIDE (etext = .);
-  .rodata    : { *(.rodata) *(.rodata.*) }
-  .rodata1   : { *(.rodata1) }
+  RODATA
   .data    :
   {
     *(.data)
@@ -29,19 +31,6 @@
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
-
-  . = ALIGN(64);
-  __start___ksymtab = .;
-  __ksymtab  : { *(__ksymtab) }
-  __stop___ksymtab = .;
-
-  __start___gpl_ksymtab = .;
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-
-  __start___kallsyms = .;	/* All kernel symbols */
-  __kallsyms : { *(__kallsyms) }
-  __stop___kallsyms = .;
 
   . = ALIGN(4096);
   __init_begin = .;
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	Thu Jan 16 18:23:06 2003
+++ b/arch/sparc64/Kconfig	Thu Jan 16 18:23:06 2003
@@ -139,6 +139,39 @@
 	depends on SMP
 	default "64"
 
+config CPU_FREQ
+	bool "CPU Frequency scaling"
+	help
+	  Clock scaling allows you to change the clock speed of CPUs on the
+	  fly.  Currently there is only a sparc64 driver for UltraSPARC-III
+	  processors.
+
+	  For details, take a look at linux/Documentation/cpufreq. 
+
+	  If in doubt, say N.
+
+config CPU_FREQ_PROC_INTF
+	bool "/proc/cpufreq interface (DEPRECATED)"
+	depends on CPU_FREQ && PROC_FS
+	help
+	  This enables the /proc/cpufreq interface for controlling
+	  CPUFreq. Please note that it is recommended to use the sysfs
+	  interface instead (which is built automatically). 
+	  
+	  For details, take a look at linux/Documentation/cpufreq. 
+	  
+	  If in doubt, say N.
+
+config US3_FREQ
+	tristate "UltraSPARC-III CPU Frequency driver"
+	depends on CPU_FREQ
+	help
+	  This adds the CPUFreq driver for UltraSPARC-III processors.
+
+	  For details, take a look at linux/Documentation/cpufreq. 
+
+	  If in doubt, say N.
+
 # Identify this as a Sparc64 build
 config SPARC64
 	bool
diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig
--- a/arch/sparc64/defconfig	Thu Jan 16 18:23:05 2003
+++ b/arch/sparc64/defconfig	Thu Jan 16 18:23:05 2003
@@ -43,6 +43,9 @@
 CONFIG_SMP=y
 # CONFIG_PREEMPT is not set
 CONFIG_NR_CPUS=4
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_PROC_INTF=y
+CONFIG_US3_FREQ=m
 CONFIG_SPARC64=y
 CONFIG_HOTPLUG=y
 CONFIG_HAVE_DEC_LOCK=y
@@ -188,13 +191,13 @@
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_NFORCE is not set
 CONFIG_BLK_DEV_NS87415=y
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -644,6 +647,8 @@
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
@@ -710,11 +715,6 @@
 CONFIG_SOUND=m
 
 #
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
 # Advanced Linux Sound Architecture
 #
 CONFIG_SND=m
@@ -779,6 +779,11 @@
 CONFIG_SND_SUN_CS4231=m
 
 #
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
 # USB support
 #
 CONFIG_USB=y
@@ -878,7 +883,7 @@
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
 CONFIG_USB_SERIAL_EMPEG=m
 CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_VISOR is not set
 CONFIG_USB_SERIAL_IPAQ=m
 # CONFIG_USB_SERIAL_IR is not set
 CONFIG_USB_SERIAL_EDGEPORT=m
@@ -975,6 +980,7 @@
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
diff -Nru a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
--- a/arch/sparc64/kernel/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/sparc64/kernel/Makefile	Thu Jan 16 18:23:05 2003
@@ -21,6 +21,7 @@
 obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
 obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
 obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
 
 ifdef CONFIG_SUNOS_EMUL
   obj-y += sys_sunos32.o sunos_ioctl32.o
diff -Nru a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
--- a/arch/sparc64/kernel/setup.c	Thu Jan 16 18:23:05 2003
+++ b/arch/sparc64/kernel/setup.c	Thu Jan 16 18:23:05 2003
@@ -30,6 +30,7 @@
 #include <linux/console.h>
 #include <linux/root_dev.h>
 #include <linux/interrupt.h>
+#include <linux/cpu.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -677,3 +678,21 @@
 
 int serial_console;
 int stop_a_enabled = 1;
+
+static struct cpu *sparc64_cpus;
+
+static int __init topology_init(void)
+{
+	int i;
+
+	sparc64_cpus = kmalloc(NR_CPUS * sizeof(struct cpu), GFP_KERNEL);
+	if (!sparc64_cpus)
+		return -ENOMEM;
+	for (i = 0; i < NR_CPUS; i++) {
+		if (cpu_possible(i))
+			register_cpu(&sparc64_cpus[i], i, NULL);
+	}
+	return 0;
+}
+
+subsys_initcall(topology_init);
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	Thu Jan 16 18:23:06 2003
+++ b/arch/sparc64/kernel/sys_sparc32.c	Thu Jan 16 18:23:06 2003
@@ -2298,10 +2298,27 @@
 		__get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
 
 		clen64 = kcmsg32->cmsg_len;
-		copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
-			       clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
-		clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
-			  CMSG32_ALIGN(sizeof(struct cmsghdr32)));
+		if (kcmsg32->cmsg_level == SOL_SOCKET &&
+		    kcmsg32->cmsg_type == SO_TIMESTAMP) {
+			struct timeval tv;
+			struct compat_timeval *tv32;
+
+			if (clen64 != CMSG_LEN(sizeof(struct timeval))) {
+				kfree(workbuf);
+				goto fail;
+			}
+			copy_from_user(&tv, CMSG_DATA(ucmsg), sizeof(tv));
+			tv32 = (struct compat_timeval *) CMSG32_DATA(kcmsg32);
+			tv32->tv_sec = tv.tv_sec;
+			tv32->tv_usec = tv.tv_usec;
+			clen32 = sizeof(*tv32) +
+				CMSG32_ALIGN(sizeof(struct cmsghdr32));
+		} else {
+			copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
+				       clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
+			clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
+				  CMSG32_ALIGN(sizeof(struct cmsghdr32)));
+		}
 		kcmsg32->cmsg_len = clen32;
 
 		ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
diff -Nru a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/sparc64/kernel/us3_cpufreq.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,319 @@
+/* us3_cpufreq.c: UltraSPARC-III cpu frequency support
+ *
+ * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ *
+ * Many thanks to Dominik Brodowski for fixing up the cpufreq
+ * infrastructure in order to make this driver easier to implement.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/cpufreq.h>
+#include <linux/threads.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <asm/head.h>
+
+static struct cpufreq_driver *cpufreq_us3_driver;
+
+struct us3_freq_percpu_info {
+	struct cpufreq_frequency_table table[4];
+	unsigned long udelay_val_ref;
+	unsigned long clock_tick_ref;
+	unsigned int ref_freq;
+};
+
+/* Indexed by cpu number. */
+static struct us3_freq_percpu_info *us3_freq_table;
+
+/* UltraSPARC-III has three dividers: 1, 2, and 32.  These are controlled
+ * in the Safari config register.
+ */
+#define SAFARI_CFG_DIV_1	0x0000000000000000UL
+#define SAFARI_CFG_DIV_2	0x0000000040000000UL
+#define SAFARI_CFG_DIV_32	0x0000000080000000UL
+#define SAFARI_CFG_DIV_MASK	0x00000000C0000000UL
+
+static unsigned long read_safari_cfg(void)
+{
+	unsigned long ret;
+
+	__asm__ __volatile__("ldxa	[%%g0] %1, %0"
+			     : "=&r" (ret)
+			     : "i" (ASI_SAFARI_CONFIG));
+	return ret;
+}
+
+static void write_safari_cfg(unsigned long val)
+{
+	__asm__ __volatile__("stxa	%0, [%%g0] %1\n\t"
+			     "membar	#Sync"
+			     : /* no outputs */
+			     : "r" (val), "i" (ASI_SAFARI_CONFIG)
+			     : "memory");
+}
+
+#ifndef CONFIG_SMP
+extern unsigned long up_clock_tick;
+unsigned long clock_tick_ref;
+unsigned int ref_freq;
+#endif
+
+static __inline__ unsigned long get_clock_tick(unsigned int cpu)
+{
+#ifdef CONFIG_SMP
+	if (us3_freq_table[cpu].clock_tick_ref)
+		return us3_freq_table[cpu].clock_tick_ref;
+	return cpu_data[cpu].clock_tick;
+#else
+	if (clock_tick_ref)
+		return clock_tick_ref;
+	return up_clock_tick;
+#endif
+}
+
+static int us3_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
+				void *data)
+{
+	struct cpufreq_freqs *freq = data;
+	unsigned int cpu = freq->cpu;
+
+#ifdef CONFIG_SMP
+	if (!us3_freq_table[cpu].ref_freq) {
+		us3_freq_table[cpu].ref_freq = freq->old;
+		us3_freq_table[cpu].udelay_val_ref = cpu_data[cpu].udelay_val;
+		us3_freq_table[cpu].clock_tick_ref = cpu_data[cpu].clock_tick;
+	}
+	if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
+	    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) {
+		cpu_data[cpu].udelay_val =
+			cpufreq_scale(us3_freq_table[cpu].udelay_val_ref,
+				      us3_freq_table[cpu].ref_freq,
+				      freq->new);
+		cpu_data[cpu].clock_tick =
+			cpufreq_scale(us3_freq_table[cpu].clock_tick_ref,
+				      us3_freq_table[cpu].ref_freq,
+				      freq->new);
+	}
+#else
+	/* In the non-SMP case, kernel/cpufreq.c takes care of adjusting
+	 * loops_per_jiffy.
+	 */
+	if (!ref_freq) {
+		ref_freq = freq->old;
+		clock_tick_ref = up_clock_tick;
+	}
+	if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
+	    (val == CPUFREQ_POSTCHANGE && freq->old > freq->new))
+		up_clock_tick = cpufreq_scale(clock_tick_ref, ref_freq, freq->new);
+#endif
+
+	return 0;
+}
+
+static struct notifier_block us3_cpufreq_notifier_block = {
+	.notifier_call	= us3_cpufreq_notifier
+};
+
+static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg)
+{
+	unsigned long clock_tick = get_clock_tick(cpu);
+	unsigned long ret;
+
+	switch (safari_cfg & SAFARI_CFG_DIV_MASK) {
+	case SAFARI_CFG_DIV_1:
+		ret = clock_tick / 1;
+		break;
+	case SAFARI_CFG_DIV_2:
+		ret = clock_tick / 2;
+		break;
+	case SAFARI_CFG_DIV_32:
+		ret = clock_tick / 32;
+		break;
+	default:
+		BUG();
+	};
+
+	return ret;
+}
+
+static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
+{
+	unsigned long new_bits, new_freq, reg, cpus_allowed;
+	struct cpufreq_freqs freqs;
+
+	if (!cpu_online(cpu))
+		return;
+
+	cpus_allowed = current->cpus_allowed;
+	set_cpus_allowed(current, (1UL << cpu));
+
+	new_freq = get_clock_tick(cpu);
+	switch (index) {
+	case 0:
+		new_bits = SAFARI_CFG_DIV_1;
+		new_freq /= 1;
+		break;
+	case 1:
+		new_bits = SAFARI_CFG_DIV_2;
+		new_freq /= 2;
+		break;
+	case 2:
+		new_bits = SAFARI_CFG_DIV_32;
+		new_freq /= 32;
+		break;
+
+	default:
+		BUG();
+	};
+
+	reg = read_safari_cfg();
+
+	freqs.old = get_current_freq(cpu, reg);
+	freqs.new = new_freq;
+	freqs.cpu = cpu;
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	reg &= ~SAFARI_CFG_DIV_MASK;
+	reg |= new_bits;
+	write_safari_cfg(reg);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	set_cpus_allowed(current, cpus_allowed);
+}
+
+static int us3freq_setpolicy(struct cpufreq_policy *policy)
+{
+	unsigned int new_index = 0;
+
+	if (cpufreq_frequency_table_setpolicy(policy,
+					      &us3_freq_table[policy->cpu].table[0],
+					      &new_index))
+		return -EINVAL;
+
+	us3_set_cpu_divider_index(policy->cpu, new_index);
+
+	return 0;
+}
+
+static int us3freq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy,
+					      &us3_freq_table[policy->cpu].table[0]);
+}
+
+static int __init us3freq_cpu_init(struct cpufreq_policy *policy)
+{
+	unsigned int cpu = policy->cpu;
+	unsigned long clock_tick = get_clock_tick(cpu);
+	struct cpufreq_frequency_table *table =
+		&us3_freq_table[cpu].table[0];
+
+	table[0].index = 0;
+	table[0].frequency = clock_tick / 1;
+	table[1].index = 1;
+	table[1].frequency = clock_tick / 2;
+	table[2].index = 2;
+	table[2].frequency = clock_tick / 32;
+	table[3].index = 0;
+	table[3].frequency = CPUFREQ_TABLE_END;
+
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cpuinfo.transition_latency = 0;
+
+	return cpufreq_frequency_table_cpuinfo(policy, table);
+}
+
+static int __exit us3freq_cpu_exit(struct cpufreq_policy *policy)
+{
+	if (cpufreq_us3_driver)
+		us3_set_cpu_divider_index(policy->cpu, 0);
+
+	return 0;
+}
+
+static int __init us3freq_init(void)
+{
+	unsigned long manuf, impl, ver;
+	int ret;
+
+	__asm__("rdpr %%ver, %0" : "=r" (ver));
+	manuf = ((ver >> 48) & 0xffff);
+	impl  = ((ver >> 32) & 0xffff);
+
+	if (manuf == CHEETAH_MANUF &&
+	    (impl == CHEETAH_IMPL || impl == CHEETAH_PLUS_IMPL)) {
+		struct cpufreq_driver *driver;
+
+		cpufreq_register_notifier(&us3_cpufreq_notifier_block,
+					  CPUFREQ_TRANSITION_NOTIFIER);
+
+		ret = -ENOMEM;
+		driver = kmalloc(sizeof(struct cpufreq_driver), GFP_KERNEL);
+		if (!driver)
+			goto err_out;
+		memset(driver, 0, sizeof(*driver));
+
+		us3_freq_table = kmalloc(
+			(NR_CPUS * sizeof(struct us3_freq_percpu_info)),
+			GFP_KERNEL);
+		if (!us3_freq_table)
+			goto err_out;
+
+		memset(us3_freq_table, 0,
+		       (NR_CPUS * sizeof(struct us3_freq_percpu_info)));
+
+		driver->verify = us3freq_verify;
+		driver->setpolicy = us3freq_setpolicy;
+		driver->init = us3freq_cpu_init;
+		driver->exit = us3freq_cpu_exit;
+		strcpy(driver->name, "UltraSPARC-III");
+
+		cpufreq_us3_driver = driver;
+		ret = cpufreq_register_driver(driver);
+		if (ret)
+			goto err_out;
+
+		return 0;
+
+err_out:
+		if (driver) {
+			kfree(driver);
+			cpufreq_us3_driver = NULL;
+		}
+		if (us3_freq_table) {
+			kfree(us3_freq_table);
+			us3_freq_table = NULL;
+		}
+		cpufreq_unregister_notifier(&us3_cpufreq_notifier_block,
+					    CPUFREQ_TRANSITION_NOTIFIER);
+		return ret;
+	}
+
+	return -ENODEV;
+}
+
+static void __exit us3freq_exit(void)
+{
+	if (cpufreq_us3_driver) {
+		cpufreq_unregister_driver(cpufreq_us3_driver);
+		cpufreq_unregister_notifier(&us3_cpufreq_notifier_block,
+					    CPUFREQ_TRANSITION_NOTIFIER);
+
+		kfree(cpufreq_us3_driver);
+		cpufreq_us3_driver = NULL;
+		kfree(us3_freq_table);
+		us3_freq_table = NULL;
+	}
+}
+
+MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
+MODULE_DESCRIPTION("cpufreq driver for UltraSPARC-III");
+MODULE_LICENSE("GPL");
+
+module_init(us3freq_init);
+module_exit(us3freq_exit);
diff -Nru a/arch/sparc64/vmlinux.lds.S b/arch/sparc64/vmlinux.lds.S
--- a/arch/sparc64/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
+++ b/arch/sparc64/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
@@ -1,4 +1,7 @@
 /* ld script to make UltraLinux kernel */
+
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", "elf64-sparc")
 OUTPUT_ARCH(sparc:v9a)
 ENTRY(_start)
@@ -16,8 +19,9 @@
   } =0
   _etext = .;
   PROVIDE (etext = .);
-  .rodata    : { *(.rodata) *(.rodata.*) }
-  .rodata1   : { *(.rodata1) }
+
+  RODATA
+
   .data    :
   {
     *(.data)
@@ -35,17 +39,6 @@
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  . = ALIGN(64);
-  __start___ksymtab = .;
-  __ksymtab  : { *(__ksymtab) }
-  __stop___ksymtab = .;
-  __start___gpl_ksymtab = .;
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-  __kstrtab  : { *(.kstrtab) }
-  __start___kallsyms = .;	/* All kernel symbols */
-  __kallsyms : { *(__kallsyms) }
-  __stop___kallsyms = .;
   . = ALIGN(8192);
   __init_begin = .;
   .init.text : { *(.init.text) }
diff -Nru a/arch/um/uml.lds.S b/arch/um/uml.lds.S
--- a/arch/um/uml.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/um/uml.lds.S	Thu Jan 16 18:23:05 2003
@@ -1,3 +1,5 @@
+#include <asm-generic/vmlinux.lds.h>
+	
 OUTPUT_FORMAT(ELF_FORMAT)
 OUTPUT_ARCH(ELF_ARCH)
 ENTRY(_start)
@@ -31,20 +33,15 @@
     *(.gnu.warning)
     *(.gnu.linkonce.t*)
   }
-  .kstrtab : { *(.kstrtab) }
 
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  . = ALIGN(64);
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
+  RODATA
+
   .fini      : { *(.fini)    } =0x9090
-  .rodata    : { *(.rodata) *(.gnu.linkonce.r*) }
-  .rodata1   : { *(.rodata1) }
   _etext = .;
   PROVIDE (etext = .);
 
diff -Nru a/arch/v850/vmlinux.lds.S b/arch/v850/vmlinux.lds.S
--- a/arch/v850/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
+++ b/arch/v850/vmlinux.lds.S	Thu Jan 16 18:23:06 2003
@@ -12,6 +12,7 @@
  */
 
 #include <linux/config.h>
+#include <asm-generic/vmlinux.lds.h>
 
 
 /* The following macros contain the usual definitions for various data areas.
@@ -38,9 +39,7 @@
 			*(.text.lock)					      \
 			*(.exitcall.exit)				      \
 		__real_etext = . ;	/* There may be data after here.  */  \
-			*(.rodata)					      \
-		. = ALIGN (0x4) ;					      \
-			*(.kstrtab)					      \
+		RODATA                                                        \
 		. = ALIGN (4) ;						      \
 		    	*(.call_table_data)				      \
 			*(.call_table_text)				      \
@@ -48,12 +47,6 @@
 		___start___ex_table = . ;				      \
 			*(__ex_table)					      \
 		___stop___ex_table = . ;				      \
-		___start___ksymtab = . ;/* Kernel symbol table.  */	      \
-			*(__ksymtab)					      \
-		___stop___ksymtab = . ;					      \
-		___start___gpl_ksymtab = . ; /* Same for GPL symbols.  */     \
-			*(__gpl_ksymtab)				      \
-		___stop___gpl_ksymtab = . ;				      \
 		. = ALIGN (4) ;						      \
 		__etext = . ;
 
diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
--- a/arch/x86_64/Kconfig	Thu Jan 16 18:23:06 2003
+++ b/arch/x86_64/Kconfig	Thu Jan 16 18:23:06 2003
@@ -13,8 +13,8 @@
 	bool
 	default y
 	help
-	  Port to the x86-64 architecture. x86-64 is an 64bit extension to the
-	  classical 32bit x86 architecture. For details see http://www.x86-64.org
+	  Port to the x86-64 architecture. x86-64 is a 64-bit extension to the
+	  classical 32-bit x86 architecture. For details see http://www.x86-64.org
 
 config X86
 	bool
@@ -68,7 +68,7 @@
 	  for kernel debugging when your machine crashes very early before
 	  the console code is initialized. For normal operation it is not
 	  recommended because it looks ugly and doesn't cooperate with 
-	  klogd/syslogd or the X server.You should normally N here, unless
+	  klogd/syslogd or the X server. You should normally N here, unless
 	  you want to debug such a crash.
 	  
 
@@ -89,8 +89,8 @@
 	bool "AMD-Hammer"
 	help
 	  Support for AMD Clawhammer/Sledgehammer CPUs. Only choice for x86-64
-	  currently so you should chose this if you want a x86-64 kernel. In fact
-	  you will have no other choice than to chose this.
+	  currently so you should choose this if you want a x86-64 kernel. In fact
+	  you will have no other choice than to choose this.
 
 config GENERIC_CPU
 	bool "Generic-x86-64"
@@ -165,7 +165,7 @@
 
 	  This code has a reasonably generic interface so that similar
 	  control registers on other processors can be easily supported
-	  as well:
+	  as well.
 
 	  Saying Y here also fixes a problem with buggy SMP BIOSes which only
 	  set the MTRRs for the boot CPU and not for the secondary CPUs. This
@@ -208,7 +208,7 @@
 	  See also the <file:Documentation/smp.tex>,
 	  <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
 	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
-	  <http://www.linuxdoc.org/docs.html#howto>.
+	  <http://www.tldp.org/docs.html#howto>.
 
 	  If you don't know what to do here, say N.
 
@@ -252,7 +252,7 @@
 	bool "IOMMU support"
 	help
 	  Support the K8 IOMMU. Needed to run systems with more than 4GB of memory
-	  properly with 32bit devices. You should probably turn this on.
+	  properly with 32-bit devices. You should probably turn this on.
 	  The iommu can be turned off at runtime with the iommu=off parameter.
 
 config DUMMY_IOMMU
@@ -261,7 +261,7 @@
 	default y
 	help
 	  Don't use IOMMU code. This will cause problems when you have more than 4GB 
-	  of memory and any 32bit devices. Don't turn on unless you know what you
+	  of memory and any 32-bit devices. Don't turn on unless you know what you
 	  are doing.
 
 config X86_MCE
@@ -287,7 +287,7 @@
 	  page on the WWW at
 	  <http://www.cs.utexas.edu/users/kharker/linux-laptop/> and the
 	  Battery Powered Linux mini-HOWTO, available from
-	  <http://www.linuxdoc.org/docs.html#howto>.
+	  <http://www.tldp.org/docs.html#howto>.
 
 	  Note that, even if you say N here, Linux on the x86 architecture
 	  will issue the hlt instruction if nothing is to be done, thereby
@@ -297,27 +297,27 @@
 	bool "Software Suspend (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && PM
 	---help---
-	  Enable the possibilty of suspendig machine. It doesn't need APM.
+	  Enable the possibilty of suspending the machine. It doesn't need APM.
 	  You may suspend your machine by 'swsusp' or 'shutdown -z <time>' 
 	  (patch for sysvinit needed). 
 
-	  It creates an image which is saved in your active swaps. By the next
-	  booting the, pass 'resume=/path/to/your/swap/file' and kernel will 
-	  detect the saved image, restore the memory from
-	  it and then it continues to run as before you've suspended.
-	  If you don't want the previous state to continue use the 'noresume'
-	  kernel option. However note that your partitions will be fsck'd and
+	  It creates an image which is saved in your active swaps. On the next
+	  boot, pass the 'resume=/path/to/your/swap/file' option and the kernel
+	  will detect the saved image, restore the memory from
+	  it, and then continue to run as before you suspended.
+	  If you don't want the previous state to continue, use the 'noresume'
+	  kernel option. However, note that your partitions will be fsck'd and
 	  you must re-mkswap your swap partitions/files.
 
 	  Right now you may boot without resuming and then later resume but
-	  in meantime you cannot use those swap partitions/files which were
+	  in the meantime you cannot use those swap partitions/files which were
 	  involved in suspending. Also in this case there is a risk that buffers
 	  on disk won't match with saved ones.
 
-	  SMP is supported ``as-is''. There's a code for it but doesn't work.
-	  There have been problems reported relating SCSI.
+	  SMP is supported ``as-is''. There's code for it but doesn't work.
+	  There have been problems reported relating to SCSI.
 
-	  This option is about getting stable. However there is still some
+	  This option is close to getting stable. However there is still some
 	  absence of features.
 
 	  For more information take a look at Documentation/swsusp.txt.
@@ -338,7 +338,7 @@
 	  VESA. If you have PCI, say Y, otherwise N.
 
 	  The PCI-HOWTO, available from
-	  <http://www.linuxdoc.org/docs.html#howto>, contains valuable
+	  <http://www.tldp.org/docs.html#howto>, contains valuable
 	  information about which PCI hardware does work under Linux and which
 	  doesn't.
 
@@ -357,8 +357,8 @@
 	  the system is running, and be able to use them quickly.  In many
 	  cases, the devices can likewise be unplugged at any time too.
 
-	  One well known example of this is PCMCIA- or PC-cards, credit-card
-	  size devices such as network cards, modems or hard drives which are
+	  One well-known example of this is PCMCIA- or PC-cards, credit-card
+	  size devices such as network cards, modems, or hard drives which are
 	  plugged into slots found on all modern laptop computers.  Another
 	  example, used on modern desktops as well as laptops, is USB.
 
@@ -390,7 +390,7 @@
 
 	  You have two choices here: ELF and A.OUT. Selecting ELF will make
 	  /proc/kcore appear in ELF core format as defined by the Executable
-	  and Linking Format specification. Selecting A.OUT will choose the
+	  and Linkable Format specification. Selecting A.OUT will choose the
 	  old "a.out" format which may be necessary for some old versions
 	  of binutils or on some architectures.
 
@@ -416,7 +416,7 @@
 	  want to say Y here.
 
 	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.linuxdoc.org/docs.html#howto>.
+	  <http://www.tldp.org/docs.html#howto>.
 
 	  If you find that after upgrading from Linux kernel 1.2 and saying Y
 	  here, you still can't run any ELF binaries (they just crash), then
@@ -438,7 +438,7 @@
 	  programs that need an interpreter to run like Java, Python or
 	  Emacs-Lisp. It's also useful if you often run DOS executables under
 	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.linuxdoc.org/docs.html#howto>). Once you have
+	  <http://www.tldp.org/docs.html#howto>). Once you have
 	  registered such a binary class with the kernel, you can start one of
 	  those programs simply by typing in its name at a shell prompt; Linux
 	  will automatically feed it to the correct interpreter.
@@ -458,8 +458,8 @@
 config IA32_EMULATION
 	bool "IA32 Emulation"
 	help
-	  Include code to run 32bit programs under an 64bit kernel. You should likely
-	  turn this on, unless you're 100% sure that you don't have any 32bit programs
+	  Include code to run 32-bit programs under a 64-bit kernel. You should likely
+	  turn this on, unless you're 100% sure that you don't have any 32-bit programs
 	  left.
 
 config COMPAT
@@ -507,13 +507,13 @@
 	  ATA Packet Interface (ATAPI) is a protocol used by EIDE tape and
 	  CD-ROM drives, similar in many respects to the SCSI protocol.
 
-	  SMART IDE (Self Monitoring, Analysis and Reporting Technology) was
+	  SMART IDE (Self-Monitoring, Analysis and Reporting Technology) was
 	  designed in order to prevent data corruption and disk crash by
-	  detecting pre hardware failure conditions (heat, access time, and
+	  detecting pre-hardware failure conditions (heat, access time, and
 	  the like...). Disks built since June 1995 may follow this standard.
-	  The kernel itself don't manage this; however there are quite a
+	  The kernel itself doesn't manage this; however there are quite a
 	  number of user programs such as smart that can query the status of
-	  SMART parameters disk.
+	  SMART parameters from disk drives.
 
 	  If you want to compile this driver as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want),
@@ -563,7 +563,7 @@
 
 source "drivers/ieee1394/Kconfig"
 
-#Currently not 64bit safe
+#Currently not 64-bit safe
 #source drivers/message/i2o/Config.in
 source "net/Kconfig"
 
@@ -600,11 +600,12 @@
 	  interrupt and DMA channel), because you will be asked for it.
 
 	  You want to read the Sound-HOWTO, available from
-	  <http://www.linuxdoc.org/docs.html#howto>. General information about
+	  <http://www.tldp.org/docs.html#howto>. General information about
 	  the modular sound system is contained in the files
 	  <file:Documentation/sound/Introduction>.  The file
-	  <file:Documentation/sound/README.OSS> contains some slightly
-	  outdated but still useful information as well.
+	  <file:Documentation/sound/oss/README.OSS> contains some slightly
+	  outdated but still useful information as well.  Newer sound
+	  driver documentation is found in <file:Documentation/sound/alsa/*>.
 
 	  If you have a PnP sound card and you want to configure it at boot
 	  time using the ISA PnP tools (read
@@ -613,7 +614,7 @@
 	  inserted in and removed from the running kernel whenever you want)
 	  and load that module after the PnP configuration is finished.  To do
 	  this, say M here and read <file:Documentation/modules.txt> as well
-	  as <file:Documentation/sound/README.modules>; the module will be
+	  as <file:Documentation/sound/oss/README.modules>; the module will be
 	  called soundcore.o.
 
 	  I'm told that even without a sound card, you can make your computer
diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile
--- a/arch/x86_64/Makefile	Thu Jan 16 18:23:06 2003
+++ b/arch/x86_64/Makefile	Thu Jan 16 18:23:06 2003
@@ -54,35 +54,31 @@
 core-y					+= arch/x86_64/kernel/ arch/x86_64/mm/
 core-$(CONFIG_IA32_EMULATION)		+= arch/x86_64/ia32/
 drivers-$(CONFIG_PCI)			+= arch/x86_64/pci/
-# FIXME: is drivers- right ?
 drivers-$(CONFIG_OPROFILE)		+= arch/x86_64/oprofile/
 
-makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/x86_64/boot $(1)
+boot := arch/x86_64/boot
 
-.PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \
-		clean archclean archmrproper
+.PHONY: bzImage bzlilo bzdisk install archmrproper
 
-BOOTIMAGE=arch/x86_64/boot/bzImage
-zImage zlilo zdisk: BOOTIMAGE=arch/x86_64/boot/zImage
+#Default target when executing "make"
+all: bzImage
 
-zImage bzImage: vmlinux
-	$(call makeboot,$(BOOTIMAGE))
+BOOTIMAGE                     := arch/x86_64/boot/bzImage
 
-compressed: zImage
+bzImage: vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
 
-zlilo bzlilo: vmlinux
-	$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zlilo)
+bzlilo: vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zlilo
 
-zdisk bzdisk: vmlinux
-	$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) zdisk)
+bzdisk: vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zdisk
 
 install: vmlinux
-	$(call makeboot,BOOTIMAGE=$(BOOTIMAGE) install)
+	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
 
 archclean:
-	$(Q)$(MAKE) $(clean)=arch/i386/boot
-
-archmrproper:
+	$(Q)$(MAKE) $(clean)=$(boot)
 
 prepare: include/asm-$(ARCH)/offset.h
 
@@ -90,10 +86,10 @@
 				   include/config/MARKER
 
 include/asm-$(ARCH)/offset.h.tmp: arch/$(ARCH)/kernel/asm-offsets.s
-	@$(generate-asm-offsets.h) < $< > $@
 
-include/asm-$(ARCH)/offset.h: include/asm-$(ARCH)/offset.h.tmp
+include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/asm-offsets.s
 	@echo -n '  Generating $@'
+	@$(generate-asm-offsets.h) < $< > $@.tmp
 	@$(update-if-changed)
 
 CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \
diff -Nru a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
--- a/arch/x86_64/boot/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/boot/Makefile	Thu Jan 16 18:23:05 2003
@@ -26,16 +26,14 @@
 #RAMDISK := -DRAMDISK=512
 
 EXTRA_TARGETS	:= vmlinux.bin bootsect bootsect.o \
-		   setup setup.o zImage bzImage
+		   setup setup.o bzImage
 
-CFLAGS += -m32
+EXTRA_CFLAGS := -m32
 
 host-progs	:= tools/build
-subdir-		:= compressed	#Let make clean descend in compressed/
+subdir-		:= compressed/	#Let make clean descend in compressed/
 # ---------------------------------------------------------------------------
 
-$(obj)/zImage:  IMAGE_OFFSET := 0x1000
-$(obj)/zImage:  EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK)
 $(obj)/bzImage: IMAGE_OFFSET := 0x100000
 $(obj)/bzImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
 $(obj)/bzImage: BUILDFLAGS   := -b
@@ -44,7 +42,7 @@
 cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
 	    $(obj)/vmlinux.bin $(ROOT_DEV) > $@
 
-$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
+$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
 			      $(obj)/vmlinux.bin $(obj)/tools/build FORCE
 	$(call if_changed,image)
 	@echo 'Kernel: $@ is ready'
diff -Nru a/arch/x86_64/boot/compressed/Makefile b/arch/x86_64/boot/compressed/Makefile
--- a/arch/x86_64/boot/compressed/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/boot/compressed/Makefile	Thu Jan 16 18:23:05 2003
@@ -11,7 +11,7 @@
 
 # cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
 # -m32
-CFLAGS := -m32 -D__KERNEL__ -I$(TOPDIR)/include -O2  
+CFLAGS := -m32 -D__KERNEL__ -Iinclude -O2  
 LDFLAGS := -m elf_i386
 
 LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 -m elf_i386
diff -Nru a/arch/x86_64/defconfig b/arch/x86_64/defconfig
--- a/arch/x86_64/defconfig	Thu Jan 16 18:23:06 2003
+++ b/arch/x86_64/defconfig	Thu Jan 16 18:23:06 2003
@@ -19,10 +19,16 @@
 #
 # General setup
 #
-CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+# CONFIG_LOG_BUF_SHIFT_17 is not set
+CONFIG_LOG_BUF_SHIFT_16=y
+# CONFIG_LOG_BUF_SHIFT_15 is not set
+# CONFIG_LOG_BUF_SHIFT_14 is not set
+# CONFIG_LOG_BUF_SHIFT_13 is not set
+# CONFIG_LOG_BUF_SHIFT_12 is not set
+CONFIG_LOG_BUF_SHIFT=16
 
 #
 # Loadable module support
@@ -85,6 +91,7 @@
 #
 CONFIG_PCI=y
 CONFIG_PCI_DIRECT=y
+# CONFIG_PCI_LEGACY_PROC is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_HOTPLUG is not set
 
@@ -163,15 +170,14 @@
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 CONFIG_BLK_DEV_AMD74XX=y
-# CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_NFORCE is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -212,6 +218,11 @@
 # CONFIG_IEEE1394 is not set
 
 #
+# Networking support
+#
+CONFIG_NET=y
+
+#
 # Networking options
 #
 CONFIG_PACKET=y
@@ -263,10 +274,6 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-
-#
-# Network device support
-#
 CONFIG_NETDEVICES=y
 
 #
@@ -286,8 +293,6 @@
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
 
 #
 # Tulip family network device support
@@ -296,6 +301,7 @@
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
+CONFIG_AMD8111_ETH=y
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_B44 is not set
 # CONFIG_DGRS is not set
@@ -315,7 +321,6 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -343,7 +348,6 @@
 #
 # Token Ring devices (depends on LLC=y)
 #
-# CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
 
@@ -446,12 +450,25 @@
 # CONFIG_I2C is not set
 
 #
+# I2C Hardware Sensors Mainboard support
+#
+
+#
+# I2C Hardware Sensors Chip support
+#
+
+#
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
@@ -470,7 +487,6 @@
 # CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_AGP_GART is not set
-# CONFIG_AGP3 is not set
 # CONFIG_DRM is not set
 # CONFIG_MWAVE is not set
 CONFIG_RAW_DRIVER=y
@@ -544,6 +560,7 @@
 # CONFIG_NFSD_V4 is not set
 CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_GSS is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
diff -Nru a/arch/x86_64/ia32/fpu32.c b/arch/x86_64/ia32/fpu32.c
--- a/arch/x86_64/ia32/fpu32.c	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/ia32/fpu32.c	Thu Jan 16 18:23:05 2003
@@ -80,9 +80,9 @@
 	int err; 
 	__u32 v;
 
-	err = __get_user(fxsave->cwd, (u16 *)&buf->cw); 
-	err |= __get_user(fxsave->swd, (u16 *)&buf->sw);
-	err |= __get_user(fxsave->twd, (u16 *)&buf->tag);
+	err = __get_user(fxsave->cwd, &buf->cw); 
+	err |= __get_user(fxsave->swd, &buf->sw);
+	err |= __get_user(fxsave->twd, &buf->tag);
 	fxsave->twd = twd_i387_to_fxsr(fxsave->twd);
 	err |= __get_user(fxsave->rip, &buf->ipoff); 
 	err |= __get_user(fxsave->rdp, &buf->dataoff); 
diff -Nru a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
--- a/arch/x86_64/ia32/ia32_signal.c	Thu Jan 16 18:23:07 2003
+++ b/arch/x86_64/ia32/ia32_signal.c	Thu Jan 16 18:23:07 2003
@@ -31,6 +31,7 @@
 #include <asm/user32.h>
 #include <asm/sigcontext32.h>
 #include <asm/fpu32.h>
+#include <asm/proto.h>
 
 #define ptr_to_u32(x) ((u32)(u64)(x))	/* avoid gcc warning */ 
 
@@ -405,18 +406,30 @@
 	if (err)
 		goto give_sigsegv;
 
-	/* Set up to return from userspace.  If provided, use a stub
-	   already in userspace.  */
-	if (ka->sa.sa_flags & SA_RESTORER) {
-		err |= __put_user((u32)(u64)ka->sa.sa_restorer, &frame->pretcode);
-	} else {
-		err |= __put_user((u32)(u64)frame->retcode, &frame->pretcode);
-		/* This is popl %eax ; movl $,%eax ; int $0x80 */
-		err |= __put_user((u16)0xb858, (short *)(frame->retcode+0));
-		err |= __put_user((u32)__NR_ia32_sigreturn, (int *)(frame->retcode+2));
-		err |= __put_user((u16)0x80cd, (short *)(frame->retcode+6));
+	/* Return stub is in 32bit vsyscall page */
+	{ 
+		void *restorer = syscall32_page + 32; 
+		if (ka->sa.sa_flags & SA_RESTORER)
+			restorer = ka->sa.sa_restorer;       
+		err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
+	}
+	/* These are actually not used anymore, but left because some 
+	   gdb versions depend on them as a marker. */
+	{ 
+		/* copy_to_user optimizes that into a single 8 byte store */
+		static const struct { 
+			u16 poplmovl;
+			u32 val;
+			u16 int80;    
+			u16 pad; 
+		} __attribute__((packed)) code = { 
+			0xb858,		 /* popl %eax ; movl $...,%eax */
+			__NR_ia32_sigreturn,   
+			0x80cd,		/* int $0x80 */
+			0,
+		}; 
+		err |= __copy_to_user(frame->retcode, &code, 8); 
 	}
-
 	if (err)
 		goto give_sigsegv;
 
@@ -486,18 +499,33 @@
 	if (err)
 		goto give_sigsegv;
 
-	/* Set up to return from userspace.  If provided, use a stub
-	   already in userspace.  */
-	if (ka->sa.sa_flags & SA_RESTORER) {
-		err |= __put_user((u32)(u64)ka->sa.sa_restorer, &frame->pretcode);
-	} else {
-		err |= __put_user(ptr_to_u32(frame->retcode), &frame->pretcode);
-		/* This is movl $,%eax ; int $0x80 */
-		err |= __put_user(0xb8, (char *)(frame->retcode+0));
-		err |= __put_user((u32)__NR_ia32_rt_sigreturn, (int *)(frame->retcode+1));
-		err |= __put_user(0x80cd, (short *)(frame->retcode+5));
+	
+	{ 
+		void *restorer = syscall32_page + 32; 
+		if (ka->sa.sa_flags & SA_RESTORER)
+			restorer = ka->sa.sa_restorer;       
+		err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
 	}
 
+	/* This is movl $,%eax ; int $0x80 */
+	/* Not actually used anymore, but left because some gdb versions
+	   need it. */ 
+	{ 
+		/* __copy_to_user optimizes that into a single 8 byte store */
+		static const struct { 
+			u8 movl; 
+			u32 val; 
+			u16 int80; 
+			u16 pad;
+			u8  pad2;				
+		} __attribute__((packed)) code = { 
+			0xb8,
+			__NR_ia32_rt_sigreturn,
+			0x80cd,
+			0,
+		}; 
+		err |= __copy_to_user(frame->retcode, &code, 8); 
+	} 
 	if (err)
 		goto give_sigsegv;
 
diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
--- a/arch/x86_64/ia32/ia32entry.S	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/ia32/ia32entry.S	Thu Jan 16 18:23:05 2003
@@ -248,7 +248,7 @@
 	.quad sys_brk		/* 45 */
 	.quad sys_setgid16
 	.quad sys_getgid16
-	.quad ni_syscall	/* signal */
+	.quad sys_signal
 	.quad sys_geteuid16
 	.quad sys_getegid16	/* 50 */
 	.quad sys_acct
@@ -299,8 +299,8 @@
 	.quad sys_getpriority
 	.quad sys_setpriority
 	.quad ni_syscall			/* old profil syscall holder */
-	.quad sys32_statfs
-	.quad sys32_fstatfs		/* 100 */
+	.quad compat_sys_statfs
+	.quad compat_sys_fstatfs		/* 100 */
 	.quad sys_ioperm
 	.quad sys32_socketcall
 	.quad sys_syslog
diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
--- a/arch/x86_64/ia32/sys_ia32.c	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/ia32/sys_ia32.c	Thu Jan 16 18:23:05 2003
@@ -404,58 +404,6 @@
 	return 0;
 }
 
-static int
-put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
-{
-	if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct statfs32)) ||
-	    __put_user (kbuf->f_type, &ubuf->f_type) ||
-	    __put_user (kbuf->f_bsize, &ubuf->f_bsize) ||
-	    __put_user (kbuf->f_blocks, &ubuf->f_blocks) ||
-	    __put_user (kbuf->f_bfree, &ubuf->f_bfree) ||
-	    __put_user (kbuf->f_bavail, &ubuf->f_bavail) ||
-	    __put_user (kbuf->f_files, &ubuf->f_files) ||
-	    __put_user (kbuf->f_ffree, &ubuf->f_ffree) ||
-	    __put_user (kbuf->f_namelen, &ubuf->f_namelen) ||
-	    __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
-	    __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]))
-		return -EFAULT;
-	return 0;
-}
-
-extern asmlinkage long sys_statfs(const char * path, struct statfs * buf);
-
-asmlinkage long
-sys32_statfs(const char * path, struct statfs32 *buf)
-{
-	int ret;
-	struct statfs s;
-	mm_segment_t old_fs = get_fs();
-	
-	set_fs (KERNEL_DS);
-	ret = sys_statfs((const char *)path, &s);
-	set_fs (old_fs);
-	if (put_statfs(buf, &s))
-		return -EFAULT;
-	return ret;
-}
-
-extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
-
-asmlinkage long
-sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
-{
-	int ret;
-	struct statfs s;
-	mm_segment_t old_fs = get_fs();
-	
-	set_fs (KERNEL_DS);
-	ret = sys_fstatfs(fd, &s);
-	set_fs (old_fs);
-	if (put_statfs(buf, &s))
-		return -EFAULT;
-	return ret;
-}
-
 static inline long
 get_tv32(struct timeval *o, struct compat_timeval *i)
 {
diff -Nru a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c
--- a/arch/x86_64/ia32/syscall32.c	Thu Jan 16 18:23:06 2003
+++ b/arch/x86_64/ia32/syscall32.c	Thu Jan 16 18:23:06 2003
@@ -1,4 +1,4 @@
-/* Copyright 2002 Andi Kleen, SuSE Labs */
+/* Copyright 2002,2003 Andi Kleen, SuSE Labs */
 
 /* vsyscall handling for 32bit processes. Map a stub page into it 
    on demand because 32bit cannot reach the kernel's fixmaps */
@@ -8,8 +8,10 @@
 #include <linux/kernel.h>
 #include <linux/gfp.h>
 #include <linux/init.h>
+#include <linux/stringify.h>
 #include <asm/proto.h>
 #include <asm/tlbflush.h>
+#include <asm/ia32_unistd.h>
 
 /* 32bit SYSCALL stub mapped into user space. */ 
 asm("	.code32\n"
@@ -20,11 +22,26 @@
     "	popl  %ebp\n"
     "	ret\n"
     "syscall32_end:\n"
+
+    /* signal trampolines */
+
+    "sig32_rt_tramp:\n"
+    "	movl $"  __stringify(__NR_ia32_rt_sigreturn) ",%eax\n"
+    "   int $0x80\n"
+    "sig32_rt_tramp_end:\n"
+
+    "sig32_tramp:\n"
+    "	popl %eax\n"
+    "	movl $"  __stringify(__NR_ia32_sigreturn) ",%eax\n"
+    "	int $0x80\n"
+    "sig32_tramp_end:\n"
     "	.code64\n"); 
 
 extern unsigned char syscall32[], syscall32_end[];
+extern unsigned char sig32_rt_tramp[], sig32_rt_tramp_end[];
+extern unsigned char sig32_tramp[], sig32_tramp_end[];
 
-static unsigned long syscall32_page; 
+char *syscall32_page; 
 
 /* RED-PEN: This knows too much about high level VM */ 
 /* Alternative would be to generate a vma with appropiate backing options
@@ -54,11 +71,16 @@
 
 static int __init init_syscall32(void)
 { 
-	syscall32_page = get_zeroed_page(GFP_KERNEL); 
+	syscall32_page = (void *)get_zeroed_page(GFP_KERNEL); 
 	if (!syscall32_page) 
 		panic("Cannot allocate syscall32 page"); 
 	SetPageReserved(virt_to_page(syscall32_page));
-	memcpy((void *)syscall32_page, syscall32, syscall32_end - syscall32);
+	memcpy(syscall32_page, syscall32, syscall32_end - syscall32);
+	memcpy(syscall32_page + 32, sig32_rt_tramp, 
+	       sig32_rt_tramp_end - sig32_rt_tramp);
+	memcpy(syscall32_page + 64, sig32_tramp, 
+	       sig32_tramp_end - sig32_tramp);	
+	return 0;
 } 
 	
 __initcall(init_syscall32); 
diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
--- a/arch/x86_64/kernel/Makefile	Thu Jan 16 18:23:06 2003
+++ b/arch/x86_64/kernel/Makefile	Thu Jan 16 18:23:06 2003
@@ -3,7 +3,7 @@
 #
 
 EXTRA_TARGETS 	:= head.o head64.o init_task.o
-
+EXTRA_AFLAGS  := -traditional
 export-objs     := x8664_ksyms.o pci-gart.o pci-dma.o
 
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o \
@@ -32,4 +32,3 @@
 
 clean-files += bootflag.c
 
-EXTRA_AFLAGS := -traditional
diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
--- a/arch/x86_64/kernel/apic.c	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/kernel/apic.c	Thu Jan 16 18:23:05 2003
@@ -39,7 +39,7 @@
 
 int prof_multiplier[NR_CPUS] = { 1, };
 int prof_old_multiplier[NR_CPUS] = { 1, };
-int prof_counter[NR_CPUS] = { 1, };
+DEFINE_PER_CPU(int, prof_counter) =  1;
 
 int get_maxlvt(void)
 {
@@ -901,7 +901,7 @@
 
 	x86_do_profile(regs);
 
-	if (--prof_counter[cpu] <= 0) {
+	if (--per_cpu(prof_counter, cpu) <= 0) {
 		/*
 		 * The multiplier may have changed since the last time we got
 		 * to this point as a result of the user writing to
@@ -910,10 +910,11 @@
 		 *
 		 * Interrupts are already masked off at this point.
 		 */
-		prof_counter[cpu] = prof_multiplier[cpu];
-		if (prof_counter[cpu] != prof_old_multiplier[cpu]) {
-			__setup_APIC_LVTT(calibration_result/prof_counter[cpu]);
-			prof_old_multiplier[cpu] = prof_counter[cpu];
+		per_cpu(prof_counter, cpu) = prof_multiplier[cpu];
+		if (per_cpu(prof_counter, cpu) != prof_old_multiplier[cpu]) {
+			__setup_APIC_LVTT(calibration_result/
+					per_cpu(prof_counter, cpu));
+			prof_old_multiplier[cpu] = per_cpu(prof_counter, cpu);
 		}
 
 #ifdef CONFIG_SMP
diff -Nru a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/kernel/entry.S	Thu Jan 16 18:23:05 2003
@@ -532,8 +532,10 @@
 	xorl %ebx,%ebx	
 	swapgs
 error_sti:	
+	bt $9,EFLAGS(%rsp)
+	jnc 1f
 	sti
-	movq %rdi,RDI(%rsp) 	
+1:	movq %rdi,RDI(%rsp) 	
 	movq %rsp,%rdi
 	movq ORIG_RAX(%rsp),%rsi	/* get error code */ 
 	movq $-1,ORIG_RAX(%rsp)
diff -Nru a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
--- a/arch/x86_64/kernel/head.S	Thu Jan 16 18:23:06 2003
+++ b/arch/x86_64/kernel/head.S	Thu Jan 16 18:23:06 2003
@@ -66,7 +66,7 @@
 	movl	%eax, %cr4
 
 	/* Setup early boot stage 4 level pagetables */
-	movl	$0x101000, %eax
+	movl	$(init_level4_pgt - __START_KERNEL_map), %eax
 	movl	%eax, %cr3
 
 	/* Setup EFER (Extended Feature Enable Register) */
@@ -89,20 +89,13 @@
 	wrmsr
 
 	xorl	%eax, %eax
-	/* Enable paging and in turn activate Long Mode */
-	btsl	$31, %eax
-	/* Enable protected mode */
-	btsl	$0, %eax
-	/* Enable MP */
-	btsl	$1, %eax
-	/* Enable ET */
-	btsl	$4, %eax
-	/* Enable NE */
-	btsl	$5, %eax
-	/* Enable WP */
-	btsl	$16, %eax
-	/* Enable AM */
-	btsl	$18, %eax
+	btsl	$31, %eax			/* Enable paging and in turn activate Long Mode */
+	btsl	$0, %eax			/* Enable protected mode */
+	btsl	$1, %eax			/* Enable MP */
+	btsl	$4, %eax			/* Enable ET */
+	btsl	$5, %eax			/* Enable NE */
+	btsl	$16, %eax			/* Enable WP */
+	btsl	$18, %eax			/* Enable AM */
 	/* Make changes effective */
 	movl	%eax, %cr0
 	jmp	reach_compatibility_mode
@@ -120,10 +113,10 @@
 	
 	/* Load new GDT with the 64bit segment using 32bit descriptor */
 	/* to avoid 32bit relocations we use fixed adresses here */
-	movl	$0x100F00, %eax
+	movl	$(pGDT32 - __START_KERNEL_map), %eax
 	lgdt	(%eax)
 
-	movl    $0x100F10, %eax
+	movl    $(ljumpvector - __START_KERNEL_map), %eax
 	/* Finally jump in 64bit mode */
 	ljmp	*(%eax)
 
@@ -205,11 +198,11 @@
 .org 0xf00
 pGDT32:
 	.word	gdt32_end-gdt_table32
-	.long	gdt_table32-__START_KERNEL+0x100000
+	.long	gdt_table32-__START_KERNEL_map
 
 .org 0xf10	
 ljumpvector:
-	.long	reach_long64-__START_KERNEL+0x100000
+	.long	reach_long64-__START_KERNEL_map
 	.word	__KERNEL_CS
 
 ENTRY(stext)
diff -Nru a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c
--- a/arch/x86_64/kernel/module.c	Thu Jan 16 18:23:06 2003
+++ b/arch/x86_64/kernel/module.c	Thu Jan 16 18:23:06 2003
@@ -1,6 +1,6 @@
 /*  Kernel module help for x86-64
     Copyright (C) 2001 Rusty Russell.
-    Copyright (C) 2002 Andi Kleen, SuSE Labs.
+    Copyright (C) 2002,2003 Andi Kleen, SuSE Labs.
 
     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
@@ -22,9 +22,115 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include <asm/system.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
 
 #define DEBUGP(fmt...) 
  
+void module_free(struct module *mod, void *module_region)
+{
+	struct vm_struct **prevp, *map;
+	int i;
+	unsigned long addr = (unsigned long)module_region;
+
+	if (!addr)
+		return;
+	write_lock(&vmlist_lock); 
+	for (prevp = &vmlist ; (map = *prevp) ; prevp = &map->next) {
+		if ((unsigned long)map->addr == addr) {
+			*prevp = map->next;
+			write_unlock(&vmlist_lock); 
+			goto found;
+		}
+	}
+	write_unlock(&vmlist_lock); 
+	printk("Trying to unmap nonexistent module vm area (%lx)\n", addr);
+	return;
+ found:
+	unmap_vm_area(map);
+	if (map->pages) {
+		for (i = 0; i < map->nr_pages; i++)
+			if (map->pages[i])
+				__free_page(map->pages[i]);	
+		kfree(map->pages);
+	}
+	kfree(map);					
+}
+
+void *module_alloc(unsigned long size)
+{
+	struct vm_struct **p, *tmp, *area;
+	struct page **pages;
+	void *addr;
+	unsigned int nr_pages, array_size, i;
+
+	if (!size)
+		return NULL; 
+	size = PAGE_ALIGN(size);
+	if (size > MODULES_LEN)
+		return NULL;
+
+	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
+	if (!area)
+		return NULL;
+	memset(area, 0, sizeof(struct vm_struct));
+
+	write_lock(&vmlist_lock);
+	addr = (void *) MODULES_VADDR;
+	for (p = &vmlist; (tmp = *p); p = &tmp->next) {
+		void *next; 
+		DEBUGP("vmlist %p %lu addr %p\n", tmp->addr, tmp->size, addr);
+		if (size + (unsigned long) addr + PAGE_SIZE < (unsigned long) tmp->addr)
+			break;
+		next = (void *) (tmp->size + (unsigned long) tmp->addr);
+		if (next > addr) 
+			addr = next;
+	}
+
+	if ((unsigned long)addr + size >= MODULES_END) {
+		write_unlock(&vmlist_lock);
+		kfree(area); 
+		return NULL;
+	}
+	DEBUGP("addr %p\n", addr);
+
+	area->next = *p;
+	*p = area;
+	area->size = size + PAGE_SIZE;
+	area->addr = addr;
+	write_unlock(&vmlist_lock);
+
+	nr_pages = size >> PAGE_SHIFT;
+	array_size = (nr_pages * sizeof(struct page *));
+
+	area->nr_pages = nr_pages;
+	area->pages = pages = kmalloc(array_size, GFP_KERNEL);
+	if (!area->pages) 
+		goto fail;
+
+	memset(area->pages, 0, array_size);
+	for (i = 0; i < nr_pages; i++) {
+		area->pages[i] = alloc_page(GFP_KERNEL);
+		if (area->pages[i] == NULL)
+			goto fail;
+	}
+	
+	if (map_vm_area(area, PAGE_KERNEL_EXECUTABLE, &pages))
+		goto fail;
+	
+	memset(addr, 0, size);
+	DEBUGP("module_alloc size %lu = %p\n", size, addr);
+	return addr;
+
+fail:
+	module_free(NULL, addr);
+	return NULL;
+}
+
 /* We don't need anything special. */
 int module_frob_arch_sections(Elf_Ehdr *hdr,
 			      Elf_Shdr *sechdrs,
diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/kernel/process.c	Thu Jan 16 18:23:05 2003
@@ -537,6 +537,11 @@
 
 	switch (code) { 
 	case ARCH_SET_GS:
+#if 1
+		/* For now. We still have one unsolved bug in long gs base context
+		   switch handling. */
+		return -EINVAL; 
+#else
 		if (addr >= TASK_SIZE) 
 			return -EPERM; 
 		get_cpu();
@@ -546,6 +551,7 @@
 		ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); 
 		put_cpu();
 		break;
+#endif
 	case ARCH_SET_FS:
 		/* Not strictly needed for fs, but do it for symmetry
 		   with gs */
@@ -594,15 +600,15 @@
  * Set a given TLS descriptor:
  * When you want addresses > 32bit use arch_prctl() 
  */
-asmlinkage int sys_set_thread_area(struct user_desc *u_info)
+int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info)
 {
-	struct thread_struct *t = &current->thread;
 	struct user_desc info;
 	struct n_desc_struct *desc;
 	int cpu, idx;
 
 	if (copy_from_user(&info, u_info, sizeof(info)))
 		return -EFAULT;
+
 	idx = info.entry_number;
 
 	/*
@@ -634,12 +640,19 @@
 		desc->a = LDT_entry_a(&info);
 		desc->b = LDT_entry_b(&info);
 	}
+	if (t == &current->thread)
 	load_TLS(t, cpu);
 
 	put_cpu();
 	return 0;
 }
 
+asmlinkage int sys_set_thread_area(struct user_desc *u_info)
+{ 
+	return do_set_thread_area(&current->thread, u_info); 
+} 
+
+
 /*
  * Get the current Thread-Local Storage area:
  */
@@ -661,7 +674,7 @@
 #define GET_USEABLE(desc)	(((desc)->b >> 20) & 1)
 #define GET_LONGMODE(desc)	(((desc)->b >> 21) & 1)
 
-asmlinkage int sys_get_thread_area(struct user_desc *u_info)
+int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info)
 {
 	struct user_desc info;
 	struct n_desc_struct *desc;
@@ -672,7 +685,7 @@
 	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
 		return -EINVAL;
 
-	desc = ((struct n_desc_struct *)current->thread.tls_array) + idx - GDT_ENTRY_TLS_MIN;
+	desc = ((struct n_desc_struct *)t->tls_array) + idx - GDT_ENTRY_TLS_MIN;
 
 	memset(&info, 0, sizeof(struct user_desc));
 	info.entry_number = idx;
@@ -690,6 +703,11 @@
 		return -EFAULT;
 	return 0;
 }
+
+asmlinkage int sys_get_thread_area(struct user_desc *u_info)
+{
+	return do_get_thread_area(&current->thread, u_info);
+} 
 
 /* 
  * Capture the user space registers if the task is not running (in user space)
diff -Nru a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
--- a/arch/x86_64/kernel/ptrace.c	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/kernel/ptrace.c	Thu Jan 16 18:23:05 2003
@@ -23,6 +23,9 @@
 #include <asm/processor.h>
 #include <asm/i387.h>
 #include <asm/debugreg.h>
+#include <asm/ldt.h>
+#include <asm/desc.h>
+#include <asm/proto.h>
 
 /*
  * does not yet catch signals sent when the child dies.
@@ -319,6 +322,22 @@
 		wake_up_process(child);
 		ret = 0;
 		break;
+	case PTRACE_SET_THREAD_AREA: {
+		int old; 
+		get_user(old,  &((struct user_desc *)data)->entry_number); 
+		put_user(addr, &((struct user_desc *)data)->entry_number);
+		ret = do_set_thread_area(&child->thread, 
+					 (struct user_desc *)data);
+		put_user(old,  &((struct user_desc *)data)->entry_number); 
+		break;
+	case PTRACE_GET_THREAD_AREA:
+		get_user(old,  &((struct user_desc *)data)->entry_number); 
+		put_user(addr, &((struct user_desc *)data)->entry_number);
+		ret = do_get_thread_area(&child->thread, 
+					 (struct user_desc *)data);
+		put_user(old,  &((struct user_desc *)data)->entry_number); 
+		break;
+	} 
 	}
 
 /*
diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/kernel/setup64.c	Thu Jan 16 18:23:05 2003
@@ -200,7 +200,7 @@
 #endif
 
 	/* Flags to clear on syscall */
-	wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE); 
+	wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); 
 
 	wrmsrl(MSR_FS_BASE, 0);
 	wrmsrl(MSR_KERNEL_GS_BASE, 0);
diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
--- a/arch/x86_64/kernel/smpboot.c	Thu Jan 16 18:23:07 2003
+++ b/arch/x86_64/kernel/smpboot.c	Thu Jan 16 18:23:07 2003
@@ -772,24 +772,16 @@
  * Cycle through the processors sending APIC IPIs to boot each.
  */
 
-extern int prof_multiplier[NR_CPUS];
-extern int prof_old_multiplier[NR_CPUS];
-extern int prof_counter[NR_CPUS];
-
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
 	int apicid, cpu;
 
 	/*
 	 * Initialize the logical to physical CPU number mapping
-	 * and the per-CPU profiling counter/multiplier
 	 */
 
 	for (apicid = 0; apicid < NR_CPUS; apicid++) {
 		x86_apicid_to_cpu[apicid] = -1;
-		prof_counter[apicid] = 1;
-		prof_old_multiplier[apicid] = 1;
-		prof_multiplier[apicid] = 1;
 	}
 
 	/*
diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
--- a/arch/x86_64/kernel/traps.c	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/kernel/traps.c	Thu Jan 16 18:23:05 2003
@@ -450,16 +450,20 @@
 	do_trap(3, SIGTRAP, "int3", regs, error_code, NULL);
 }
 
+extern void dump_pagetable(unsigned long);
+
 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
 {
 #ifdef CONFIG_CHECKING
        { 
                unsigned long gs; 
-               struct x8664_pda *pda = cpu_pda + stack_smp_processor_id(); 
+               struct x8664_pda *pda = cpu_pda + hard_smp_processor_id(); 
                rdmsrl(MSR_GS_BASE, gs); 
                if (gs != (unsigned long)pda) { 
                        wrmsrl(MSR_GS_BASE, pda); 
+		       oops_in_progress++;
                        printk("general protection handler: wrong gs %lx expected %p\n", gs, pda);
+		       oops_in_progress--;
                }
        }
 #endif
diff -Nru a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
--- a/arch/x86_64/lib/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/lib/Makefile	Thu Jan 16 18:23:05 2003
@@ -2,18 +2,15 @@
 # Makefile for x86_64-specific library files.
 #
 
-EXTRA_CFLAGS_csum-partial.o := -funroll-loops
+L_TARGET := lib.a
+export-objs := io.o csum-wrappers.o csum-partial.o
+
+CFLAGS_csum-partial.o := -funroll-loops
 
-L_TARGET = lib.a
-obj-y  = csum-partial.o csum-copy.o csum-wrappers.o delay.o \
+obj-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
 	usercopy.o getuser.o putuser.o  \
 	thunk.o io.o clear_page.o copy_page.o bitstr.o
-obj-y += memcpy.o
-obj-y += memmove.o
-obj-y += memset.o
-obj-y += copy_user.o
-
-export-objs := io.o csum-wrappers.o csum-partial.o
+obj-y += memcpy.o memmove.o memset.o copy_user.o
 
 obj-$(CONFIG_IO_DEBUG) += iodebug.o
 obj-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
diff -Nru a/arch/x86_64/lib/usercopy.c b/arch/x86_64/lib/usercopy.c
--- a/arch/x86_64/lib/usercopy.c	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/lib/usercopy.c	Thu Jan 16 18:23:05 2003
@@ -109,19 +109,34 @@
 
 long strnlen_user(const char *s, long n)
 {
-	unsigned long res = 0;
+	long res = 0;
 	char c;
 
 	if (!access_ok(VERIFY_READ, s, n))
 		return 0;
 
 	while (1) {
+		if (res>n)
+			return n+1;
+		if (__get_user(c, s))
+			return 0;
+		if (!c)
+			return res+1;
+		res++;
+		s++;
+	}
+}
+
+long strlen_user(const char *s)
+{
+	long res = 0;
+	char c;
+
+	for (;;) {
 		if (get_user(c, s))
 			return 0;
 		if (!c)
 			return res+1;
-		if (res>n)
-			return n+1;
 		res++;
 		s++;
 	}
diff -Nru a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile
--- a/arch/x86_64/mm/Makefile	Thu Jan 16 18:23:06 2003
+++ b/arch/x86_64/mm/Makefile	Thu Jan 16 18:23:06 2003
@@ -4,5 +4,5 @@
 
 export-objs := pageattr.o
 
-obj-y	 := init.o fault.o ioremap.o extable.o modutil.o pageattr.o
+obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff -Nru a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
--- a/arch/x86_64/mm/init.c	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/mm/init.c	Thu Jan 16 18:23:05 2003
@@ -161,7 +161,6 @@
 } temp_mappings[] __initdata = { 
 	{ &temp_boot_pmds[0], (void *)(40UL * 1024 * 1024) },
 	{ &temp_boot_pmds[1], (void *)(42UL * 1024 * 1024) }, 
-	{ &temp_boot_pmds[2], (void *)(44UL * 1024 * 1024) }, 
 	{}
 }; 
 
@@ -315,8 +314,6 @@
 {
 	int codesize, reservedpages, datasize, initsize;
 	int tmp;
-
-	printk("mem_init\n");
 
 	if (!mem_map)
 		BUG();
diff -Nru a/arch/x86_64/mm/modutil.c b/arch/x86_64/mm/modutil.c
--- a/arch/x86_64/mm/modutil.c	Thu Jan 16 18:23:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,127 +0,0 @@
-/*  arch/x86_64/mm/modutil.c
- *
- *  Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- *  Based upon code written by Linus Torvalds and others.
- * 
- *  Blatantly copied from sparc64 for x86-64 by Andi Kleen. 
- *  Should use direct mapping with 2MB pages. This would need extension
- *  of the kernel mapping.
- */
- 
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/err.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-/* FIXME: If module_region == mod->init_region, trim exception
-   table entries. */
-void module_free(struct module *mod, void *module_region)
-{
-	struct vm_struct **p, *tmp;
-	int i;
-	unsigned long addr = (unsigned long)module_region;
-
-	if (!addr)
-		return;
-	if ((PAGE_SIZE-1) & addr) {
-		printk("Trying to unmap module with bad address (%lx)\n", addr);
-		return;
-	}
-	write_lock(&vmlist_lock); 
-	for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
-		if ((unsigned long)tmp->addr == addr) {
-			*p = tmp->next;
-			write_unlock(&vmlist_lock); 
-			goto found;
-		}
-	}
-	write_unlock(&vmlist_lock); 
-	printk("Trying to unmap nonexistent module vm area (%lx)\n", addr);
-	return;
- found:
-	unmap_vm_area(tmp);
-	for (i = 0; i < tmp->nr_pages; i++) {
-		if (unlikely(!tmp->pages[i]))
-			BUG();
-		__free_page(tmp->pages[i]);
-	}
-	
-	kfree(tmp->pages);
-	kfree(tmp);					
-}
-
-void * module_alloc (unsigned long size)
-{
-	struct vm_struct **p, *tmp, *area;
-	struct page **pages;
-	void * addr;
-	unsigned int nr_pages, array_size, i;
-
-	if (!size)
-		return NULL;
-	size = PAGE_ALIGN(size);
-	if (size > MODULES_LEN)
-		return ERR_PTR(-ENOMEM);
-		
-	addr = (void *) MODULES_VADDR;
-	for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
-		if (size + (unsigned long) addr < (unsigned long) tmp->addr)
-			break;
-		addr = (void *) (tmp->size + (unsigned long) tmp->addr);
-	}
-	if ((unsigned long) addr + size >= MODULES_END)
-		return ERR_PTR(-ENOMEM);
-	
-	area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
-	if (!area)
-		return ERR_PTR(-ENOMEM);
-	area->size = size + PAGE_SIZE;
-	area->addr = addr;
-	area->next = *p;
-	area->pages = NULL;
-	area->nr_pages = 0;
-	area->phys_addr = 0;
-	*p = area;
-
-	nr_pages = size >> PAGE_SHIFT;
-	array_size = (nr_pages * sizeof(struct page *));
-
-	area->nr_pages = nr_pages;
-	area->pages = pages = kmalloc(array_size, GFP_KERNEL);
-	if (!area->pages)
-		goto fail;
-
-	memset(area->pages, 0, array_size);
-
-	for (i = 0; i < area->nr_pages; i++) {
-		area->pages[i] = alloc_page(GFP_KERNEL);
-		if (unlikely(!area->pages[i]))
-			goto fail;
-	}
-	
-	if (map_vm_area(area, PAGE_KERNEL_EXECUTABLE, &pages)) {
-		unmap_vm_area(area);
-		goto fail;
-	}
-
-	memset(area->addr, 0, size);
-	return area->addr;
-
-fail:
-	if (area->pages) {
-		for (i = 0; i < area->nr_pages; i++) {
-			if (area->pages[i])
-				__free_page(area->pages[i]);
-		}
-		kfree(area->pages);
-	}
-	kfree(area);
-
-	return ERR_PTR(-ENOMEM);
-}
-
diff -Nru a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile
--- a/arch/x86_64/pci/Makefile	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/pci/Makefile	Thu Jan 16 18:23:05 2003
@@ -1,14 +1,8 @@
-
+#
+# Makefile for X86_64 specific PCI routines
+#
 obj-y		:= x86-64.o
-
-obj-$(CONFIG_PCI_DIRECT)	+= direct.o
-
+obj-$(CONFIG_PCI_DIRECT)+= direct.o
 obj-y		+= fixup.o
-
-ifdef	CONFIG_ACPI_PCI
-obj-y		+= acpi.o
-endif
-obj-y		+= legacy.o
-
-
-obj-y		+= irq.o common.o
+obj-$(CONFIG_ACPI_PCI)	+= acpi.o
+obj-y			+= legacy.o irq.o common.o
diff -Nru a/arch/x86_64/vmlinux.lds.S b/arch/x86_64/vmlinux.lds.S
--- a/arch/x86_64/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
+++ b/arch/x86_64/vmlinux.lds.S	Thu Jan 16 18:23:05 2003
@@ -1,6 +1,9 @@
 /* ld script to make x86-64 Linux kernel
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
  */
+
+#include <asm-generic/vmlinux.lds.h>
+
 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
 OUTPUT_ARCH(i386:x86-64)
 ENTRY(_start)
@@ -18,25 +21,12 @@
 
   _etext = .;			/* End of text section */
 
-  .rodata : { *(.rodata) *(.rodata.*) }
-  .kstrtab : { *(.kstrtab) }
-
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __ex_table : { *(__ex_table) }
   __stop___ex_table = .;
 
-  . = ALIGN(64); 
-  __start___ksymtab = .;	/* Kernel symbol table */
-  __ksymtab : { *(__ksymtab) }
-  __stop___ksymtab = .;
-  __start___gpl_ksymtab = .;	/* Kernel symbol table:	GPL-only symbols */
-  __gpl_ksymtab : { *(__gpl_ksymtab) }
-  __stop___gpl_ksymtab = .;
-
-  __start___kallsyms = .;	/* All kernel symbols */
-  __kallsyms : { *(__kallsyms) }
-  __stop___kallsyms = .;
+  RODATA
 
   .data : {			/* Data */
 	*(.data)
@@ -83,11 +73,6 @@
   . = ALIGN(4096); 
   .data.boot_pgt : { *(.data.boot_pgt) }
 
-  . = ALIGN(4096);
-  __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
-  __initramfs_end = .;
-	
   . = ALIGN(4096);		/* Init code and data */
   __init_begin = .;
   .init.text : { *(.init.text) }
@@ -110,6 +95,10 @@
 	*(.initcall7.init)
   }
   __initcall_end = .;
+  . = ALIGN(4096);
+  __initramfs_start = .;
+  .init.ramfs : { *(.init.ramfs) }
+  __initramfs_end = .;	
   . = ALIGN(32);
   __per_cpu_start = .;
   .data.percpu  : { *(.data.percpu) }
diff -Nru a/crypto/Kconfig b/crypto/Kconfig
--- a/crypto/Kconfig	Thu Jan 16 18:23:07 2003
+++ b/crypto/Kconfig	Thu Jan 16 18:23:07 2003
@@ -53,6 +53,18 @@
 	  This version of SHA implements a 256 bit hash with 128 bits of
 	  security against collision attacks.
 
+config CRYPTO_SHA512
+	tristate "SHA384 and SHA512 digest algorithms"
+	depends on CRYPTO
+	help
+	  SHA512 secure hash standard (DFIPS 180-2).
+	  
+	  This version of SHA implements a 512 bit hash with 256 bits of
+	  security against collision attacks.
+
+	  This code also includes SHA-384, a 384 bit hash with 192 bits
+	  of security against collision attacks.
+
 config CRYPTO_DES
 	tristate "DES and Triple DES EDE cipher algorithms"
 	depends on CRYPTO
diff -Nru a/crypto/Makefile b/crypto/Makefile
--- a/crypto/Makefile	Thu Jan 16 18:23:07 2003
+++ b/crypto/Makefile	Thu Jan 16 18:23:07 2003
@@ -16,6 +16,7 @@
 obj-$(CONFIG_CRYPTO_MD5) += md5.o
 obj-$(CONFIG_CRYPTO_SHA1) += sha1.o
 obj-$(CONFIG_CRYPTO_SHA256) += sha256.o
+obj-$(CONFIG_CRYPTO_SHA512) += sha512.o
 obj-$(CONFIG_CRYPTO_DES) += des.o
 obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
 obj-$(CONFIG_CRYPTO_TWOFISH) += twofish.o
diff -Nru a/crypto/des.c b/crypto/des.c
--- a/crypto/des.c	Thu Jan 16 18:23:07 2003
+++ b/crypto/des.c	Thu Jan 16 18:23:07 2003
@@ -1279,10 +1279,8 @@
 		goto out;
 
 	ret = crypto_register_alg(&des3_ede_alg);
-	if (ret < 0) {
+	if (ret < 0)
 		crypto_unregister_alg(&des_alg);
-		goto out;
-	}
 out:	
 	return ret;
 }
diff -Nru a/crypto/sha512.c b/crypto/sha512.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/crypto/sha512.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,373 @@
+/* SHA-512 code by Jean-Luc Cooke <jlcooke@certainkey.com>
+ *
+ * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com>
+ * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
+ * Copyright (c) 2003 Kyle McMartin <kyle@debian.org>
+ *
+ * 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, or (at your option) any
+ * later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/crypto.h>
+
+#include <asm/scatterlist.h>
+#include <asm/byteorder.h>
+
+#define SHA384_DIGEST_SIZE 48
+#define SHA512_DIGEST_SIZE 64
+#define SHA384_HMAC_BLOCK_SIZE  96
+#define SHA512_HMAC_BLOCK_SIZE 128
+
+struct sha512_ctx {
+	u64 state[8];
+	u32 count[4];
+	u8 buf[128];
+};
+
+static inline u64 Ch(u64 x, u64 y, u64 z)
+{
+        return ((x & y) ^ (~x & z));
+}
+
+static inline u64 Maj(u64 x, u64 y, u64 z)
+{
+        return ((x & y) ^ (x & z) ^ (y & z));
+}
+
+static inline u64 RORu64(u64 x, u64 y)
+{
+        return (x >> y) | (x << (64 - y));
+}
+
+const u64 sha512_K[80] = {
+        0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
+        0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
+        0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
+        0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
+        0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
+        0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
+        0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
+        0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
+        0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
+        0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
+        0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
+        0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
+        0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
+        0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
+        0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
+        0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
+        0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
+        0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
+        0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
+        0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+        0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
+        0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
+        0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
+        0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
+        0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
+        0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
+        0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
+};
+
+#define e0(x)       (RORu64(x,28) ^ RORu64(x,34) ^ RORu64(x,39))
+#define e1(x)       (RORu64(x,14) ^ RORu64(x,18) ^ RORu64(x,41))
+#define s0(x)       (RORu64(x, 1) ^ RORu64(x, 8) ^ (x >> 7))
+#define s1(x)       (RORu64(x,19) ^ RORu64(x,61) ^ (x >> 6))
+
+/* H* initial state for SHA-512 */
+#define H0         0x6a09e667f3bcc908
+#define H1         0xbb67ae8584caa73b
+#define H2         0x3c6ef372fe94f82b
+#define H3         0xa54ff53a5f1d36f1
+#define H4         0x510e527fade682d1
+#define H5         0x9b05688c2b3e6c1f
+#define H6         0x1f83d9abfb41bd6b
+#define H7         0x5be0cd19137e2179
+
+/* H'* initial state for SHA-384 */
+#define HP0 0xcbbb9d5dc1059ed8
+#define HP1 0x629a292a367cd507
+#define HP2 0x9159015a3070dd17
+#define HP3 0x152fecd8f70e5939
+#define HP4 0x67332667ffc00b31
+#define HP5 0x8eb44a8768581511
+#define HP6 0xdb0c2e0d64f98fa7
+#define HP7 0x47b5481dbefa4fa4
+
+static inline void LOAD_OP(int I, u64 *W, const u8 *input)
+{
+        u64 t1  = input[(8*I)  ] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+1] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+2] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+3] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+4] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+5] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+6] & 0xff;
+        t1 <<= 8;
+        t1 |= input[(8*I)+7] & 0xff;
+        W[I] = t1;
+}
+
+static inline void BLEND_OP(int I, u64 *W)
+{
+        W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
+}
+
+static void
+sha512_transform(u64 *state, const u8 *input)
+{
+	u64 a, b, c, d, e, f, g, h, t1, t2;
+	u64 W[80];
+
+	int i;
+
+	/* load the input */
+        for (i = 0; i < 16; i++)
+                LOAD_OP(i, W, input);
+
+        for (i = 16; i < 80; i++) {
+                BLEND_OP(i, W);
+        }
+
+	/* load the state into our registers */
+	a=state[0];   b=state[1];   c=state[2];   d=state[3];  
+	e=state[4];   f=state[5];   g=state[6];   h=state[7];  
+  
+	/* now iterate */
+	for (i=0; i<80; i+=8) {
+		t1 = h + e1(e) + Ch(e,f,g) + sha512_K[i  ] + W[i  ];
+		t2 = e0(a) + Maj(a,b,c);    d+=t1;    h=t1+t2;
+		t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+1];
+		t2 = e0(h) + Maj(h,a,b);    c+=t1;    g=t1+t2;
+		t1 = f + e1(c) + Ch(c,d,e) + sha512_K[i+2] + W[i+2];
+		t2 = e0(g) + Maj(g,h,a);    b+=t1;    f=t1+t2;
+		t1 = e + e1(b) + Ch(b,c,d) + sha512_K[i+3] + W[i+3];
+		t2 = e0(f) + Maj(f,g,h);    a+=t1;    e=t1+t2;
+		t1 = d + e1(a) + Ch(a,b,c) + sha512_K[i+4] + W[i+4];
+		t2 = e0(e) + Maj(e,f,g);    h+=t1;    d=t1+t2;
+		t1 = c + e1(h) + Ch(h,a,b) + sha512_K[i+5] + W[i+5];
+		t2 = e0(d) + Maj(d,e,f);    g+=t1;    c=t1+t2;
+		t1 = b + e1(g) + Ch(g,h,a) + sha512_K[i+6] + W[i+6];
+		t2 = e0(c) + Maj(c,d,e);    f+=t1;    b=t1+t2;
+		t1 = a + e1(f) + Ch(f,g,h) + sha512_K[i+7] + W[i+7];
+		t2 = e0(b) + Maj(b,c,d);    e+=t1;    a=t1+t2;
+	}
+  
+	state[0] += a; state[1] += b; state[2] += c; state[3] += d;  
+	state[4] += e; state[5] += f; state[6] += g; state[7] += h;  
+
+	/* erase our data */
+	a = b = c = d = e = f = g = h = t1 = t2 = 0;
+	memset(W, 0, 80 * sizeof(u64));
+}
+
+static void
+sha512_init(void *ctx)
+{
+        struct sha512_ctx *sctx = ctx;
+	sctx->state[0] = H0;
+	sctx->state[1] = H1;
+	sctx->state[2] = H2;
+	sctx->state[3] = H3;
+	sctx->state[4] = H4;
+	sctx->state[5] = H5;
+	sctx->state[6] = H6;
+	sctx->state[7] = H7;
+	sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
+	memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+static void
+sha384_init(void *ctx)
+{
+        struct sha512_ctx *sctx = ctx;
+        sctx->state[0] = HP0;
+        sctx->state[1] = HP1;
+        sctx->state[2] = HP2;
+        sctx->state[3] = HP3;
+        sctx->state[4] = HP4;
+        sctx->state[5] = HP5;
+        sctx->state[6] = HP6;
+        sctx->state[7] = HP7;
+        sctx->count[0] = sctx->count[1] = sctx->count[2] = sctx->count[3] = 0;
+        memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+static void
+sha512_update(void *ctx, const u8 *data, unsigned int len)
+{
+        struct sha512_ctx *sctx = ctx;
+
+	unsigned int i, index, part_len;
+
+	/* Compute number of bytes mod 128 */
+	index = (unsigned int)((sctx->count[0] >> 3) & 0x7F);
+	
+	/* Update number of bits */
+	if ((sctx->count[0] += (len << 3)) < (len << 3)) {
+		if ((sctx->count[1] += 1) < 1)
+			if ((sctx->count[2] += 1) < 1)
+				sctx->count[3]++;
+		sctx->count[1] += (len >> 29);
+	}
+	
+        part_len = 128 - index;
+	
+	/* Transform as many times as possible. */
+	if (len >= part_len) {
+		memcpy(&sctx->buf[index], data, part_len);
+		sha512_transform(sctx->state, sctx->buf);
+
+		for (i = part_len; i + 127 < len; i+=128)
+			sha512_transform(sctx->state, &data[i]);
+
+		index = 0;
+	} else {
+		i = 0;
+	}
+
+	/* Buffer remaining input */
+	memcpy(&sctx->buf[index], &data[i], len - i);
+}
+
+static void
+sha512_final(void *ctx, u8 *hash)
+{
+        struct sha512_ctx *sctx = ctx;
+	
+        const static u8 padding[128] = { 0x80, };
+
+        u32 t;
+	u64 t2;
+        u8 bits[128];
+	unsigned int index, pad_len;
+	int i, j;
+
+        index = pad_len = t = i = j = 0;
+        t2 = 0;
+
+	/* Save number of bits */
+	t = sctx->count[0];
+	bits[15] = t; t>>=8;
+	bits[14] = t; t>>=8;
+	bits[13] = t; t>>=8;
+	bits[12] = t; 
+	t = sctx->count[1];
+	bits[11] = t; t>>=8;
+	bits[10] = t; t>>=8;
+	bits[9 ] = t; t>>=8;
+	bits[8 ] = t; 
+	t = sctx->count[2];
+	bits[7 ] = t; t>>=8;
+	bits[6 ] = t; t>>=8;
+	bits[5 ] = t; t>>=8;
+	bits[4 ] = t; 
+	t = sctx->count[3];
+	bits[3 ] = t; t>>=8;
+	bits[2 ] = t; t>>=8;
+	bits[1 ] = t; t>>=8;
+	bits[0 ] = t; 
+
+	/* Pad out to 112 mod 128. */
+	index = (sctx->count[0] >> 3) & 0x7f;
+	pad_len = (index < 112) ? (112 - index) : ((128+112) - index);
+	sha512_update(sctx, padding, pad_len);
+
+	/* Append length (before padding) */
+	sha512_update(sctx, bits, 16);
+
+	/* Store state in digest */
+	for (i = j = 0; i < 8; i++, j += 8) {
+		t2 = sctx->state[i];
+		hash[j+7] = (char)t2 & 0xff; t2>>=8;
+		hash[j+6] = (char)t2 & 0xff; t2>>=8;
+		hash[j+5] = (char)t2 & 0xff; t2>>=8;
+		hash[j+4] = (char)t2 & 0xff; t2>>=8;
+		hash[j+3] = (char)t2 & 0xff; t2>>=8;
+		hash[j+2] = (char)t2 & 0xff; t2>>=8;
+		hash[j+1] = (char)t2 & 0xff; t2>>=8;
+		hash[j  ] = (char)t2 & 0xff;
+	}
+	
+	/* Zeroize sensitive information. */
+	memset(sctx, 0, sizeof(struct sha512_ctx));
+}
+
+static void sha384_final(void *ctx, u8 *hash)
+{
+        struct sha512_ctx *sctx = ctx;
+        u8 D[64];
+
+        sha512_final(sctx, D);
+
+        memcpy(hash, D, 48);
+        memset(D, 0, 64);
+}
+
+static struct crypto_alg sha512 = {
+        .cra_name       = "sha512",
+        .cra_flags      = CRYPTO_ALG_TYPE_DIGEST,
+        .cra_blocksize  = SHA512_HMAC_BLOCK_SIZE,
+        .cra_ctxsize    = sizeof(struct sha512_ctx),
+        .cra_module     = THIS_MODULE,
+        .cra_list       = LIST_HEAD_INIT(sha512.cra_list),
+        .cra_u          = { .digest = {
+                                .dia_digestsize = SHA512_DIGEST_SIZE,
+                                .dia_init       = sha512_init,
+                                .dia_update     = sha512_update,
+                                .dia_final      = sha512_final }
+        }
+};
+
+static struct crypto_alg sha384 = {
+        .cra_name       = "sha384",
+        .cra_flags      = CRYPTO_ALG_TYPE_DIGEST,
+        .cra_blocksize  = SHA384_HMAC_BLOCK_SIZE,
+        .cra_ctxsize    = sizeof(struct sha512_ctx),
+        .cra_module     = THIS_MODULE,
+        .cra_list       = LIST_HEAD_INIT(sha384.cra_list),
+        .cra_u          = { .digest = {
+                                .dia_digestsize = SHA384_DIGEST_SIZE,
+                                .dia_init       = sha384_init,
+                                .dia_update     = sha512_update,
+                                .dia_final      = sha384_final }
+        }
+};
+
+static int __init init(void)
+{
+        int ret = 0;
+
+        if ((ret = crypto_register_alg(&sha384)) < 0)
+                goto out;
+        if ((ret = crypto_register_alg(&sha512)) < 0)
+                crypto_unregister_alg(&sha384);
+out:
+        return ret;
+}
+
+static void __exit fini(void)
+{
+        crypto_unregister_alg(&sha384);
+        crypto_unregister_alg(&sha512);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA-512 and SHA-384 Secure Hash Algorithms");
diff -Nru a/crypto/tcrypt.c b/crypto/tcrypt.c
--- a/crypto/tcrypt.c	Thu Jan 16 18:23:06 2003
+++ b/crypto/tcrypt.c	Thu Jan 16 18:23:06 2003
@@ -48,7 +48,7 @@
 
 static char *check[] = {
 	"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
-	"twofish", "serpent",
+	"twofish", "serpent", "sha384", "sha512", "md4", "aes",
 	 NULL
 };
 
@@ -549,6 +549,110 @@
 	crypto_free_tfm(tfm);
 }
 
+static void
+test_sha384(void)
+{
+	char *p;
+	unsigned int i;
+	struct crypto_tfm *tfm;
+	struct sha384_testvec *sha384_tv;
+	struct scatterlist sg[2];
+	unsigned int tsize;
+	char result[SHA384_DIGEST_SIZE];
+
+	printk("\ntesting sha384\n");
+
+	tsize = sizeof (sha384_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, sha384_tv_template, tsize);
+	sha384_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("sha384", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for sha384\n");
+		return;
+	}
+
+	for (i = 0; i < SHA384_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = sha384_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(sha384_tv[i].plaintext);
+
+		crypto_digest_init(tfm);
+		crypto_digest_update(tfm, sg, 1);
+		crypto_digest_final(tfm, result);
+
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, sha384_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	crypto_free_tfm(tfm);
+}
+
+static void
+test_sha512(void)
+{
+	char *p;
+	unsigned int i;
+	struct crypto_tfm *tfm;
+	struct sha512_testvec *sha512_tv;
+	struct scatterlist sg[2];
+	unsigned int tsize;
+	char result[SHA512_DIGEST_SIZE];
+
+	printk("\ntesting sha512\n");
+
+	tsize = sizeof (sha512_tv_template);
+	if (tsize > TVMEMSIZE) {
+		printk("template (%u) too big for tvmem (%u)\n", tsize,
+		       TVMEMSIZE);
+		return;
+	}
+
+	memcpy(tvmem, sha512_tv_template, tsize);
+	sha512_tv = (void *) tvmem;
+
+	tfm = crypto_alloc_tfm("sha512", 0);
+	if (tfm == NULL) {
+		printk("failed to load transform for sha512\n");
+		return;
+	}
+
+	for (i = 0; i < SHA512_TEST_VECTORS; i++) {
+		printk("test %u:\n", i + 1);
+		memset(result, 0, sizeof (result));
+
+		p = sha512_tv[i].plaintext;
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = ((long) p & ~PAGE_MASK);
+		sg[0].length = strlen(sha512_tv[i].plaintext);
+
+		crypto_digest_init(tfm);
+		crypto_digest_update(tfm, sg, 1);
+		crypto_digest_final(tfm, result);
+
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
+		printk("%s\n",
+		       memcmp(result, sha512_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ? "fail" :
+		       "pass");
+	}
+
+	crypto_free_tfm(tfm);
+}
+
 void
 test_des(void)
 {
@@ -2117,6 +2221,8 @@
 		test_twofish();
 		test_serpent();
 		test_aes();
+		test_sha384();
+		test_sha512();
 #ifdef CONFIG_CRYPTO_HMAC
 		test_hmac_md5();
 		test_hmac_sha1();
@@ -2163,7 +2269,15 @@
 	case 10:
 		test_aes();
 		break;
+
+	case 11:
+		test_sha384();
+		break;
 		
+	case 12:
+		test_sha512();
+		break;
+
 #ifdef CONFIG_CRYPTO_HMAC
 	case 100:
 		test_hmac_md5();
diff -Nru a/crypto/tcrypt.h b/crypto/tcrypt.h
--- a/crypto/tcrypt.h	Thu Jan 16 18:23:07 2003
+++ b/crypto/tcrypt.h	Thu Jan 16 18:23:07 2003
@@ -20,6 +20,8 @@
 #define MD4_DIGEST_SIZE		16
 #define SHA1_DIGEST_SIZE	20
 #define SHA256_DIGEST_SIZE	32
+#define SHA384_DIGEST_SIZE	48
+#define SHA512_DIGEST_SIZE	64
 
 /*
  * MD4 test vectors from RFC1320
@@ -587,6 +589,113 @@
 	    0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
 	    0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
 	    0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
+	},
+};
+
+/*
+ * SHA384 test vectors from from NIST and kerneli
+ */
+#define SHA384_TEST_VECTORS	4
+
+struct sha384_testvec {
+	char plaintext[128];
+	char digest[SHA384_DIGEST_SIZE];
+} sha384_tv_template[] = {
+
+	{ "abc",
+	  { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
+	    0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
+	    0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
+	    0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
+	    0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
+	    0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
+	},
+	
+	{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	  { 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39,
+	    0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39,
+	    0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab,
+	    0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6,
+	    0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f,
+	    0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b  }
+	},
+	
+	{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+	  "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+	  { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
+	    0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
+	    0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
+	    0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
+	    0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
+	    0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39  }
+	},
+	
+	{ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+	  "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+	  { 0x3d, 0x20, 0x89, 0x73, 0xab, 0x35, 0x08, 0xdb,
+	    0xbd, 0x7e, 0x2c, 0x28, 0x62, 0xba, 0x29, 0x0a,
+	    0xd3, 0x01, 0x0e, 0x49, 0x78, 0xc1, 0x98, 0xdc,
+	    0x4d, 0x8f, 0xd0, 0x14, 0xe5, 0x82, 0x82, 0x3a,
+	    0x89, 0xe1, 0x6f, 0x9b, 0x2a, 0x7b, 0xbc, 0x1a,
+	    0xc9, 0x38, 0xe2, 0xd1, 0x99, 0xe8, 0xbe, 0xa4 }
+	},
+};
+
+/*
+ * SHA512 test vectors from from NIST and kerneli
+ */
+#define SHA512_TEST_VECTORS	4
+
+struct sha512_testvec {
+	char plaintext[128];
+	char digest[SHA512_DIGEST_SIZE];
+} sha512_tv_template[] = {
+
+	{ "abc",
+	  { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
+	    0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
+	    0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+	    0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
+	    0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
+	    0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+	    0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
+	    0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
+	},
+	
+	{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+	  { 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a,
+	    0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16,
+	    0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8,
+	    0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35,
+	    0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9,
+	    0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0,
+	    0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03,
+	    0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 }
+	},
+	
+	{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+	  "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+	  { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
+	    0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
+	    0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
+	    0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
+	    0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
+	    0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
+	    0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
+	    0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
+	},
+	
+	{ "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd"
+	  "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz",
+	  { 0x93, 0x0d, 0x0c, 0xef, 0xcb, 0x30, 0xff, 0x11,
+	    0x33, 0xb6, 0x89, 0x81, 0x21, 0xf1, 0xcf, 0x3d,
+	    0x27, 0x57, 0x8a, 0xfc, 0xaf, 0xe8, 0x67, 0x7c,
+	    0x52, 0x57, 0xcf, 0x06, 0x99, 0x11, 0xf7, 0x5d,
+	    0x8f, 0x58, 0x31, 0xb5, 0x6e, 0xbf, 0xda, 0x67,
+	    0xb2, 0x78, 0xe6, 0x6d, 0xff, 0x8b, 0x84, 0xfe,
+	    0x2b, 0x28, 0x70, 0xf7, 0x42, 0xa5, 0x80, 0xd8,
+	    0xed, 0xb4, 0x19, 0x87, 0x23, 0x28, 0x50, 0xc9
+	  }
 	},
 };
 
diff -Nru a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile	Thu Jan 16 18:23:06 2003
+++ b/drivers/Makefile	Thu Jan 16 18:23:06 2003
@@ -44,3 +44,4 @@
 obj-$(CONFIG_HOTPLUG_PCI)	+= hotplug/
 obj-$(CONFIG_ISDN_BOOL)		+= isdn/
 obj-$(CONFIG_MCA)		+= mca/
+obj-$(CONFIG_EISA)		+= eisa/
diff -Nru a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
--- a/drivers/acorn/block/fd1772.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/acorn/block/fd1772.c	Thu Jan 16 18:23:05 2003
@@ -1528,7 +1528,7 @@
 int fd1772_init(void)
 {
 	static spinlock_t lock = SPIN_LOCK_UNLOCKED;
-	int i;
+	int i, err = -ENOMEM;
 
 	if (!machine_is_archimedes())
 		return 0;
@@ -1536,27 +1536,25 @@
 	for (i = 0; i < FD_MAX_UNITS; i++) {
 		disks[i] = alloc_disk(1);
 		if (!disks[i])
-			goto out;
+			goto err_disk;
 	}
 
-	if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) {
+	err = register_blkdev(MAJOR_NR, "fd", &floppy_fops);
+	if (err) {
 		printk("Unable to get major %d for floppy\n", MAJOR_NR);
-		goto out;
+		goto err_disk;
 	}
 
+	err = -EBUSY;
 	if (request_dma(FLOPPY_DMA, "fd1772")) {
 		printk("Unable to grab DMA%d for the floppy (1772) driver\n", FLOPPY_DMA);
-		unregister_blkdev(MAJOR_NR, "fd");
-		goto out;
+		goto err_blkdev;
 	};
 
 	if (request_dma(FIQ_FD1772, "fd1772 end")) {
 		printk("Unable to grab DMA%d for the floppy (1772) driver\n", FIQ_FD1772);
-		unregister_blkdev(MAJOR_NR, "fd");
-		free_dma(FLOPPY_DMA);
-		goto out;
+		goto err_dma1;
 	};
-	enable_dma(FIQ_FD1772);	/* This inserts a call to our command end routine */
 
 	/* initialize variables */
 	SelectedDrive = -1;
@@ -1570,6 +1568,12 @@
 	   out of some special memory... */
 	DMABuffer = (char *) kmalloc(2048);	/* Copes with pretty large sectors */
 #endif
+	err = -ENOMEM;
+	if (!DMAbuffer)
+		goto err_dma2;
+
+	enable_dma(FIQ_FD1772);	/* This inserts a call to our command end routine */
+
 	blk_init_queue(&floppy_queue, do_fd_request, &lock);
 	for (i = 0; i < FD_MAX_UNITS; i++) {
 		unit[i].track = -1;
@@ -1590,8 +1594,18 @@
 	config_types();
 
 	return 0;
-out:
+
+ err_dma2:
+	free_dma(FIQ_FD1772);
+
+ err_dma1:
+	free_dma(FLOPPY_DMA);
+
+ err_blkdev:
+	unregister_blkdev(MAJOR_NR, "fd");
+
+ err_disk:
 	while (i--)
 		put_disk(disks[i]);
-	return 1;
+	return err;
 }
diff -Nru a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
--- a/drivers/atm/nicstar.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/atm/nicstar.c	Thu Jan 16 18:23:05 2003
@@ -345,9 +345,6 @@
    
    XPRINTK("nicstar: cleanup_module() called.\n");
 
-   if (MOD_IN_USE)
-      printk("nicstar: module in use, remove delayed.\n");
-
    del_timer(&ns_timer);
 
    for (i = 0; i < NS_MAX_CARDS; i++)
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/base/bus.c	Thu Jan 16 18:23:05 2003
@@ -282,26 +282,23 @@
  *	Walk the list of drivers that the bus has and call bus_match() 
  *	for each pair. If a compatible pair is found, break out and return.
  */
-static int device_attach(struct device * dev)
+static void device_attach(struct device * dev)
 {
  	struct bus_type * bus = dev->bus;
 	struct list_head * entry;
-	int error = 0;
 
 	if (dev->driver) {
 		device_bind_driver(dev);
-		return 0;
+		return;
 	}
 
-	if (!bus->match)
-		return 0;
-
-	list_for_each(entry,&bus->drivers.list) {
-		struct device_driver * drv = to_drv(entry);
-		if (!(error = bus_match(dev,drv)))
-			break;
+	if (bus->match) {
+		list_for_each(entry,&bus->drivers.list) {
+			struct device_driver * drv = to_drv(entry);
+			if (!bus_match(dev,drv))
+				break;
+		}
 	}
-	return error;
 }
 
 
@@ -318,22 +315,21 @@
  *	Note that we ignore the error from bus_match(), since it's perfectly
  *	valid for a driver not to bind to any devices.
  */
-static int driver_attach(struct device_driver * drv)
+static void driver_attach(struct device_driver * drv)
 {
 	struct bus_type * bus = drv->bus;
 	struct list_head * entry;
 
 	if (!bus->match)
-		return 0;
+		return;
 
 	list_for_each(entry,&bus->devices.list) {
 		struct device * dev = container_of(entry,struct device,bus_list);
 		if (!dev->driver) {
-			if (!bus_match(dev,drv) && dev->driver)
+			if (!bus_match(dev,drv))
 				devclass_add_device(dev);
 		}
 	}
-	return 0;
 }
 
 
@@ -393,8 +389,7 @@
 		down_write(&dev->bus->subsys.rwsem);
 		pr_debug("bus %s: add device %s\n",bus->name,dev->bus_id);
 		list_add_tail(&dev->bus_list,&dev->bus->devices.list);
-		if ((error = device_attach(dev)))
-			list_del_init(&dev->bus_list);
+		device_attach(dev);
 		up_write(&dev->bus->subsys.rwsem);
 		sysfs_create_link(&bus->devices.kobj,&dev->kobj,dev->bus_id);
 	}
@@ -446,11 +441,8 @@
 		}
 
 		down_write(&bus->subsys.rwsem);
-		if (!(error = devclass_add_driver(drv))) {
-			if ((error = driver_attach(drv))) {
-				devclass_remove_driver(drv);
-			}
-		}
+		if (!(error = devclass_add_driver(drv)))
+			driver_attach(drv);
 		up_write(&bus->subsys.rwsem);
 
 		if (error) {
diff -Nru a/drivers/base/node.c b/drivers/base/node.c
--- a/drivers/base/node.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/base/node.c	Thu Jan 16 18:23:05 2003
@@ -28,10 +28,10 @@
 };
 
 
-static ssize_t node_read_cpumap(struct device * dev, char * buf, size_t count, loff_t off)
+static ssize_t node_read_cpumap(struct device * dev, char * buf)
 {
 	struct node *node_dev = to_node(to_root(dev));
-        return off ? 0 : sprintf(buf,"%lx\n",node_dev->cpumap);
+        return sprintf(buf,"%lx\n",node_dev->cpumap);
 }
 static DEVICE_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
 
diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c
--- a/drivers/block/elevator.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/block/elevator.c	Thu Jan 16 18:23:06 2003
@@ -431,10 +431,12 @@
 void elv_unregister_queue(struct gendisk *disk)
 {
 	request_queue_t *q = disk->queue;
-	elevator_t *e = &q->elevator;
 
-	kobject_unregister(&e->kobj);
-	kobject_put(&disk->kobj);
+	if (q) {
+		elevator_t * e = &q->elevator;
+		kobject_unregister(&e->kobj);
+		kobject_put(&disk->kobj);
+	}
 }
 
 elevator_t elevator_noop = {
diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig
--- a/drivers/char/Kconfig	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/Kconfig	Thu Jan 16 18:23:05 2003
@@ -819,7 +819,7 @@
 	  inserted in and removed from the running kernel whenever you want).
 	  The module is called genrtc.o. If you want to compile it as a module,
 	  say M here and read <file:Documentation/modules.txt>. To load the
-	  module automaticaly add 'alias char-major-10-135 genrtc' to your
+	  module automatically add 'alias char-major-10-135 genrtc' to your
 	  /etc/modules.conf
 
 config GEN_RTC_X
diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/agp/agp.h	Thu Jan 16 18:23:05 2003
@@ -1,5 +1,5 @@
 /*
- * AGPGART module
+ * AGPGART
  * Copyright (C) 2002 Dave Jones
  * Copyright (C) 1999 Jeff Hartmann
  * Copyright (C) 1999 Precision Insight, Inc.
@@ -32,28 +32,8 @@
 
 extern struct agp_bridge_data agp_bridge;
 
-/* Generic routines. */
-void agp_generic_agp_enable(u32 mode);
-int agp_generic_agp_3_0_enable(u32 mode);
-int agp_generic_create_gatt_table(void);
-int agp_generic_free_gatt_table(void);
-agp_memory *agp_create_memory(int scratch_pages);
-int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type);
-int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type);
-agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
-void agp_generic_free_by_type(agp_memory * curr);
-void *agp_generic_alloc_page(void);
-void agp_generic_destroy_page(void *addr);
-int agp_generic_suspend(void);
-void agp_generic_resume(void);
-void agp_free_key(int key);
-int agp_num_entries(void);
-
 #define PFX "agpgart: "
 
-int agp_register_driver (struct pci_dev *dev);
-int agp_unregister_driver(void);
-
 #ifdef CONFIG_SMP
 static void ipi_handler(void *null)
 {
@@ -378,19 +358,31 @@
 	int (*chipset_setup) (struct pci_dev *pdev);	/* used to override generic */
 };
 
-struct agp_bridge_info {
-	unsigned short vendor_id;
-	const char *vendor_name;
-	int (*chipset_setup) (struct pci_dev *pdev);
-	struct agp_device_ids *ids;
+struct agp_driver {
+	struct module *owner;
+	struct pci_dev *dev;
 };
 
-extern struct agp_bridge_info ali_agp_bridge_info;
-extern struct agp_bridge_info amd_k8_agp_bridge_info;
-extern struct agp_bridge_info amd_agp_bridge_info;
-extern struct agp_bridge_info intel_agp_bridge_info;
-extern struct agp_bridge_info sis_agp_bridge_info;
-extern struct agp_bridge_info via_agp_bridge_info;
-extern struct agp_bridge_info hp_agp_bridge_info;
+
+/* Generic routines. */
+void agp_generic_agp_enable(u32 mode);
+int agp_generic_agp_3_0_enable(u32 mode);
+int agp_generic_create_gatt_table(void);
+int agp_generic_free_gatt_table(void);
+agp_memory *agp_create_memory(int scratch_pages);
+int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type);
+int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type);
+agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
+void agp_generic_free_by_type(agp_memory * curr);
+void *agp_generic_alloc_page(void);
+void agp_generic_destroy_page(void *addr);
+int agp_generic_suspend(void);
+void agp_generic_resume(void);
+void agp_free_key(int key);
+int agp_num_entries(void);
+int agp_register_driver (struct agp_driver *drv);
+int agp_unregister_driver(struct agp_driver *drv);
+u32 agp_collect_device_status(u32 mode, u32 command);
+void agp_device_command(u32 command, int agp_v3);
 
 #endif				/* _AGP_BACKEND_PRIV_H */
diff -Nru a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
--- a/drivers/char/agp/ali-agp.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/agp/ali-agp.c	Thu Jan 16 18:23:06 2003
@@ -336,6 +336,9 @@
 	return -ENODEV;
 }
 
+static struct agp_driver ali_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_ali_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -350,8 +353,9 @@
 		agp_bridge.dev = dev;
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
-		agp_register_driver(dev);
+		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+		ali_agp_driver.dev = dev;
+		agp_register_driver(&ali_agp_driver);
 		return 0;
 	}
 	return -ENODEV;	
@@ -390,7 +394,7 @@
 
 static void __exit agp_ali_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&ali_agp_driver);
 	pci_unregister_driver(&agp_ali_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
--- a/drivers/char/agp/amd-k7-agp.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/char/agp/amd-k7-agp.c	Thu Jan 16 18:23:07 2003
@@ -6,6 +6,9 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
+#include <linux/gfp.h>
+#include <linux/page-flags.h>
+#include <linux/mm.h>
 #include "agp.h"
 
 static int agp_try_unsupported __initdata = 0;
@@ -437,6 +440,10 @@
 }
 
 
+static struct agp_driver amd_k7_agp_driver = {
+	.owner = THIS_MODULE,
+};
+
 /* Supported Device Scanning routine */
 
 static int __init agp_amdk7_probe (struct pci_dev *dev, const struct pci_device_id *ent)
@@ -451,8 +458,9 @@
 		agp_bridge.dev = dev;
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
-		agp_register_driver(dev);
+		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+		amd_k7_agp_driver.dev = dev;
+		agp_register_driver(&amd_k7_agp_driver);
 		return 0;
 	}
 	return -ENODEV;
@@ -491,7 +499,7 @@
 
 static void __exit agp_amdk7_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&amd_k7_agp_driver);
 	pci_unregister_driver(&agp_amdk7_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/amd-k8-agp.c b/drivers/char/agp/amd-k8-agp.c
--- a/drivers/char/agp/amd-k8-agp.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/agp/amd-k8-agp.c	Thu Jan 16 18:23:06 2003
@@ -336,7 +336,6 @@
 	struct pci_dev *device = NULL;
 	u32 command, scratch; 
 	u8 cap_ptr;
-	u8 agp_v3;
 	u8 v3_devs=0;
 
 	/* FIXME: If 'mode' is x1/x2/x4 should we call the AGPv2 routines directly ?
@@ -369,77 +368,14 @@
 	}
 
 
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &command);
-
-	/*
-	 * PASS2: go through all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			printk (KERN_INFO "AGP: Setting up AGPv3 capable device at %d:%d:%d\n",
-					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
-			agp_v3 = (scratch & (1<<3) ) >>3;
-
-			/* adjust RQ depth */
-			command =
-			    ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x200) && (scratch & 0x200) && (mode & 0x200)))
-				command &= ~0x200;
-
-			/* disable FW if it's not supported */
-			if (!((command & 0x10) && (scratch & 0x10) && (mode & 0x10)))
-				command &= ~0x10;
-
-			if (!((command & 2) && (scratch & 2) && (mode & 2))) {
-				command &= ~2;		/* 8x */
-				printk (KERN_INFO "AGP: Putting device into 8x mode\n");
-			}
-
-			if (!((command & 1) && (scratch & 1) && (mode & 1))) {
-				command &= ~1;		/* 4x */
-				printk (KERN_INFO "AGP: Putting device into 4x mode\n");
-			}
-		}
-	}
-	/*
-	 * PASS3: Figure out the 8X/4X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
-
-	if (command & 2)
-		command &= ~5;	/* 8X */
-
-	if (command & 1)
-		command &= ~6;	/* 4X */
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &command);
 
+	command = agp_collect_device_status(mode, command);
 	command |= 0x100;
 
-	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx+8, command);
+	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_COMMAND, command);
 
-	/*
-	 * PASS4: Go through all AGP devices and update the
-	 *        command registers.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
+	agp_device_command(command, 1);
 }
 
 
@@ -472,6 +408,9 @@
 	return 0;
 }
 
+static struct agp_driver amd_k8_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_amdk8_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -485,9 +424,10 @@
 	agp_bridge.capndx = cap_ptr;
 
 	/* Fill in the mode register */
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
 	amd_8151_setup(dev);
-	agp_register_driver(dev);
+	amd_k8_agp_driver.dev = dev;
+	agp_register_driver(&amd_k8_agp_driver);
 	return 0;
 }
 
@@ -527,7 +467,7 @@
 
 static void __exit agp_amdk8_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&amd_k8_agp_driver);
 	pci_unregister_driver(&agp_amdk8_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
--- a/drivers/char/agp/backend.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/agp/backend.c	Thu Jan 16 18:23:06 2003
@@ -34,6 +34,8 @@
 #include <linux/miscdevice.h>
 #include <linux/pm.h>
 #include <linux/agp_backend.h>
+#include <linux/vmalloc.h>
+#include <asm/io.h>
 #include "agp.h"
 
 /* Due to XFree86 brain-damage, we can't go to 1.0 until they
@@ -217,36 +219,48 @@
 
 static int agp_count=0;
 
-int agp_register_driver (struct pci_dev *dev)
+int agp_register_driver (struct agp_driver *drv)
 {
 	int ret_val;
 
+	if (drv->dev == NULL) {
+		printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n");
+		return -EINVAL;
+	}
+
 	if (agp_count==1) {
 		printk (KERN_DEBUG PFX "Only one agpgart device currently supported.\n");
 		return -ENODEV;
 	}
 
-	ret_val = agp_backend_initialize(dev);
-	if (ret_val) {
-		agp_bridge.type = NOT_SUPPORTED;
-		return ret_val;
-	}
+	/* Grab reference on the chipset driver. */
+	if (!try_module_get(drv->owner))
+		return -EINVAL;
+
+	ret_val = agp_backend_initialize(drv->dev);
+	if (ret_val)
+		goto err_out;
+
 	ret_val = agp_frontend_initialize();
-	if (ret_val) {
-		agp_bridge.type = NOT_SUPPORTED;
-		agp_backend_cleanup();
-		return ret_val;
-	}
+	if (ret_val)
+		goto frontend_err;
 
+	/* FIXME: What to do with this? */
 	inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
 
 	pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
-
 	agp_count++;
 	return 0;
+
+frontend_err:
+	agp_backend_cleanup();
+err_out:
+	agp_bridge.type = NOT_SUPPORTED;
+	module_put(drv->owner);
+	return ret_val;
 }
 
-int agp_unregister_driver(void)
+int agp_unregister_driver(struct agp_driver *drv)
 {
 	agp_bridge.type = NOT_SUPPORTED;
 	pm_unregister_all(agp_power);
@@ -254,6 +268,7 @@
 	agp_backend_cleanup();
 	inter_module_unregister("drm_agp");
 	agp_count--;
+	module_put(drv->owner);
 	return 0;
 }
 
diff -Nru a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
--- a/drivers/char/agp/frontend.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/agp/frontend.c	Thu Jan 16 18:23:05 2003
@@ -34,8 +34,10 @@
 #include <linux/miscdevice.h>
 #include <linux/agp_backend.h>
 #include <linux/agpgart.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
 #include <asm/uaccess.h>
-
+#include <asm/pgtable.h>
 #include "agp.h"
 
 static struct agp_front_data agp_fe;
diff -Nru a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
--- a/drivers/char/agp/generic.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/agp/generic.c	Thu Jan 16 18:23:05 2003
@@ -116,7 +116,6 @@
 	agp_free_key(curr->key);
 	vfree(curr->memory);
 	kfree(curr);
-	MOD_DEC_USE_COUNT;
 }
 
 #define ENTRIES_PER_PAGE		(PAGE_SIZE / sizeof(unsigned long))
@@ -138,17 +137,12 @@
 		return new;
 	}
 
-	/* We always increase the module count, since free auto-decrements it */
-	MOD_INC_USE_COUNT;
-
 	scratch_pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
 
 	new = agp_create_memory(scratch_pages);
 
-	if (new == NULL) {
-		MOD_DEC_USE_COUNT;
+	if (new == NULL)
 		return NULL;
-	}
 
 	for (i = 0; i < page_count; i++) {
 		void *addr = agp_bridge.agp_alloc_page();
@@ -313,93 +307,106 @@
 
 
 /* Generic Agp routines - Start */
-void agp_generic_agp_enable(u32 mode)
+
+u32 agp_collect_device_status(u32 mode, u32 command)
 {
-	struct pci_dev *device = NULL;
-	u32 command, scratch; 
-	u8 cap_ptr;
-
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &command);
-
-	/*
-	 * PASS1: go through all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
+	struct pci_dev *device;
+	u8 agp;
+	u32 scratch; 
 
 	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
-
-			/* adjust RQ depth */
-			command = ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x00000200) &&
-			      (scratch & 0x00000200) &&
-			      (mode & 0x00000200)))
-				command &= ~0x00000200;
-
-			/* disable FW if it's not supported */
-			if (!((command & 0x00000010) &&
-			      (scratch & 0x00000010) &&
-			      (mode & 0x00000010)))
-				command &= ~0x00000010;
-
-			if (!((command & 4) &&
-			      (scratch & 4) &&
-			      (mode & 4)))
-				command &= ~0x00000004;
-
-			if (!((command & 2) &&
-			      (scratch & 2) &&
-			      (mode & 2)))
-				command &= ~0x00000002;
-
-			if (!((command & 1) &&
-			      (scratch & 1) &&
-			      (mode & 1)))
-				command &= ~0x00000001;
-		}
+		agp = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (!agp)
+			continue;
+
+		/*
+		 * Ok, here we have a AGP device. Disable impossible 
+		 * settings, and adjust the readqueue to the minimum.
+		 */
+		pci_read_config_dword(device, agp + PCI_AGP_STATUS, &scratch);
+
+		/* adjust RQ depth */
+		command = ((command & ~0xff000000) |
+		     min_t(u32, (mode & 0xff000000),
+			 min_t(u32, (command & 0xff000000),
+			     (scratch & 0xff000000))));
+
+		/* disable SBA if it's not supported */
+		if (!((command & 0x00000200) &&
+		      (scratch & 0x00000200) &&
+		      (mode & 0x00000200)))
+			command &= ~0x00000200;
+
+		/* disable FW if it's not supported */
+		if (!((command & 0x00000010) &&
+		      (scratch & 0x00000010) &&
+		      (mode & 0x00000010)))
+			command &= ~0x00000010;
+
+		if (!((command & 4) &&
+		      (scratch & 4) &&
+		      (mode & 4)))
+			command &= ~0x00000004;
+
+		if (!((command & 2) &&
+		      (scratch & 2) &&
+		      (mode & 2)))
+			command &= ~0x00000002;
+
+		if (!((command & 1) &&
+		      (scratch & 1) &&
+		      (mode & 1)))
+			command &= ~0x00000001;
 	}
-	/*
-	 * PASS2: Figure out the 4X/2X/1X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
 
 	if (command & 4)
 		command &= ~3;	/* 4X */
 
 	if (command & 2)
-		command &= ~5;	/* 2X */
+		command &= ~5;	/* 2X (8X for AGP3.0) */
 
 	if (command & 1)
-		command &= ~6;	/* 1X */
+		command &= ~6;	/* 1X (4X for AGP3.0) */
 
-	command |= 0x00000100;
+	return command;
+}
 
-	pci_write_config_dword(agp_bridge.dev,
-			       agp_bridge.capndx + 8,
-			       command);
+void agp_device_command(u32 command, int agp_v3)
+{
+	struct pci_dev *device;
+	int mode;
 
-	/*
-	 * PASS3: Go throu all AGP devices and update the
-	 *        command registers.
-	 */
+	mode = command & 0x7;
+	if (agp_v3)
+		mode *= 4;
 
 	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
+		u8 agp = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (!agp)
+			continue;
+
+		printk(KERN_INFO PFX "Putting AGP V%d device at %s into %dx mode\n",
+				agp_v3 ? 3 : 2, device->slot_name, mode);
+		pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command);
 	}
+}
+
+void agp_generic_agp_enable(u32 mode)
+{
+	u32 command;
+
+	pci_read_config_dword(agp_bridge.dev,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
+			      &command);
+
+	command = agp_collect_device_status(mode, command);
+	command |= 0x100;
+
+	pci_write_config_dword(agp_bridge.dev,
+			       agp_bridge.capndx + PCI_AGP_COMMAND,
+			       command);
+
+	agp_device_command(command, 0);
 }
 
 int agp_generic_create_gatt_table(void)
diff -Nru a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
--- a/drivers/char/agp/hp-agp.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/agp/hp-agp.c	Thu Jan 16 18:23:06 2003
@@ -368,10 +368,15 @@
 	return -ENODEV;
 }
 
+static struct agp_driver hp_agp_driver = {
+	.owner = THIS_MODULE;
+};
+
 static int __init agp_hp_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	if (agp_find_supported_device(dev) == 0) {
-		agp_register_driver(dev);
+		hp_agp_driver.dev = dev;
+		agp_register_driver(&hp_agp_driver);
 		return 0;
 	}
 	return -ENODEV;
@@ -410,7 +415,7 @@
 
 static void __exit agp_hp_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&hp_agp_driver);
 	pci_unregister_driver(&agp_hp_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
--- a/drivers/char/agp/i460-agp.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/agp/i460-agp.c	Thu Jan 16 18:23:06 2003
@@ -559,6 +559,10 @@
 	return 0;
 }
 
+static struct agp_driver i460_agp_driver = {
+	.owner = THIS_MODULE;
+};
+
 static int __init agp_intel_i460_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	u8 cap_ptr = 0;
@@ -570,7 +574,8 @@
 	agp_bridge.dev = dev;
 	agp_bridge.capndx = cap_ptr;
 	intel_i460_setup(dev);
-	agp_register_driver(dev);
+	i460_agp_driver.dev = dev;
+	agp_register_driver(&i460_agp_driver);
 	return 0;
 }
 
@@ -607,7 +612,7 @@
 
 static void __exit agp_intel_i460_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&i460_agp_driver);
 	pci_unregister_driver(&agp_intel_i460_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/i7x05-agp.c b/drivers/char/agp/i7x05-agp.c
--- a/drivers/char/agp/i7x05-agp.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/agp/i7x05-agp.c	Thu Jan 16 18:23:05 2003
@@ -164,6 +164,9 @@
 	return -ENODEV;
 }
 
+static struct agp_driver i7x05_agp_driver = {
+	.owner = THIS_MODULE;
+};
 
 static int __init agp_i7x05_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -177,8 +180,9 @@
 		agp_bridge.dev = dev;
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode)
-		agp_register_driver(dev);
+		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode)
+		i7x05_agp_driver.dev = dev;
+		agp_register_driver(&i7x05_agp_driver);
 		return 0;
 	}
 	return -ENODEV;
@@ -218,7 +222,7 @@
 
 static void __exit agp_i7x05_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&i7x05_agp_driver);
 	pci_unregister_driver(&agp_i7x05_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
--- a/drivers/char/agp/intel-agp.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/agp/intel-agp.c	Thu Jan 16 18:23:05 2003
@@ -195,7 +195,6 @@
 		new->page_count = pg_count;
 		new->num_scratch_pages = 0;
 		vfree(new->memory);
-		MOD_INC_USE_COUNT;
 		return new;
 	}
 	if(type == AGP_PHYS_MEMORY) {
@@ -212,7 +211,6 @@
 		if (new == NULL)
 			return NULL;
 
-		MOD_INC_USE_COUNT;
 		addr = agp_bridge.agp_alloc_page();
 
 		if (addr == NULL) {
@@ -238,7 +236,6 @@
 		vfree(curr->memory);
 	}
 	kfree(curr);
-	MOD_DEC_USE_COUNT;
 }
 
 static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
@@ -507,7 +504,6 @@
 
 		if (nw == NULL) return(NULL);
 
-		MOD_INC_USE_COUNT;
 		addr = agp_bridge.agp_alloc_page();
 		if (addr == NULL) {
 			/* free this structure */
@@ -1423,17 +1419,21 @@
 	agp_bridge.capndx = cap_ptr;
 
 	/* Fill in the mode register */
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
 
 	/* probe for known chipsets */
 	return agp_lookup_host_bridge(dev);
 }
 
+static struct agp_driver intel_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_intel_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	if (agp_find_supported_device(dev) == 0) {
-		agp_register_driver(dev);
+		intel_agp_driver.dev = dev;	
+		agp_register_driver(&intel_agp_driver);
 		return 0;
 	}
 	return -ENODEV;	
@@ -1479,7 +1479,7 @@
 
 static void __exit agp_intel_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&intel_agp_driver);
 	pci_unregister_driver(&agp_intel_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
--- a/drivers/char/agp/sis-agp.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/agp/sis-agp.c	Thu Jan 16 18:23:05 2003
@@ -221,6 +221,9 @@
 	return -ENODEV;
 }
 
+static struct agp_driver sis_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_sis_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -235,8 +238,9 @@
 		agp_bridge.dev = dev;
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
-		agp_register_driver(dev);
+		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+		sis_agp_driver.dev = dev;
+		agp_register_driver(&sis_agp_driver);
 		return 0;
 	}
 	return -ENODEV;
@@ -275,7 +279,7 @@
 
 static void __exit agp_sis_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&sis_agp_driver);
 	pci_unregister_driver(&agp_sis_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
--- a/drivers/char/agp/sworks-agp.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/agp/sworks-agp.c	Thu Jan 16 18:23:05 2003
@@ -229,8 +229,6 @@
 	struct aper_size_info_lvl2 *current_size;
 	u32 temp;
 	u8 enable_reg;
-	u8 cap_ptr;
-	u32 cap_id;
 	u16 cap_reg;
 
 	current_size = A_SIZE_LVL2(agp_bridge.current_size);
@@ -257,22 +255,11 @@
 			      SVWRKS_AGP_ENABLE, enable_reg);
 	agp_bridge.tlb_flush(NULL);
 
-	pci_read_config_byte(serverworks_private.svrwrks_dev, 0x34, &cap_ptr);
-	if (cap_ptr != 0) {
-		do {
-			pci_read_config_dword(serverworks_private.svrwrks_dev,
-					      cap_ptr, &cap_id);
-
-			if ((cap_id & 0xff) != 0x02)
-				cap_ptr = (cap_id >> 8) & 0xff;
-		}
-		while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0));
-	}
-	agp_bridge.capndx = cap_ptr;
+	agp_bridge.capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP);
 
 	/* Fill in the mode register */
 	pci_read_config_dword(serverworks_private.svrwrks_dev,
-			      agp_bridge.capndx+4, &agp_bridge.mode);
+			      agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
 
 	pci_read_config_byte(agp_bridge.dev, SVWRKS_CACHING, &enable_reg);
 	enable_reg &= ~0x3;
@@ -413,104 +400,24 @@
 
 static void serverworks_agp_enable(u32 mode)
 {
-	struct pci_dev *device = NULL;
-	u32 command, scratch, cap_id;
-	u8 cap_ptr;
+	u32 command;
 
 	pci_read_config_dword(serverworks_private.svrwrks_dev,
-			      agp_bridge.capndx + 4,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
 			      &command);
 
-	/*
-	 * PASS1: go throu all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
-
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			do {
-				pci_read_config_dword(device,
-						      cap_ptr, &cap_id);
-
-				if ((cap_id & 0xff) != 0x02)
-					cap_ptr = (cap_id >> 8) & 0xff;
-			}
-			while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
-		}
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
-
-			/* adjust RQ depth */
-			command =
-			    ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x00000200) &&
-			      (scratch & 0x00000200) &&
-			      (mode & 0x00000200)))
-				command &= ~0x00000200;
-
-			/* disable FW */
-			command &= ~0x00000010;
-
-			command &= ~0x00000008;
-
-			if (!((command & 4) &&
-			      (scratch & 4) &&
-			      (mode & 4)))
-				command &= ~0x00000004;
-
-			if (!((command & 2) &&
-			      (scratch & 2) &&
-			      (mode & 2)))
-				command &= ~0x00000002;
-
-			if (!((command & 1) &&
-			      (scratch & 1) &&
-			      (mode & 1)))
-				command &= ~0x00000001;
-		}
-	}
-	/*
-	 * PASS2: Figure out the 4X/2X/1X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
+	command = agp_collect_device_status(mode, command);
 
-	if (command & 4) {
-		command &= ~3;	/* 4X */
-	}
-	if (command & 2) {
-		command &= ~5;	/* 2X */
-	}
-	if (command & 1) {
-		command &= ~6;	/* 1X */
-	}
-	command |= 0x00000100;
+	command &= ~0x10;	/* disable FW */
+	command &= ~0x08;
+
+	command |= 0x100;
 
 	pci_write_config_dword(serverworks_private.svrwrks_dev,
-			       agp_bridge.capndx + 8,
+			       agp_bridge.capndx + PCI_AGP_COMMAND,
 			       command);
 
-	/*
-	 * PASS3: Go throu all AGP devices and update the
-	 *        command registers.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
+	agp_device_command(command, 0);
 }
 
 static int __init serverworks_setup (struct pci_dev *pdev)
@@ -618,11 +525,15 @@
 	return -ENODEV;
 }
 
+static struct agp_driver serverworks_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_serverworks_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	if (agp_find_supported_device(dev) == 0) {
-		agp_register_driver(dev);
+		serverworks_agp_driver.dev = dev;
+		agp_register_driver(&serverworks_agp_driver);
 		return 0;
 	}
 	return -ENODEV;	
@@ -661,7 +572,7 @@
 
 static void __exit agp_serverworks_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&serverworks_agp_driver);
 	pci_unregister_driver(&agp_serverworks_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
--- a/drivers/char/agp/via-agp.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/agp/via-agp.c	Thu Jan 16 18:23:06 2003
@@ -244,6 +244,9 @@
 	return -ENODEV;
 }
 
+static struct agp_driver via_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -258,8 +261,9 @@
 		agp_bridge.dev = dev;
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
-		agp_register_driver(dev);
+		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+		via_agp_driver.dev = dev;
+		agp_register_driver(&via_agp_driver);
 		return 0;
 	}
 	return -ENODEV;	
@@ -298,7 +302,7 @@
 
 static void __exit agp_via_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&via_agp_driver);
 	pci_unregister_driver(&agp_via_pci_driver);
 }
 
diff -Nru a/drivers/char/agp/via-kt400.c b/drivers/char/agp/via-kt400.c
--- a/drivers/char/agp/via-kt400.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/agp/via-kt400.c	Thu Jan 16 18:23:06 2003
@@ -100,6 +100,9 @@
 		printk (KERN_INFO PFX "agp_generic_agp_3_0_enable() failed\n");
 }
 
+static struct agp_driver via_kt400_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -147,9 +150,10 @@
 	agp_bridge.cant_use_aperture = 0;
 
 	/* Fill in the mode register */
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+4, &agp_bridge.mode);
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
 
-	agp_register_driver(dev);
+	via_kt400_agp_driver.dev = dev;
+	agp_register_driver(&via_kt400_agp_driver);
 	return 0;
 }
 
@@ -186,7 +190,7 @@
 
 static void __exit agp_via_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&via_kt400_agp_driver);
 	pci_unregister_driver(&agp_via_pci_driver);
 }
 
diff -Nru a/drivers/char/i8k.c b/drivers/char/i8k.c
--- a/drivers/char/i8k.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/i8k.c	Thu Jan 16 18:23:05 2003
@@ -27,7 +27,7 @@
 
 #include <linux/i8k.h>
 
-#define I8K_VERSION		"1.7 21/11/2001"
+#define I8K_VERSION		"1.13 14/05/2002"
 
 #define I8K_SMM_FN_STATUS	0x0025
 #define I8K_SMM_POWER_STATUS	0x0069
@@ -67,14 +67,17 @@
 static char serial_number[16] = "?";
 
 static int force = 0;
+static int restricted = 0;
 static int power_status = 0;
 
 MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
 MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
 MODULE_LICENSE("GPL");
 MODULE_PARM(force, "i");
+MODULE_PARM(restricted, "i");
 MODULE_PARM(power_status, "i");
 MODULE_PARM_DESC(force, "Force loading without checking for supported models");
+MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
 MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
 
 static ssize_t i8k_read(struct file *, char *, size_t, loff_t *);
@@ -370,6 +373,9 @@
 	break;
 
     case I8K_SET_FAN:
+	if (restricted && !capable(CAP_SYS_ADMIN)) {
+	    return -EPERM;
+	}
 	if (copy_from_user(&val, (int *)arg, sizeof(int))) {
 	    return -EFAULT;
 	}
diff -Nru a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
--- a/drivers/char/pcmcia/synclink_cs.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/pcmcia/synclink_cs.c	Thu Jan 16 18:23:05 2003
@@ -2513,10 +2513,6 @@
 		return get_stats(info,(struct mgsl_icount*)arg);
 	case MGSL_IOCWAITEVENT:
 		return wait_events(info,(int*)arg);
-	case MGSL_IOCCLRMODCOUNT:
-		while(MOD_IN_USE)
-			MOD_DEC_USE_COUNT;
-		return 0;
 	case TIOCMIWAIT:
 		return modem_input_wait(info,(int)arg);
 	case TIOCGICOUNT:
@@ -2694,8 +2690,7 @@
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("%s(%d):mgslpc_close(%s) exit, count=%d\n", __FILE__,__LINE__,
 			tty->driver.name, info->count);
-	if(MOD_IN_USE)
-		MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
 }
 
 /* Wait until the transmitter is empty.
@@ -3003,8 +2998,7 @@
 	
 cleanup:			
 	if (retval) {
-		if(MOD_IN_USE)
-			MOD_DEC_USE_COUNT;
+		MOD_DEC_USE_COUNT;
 		if(info->count)
 			info->count--;
 	}
diff -Nru a/drivers/char/synclink.c b/drivers/char/synclink.c
--- a/drivers/char/synclink.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/synclink.c	Thu Jan 16 18:23:05 2003
@@ -3119,11 +3119,6 @@
 			return mgsl_wait_event(info,(int*)arg);
 		case MGSL_IOCLOOPTXDONE:
 			return mgsl_loopmode_send_done(info);
-		case MGSL_IOCCLRMODCOUNT:
-			while(MOD_IN_USE)
-				MOD_DEC_USE_COUNT;
-			return 0;
-
 		/* Wait for modem input (DCD,RI,DSR,CTS) change
 		 * as specified by mask in arg (TIOCM_RNG/DSR/CD/CTS)
 		 */
@@ -3328,8 +3323,7 @@
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__,
 			tty->driver.name, info->count);
-	if(MOD_IN_USE)
-		MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
 			
 }	/* end of mgsl_close() */
 
@@ -3689,8 +3683,7 @@
 	
 cleanup:			
 	if (retval) {
-		if(MOD_IN_USE)
-			MOD_DEC_USE_COUNT;
+		MOD_DEC_USE_COUNT;
 		if(info->count)
 			info->count--;
 	}
diff -Nru a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
--- a/drivers/char/synclinkmp.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/synclinkmp.c	Thu Jan 16 18:23:05 2003
@@ -826,8 +826,7 @@
 
 cleanup:
 	if (retval) {
-		if(MOD_IN_USE)
-			MOD_DEC_USE_COUNT;
+		MOD_DEC_USE_COUNT;
 		if(info->count)
 			info->count--;
 	}
@@ -926,8 +925,7 @@
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__,
 			tty->driver.name, info->count);
-	if(MOD_IN_USE)
-		MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
 }
 
 /* Called by tty_hangup() when a hangup is signaled.
@@ -1415,10 +1413,6 @@
 		return wait_mgsl_event(info,(int*)arg);
 	case MGSL_IOCLOOPTXDONE:
 		return 0; // TODO: Not supported, need to document
-	case MGSL_IOCCLRMODCOUNT:
-		while(MOD_IN_USE)
-			MOD_DEC_USE_COUNT;
-		return 0;
 		/* Wait for modem input (DCD,RI,DSR,CTS) change
 		 * as specified by mask in arg (TIOCM_RNG/DSR/CD/CTS)
 		 */
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/tty_io.c	Thu Jan 16 18:23:06 2003
@@ -833,6 +833,11 @@
 	 * and locked termios may be retained.)
 	 */
 
+	if (!try_module_get(driver->owner)) {
+		retval = -ENODEV;
+		goto end_init;
+	}
+
 	o_tty = NULL;
 	tp = o_tp = NULL;
 	ltp = o_ltp = NULL;
@@ -991,6 +996,7 @@
 	free_tty_struct(tty);
 
 fail_no_mem:
+	module_put(driver->owner);
 	retval = -ENOMEM;
 	goto end_init;
 
@@ -1033,6 +1039,7 @@
 	tty->magic = 0;
 	(*tty->driver.refcount)--;
 	list_del(&tty->tty_files);
+	module_put(tty->driver.owner);
 	free_tty_struct(tty);
 }
 
@@ -1836,6 +1843,8 @@
 #else
 	struct tty_struct *tty = arg;
 	struct task_struct *p;
+	struct list_head *l;
+	struct pid *pid;
 	int session;
 	int		i;
 	struct file	*filp;
@@ -1848,9 +1857,8 @@
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
 	read_lock(&tasklist_lock);
-	for_each_process(p) {
-		if ((p->tty == tty) ||
-		    ((session > 0) && (p->session == session))) {
+	for_each_task_pid(session, PIDTYPE_SID, p, l, pid) {
+		if (p->tty == tty || session > 0) {
 			printk(KERN_NOTICE "SAK: killed process %d"
 			    " (%s): p->session==tty->session\n",
 			    p->pid, p->comm);
diff -Nru a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
--- a/drivers/char/watchdog/acquirewdt.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/watchdog/acquirewdt.c	Thu Jan 16 18:23:06 2003
@@ -24,24 +24,18 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
 
 static int acq_is_open;
 static spinlock_t acq_lock;
diff -Nru a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c
--- a/drivers/char/watchdog/advantechwdt.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/advantechwdt.c	Thu Jan 16 18:23:05 2003
@@ -13,64 +13,49 @@
  *	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.
- *	
- *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide 
- *	warranty for any of this software. This material is provided 
- *	"AS-IS" and at no charge.	
+ *
+ *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ *	warranty for any of this software. This material is provided
+ *	"AS-IS" and at no charge.
  *
  *	(c) Copyright 1995    Alan Cox <alan@redhat.com>
  *
- *      14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
- *          Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
- *          Added timeout module option to override default
+ *	14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
+ *	    Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
  */
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
-static int advwdt_is_open;
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+static unsigned long advwdt_is_open;
 static char adv_expect_close;
-static spinlock_t advwdt_lock;
 
 /*
  *	You must set these - there is no sane way to probe for this board.
  *
  *	To enable or restart, write the timeout value in seconds (1 to 63)
- *	to I/O port WDT_START.  To disable, read I/O port WDT_STOP.
+ *	to I/O port wdt_start.  To disable, read I/O port wdt_stop.
  *	Both are 0x443 for most boards (tested on a PCA-6276VE-00B1), but
  *	check your manual (at least the PCA-6159 seems to be different -
- *	the manual says WDT_STOP is 0x43, not 0x443).
+ *	the manual says wdt_stop is 0x43, not 0x443).
  *	(0x43 is also a write-only control register for the 8254 timer!)
- *
- *	TODO: module parameters to set the I/O port addresses
  */
  
-#define WDT_STOP 0x443
-#define WDT_START 0x443
-
-#define WD_TIMO 60		/* 1 minute */
+static int wdt_stop = 0x443;
+static int wdt_start = 0x443;
 
-static int timeout = WD_TIMO;	/* in seconds */
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=60)"); 
+static int wd_margin = 60; /* 60 sec default timeout */
 
 #ifdef CONFIG_WATCHDOG_NOWAYOUT
 static int nowayout = 1;
@@ -84,12 +69,44 @@
 /*
  *	Kernel methods.
  */
- 
+
+#ifndef MODULE
+
+static int __init adv_setup(char *str)
+{
+	int ints[4];
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+
+	if(ints[0] > 0){
+		wdt_stop = ints[1];
+		if(ints[0] > 1)
+			wdt_start = ints[2];
+	}
+
+	return 1;
+}
+
+__setup("advwdt=", adv_setup);
+
+#endif /* !MODULE */
+
+MODULE_PARM(wdt_stop, "i");
+MODULE_PARM_DESC(wdt_stop, "Advantech WDT 'stop' io port (default 0x443)");
+MODULE_PARM(wdt_start, "i");
+MODULE_PARM_DESC(wdt_start, "Advantech WDT 'start' io port (default 0x443)");
+
 static void
 advwdt_ping(void)
 {
 	/* Write a watchdog value */
-	outb_p(timeout, WDT_START);
+	outb_p(wd_margin, wdt_start);
+}
+
+static void
+advwdt_disable(void)
+{
+	inb_p(wdt_stop);
 }
 
 static ssize_t
@@ -118,16 +135,11 @@
 	return count;
 }
 
-static ssize_t
-advwdt_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-{
-	return -EINVAL;
-}
-
 static int
 advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	  unsigned long arg)
 {
+	int new_margin;
 	static struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
 		.firmware_version = 1,
@@ -139,16 +151,47 @@
 	  if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
 	    return -EFAULT;
 	  break;
-	  
+
 	case WDIOC_GETSTATUS:
-	  if (copy_to_user((int *)arg, &advwdt_is_open,  sizeof(int)))
-	    return -EFAULT;
-	  break;
+	case WDIOC_GETBOOTSTATUS:
+	  return put_user(0, (int *)arg);
 
 	case WDIOC_KEEPALIVE:
 	  advwdt_ping();
 	  break;
 
+	case WDIOC_SETTIMEOUT:
+	  if (get_user(new_margin, (int *)arg))
+		  return -EFAULT;
+	  if ((new_margin < 1) || (new_margin > 63))
+		  return -EINVAL;
+	  wd_margin = new_margin;
+	  advwdt_ping();
+	  /* Fall */
+
+	case WDIOC_GETTIMEOUT:
+	  return put_user(wd_margin, (int *)arg);
+
+	case WDIOC_SETOPTIONS:
+	{
+	  int options, retval = -EINVAL;
+
+	  if (get_user(options, (int *)arg))
+	    return -EFAULT;
+
+	  if (options & WDIOS_DISABLECARD) {
+	    advwdt_disable();
+	    retval = 0;
+	  }
+
+	  if (options & WDIOS_ENABLECARD) {
+	    advwdt_ping();
+	    retval = 0;
+	  }
+
+	  return retval;
+	}
+
 	default:
 	  return -ENOTTY;
 	}
@@ -158,37 +201,27 @@
 static int
 advwdt_open(struct inode *inode, struct file *file)
 {
-	if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
-		spin_lock(&advwdt_lock);
-		if (advwdt_is_open) {
-			spin_unlock(&advwdt_lock);
-			return -EBUSY;
-		}
+	if (test_and_set_bit(0, &advwdt_is_open))
+		return -EBUSY;
+	/*
+	 *	Activate
+	 */
 
-		if (nowayout)
-			MOD_INC_USE_COUNT;
-
-		/* Activate */
-		advwdt_is_open = 1;
-		advwdt_ping();
-		spin_unlock(&advwdt_lock);
-		return 0;
-	} else {
-		return -ENODEV;
-	}
+	advwdt_ping();
+	return 0;
 }
 
 static int
 advwdt_close(struct inode *inode, struct file *file)
 {
-	if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
-		spin_lock(&advwdt_lock);
-		if (!nowayout)
-			inb_p(WDT_STOP);
-
-		advwdt_is_open = 0;
-		spin_unlock(&advwdt_lock);
+	if (adv_expect_close == 42) {
+		advwdt_disable();
+	} else {
+		printk(KERN_CRIT "advancetechwdt: Unexpected close, not stopping watchdog!\n");
+		advwdt_ping();
 	}
+	clear_bit(0, &advwdt_is_open);
+	adv_expect_close = 0;
 	return 0;
 }
 
@@ -200,10 +233,10 @@
 advwdt_notify_sys(struct notifier_block *this, unsigned long code,
 	void *unused)
 {
-	if (code == SYS_DOWN || code == SYS_HALT)
+	if (code == SYS_DOWN || code == SYS_HALT) {
 		/* Turn the WDT off */
-		inb_p(WDT_STOP);
-
+		advwdt_disable();
+	}
 	return NOTIFY_DONE;
 }
  
@@ -213,7 +246,6 @@
  
 static struct file_operations advwdt_fops = {
 	.owner		= THIS_MODULE,
-	.read		= advwdt_read,
 	.write		= advwdt_write,
 	.ioctl		= advwdt_ioctl,
 	.open		= advwdt_open,
@@ -237,35 +269,22 @@
 	.priority = 0
 };
 
-static void __init
-advwdt_validate_timeout(void)
-{
-	if (timeout < 1 || timeout > 63) {
-		timeout = WD_TIMO;
-		printk(KERN_INFO "advantechwdt: timeout value must be 1 <= x <= 63, using %d\n", timeout);
-	}
-}
-
 static int __init
 advwdt_init(void)
 {
-	printk("WDT driver for Advantech single board computer initialising.\n");
+	printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
 
-	advwdt_validate_timeout();
-	spin_lock_init(&advwdt_lock);
 	if (misc_register(&advwdt_miscdev))
 		return -ENODEV;
-#if WDT_START != WDT_STOP
-	if (!request_region(WDT_STOP, 1, "Advantech WDT")) {
-		misc_deregister(&advwdt_miscdev);
+	if (wdt_stop != wdt_start)
+		if (!request_region(wdt_stop, 1, "Advantech WDT")) {
+			misc_deregister(&advwdt_miscdev);
 		return -EIO;
 	}
-#endif
-	if (!request_region(WDT_START, 1, "Advantech WDT")) {
+	if (!request_region(wdt_start, 1, "Advantech WDT")) {
 		misc_deregister(&advwdt_miscdev);
-#if WDT_START != WDT_STOP
-		release_region(WDT_STOP, 1);
-#endif
+		if (wdt_stop != wdt_start)
+			release_region(wdt_stop, 1);
 		return -EIO;
 	}
 	register_reboot_notifier(&advwdt_notifier);
@@ -277,14 +296,15 @@
 {
 	misc_deregister(&advwdt_miscdev);
 	unregister_reboot_notifier(&advwdt_notifier);
-#if WDT_START != WDT_STOP
-	release_region(WDT_STOP,1);
-#endif
-	release_region(WDT_START,1);
+	if(wdt_stop != wdt_start)
+		release_region(wdt_stop,1);
+	release_region(wdt_start,1);
 }
 
 module_init(advwdt_init);
 module_exit(advwdt_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marek Michalkiewicz <marekm@linux.org.pl>");
+MODULE_DESCRIPTION("Advantech Single Board Computer WDT driver");
 
diff -Nru a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
--- a/drivers/char/watchdog/alim7101_wdt.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/watchdog/alim7101_wdt.c	Thu Jan 16 18:23:06 2003
@@ -30,25 +30,19 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
 #include <linux/timer.h>
-#include <linux/sched.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
 
 #define OUR_NAME "alim7101_wdt"
 
diff -Nru a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
--- a/drivers/char/watchdog/eurotechwdt.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/eurotechwdt.c	Thu Jan 16 18:23:05 2003
@@ -3,78 +3,82 @@
  *
  *	(c) Copyright 2001 Ascensit <support@ascensit.com>
  *	(c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
+ *	(c) Copyright 2002 Rob Radez <rob@osinvestor.com>
  *
  *	Based on wdt.c.
  *	Original copyright messages:
  *
- *	(c) Copyright 1996-1997 Alan Cox <alan@redhat.com>, All Rights Reserved.
- *	http://www.redhat.com
+ *      (c) Copyright 1996-1997 Alan Cox <alan@redhat.com>, All Rights Reserved.
+ *                              http://www.redhat.com
  *
- *	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.
- *
- *	Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
- *	warranty for any of this software. This material is provided
- *	"AS-IS" and at no charge.
- *
- *	(c) Copyright 1995 Alan Cox <alan@lxorguk.ukuu.org.uk>
- *
- *	14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
- *	  Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
- *	  Added timeout module option to override default
+ *      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.
+ *
+ *      Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
+ *      warranty for any of this software. This material is provided
+ *      "AS-IS" and at no charge.
+ *
+ *      (c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>*
+ */
+
+/* Changelog:
+ *
+ * 2002/04/25 - Rob Radez
+ *	clean up #includes
+ *	clean up locking
+ *	make __setup param unique
+ *	proper options in watchdog_info
+ *	add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls
+ *	add expect_close support
+ *
+ * 2001 - Rodolfo Giometti
+ *	Initial release
+ *
+ * 2002.05.30 - Joel Becker <joel.becker@oracle.com>
+ * 	Added Matt Domsch's nowayout module option.
  */
 
 #include <linux/config.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-#include <linux/spinlock.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static int eurwdt_is_open;
-static spinlock_t eurwdt_lock;
+static unsigned long eurwdt_is_open;
+static int eurwdt_timeout;
 static char eur_expect_close;
- 
+
 /*
  * You must set these - there is no sane way to probe for this board.
- * You can use wdt=x,y to set these now.
+ * You can use eurwdt=x,y to set these now.
  */
  
 static int io = 0x3f0;
 static int irq = 10;
 static char *ev = "int";
  
-#define WDT_TIMEOUT		60	/* 1 minute */
-static int timeout = WDT_TIMEOUT;
-
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Eurotech WDT timeout in seconds (default=60)"); 
+#define WDT_TIMEOUT		60                /* 1 minute */
 
 #ifdef CONFIG_WATCHDOG_NOWAYOUT
 static int nowayout = 1;
 #else
 static int nowayout = 0;
 #endif
+
 MODULE_PARM(nowayout,"i");
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
-
 /*
  * Some symbolic names 
  */
@@ -115,7 +119,7 @@
 	return 1;
 }
  
-__setup("wdt=", eurwdt_setup);
+__setup("eurwdt=", eurwdt_setup);
 
 #endif /* !MODULE */
  
@@ -124,22 +128,13 @@
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(irq, "Eurotech WDT irq (default=10)");
 MODULE_PARM(ev, "s");
-MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `reboot')");
+MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `int')");
 
 
 /*
  * Programming support
  */
 
-static void __init eurwdt_validate_timeout(void)
-{
-	if (timeout < 0 || timeout > 255) {
-		timeout = WDT_TIMEOUT;
-		printk(KERN_INFO "eurwdt: timeout must be 0 < x < 255, using %d\n",
-			timeout);
-	}
-}
-
 static inline void eurwdt_write_reg(u8 index, u8 data)
 {
 	outb(index, io);
@@ -214,7 +209,7 @@
 static void eurwdt_ping(void)
 {
 	/* Write the watchdog default value */
-	eurwdt_set_timeout(timeout);
+	eurwdt_set_timeout(eurwdt_timeout);
 }
  
 /**
@@ -250,10 +245,9 @@
 			}
 		}
 		eurwdt_ping();	/* the default timeout */
-		return 1;
 	}
 
-	return 0;
+	return count;
 }
 
 /**
@@ -271,12 +265,13 @@
 	unsigned int cmd, unsigned long arg)
 {
 	static struct watchdog_info ident = {
-		.options	  = WDIOF_CARDRESET,
+		.options	  = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
 		.firmware_version = 1,
 		.identity	  = "WDT Eurotech CPU-1220/1410",
 	};
 
 	int time;
+	int options, retval = -EINVAL;
  
 	switch(cmd) {
 	default:
@@ -286,6 +281,7 @@
 		return copy_to_user((struct watchdog_info *)arg, &ident,
 			sizeof(ident)) ? -EFAULT : 0;
  
+	case WDIOC_GETSTATUS:
 	case WDIOC_GETBOOTSTATUS:
 		return put_user(0, (int *) arg);
 
@@ -301,9 +297,26 @@
 		if (time < 0 || time > 255)
 			return -EINVAL;
 
-		timeout = time; 
+		eurwdt_timeout = time; 
 		eurwdt_set_timeout(time); 
-		return 0;
+		/* Fall */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(eurwdt_timeout, (int *)arg);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(options, (int *)arg))
+			return -EFAULT;
+		if (options & WDIOS_DISABLECARD) {
+			eurwdt_disable_timer();
+			retval = 0;
+		}
+		if (options & WDIOS_ENABLECARD) {
+			eurwdt_activate_timer();
+			eurwdt_ping();
+			retval = 0;
+		}
+		return retval;
 	}
 }
 
@@ -318,32 +331,12 @@
  
 static int eurwdt_open(struct inode *inode, struct file *file)
 {
-	switch (minor(inode->i_rdev)) {
-	case WATCHDOG_MINOR:
-		spin_lock(&eurwdt_lock);
-		if (eurwdt_is_open) {
-			spin_unlock(&eurwdt_lock);
-			return -EBUSY;
-		}
-		 if (nowayout)
-			 MOD_INC_USE_COUNT;
-
-		eurwdt_is_open = 1;
-
-		/* Activate the WDT */
-		eurwdt_activate_timer(); 
-
-		spin_unlock(&eurwdt_lock);
-
-		MOD_INC_USE_COUNT;
-		return 0;
-
-	case TEMP_MINOR:
-		return 0;
-
-	default:
-		return -ENODEV;
-	}
+	if (test_and_set_bit(0, &eurwdt_is_open))
+		return -EBUSY;
+	eurwdt_timeout = WDT_TIMEOUT;	/* initial timeout */
+	/* Activate the WDT */
+	eurwdt_activate_timer();
+	return 0;
 }
  
 /**
@@ -360,14 +353,14 @@
  
 static int eurwdt_release(struct inode *inode, struct file *file)
 {
-	if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
-		if (!nowayout)
-			eurwdt_disable_timer();
-
-		eurwdt_is_open = 0;
-		MOD_DEC_USE_COUNT;
-	}
-
+	if (eur_expect_close == 42) {
+		eurwdt_disable_timer();
+	} else {
+		printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n");
+		eurwdt_ping();
+    }
+	clear_bit(0, &eurwdt_is_open);
+	eur_expect_close = 0;
 	return 0;
 }
  
@@ -456,7 +449,6 @@
 {
 	int ret;
 
-	eurwdt_validate_timeout();
 	ret = misc_register(&eurwdt_miscdev);
 	if (ret) {
 		printk(KERN_ERR "eurwdt: can't misc_register on minor=%d\n",
@@ -488,8 +480,6 @@
 	printk(KERN_INFO "Eurotech WDT driver 0.01 at %X (Interrupt %d)"
 		" - timeout event: %s\n", 
 		io, irq, (!strcmp("int", ev) ? "int" : "reboot"));
-
-	spin_lock_init(&eurwdt_lock);
 
 out:
 	return ret;
diff -Nru a/drivers/char/watchdog/i810-tco.c b/drivers/char/watchdog/i810-tco.c
--- a/drivers/char/watchdog/i810-tco.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/i810-tco.c	Thu Jan 16 18:23:05 2003
@@ -47,9 +47,6 @@
  
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/reboot.h>
diff -Nru a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
--- a/drivers/char/watchdog/ib700wdt.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/watchdog/ib700wdt.c	Thu Jan 16 18:23:07 2003
@@ -33,24 +33,18 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
 
 static int ibwdt_is_open;
 static spinlock_t ibwdt_lock;
@@ -92,15 +86,32 @@
  *
  */
 
+static int wd_times[] = {
+	30,	/* 0x0 */
+	28,	/* 0x1 */
+	26,	/* 0x2 */
+	24,	/* 0x3 */
+	22,	/* 0x4 */
+	20,	/* 0x5 */
+	18,	/* 0x6 */
+	16,	/* 0x7 */
+	14,	/* 0x8 */
+	12,	/* 0x9 */
+	10,	/* 0xA */
+	8,	/* 0xB */
+	6,	/* 0xC */
+	4,	/* 0xD */
+	2,	/* 0xE */
+	0,	/* 0xF */
+};
+
 #define WDT_STOP 0x441
 #define WDT_START 0x443
 
+/* Default timeout */
 #define WD_TIMO 0		/* 30 seconds +/- 20%, from table */
 
-static int timeout_val = WD_TIMO;	/* value in table */
-static int timeout = 30;	        /* in seconds */
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, 0 < n < 30, must be even (default=30)");
+static int wd_margin = WD_TIMO;
 
 #ifdef CONFIG_WATCHDOG_NOWAYOUT
 static int nowayout = 1;
@@ -111,22 +122,16 @@
 MODULE_PARM(nowayout,"i");
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
+
 /*
  *	Kernel methods.
  */
 
-static void __init
-ibwdt_validate_timeout(void)
-{
-	timeout_val = (30 - timeout) / 2;
-	if (timeout_val < 0 || timeout_val > 0xF) timeout_val = WD_TIMO;
-}
-
 static void
 ibwdt_ping(void)
 {
 	/* Write a watchdog value */
-	outb_p(timeout_val, WDT_START);
+	outb_p(wd_times[wd_margin], WDT_START);
 }
 
 static ssize_t
@@ -145,7 +150,6 @@
 
 			for (i = 0; i != count; i++) {
 				char c;
-
 				if (get_user(c, buf + i))
 					return -EFAULT;
 				if (c == 'V')
@@ -168,6 +172,8 @@
 ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	  unsigned long arg)
 {
+	int i, new_margin;
+
 	static struct watchdog_info ident = {
 		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
 		.firmware_version = 1,
@@ -189,6 +195,22 @@
 	  ibwdt_ping();
 	  break;
 
+	case WDIOC_SETTIMEOUT:
+	  if (get_user(new_margin, (int *)arg))
+		  return -EFAULT;
+	  if ((new_margin < 0) || (new_margin > 30))
+		  return -EINVAL;
+	  for (i = 0x0F; i > -1; i--)
+		  if (wd_times[i] > new_margin)
+			  break;
+	  wd_margin = i;
+	  ibwdt_ping();
+	  /* Fall */
+
+	case WDIOC_GETTIMEOUT:
+	  return put_user(wd_times[wd_margin], (int *)arg);
+	  break;
+
 	default:
 	  return -ENOTTY;
 	}
@@ -223,7 +245,7 @@
 	if (minor(inode->i_rdev) == WATCHDOG_MINOR) {
 		spin_lock(&ibwdt_lock);
 		if (expect_close)
-			outb_p(timeout_val, WDT_STOP);
+			outb_p(wd_times[wd_margin], WDT_STOP);
 		else
 			printk(KERN_CRIT "WDT device closed unexpectedly.  WDT will not stop!\n");
 
@@ -243,7 +265,7 @@
 {
 	if (code == SYS_DOWN || code == SYS_HALT) {
 		/* Turn the WDT off */
-		outb_p(timeout_val, WDT_STOP);
+		outb_p(wd_times[wd_margin], WDT_STOP);
 	}
 	return NOTIFY_DONE;
 }
@@ -283,7 +305,6 @@
 {
 	printk("WDT driver for IB700 single board computer initialising.\n");
 
-	ibwdt_validate_timeout();
 	spin_lock_init(&ibwdt_lock);
 	if (misc_register(&ibwdt_miscdev))
 		return -ENODEV;
diff -Nru a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
--- a/drivers/char/watchdog/indydog.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/char/watchdog/indydog.c	Thu Jan 16 18:23:07 2003
@@ -19,7 +19,6 @@
 #include <linux/mm.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <asm/sgi/sgimc.h>
diff -Nru a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
--- a/drivers/char/watchdog/machzwd.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/machzwd.c	Thu Jan 16 18:23:05 2003
@@ -30,25 +30,19 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
 
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
 
 /* ports */
 #define ZF_IOBASE	0x218
diff -Nru a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
--- a/drivers/char/watchdog/mixcomwd.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/mixcomwd.c	Thu Jan 16 18:23:05 2003
@@ -38,15 +38,11 @@
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/miscdevice.h>
 #include <linux/ioport.h>
 #include <linux/watchdog.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
diff -Nru a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
--- a/drivers/char/watchdog/pcwd.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/pcwd.c	Thu Jan 16 18:23:05 2003
@@ -45,27 +45,17 @@
  */
 
 #include <linux/module.h>
-
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
 #include <linux/timer.h>
 #include <linux/config.h>
-#include <linux/kernel.h>
 #include <linux/wait.h>
-#include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff -Nru a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
--- a/drivers/char/watchdog/sa1100_wdt.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/sa1100_wdt.c	Thu Jan 16 18:23:05 2003
@@ -24,7 +24,6 @@
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
diff -Nru a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
--- a/drivers/char/watchdog/sbc60xxwdt.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/watchdog/sbc60xxwdt.c	Thu Jan 16 18:23:06 2003
@@ -56,24 +56,19 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
 
 #define OUR_NAME "sbc60xxwdt"
 
diff -Nru a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
--- a/drivers/char/watchdog/sc1200wdt.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/sc1200wdt.c	Thu Jan 16 18:23:05 2003
@@ -28,20 +28,19 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/ioport.h>
 #include <linux/spinlock.h>
-#include <linux/ioport.h>
-#include <asm/semaphore.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/isapnp.h>
 #include <linux/pci.h>
+
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
 
 #define SC1200_MODULE_VER	"build 20020303"
 #define SC1200_MODULE_NAME	"sc1200wdt"
diff -Nru a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
--- a/drivers/char/watchdog/sc520_wdt.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/sc520_wdt.c	Thu Jan 16 18:23:05 2003
@@ -49,24 +49,18 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
 #include <linux/timer.h>
-#include <linux/sched.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
 
 /*
  * The SC520 can timeout anywhere from 492us to 32.21s.
diff -Nru a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c
--- a/drivers/char/watchdog/scx200_wdt.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/watchdog/scx200_wdt.c	Thu Jan 16 18:23:06 2003
@@ -19,18 +19,16 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/pci.h>
+#include <linux/scx200.h>
+
 #include <asm/uaccess.h>
 #include <asm/io.h>
-
-#include <linux/scx200.h>
 
 #define NAME "scx200_wdt"
 
diff -Nru a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
--- a/drivers/char/watchdog/shwdt.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/shwdt.c	Thu Jan 16 18:23:05 2003
@@ -16,7 +16,6 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
diff -Nru a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
--- a/drivers/char/watchdog/softdog.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/softdog.c	Thu Jan 16 18:23:05 2003
@@ -27,21 +27,21 @@
  *  19980911 Alan Cox
  *	Made SMP safe for 2.3.x
  *
- *  20011214 Matt Domsch <Matt_Domsch@dell.com>
- *      Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
- *      Didn't add timeout option, as soft_margin option already exists.
+ *  20011127 Joel Becker (jlbec@evilplan.org>
+ *	Added soft_noboot; Allows testing the softdog trigger without 
+ *	requiring a recompile.
+ *	Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT.
+ *
+ *  20020530 Joel Becker <joel.becker@oracle.com>
+ *  	Added Matt Domsch's nowayout module option.
  */
  
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/reboot.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 
@@ -49,8 +49,15 @@
 
 static int expect_close = 0;
 static int soft_margin = TIMER_MARGIN;	/* in seconds */
+#ifdef ONLY_TESTING
+static int soft_noboot = 1;
+#else
+static int soft_noboot = 0;
+#endif  /* ONLY_TESTING */
 
 MODULE_PARM(soft_margin,"i");
+MODULE_PARM(soft_noboot,"i");
+MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_WATCHDOG_NOWAYOUT
 static int nowayout = 1;
@@ -60,7 +67,6 @@
 
 MODULE_PARM(nowayout,"i");
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
-MODULE_LICENSE("GPL");
 
 /*
  *	Our timer
@@ -70,7 +76,7 @@
 
 static struct timer_list watchdog_ticktock =
 		TIMER_INITIALIZER(watchdog_fire, 0, 0);
-static int timer_alive;
+static unsigned long timer_alive;
 
 
 /*
@@ -79,13 +85,14 @@
  
 static void watchdog_fire(unsigned long data)
 {
-#ifdef ONLY_TESTING
-	printk(KERN_CRIT "SOFTDOG: Would Reboot.\n");
-#else
-	printk(KERN_CRIT "SOFTDOG: Initiating system reboot.\n");
-	machine_restart(NULL);
-	printk("WATCHDOG: Reboot didn't ?????\n");
-#endif
+	if (soft_noboot)
+		printk(KERN_CRIT "SOFTDOG: Triggered - Reboot ignored.\n");
+	else
+	{
+		printk(KERN_CRIT "SOFTDOG: Initiating system reboot.\n");
+		machine_restart(NULL);
+		printk("SOFTDOG: Reboot didn't ?????\n");
+	}
 }
 
 /*
@@ -94,7 +101,7 @@
  
 static int softdog_open(struct inode *inode, struct file *file)
 {
-	if(timer_alive)
+	if(test_and_set_bit(0, &timer_alive))
 		return -EBUSY;
 	if (nowayout) {
 		MOD_INC_USE_COUNT;
@@ -103,7 +110,6 @@
 	 *	Activate timer
 	 */
 	mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
-	timer_alive=1;
 	return 0;
 }
 
@@ -113,12 +119,12 @@
 	 *	Shut off the timer.
 	 * 	Lock it in if it's a module and we set nowayout
 	 */
-	if(!nowayout) {
+	if (expect_close) {
 		del_timer(&watchdog_ticktock);
 	} else {
 		printk(KERN_CRIT "SOFTDOG: WDT device closed unexpectedly.  WDT will not stop!\n");
 	}
-	timer_alive=0;
+	clear_bit(0, &timer_alive);
 	return 0;
 }
 
@@ -156,6 +162,7 @@
 static int softdog_ioctl(struct inode *inode, struct file *file,
 	unsigned int cmd, unsigned long arg)
 {
+	int new_margin;
 	static struct watchdog_info ident = {
 		.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
 		.identity = "Software Watchdog",
@@ -173,6 +180,16 @@
 		case WDIOC_KEEPALIVE:
 			mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
 			return 0;
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_margin, (int *)arg))
+				return -EFAULT;
+			if (new_margin < 1)
+				return -EINVAL;
+			soft_margin = new_margin;
+			mod_timer(&watchdog_ticktock, jiffies+(soft_margin*HZ));
+			/* Fall */
+		case WDIOC_GETTIMEOUT:
+			return put_user(soft_margin, (int *)arg);
 	}
 }
 
diff -Nru a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c
--- a/drivers/char/watchdog/w83877f_wdt.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/watchdog/w83877f_wdt.c	Thu Jan 16 18:23:06 2003
@@ -42,24 +42,18 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
 #include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/smp_lock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
 
 #define OUR_NAME "w83877f_wdt"
 
@@ -220,6 +214,8 @@
 		case WATCHDOG_MINOR:
 			/* Just in case we're already talking to someone... */
 			if(test_and_set_bit(0, &wdt_is_open)) {
+				/* Davej: Is this unlock bogus? */
+				spin_unlock(&wdt_spinlock);
 				return -EBUSY;
 			}
 			/* Good, fire up the show */
@@ -242,7 +238,7 @@
 			printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
 		}
 	}
-	wdt_is_open = 0;
+	clear_bit(0, &wdt_is_open);
 	return 0;
 }
 
diff -Nru a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
--- a/drivers/char/watchdog/wafer5823wdt.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/char/watchdog/wafer5823wdt.c	Thu Jan 16 18:23:07 2003
@@ -27,16 +27,15 @@
  */
 
 #include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
 
 static unsigned long wafwdt_is_open;
 static spinlock_t wafwdt_lock;
diff -Nru a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
--- a/drivers/char/watchdog/wdt.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/watchdog/wdt.c	Thu Jan 16 18:23:06 2003
@@ -27,22 +27,17 @@
  *		Tim Hockin	:	Added insmod parameters, comment cleanup
  *					Parameterized timeout
  *		Tigran Aivazian	:	Restructured wdt_init() to handle failures
- *		Matt Domsch	:	added nowayout and timeout module options
+ *		Joel Becker	:	Added WDIOC_GET/SETTIMEOUT
+ *		Matt Domsch	:	Added nowayout module option
  */
 
 #include <linux/config.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include "wd501p.h"
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
@@ -50,6 +45,7 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
+#include "wd501p.h"
 
 static unsigned long wdt_is_open;
 static int expect_close;
@@ -62,12 +58,10 @@
 static int io=0x240;
 static int irq=11;
 
+/* Default margin */
 #define WD_TIMO (100*60)		/* 1 minute */
 
-static int timeout_val = WD_TIMO;	/* value passed to card */
-static int timeout = 60;	        /* in seconds */
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=60)");
+static int wd_margin = WD_TIMO;
 
 #ifdef CONFIG_WATCHDOG_NOWAYOUT
 static int nowayout = 1;
@@ -78,12 +72,6 @@
 MODULE_PARM(nowayout,"i");
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
-static void __init
-wdt_validate_timeout(void)
-{
-	timeout_val = timeout * 100;
-}
-
 #ifndef MODULE
 
 /**
@@ -238,7 +226,7 @@
 	/* Write a watchdog value */
 	inb_p(WDT_DC);
 	wdt_ctr_mode(1,2);
-	wdt_ctr_load(1,timeout_val);		/* Timeout */
+	wdt_ctr_load(1,wd_margin);		/* Timeout */
 	outb_p(0, WDT_DC);
 }
 
@@ -329,6 +317,8 @@
 static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	unsigned long arg)
 {
+	int new_margin;
+
 	static struct watchdog_info ident=
 	{
 		.options = WDIOF_OVERHEAT|WDIOF_POWERUNDER|WDIOF_POWEROVER
@@ -353,6 +343,17 @@
 		case WDIOC_KEEPALIVE:
 			wdt_ping();
 			return 0;
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_margin, (int *)arg))
+				return -EFAULT;
+			/* Arbitrary, can't find the card's limits */
+			if ((new_margin < 0) || (new_margin > 60))
+				return -EINVAL;
+			wd_margin = new_margin * 100;
+			wdt_ping();
+			/* Fall */
+		case WDIOC_GETTIMEOUT:
+			return put_user(wd_margin / 100, (int *)arg);
 	}
 }
 
@@ -375,19 +376,17 @@
 		case WATCHDOG_MINOR:
 			if(test_and_set_bit(0, &wdt_is_open))
 				return -EBUSY;
-			if (nowayout) {
-				MOD_INC_USE_COUNT;
-			}
 			/*
 			 *	Activate 
 			 */
 	 
+			wdt_is_open=1;
 			inb_p(WDT_DC);		/* Disable */
 			wdt_ctr_mode(0,3);
 			wdt_ctr_mode(1,2);
 			wdt_ctr_mode(2,0);
 			wdt_ctr_load(0, 8948);		/* count at 100Hz */
-			wdt_ctr_load(1,timeout_val);	/* Timeout */
+			wdt_ctr_load(1,wd_margin);	/* Timeout 120 seconds */
 			wdt_ctr_load(2,65535);
 			outb_p(0, WDT_DC);	/* Enable */
 			return 0;
@@ -525,7 +524,6 @@
 {
 	int ret;
 
-	wdt_validate_timeout();
 	ret = misc_register(&wdt_miscdev);
 	if (ret) {
 		printk(KERN_ERR "wdt: can't misc_register on minor=%d\n", WATCHDOG_MINOR);
diff -Nru a/drivers/char/watchdog/wdt285.c b/drivers/char/watchdog/wdt285.c
--- a/drivers/char/watchdog/wdt285.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/char/watchdog/wdt285.c	Thu Jan 16 18:23:05 2003
@@ -25,7 +25,6 @@
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/smp_lock.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
@@ -124,10 +123,10 @@
 static int watchdog_ioctl(struct inode *inode, struct file *file,
 	unsigned int cmd, unsigned long arg)
 {
-	int i;
+	int i, new_margin;
 	static struct watchdog_info ident=
 	{
-		0,
+		WDIOF_SETTIMEOUT,
 		0,
 		"Footbridge Watchdog"
 	};
@@ -145,6 +144,17 @@
 		case WDIOC_KEEPALIVE:
 			watchdog_ping();
 			return 0;
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_margin, (int *)arg))
+				return -EFAULT;
+			/* Arbitrary, can't find the card's limits */
+			if ((new_marg < 0) || (new_margin > 60))
+				return -EINVAL;
+			soft_margin = new_margin;
+			watchdog_ping();
+			/* Fall */
+		case WDIOC_GETTIMEOUT:
+			return put_user(soft_margin, (int *)arg);
 	}
 }
 
@@ -166,10 +176,15 @@
 
 static int __init footbridge_watchdog_init(void)
 {
+	int retval;
+
 	if (machine_is_netwinder())
 		return -ENODEV;
 
-	misc_register(&watchdog_miscdev);
+	retval = misc_register(&watchdog_miscdev);
+	if(retval < 0)
+		return retval;
+
 	printk("Footbridge Watchdog Timer: 0.01, timer margin: %d sec\n", 
 	       soft_margin);
 	if (machine_is_cats())
diff -Nru a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
--- a/drivers/char/watchdog/wdt977.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/watchdog/wdt977.c	Thu Jan 16 18:23:06 2003
@@ -25,7 +25,6 @@
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/watchdog.h>
 
 #include <asm/io.h>
diff -Nru a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
--- a/drivers/char/watchdog/wdt_pci.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/char/watchdog/wdt_pci.c	Thu Jan 16 18:23:06 2003
@@ -30,21 +30,18 @@
  *		Alan Cox	:	Split ISA and PCI cards into two drivers
  *		Jeff Garzik	:	PCI cleanups
  *		Tigran Aivazian	:	Restructured wdtpci_init_one() to handle failures
- *		Matt Domsch	:	added nowayout and timeout module options
+ *		Joel Becker 	:	Added WDIOC_GET/SETTIMEOUT
+ *		Zwane Mwaikambo	:	Magic char closing, locking changes, cleanups
+ *		Matt Domsch	:	nowayout module option
  */
 
 #include <linux/config.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/fcntl.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
@@ -72,23 +69,18 @@
 #define PCI_DEVICE_ID_WDG_CSM 0x22c0
 #endif
 
-static unsigned long wdt_is_open;
+static struct semaphore open_sem;
+static spinlock_t wdtpci_lock;
 static int expect_close = 0;
 
-/*
- *	You must set these - there is no sane way to probe for this board.
- *	You can use wdt=x,y to set these now.
- */
- 
-static int io=0x240;
-static int irq=11;
+static int io;
+static int irq;
 
+/* Default timeout */
 #define WD_TIMO (100*60)		/* 1 minute */
+#define WD_TIMO_MAX (WD_TIMO*60)	/* 1 hour(?) */
 
-static int timeout_val = WD_TIMO;	/* value passed to card */
-static int timeout = 60;	        /* in seconds */
-MODULE_PARM(timeout,"i");
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=60)");
+static int wd_margin = WD_TIMO;
 
 #ifdef CONFIG_WATCHDOG_NOWAYOUT
 static int nowayout = 1;
@@ -99,43 +91,6 @@
 MODULE_PARM(nowayout,"i");
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
-static void __init
-wdtpci_validate_timeout(void)
-{
-	timeout_val = timeout * 100;
-}
-
-#ifndef MODULE
-
-/**
- *	wdtpci_setup:
- *	@str: command line string
- *
- *	Setup options. The board isn't really probe-able so we have to
- *	get the user to tell us the configuration. Sane people build it 
- *	modular but the others come here.
- */
- 
-static int __init wdtpci_setup(char *str)
-{
-	int ints[4];
-
-	str = get_options (str, ARRAY_SIZE(ints), ints);
-
-	if (ints[0] > 0)
-	{
-		io = ints[1];
-		if(ints[0] > 1)
-			irq = ints[2];
-	}
-
-	return 1;
-}
-
-__setup("wdt=", wdtpci_setup);
-
-#endif /* !MODULE */
- 
 /*
  *	Programming support
  */
@@ -251,11 +206,15 @@
  
 static void wdtpci_ping(void)
 {
+	unsigned long flags;
+
 	/* Write a watchdog value */
+	spin_lock_irqsave(&wdtpci_lock, flags);
 	inb_p(WDT_DC);
 	wdtpci_ctr_mode(1,2);
-	wdtpci_ctr_load(1,timeout_val);		/* Timeout */
+	wdtpci_ctr_load(1,wd_margin);		/* Timeout */
 	outb_p(0, WDT_DC);
+	spin_unlock_irqrestore(&wdtpci_lock, flags);
 }
 
 /**
@@ -275,10 +234,12 @@
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
 
-	if(count)
-	{
+	if (count) {
 		if (!nowayout) {
 			size_t i;
+
+			expect_close = 0;
+
 			for (i = 0; i != count; i++) {
 				char c;
 				if(get_user(c, buf+i))
@@ -288,9 +249,9 @@
 			}
 		}
 		wdtpci_ping();
-		return 1;
 	}
-	return 0;
+
+	return count;
 }
 
 /**
@@ -342,6 +303,7 @@
 static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	unsigned long arg)
 {
+	int new_margin;
 	static struct watchdog_info ident = {
 		.options	= WDIOF_OVERHEAT  | WDIOF_POWERUNDER |
 				  WDIOF_POWEROVER | WDIOF_EXTERN1 |
@@ -366,6 +328,18 @@
 		case WDIOC_KEEPALIVE:
 			wdtpci_ping();
 			return 0;
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_margin, (int *)arg))
+				return -EFAULT;
+			/* Arbitrary, can't find the card's limits */
+			new_margin *= 100;
+			if ((new_margin < 0) || (new_margin > WD_TIMO_MAX))
+				return -EINVAL;
+			wd_margin = new_margin;
+			wdtpci_ping();
+			/* Fall */
+		case WDIOC_GETTIMEOUT:
+			return put_user(wd_margin / 100, (int *)arg);
 	}
 }
 
@@ -383,20 +357,22 @@
  
 static int wdtpci_open(struct inode *inode, struct file *file)
 {
+	unsigned long flags;
+
 	switch(minor(inode->i_rdev))
 	{
 		case WATCHDOG_MINOR:
-			if( test_and_set_bit(0,&wdt_is_open) ) 
-			{
+			if (down_trylock(&open_sem))
 				return -EBUSY;
-			}
+
 			if (nowayout) {
 				MOD_INC_USE_COUNT;
 			}
 			/*
 			 *	Activate 
 			 */
-
+			spin_lock_irqsave(&wdtpci_lock, flags);
+			
 			inb_p(WDT_DC);		/* Disable */
 
 			/*
@@ -418,9 +394,10 @@
 			wdtpci_ctr_mode(1,2);
 			wdtpci_ctr_mode(2,1);
 			wdtpci_ctr_load(0,20833);	/* count at 100Hz */
-			wdtpci_ctr_load(1,timeout_val); /* Timeout */
+			wdtpci_ctr_load(1,wd_margin);/* Timeout 60 seconds */
 			/* DO NOT LOAD CTR2 on PCI card! -- JPN */
 			outb_p(0, WDT_DC);	/* Enable */
+			spin_unlock_irqrestore(&wdtpci_lock, flags);
 			return 0;
 		case TEMP_MINOR:
 			return 0;
@@ -443,13 +420,19 @@
  
 static int wdtpci_release(struct inode *inode, struct file *file)
 {
-	if(minor(inode->i_rdev)==WATCHDOG_MINOR)
-	{
-		if (!nowayout) {
+
+	if (minor(inode->i_rdev)==WATCHDOG_MINOR) {
+		unsigned long flags;
+		if (expect_close) {
+			spin_lock_irqsave(&wdtpci_lock, flags);
 			inb_p(WDT_DC);		/* Disable counters */
 			wdtpci_ctr_load(2,0);	/* 0 length reset pulses now */
+			spin_unlock_irqrestore(&wdtpci_lock, flags);
+		} else {
+			printk(KERN_CRIT PFX "Unexpected close, not stopping timer!");
+			wdtpci_ping();
 		}
-		clear_bit(0, &wdt_is_open );
+		up(&open_sem);
 	}
 	return 0;
 }
@@ -469,11 +452,14 @@
 static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
 	void *unused)
 {
-	if(code==SYS_DOWN || code==SYS_HALT)
-	{
+	unsigned long flags;
+
+	if (code==SYS_DOWN || code==SYS_HALT) {
 		/* Turn the card off */
+		spin_lock_irqsave(&wdtpci_lock, flags);
 		inb_p(WDT_DC);
 		wdtpci_ctr_load(2,0);
+		spin_unlock_irqrestore(&wdtpci_lock, flags);
 	}
 	return NOTIFY_DONE;
 }
@@ -533,6 +519,9 @@
 	if (pci_enable_device (dev))
 		goto out;
 
+	sema_init(&open_sem, 1);
+	spin_lock_init(&wdtpci_lock);
+
 	irq = dev->irq;
 	io = pci_resource_start (dev, 2);
 	printk ("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X "
@@ -650,8 +639,6 @@
 	
 	if (rc < 1)
 		return -ENODEV;
-
-	wdtpci_validate_timeout();
 	
 	return 0;
 }
diff -Nru a/drivers/eisa/Kconfig b/drivers/eisa/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/eisa/Kconfig	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,20 @@
+#
+# PCI configuration
+#
+config EISA_NAMES
+	bool "EISA device name database"
+	depends on EISA
+	default y
+	---help---
+	  By default, the kernel contains a database of all known EISA
+	  device names to make the information in sysfs comprehensible
+	  to the user. This database increases size of the kernel
+	  image by about 40KB, but it gets freed after the system
+	  boots up, so it doesn't take up kernel memory. Anyway, if
+	  you are building an installation floppy or kernel for an
+	  embedded system where kernel image size really matters, you
+	  can disable this feature and you'll get device ID instead of
+	  names.
+
+	  When in doubt, say Y.
+
diff -Nru a/drivers/eisa/Makefile b/drivers/eisa/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/eisa/Makefile	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,18 @@
+# Makefile for the Linux device tree
+
+obj-$(CONFIG_EISA)	+= eisa-bus.o
+
+export-objs	:= eisa-bus.o
+
+clean-files:= devlist.h
+
+# Ugly hack to get DEVICE_NAME_SIZE value...
+DEVICE_NAME_SIZE:=$(shell awk '$$1=="\#define" && $$2=="DEVICE_NAME_SIZE" {print $$3-1}' $(srctree)/include/linux/device.h)
+
+$(obj)/eisa-bus.o: $(obj)/devlist.h
+
+$(obj)/devlist.h: $(src)/eisa.ids $(srctree)/include/linux/device.h
+	sed -e '/^#/D' -e 's/^\([[:alnum:]]\{7\}\) \+"\([^"]\{1,$(DEVICE_NAME_SIZE)\}\).*"/EISA_DEVINFO ("\1", "\2"),/' $< > $@
+
+$(src)/eisa.ids:
+	touch $@
diff -Nru a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/eisa/eisa-bus.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,218 @@
+/*
+ * EISA bus support functions for sysfs.
+ *
+ * (C) 2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
+ *
+ * This code is released under the GPL version 2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/eisa.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+#define EISA_DEVINFO(i,s) { .id = { .sig = i }, .name = s }
+
+struct eisa_device_info {
+	struct eisa_device_id id;
+	char name[DEVICE_NAME_SIZE];
+};
+
+struct eisa_device_info __initdata eisa_table[] = {
+#ifdef CONFIG_EISA_NAMES
+#include "devlist.h"
+#endif
+};
+
+#define EISA_INFOS (sizeof (eisa_table) / (sizeof (struct eisa_device_info)))
+
+static void __init eisa_name_device (struct eisa_device *edev)
+{
+	int i;
+
+	for (i = 0; i < EISA_INFOS; i++) {
+		if (!strcmp (edev->id.sig, eisa_table[i].id.sig)) {
+			strncpy (edev->dev.name,
+				 eisa_table[i].name,
+				 DEVICE_NAME_SIZE - 1);
+			return;
+		}
+	}
+
+	/* No name was found */
+	sprintf (edev->dev.name, "EISA device %.7s", edev->id.sig);
+}
+
+static char __init *decode_eisa_sig(unsigned long addr)
+{
+        static char sig_str[EISA_SIG_LEN];
+	u8 sig[4];
+        u16 rev;
+	int i;
+
+	sig[0] = inb (addr);
+
+	if (sig[0] & 0x80)
+                return NULL;
+
+	for (i = 1; i < 4; i++)
+		sig[i] = inb (addr + i);
+	
+        sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
+        sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
+        sig_str[2] = (sig[1] & 0x1f) + ('A' - 1);
+        rev = (sig[2] << 8) | sig[3];
+        sprintf(sig_str + 3, "%04X", rev);
+
+        return sig_str;
+}
+
+static int eisa_bus_match (struct device *dev, struct device_driver *drv)
+{
+	struct eisa_device *edev = to_eisa_device (dev);
+	struct eisa_driver *edrv = to_eisa_driver (drv);
+	const struct eisa_device_id *eids = edrv->id_table;
+
+	if (!eids)
+		return 0;
+
+	while (strlen (eids->sig)) {
+		if (!strcmp (eids->sig, edev->id.sig))
+			return 1;
+
+		eids++;
+	}
+
+	return 0;
+}
+
+struct bus_type eisa_bus_type = {
+	.name  = "eisa",
+	.match = eisa_bus_match,
+};
+
+/* The default EISA device parent (virtual root device). */
+static struct device eisa_bus_root = {
+       .name           = "EISA Bridge",
+       .bus_id         = "eisa",
+};
+
+int eisa_driver_register (struct eisa_driver *edrv)
+{
+	int r;
+	
+	edrv->driver.bus = &eisa_bus_type;
+	if ((r = driver_register (&edrv->driver)) < 0)
+		return r;
+
+	return 1;
+}
+
+void eisa_driver_unregister (struct eisa_driver *edrv)
+{
+	driver_unregister (&edrv->driver);
+}
+
+static ssize_t eisa_show_sig (struct device *dev, char *buf)
+{
+        struct eisa_device *edev = to_eisa_device (dev);
+        return sprintf (buf,"%s\n", edev->id.sig);
+}
+
+static DEVICE_ATTR(signature, S_IRUGO, eisa_show_sig, NULL);
+
+static void __init eisa_register_device (char *sig, int slot)
+{
+	struct eisa_device *edev;
+
+	if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL)))
+		return;
+
+	memset (edev, 0, sizeof (*edev));
+	memcpy (edev->id.sig, sig, 7);
+	edev->slot = slot;
+	edev->base_addr = 0x1000 * slot;
+	eisa_name_device (edev);
+	edev->dev.parent = &eisa_bus_root;
+	edev->dev.bus = &eisa_bus_type;
+	sprintf (edev->dev.bus_id, "00:%02X", slot);
+
+	/* Don't register resource for slot 0, since this will surely
+	 * fail... :-( */
+
+	if (slot) {
+		edev->res.name  = edev->dev.name;
+		edev->res.start = edev->base_addr;
+		edev->res.end   = edev->res.start + 0xfff;
+		edev->res.flags = IORESOURCE_IO;
+
+		if (request_resource (&ioport_resource, &edev->res)) {
+			printk (KERN_WARNING \
+				"Cannot allocate resource for EISA slot %d\n",
+				slot);
+			kfree (edev);
+			return;
+		}
+	}
+	
+	if (device_register (&edev->dev)) {
+		kfree (edev);
+		return;
+	}
+
+	device_create_file (&edev->dev, &dev_attr_signature);
+}
+
+static int __init eisa_probe (void)
+{
+        int i, c;
+        char *str;
+        unsigned long slot_addr;
+
+        printk (KERN_INFO "EISA: Probing bus...\n");
+        for (c = 0, i = 0; i <= EISA_MAX_SLOTS; i++) {
+                slot_addr = (0x1000 * i) + EISA_VENDOR_ID_OFFSET;
+                if ((str = decode_eisa_sig (slot_addr))) {
+			if (!i)
+				printk (KERN_INFO "EISA: Motherboard %s detected\n",
+					str);
+			else {
+				printk (KERN_INFO "EISA: slot %d : %s detected.\n",
+					i, str);
+
+				c++;
+			}
+
+			eisa_register_device (str, i);
+                }
+        }
+        printk (KERN_INFO "EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s");
+
+	return 0;
+}
+
+static int __init eisa_init (void)
+{
+	int r;
+	
+	if ((r = bus_register (&eisa_bus_type)))
+		return r;
+	
+	if ((r = device_register (&eisa_bus_root))) {
+		bus_unregister (&eisa_bus_type);
+		return r;
+	}
+
+	printk (KERN_INFO "EISA bus registered\n");
+	return eisa_probe ();
+}
+
+postcore_initcall (eisa_init);
+
+EXPORT_SYMBOL (eisa_bus_type);
+EXPORT_SYMBOL (eisa_driver_register);
+EXPORT_SYMBOL (eisa_driver_unregister);
diff -Nru a/drivers/eisa/eisa.ids b/drivers/eisa/eisa.ids
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/eisa/eisa.ids	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,1155 @@
+# This list is a compilation of EISA ids.
+# It also includes numerous ISA cards for which an EISA id
+# has been allocated.
+#
+# Please send any patch/addition/correction to
+# Marc Zyngier <maz@wild-wind.fr.eu.org>
+#
+# Many entries were contributed by Andries.Brouwer@cwi.nl
+
+ABP0510 "Advansys ABP-510 ISA SCSI Host Adapter"
+ABP0540 "Advansys ABP-540/542 ISA SCSI Host Adapter"
+ABP7401 "AdvanSys ABP-740/742 EISA Single Channel SCSI Host Adapter"
+ABP7501 "AdvanSys ABP-750/752 EISA Dual Channel SCSI Host Adapter"
+ACC1200 "ACCTON EtherCombo-32 Ethernet Adapter"
+ACC120A "ACCTON EtherCombo-32 Ethernet Adapter"
+ACC1650 "Accton MPX Ethernet Adapter (EN165x)"
+ACC1660 "Accton MPX Ethernet Adapter (EN166x)"
+ACE1010 "ACME Super Fast System Board"
+ACE2010 "ACME PC Network"
+ACE3010 "ACME Arcnet Plan"
+ACE3030 "ACME Sample VS Board 1"
+ACE4010 "ACME Tape Controller"
+ACE5010 "ACME VDU Video Board"
+ACE6010 "ACME Disk Controller"
+ACE7010 "ACME Multi-Function Board"
+ACR1201 "Acer 1200 486/25 EISA System Board"
+ACR1211 "AcerFrame 3000SP33 486/33 EISA System Board"
+ACR1341 "M1 486SX/20 CPU Board"
+ACR1351 "M1 486SX/20 CPU Board"
+ACR1361 "M1 487/20 CPU Board"
+ACR1371 "M1 487/20 CPU Board"
+ACR1381 "M1 486/20 CPU Board"
+ACR1391 "M1 486/20 CPU Board"
+ACR1581 "M1 486/33 CPU Board"
+ACR1591 "M1 486/33 CPU Board"
+ACR15A1 "M1 486/33 CPU Board"
+ACR15B1 "M1 486/33 CPU Board"
+ACR1701 "AcerFrame 1000"
+ACR1711 "AcerFrame 1000 486/33 SYSTEM-2"
+ACR1801 "Acer P43WE EISA System Board"
+ACR3211 "AcerFrame 3000MP 486 SYSTEM-1"
+ACR3221 "AcerFrame 486 Series SYSTEM-2"
+ACR3231 "AcerFrame 486 Series SYSTEM-3"
+ACR3241 "AcerFrame 486 Series SYSTEM-4"
+ACR3261 "AcerFrame 3000MP 486 SYSTEM-1"
+ACR3271 "AcerFrame 486 Series SYSTEM-2"
+ACR3281 "AcerFrame 486 Series SYSTEM-3"
+ACR3291 "AcerFrame 486 Series SYSTEM-4"
+ACR4509 "ACER/Altos M1 System Board"
+ADI0001 "Lightning Networks 32-Bit EISA Ethernet LAN Adapter"
+ADP0000 "Adaptec AHA-1740 SCSI"
+ADP0001 "Adaptec AHA-1740A SCSI"
+ADP0002 "Adaptec AHA-1742A SCSI"
+ADP0100 "Adaptec AHA-1540/1542 ISA SCSI Host Adapter"
+AIM0002 "AUVA OPTi/EISA 32-Bit 486 All-in-One System Board"
+ADP0200 "Adaptec AHA-1520/1522 ISA SCSI Host Adapter"
+ADP0400 "Adaptec AHA-1744 SCSI"
+ADP7756 "Adaptec AHA-284x SCSI (BIOS enabled)"
+ADP7757 "Adaptec AHA-284x SCSI (BIOS disabled)"
+ADP7770 "Adaptec AIC-7770 SCSI (on motherboard)"
+ADP7771 "Adaptec AHA-274x SCSI"
+AEI0401 "486EI EISA System Board"
+AEO0301 "486EO EISA System Board"
+AIR0101 "AIR486SE/25/33 EISA Baby AT-foot print motherboard."
+AIR0103 "AIR486SE/25/33/50"
+AIR0201 "AIR486LE/25/33/50"
+AIR0301 "AIR 486EO EISA System Board"
+AIR0401 "486EI EISA System Board"
+AIR0501 "AIR 586EP PCI/EISA System Board"
+AIR0601 "AIR 54CEP PCI/EISA System Board"
+AIR0701 "AIR 54CDP PCI/EISA System Board"
+AIR0702 "AIR 54CDP PCI/EISA Dual-Processors System Board"
+AIR0901 "AIR 54TDP PCI/EISA Dual-Processors System Board"
+AIR1001 "AIR P6NDP PCI/EISA Dual-Pentium Processor System Board"
+AIR2001 "AIR SCSI-2E"
+AIR2101 "AIR SCSI-2V"
+AIR3001 "ENET2E EISA BUS MASTER ETHERNET ADAPTER"
+AIR3101 "ENET-2V LOCAL BUS MASTER ETHERNET ADAPTER"
+ALR0001 "Power/Business VEISA System Board"
+ALR0041 "PowerPro System Board"
+ALR0181 "PowerPro System Board"
+ALR0241 "Evolution V Pentium Tower System Board"
+ALR0341 "EISA PCI base System Board"
+ALR3000 "80486 Processor Module"
+ALR3010 "Pentium Processor Board"
+ALR3023 "ALR 16-bit VGA without Parallel port"
+ALR8580 "Advanced Disk Array Caching EISA Controller"
+ALRA0C1 "System Board"
+ALRA301 "Revolution Q-SMP System Board"
+ALRA311 "Revolution Q-2SMP System Board"
+ALRB0A0 "Primary System Processor Board - 80486DX2/66"
+ALRB0B0 "Secondary System Processor Board - 80486DX2/66"
+AMI44C1 "AMI SCSI Host Adapter - Series 44"
+AMI15C1 "AMI SCSI Host Adapter"
+AMI15D1 "AMI SCSI Host Adapter - Rev 2"
+AMI15E1 "AMI Normal Single Ended EISA SCSI CACHING Controller-Ver 1.22"
+AMI16B1 "AMI ENTERPRISE EISA system board"
+AMI2509 "AMI ENTERPRISE EISA system board"
+AMI25B1 "AMI ENTERPRISE EISA system board"
+AMI28A1 "AMI EZ-FLEX EISA System Board"
+AMI44D2 "AMI Fast Single Ended EISA SCSI CACHING Controller"
+AMI4801 "AMI Series 48 EISA Fast SCSI Host Adapter"
+AMI68B1 "AMI Enterprise III 486 EISA System Board"
+APS0101 "EISA PIP INTERFACE"
+APS0102 "EISA PIP INTERFACE"
+APS0103 "EISA PIP INTERFACE"
+ARC0010 "Alta EtherTPI/Combo"
+ARC0020 "Alta TokenCombo-16 S/U"
+ASU0100 "ASUS EISA-SC100 SCSI Cache Host Adapter (CFG file V2.0)"
+ASU0500 "ASUS EISA-L500 Ethernet LAN ADAPTER"
+ASU4001 "EISA-486C Main Board"
+ASU4101 "EISA-486E Main Board"
+ASU4201 "EISA-486A Main Board"
+ASU4301 "EISA-486SI Main Board"
+ASU4501 "Mini EISA-486H Main Board"
+ASU4701 "Mini EISA-486AS Main Board"
+ASU4901 "VL/EISA-486SV1 Main Board"
+ASU5101 "PCI/E-P5MP4 or PCI/E-P54NP4 Main Board V2.3"
+ASU5201 "P/E-P55T2P4D  Main Board (CFG File V1.2)"
+ATI1500 "ATI AT-1500 Ethernet Adapter Card"
+ATI1700 "ATI AT-1700 Ethernet Adapter Card"
+ATI4400 "mach32 EISA Video Accelerator Card"
+ATI4402 "mach32 EISA Video Accelerator Card"
+ATI4410 "mach32 Video Accelerator Card"
+ATI4420 "mach32 Video Accelerator Card"
+ATI4430 "mach32 VLB Video Accelerator Card"
+ATT2402 "AT&T SCSI Host Adapter A (StarServer E)"
+ATT2404 "DPT SCSI Host Bus Adapter (PM2012B/9X)"
+AVI2E01 "AVIEW2E EISA SVGA Adapter"
+AVM0001 "AVM ISDN-Controller A1"
+BAN0440 "Banyan ICA"
+BAN0670 "Banyan ICAplus"
+BAN0680 "Banyan ICA/RM"
+BUS4201 "BusTek/BusLogic Bt74xB 32-Bit Bus Master EISA-to-SCSI Host Adapter"
+BUS4202 "BusTek/BusLogic Bt74xC 32-Bit Bus Master EISA-to-SCSI Host Adapter"
+BUS6001 "BusTek/BusLogic Bt760 32-Bit Bus Master EISA-to-Ethernet Controller"
+BUS6301 "BusTek/BusLogic Bt763E EISA 32-Bit 82596-based Ethernet Controller"
+CCI0000 "Cache Computers, Inc. Memory Refresh Controller"
+CCI1001 "Cache Computers Inc. 486/25  EISA System Board"
+CCI2001 "Cache Computers Inc. 486/33  EISA System Board"
+CCI3001 "Cache Computers, Inc. Modular EISA System Board"
+CCI3009 "Cache Computers Inc. Modular EISA System Board"
+CCI4000 "Cache Computers, Inc. 486/33 CPU Board"
+CCI4001 "Cache Computers, Inc. 486/33 CPU Board"
+CCI5001 "Cache Computers, Inc. 486/50 CPU Board"
+CCI6001 "Cache Computer EISA Ethernet LAN Adapter"
+CCI7001 "Cache Computers, Inc. EISA System Board"
+CCI8001 "Cache Computers, Inc. EISA System Board"
+CHAA041 "Chase AT4 Intelligent Serial Controller"
+CHAA081 "Chase AT8 Intelligent Serial Controller"
+CHAA091 "Chase AT8+ Intelligent Serial Controller"
+CHAA161 "Chase AT16 Intelligent Serial Controller"
+CHAA171 "Chase AT16+ Intelligent Serial Controller"
+CMD0003 "CMD Technology, Inc. EISA SCSI Host Adapter"
+CNT2000 "900E/950E EISA Bus 32-bit Ethernet LAN Adapter"
+COG5000 "Cogent eMASTER+ AT Combo 16-Bit Workstation Ethernet Adapter"
+COG7002 "Cogent eMASTER+ ATS Combo Bus-Mastering Ethernet Adapter"
+COG9002 "Cogent eMASTER+ EISA XL 32-Bit Burst-mode Ethernet Adapter"
+CPQ0101 "Compaq SYSTEMPRO System Board"
+CPQ0109 "Compaq SYSTEMPRO System Board (ASSY # 001981)"
+CPQ0401 "Compaq DESKPRO 486/33L or 386/33L System Board"
+CPQ0501 "Compaq DESKPRO/M System Board"
+CPQ0509 "Compaq DESKPRO/M System Board with Audio"
+CPQ0511 "Compaq SYSTEMPRO/LT System Board"
+CPQ0601 "Compaq ProSignia Server"
+CPQ0609 "Compaq ProSignia Server"
+CPQ0611 "Compaq ProSignia Server"
+CPQ0621 "Compaq ProSignia Server (ASSY # 3154)"
+CPQ0629 "Compaq ProSignia Server (ASSY # 3154)"
+CPQ0631 "Compaq ProLiant 1000 Server"
+CPQ0639 "Compaq ProLiant 1000 Server"
+CPQ1001 "Compaq Portable 486"
+CPQ1009 "Compaq Portable 486/66"
+CPQ1201 "Compaq DESKPRO 486/25"
+CPQ1301 "Compaq DESKPRO 486/50L"
+CPQ1401 "Compaq Portable 486c"
+CPQ1409 "Compaq Portable 486c/66"
+CPQ1501 "Compaq SYSTEMPRO/XL Server"
+CPQ1509 "Compaq ProLiant 4000 Server"
+CPQ1519 "Compaq ProLiant 2000 Server"
+CPQ3001 "Compaq Advanced VGA"
+CPQ3011 "Compaq QVision 1024/E Video Controller"
+CPQ3021 "Compaq QVision 1024/I Video Controller"
+CPQ3111 "Compaq QVision 1024/E Graphics Controller"
+CPQ3112 "Compaq QVision 1280/E Graphics Controller"
+CPQ3121 "Compaq QVision 1024/I Graphics Controller"
+CPQ3122 "Compaq QVision 1280/I Graphics Controller"
+CPQ4001 "Compaq 32-Bit Intelligent Drive Array Controller"
+CPQ4002 "Compaq Intelligent Drive Array Controller-2"
+CPQ4010 "Compaq 32-Bit Intelligent Drive Array Expansion Controller"
+CPQ4020 "Compaq SMART Array Controller"
+CPQ4300 "Compaq Advanced ESDI Fixed Disk Controller"
+CPQ4401 "Compaq Integrated SCSI-2 Options Port"
+CPQ4410 "Compaq Integrated 32-Bit Fast-SCSI-2 Controller"
+CPQ4411 "Compaq 32-Bit Fast-SCSI-2 Controller"
+CPQ4420 "Compaq 6260 SCSI-2 Controller"
+CPQ5000 "Compaq 386/33 System Processor Board used as Secondary"
+CPQ5281 "Compaq 486/50 System Processor Board used as Secondary"
+CPQ5282 "Compaq 486/50 System Processor Board used as Secondary"
+CPQ5287 "Compaq 5/66 System Processor Board used as Secondary"
+CPQ528F "Compaq 486DX2/66 System Processor Board used as Secondary"
+CPQ5900 "Compaq 486/33 System Processor Board used as Secondary"
+CPQ5A00 "Compaq 486/33 System Processor Board (ASSY # 002013) used as Secondary"
+CPQ5B00 "Compaq 486DX2/66 System Processor Board used as Secondary"
+CPQ5C00 "Compaq 486/33 System Processor Board used as Secondary"
+CPQ6000 "Compaq 32-Bit DualSpeed Token Ring Controller"
+CPQ6001 "Compaq 32-Bit DualSpeed Token Ring Controller"
+CPQ6100 "Compaq 32-Bit NetFlex Controller"
+CPQ6101 "Compaq NetFlex-2 Controller"
+CPQ6200 "Compaq DualPort Ethernet Controller"
+CPQ7000 "Compaq 32-Bit Server Manager/R Board"
+CPQ7001 "Compaq 32-Bit Server Manager/R Board"
+CPQ9004 "Compaq 386/33 Processor Board"
+CPQ9005 "Compaq 386/25 Processor Board"
+CPQ9013 "Compaq 486DX2/66 System Processor Board used as Primary"
+CPQ9014 "Compaq 486/33 System Processor Board used as Primary"
+CPQ9015 "Compaq 486/33 Processor Board"
+CPQ9016 "Compaq 486DX2/66 Processor Board"
+CPQ9017 "Compaq 486DX2/50 Processor Board"
+CPQ9018 "Compaq 486/33 Processor Board (8 MB)"
+CPQ9034 "Compaq 486SX/25 Processor Board"
+CPQ9035 "Compaq 486SX/16 Processor Board"
+CPQ9036 "Compaq 486SX/25 Processor Board (8 MB)"
+CPQ9037 "Compaq 486SX/16 Processor Board (8 MB)"
+CPQ9038 "Compaq 486SX/33 Processor Board (8 MB)"
+CPQ903C "Compaq 486SX/33 Processor Board (4 MB)"
+CPQ9040 "Compaq 5/66 Processor Board"
+CPQ9041 "Compaq 5/66 Processor Board"
+CPQ9042 "Compaq 5/66 Processor Board"
+CPQ9043 "Compaq 5/66 Processor Board"
+CPQ9044 "Compaq 5/60 Processor Board"
+CPQ9045 "Compaq 5/60 Processor Board"
+CPQ9046 "Compaq 5/60 Processor Board"
+CPQ9047 "Compaq 5/60 Processor Board"
+CPQ9281 "Compaq 486/50 System Processor Board used as Primary"
+CPQ9282 "Compaq 486/50 System Processor Board used as Primary"
+CPQ9287 "Compaq 5/66 System Processor Board used as Primary"
+CPQ928F "Compaq 486DX2/66 System Processor Board used as Primary"
+CPQ9381 "Compaq 486/50 System Processor Board"
+CPQ9382 "Compaq 486/50 System Processor Board"
+CPQ9387 "Compaq 5/66 System Processor Board"
+CPQ9481 "Compaq 486/50 System Processor Board"
+CPQ9482 "Compaq 486/50 System Processor Board"
+CPQ9487 "Compaq 5/66 System Processor Board"
+CPQ9901 "Compaq 486SX/16 Processor Board"
+CPQ9902 "Compaq 486SX/16 Processor Board"
+CPQ9903 "Compaq 486SX/25 Processor Board"
+CPQ9904 "Compaq 486SX/25 Processor Board"
+CPQ9905 "Compaq 486SX/25 Processor Board"
+CPQ9906 "Compaq 486/33 Processor Board"
+CPQ9907 "Compaq 486DX2/66 Processor Board"
+CPQ9908 "Compaq 486SX/16 Processor Board"
+CPQ9909 "Compaq 486SX/16 Processor Board"
+CPQ990A "Compaq 486SX/25 Processor Board"
+CPQ990B "Compaq 486SX/25 Processor Board"
+CPQ990C "Compaq 486SX/25 Processor Board"
+CPQ990D "Compaq 486/33 Processor Board"
+CPQ990E "Compaq 486SX/33 Processor Board (8 MB)"
+CPQ990F "Compaq 486SX/33 Processor Board (8 MB)"
+CPQ9990 "Compaq 386/33 System Processor Board used as Primary"
+CPQ9991 "Compaq 386/33 Desktop Processor Board"
+CPQ9999 "Compaq 486/33 System Processor Board used as Primary"
+CPQ999A "Compaq 486/33 Desktop Processor Board"
+CPQA000 "Compaq Enhanced Option Slot Serial Board"
+CPQA010 "Compaq Enhanced Option Slot Modem Board"
+CPQA020 "Compaq Integrated CD Rom Adapter"
+CPQA030 "Compaq Integrated CD Rom Adapter"
+CPQF000 "Compaq Fixed Disk Drive Feature"
+CPQF100 "Compaq Ethernet 16TP Controller"
+CPQFA0D "Compaq SYSTEMPRO 4-Socket System Memory Board"
+CPQFA0E "Compaq SYSTEMPRO 6-Socket System Memory Board"
+CPQFA0F "Compaq DESKPRO 486/25 System Memory Board"
+CPQFA1A "Compaq DESKPRO 3-Socket System Memory Board"
+CPQFA1B "Compaq DESKPRO 486/50 System Memory Board"
+CPQFA1C "Compaq System Memory Expansion Board"
+CPQFA1D "Compaq SYSTEMPRO/XL Memory Expansion Board"
+CPQFB03 "Compaq Async/Parallel Printer Intf Assy 000990"
+CPQFB07 "Compaq DESKPRO 2400 Baud Modem"
+CPQFC0B "Compaq Advanced Graphics 1024 Board"
+CPQFD08 "Compaq 135Mb, 150/250Mb Tape Adapter"
+CPQFD13 "Compaq 15MHz ESDI Fixed Disk Controller 001283"
+CPQFD17 "Compaq SCSI Tape Adapter"
+CPX0301 "Universal 10/100VG Selectable EISA LAN Adapter"
+CRS3203 "Crescendo 320 FDDI/CDDI EISA Adapter"
+CRS3204 "Cisco CDDI/FDDI EISA Adapter"
+CSI0690 "CSI F70X9 EISA FDDI DNI adapter card"
+CUI0000 "CUI Examples -- Virtual Board"
+DBI0101 "Digi C/X Host Adapter - EISA"
+DBI0102 "Digi C/X Host Adapter - EISA"
+DBI0201 "Digi EISA/Xem Host Adapter"
+DBI0301 "Digi EPC/X Host Adapter - EISA"
+DBI0501 "Digi Ports/Xem Host Adapter - ISA"
+DBI0601 "Digi EPC/X Host Adapter - ISA"
+DBI0701 "Digi C/X Host Adapter - ISA"
+DBI0801 "Digi PC/Xr - ISA"
+DBI0901 "Digi PC/Xt - ISA"
+DBI0C01 "Digi DataFire - ISA"
+DBI0D01 "Digi DataFire/4 - ISA"
+DBI0E01 "Digi PC IMAC - ISA"
+DBI0F01 "Digi PC IMAC/4 - ISA"
+DBI1001 "Digi PC/Xe - ISA"
+DBI1101 "Digi ES/4 Host Adapter - EISA"
+DBI1201 "Digi Acceleport Xr 920 - ISA"
+DEC1011 "Digital EISA Video Controller (EVC-1)"
+DEC1021 "Digital EISA SCSI Controller (ESC-1)"
+DEC1031 "DECpc MTE Series System Board"
+DEC2030 "Digital Ethernet Controller (DE203)"
+DEC2040 "Digital Ethernet Controller (DE204)"
+DEC2050 "Digital Ethernet Controller (DE205)"
+DEC2400 "DECpc AXP/150 System Board"
+DEC2500 "DEC EISA NVRAM for Alpha AXP"
+DEC2A01 "Digital AlphaServer 2100 Family System Board"
+DEC2E00 "Digital KFESA DSSI EISA Host Adapter"
+DEC2F00 "Digital WANcontroller/EISA (DNSES)"
+DEC3001 "DEC FDDIcontroller/EISA Adapter"
+DEC3002 "DEC FDDIcontroller/EISA Adapter"
+DEC3003 "DEC FDDIcontroller/EISA Adapter"
+DEC3004 "DEC FDDI Controller"
+DEC4220 "Digital EISA Ethernet Controller (DE422-SA)"
+DEC4250 "Digital EtherWORKS Turbo EISA (DE425-AA)"
+DEC5000 "Digital AlphaServer 1000, 1000A and AlphaStation 600A System Board"
+DEC5100 "Digital AlphaStation 600 Family System Board"
+DEC5301 "Digital 800 AlphaServer Family System Board"
+DEC6000 "Digital AlphaServer 8200 and 8400 Family System Board"
+DEC6400 "Digital AlphaServer 4100 System Board"
+DEC8101 "DEC VGA 1024 Graphics Adapter"
+DEC8102 "DEC 8514/A-Compatible Graphics Adapter"
+DEC8103 "DECpc VGA 1024 NI Graphics Adapter"
+DEC8300 "DEC DEPCA LC Ethernet Controller"
+DEC8301 "DEC DEPCA TURBO Ethernet Controller"
+DEL0000 "Generic ISA Board"
+DEL0001 "Dell System(R) 425E(TM) System Board"
+DEL0002 "Dell System(R) 433E(TM) System Board"
+DEL0003 "Dell System(R) 425TE(TM) System Board"
+DEL0004 "Dell System(R) 433TE(TM) System Board"
+DEL0005 "Dell Powerline(TM) Workstation 433DE(TM) System Board"
+DEL0006 "Dell Powerline(TM) Workstation 420DE(TM) System Board"
+DEL0007 "Dell Powerline(TM) Workstation 450DE(TM) System Board"
+DEL0008 "Dell Powerline(TM) Server 433SE(TM) System Board"
+DEL0009 "Dell Powerline(TM) Server 420SE(TM) System Board"
+DEL000A "Dell Powerline(TM) Server 450SE(TM) System Board"
+DEL000B "Dell PowerLine(TM) Workstation 425DE(TM) System Board"
+DEL000C "Dell PowerLine(TM) Server 425SE(TM) System Board"
+DEL0011 "Dell Powerline(TM) Server 450SE/2(TM) System Board"
+DEL0019 "Dell Powerline(TM) Server 466SE(TM) System Board"
+DEL0021 "Dell Powerline(TM) Workstation 450DE/2(TM) System Board"
+DEL0029 "Dell Powerline(TM) Workstation 466DE(TM) System Board"
+DEL002A "Dell Powerline(TM) Workstation P60/DE(TM) System Board"
+DEL002B "Dell Powerline(TM) Workstation P66/DE(TM) System Board"
+DEL002C "Dell Powerline(TM) Workstation P60/SE(TM) System Board"
+DEL002D "Dell Powerline(TM) Workstation P66/SE(TM) System Board"
+DEL0031 "Dell 486/ME System Board"
+DEL0036 "Dell 406x/XE System Board"
+DEL0038 "Dell 456x/XE System Board"
+DEL0054 "Dell System PowerEdge 2100"
+DEL0058 "Dell System PowerEdge 4100"
+DEL005A "Dell System PowerEdge 2200"
+DEL005C "Dell System PowerEdge 4200"
+DEL2100 "Dell Remote Server Assistant Card"
+DEL4001 "Dell Drive Array"
+DEL4002 "Dell SCSI Array Controller"
+DEL6001 "Dell DGX Video Subsystem"
+DELFC00 "Dell GPX-1024 Graphics Performance Accelerator"
+DELFC01 "Dell VGA Professional 16-bit"
+DELFC02 "Paradise Hi-Res Graphics Adapter"
+DELFC03 "Paradise Hi-Res Graphics Card"
+DELFD00 "UltraStor 12F/12F-24 ESDI/Diskette Cntrl"
+DELFD02 "Archive XL Tape Host Adapter"
+DELFD03 "Wangtek Tape Host Adapter"
+DELFD05 "Adaptec AHA-1510 ISA SCSI Host Adapter"
+DIS0000 "NETSERVER LH PRO - DISABLE SCSI B - FOR TEST & EVALUATION ONLY"
+DPT2402 "DPT SCSI Host Bus Adapter (PM2012A/9X)"
+DPT2403 "DPT SCSI Host Bus Adapter (PM2012A/90)"
+DPTA401 "DPT SCSI Host Bus Adapter (PM2012B/9X)"
+DPTA402 "DPT SCSI Host Bus Adapter (PM2012B2/9X) - Banyan Vines"
+DPTA410 "DPT SCSI Host Bus Adapter (PM2X22A/9X)"
+DPTA501 "DPT SCSI Host Bus Adapter (PM2012B1/9X)"
+DPTA502 "DPT SCSI Host Bus Adapter (PM2012B2/9X)"
+DPTA701 "DPT SCSI Host Bus Adapter (PM2011B1/9X)"
+DPTBC01 "DPT ESDI Caching Hard Disk Controller (PM3011/7X)"
+DTC1101 "DTC2290 EISA IDE Controller"
+DTC3101 "DTC3290 Host Adapter"
+DTI0000 "Evolution RISC PC"
+DTI2000 "DTI ESP2000A/ESP2000 EISA System Processor Board"
+DTI2002 "DTI ESP2002 Integrated EISA System Processor"
+DTK0001 "DTK PLM-3300I 80486 EISA Board"
+DTK0003 "DTK PLM-3331P EISACACHE486 33/25/50 MHZ"
+ECS0580 "DI-580A EISA SCSI Host Adapter"
+ECS0590 "DI-590 EISA SCSI Cache Host Adapter"
+ELS8041 "ELSA  WINNER 1000  Enhanced VGA"
+ETI1001 "NE3300 Ethernet Rev. C & D"
+EVX0002 "PN-3000 System Board"
+FCT0001 "EISA SYSTEM BOARD"
+FCT0002 "386 EISA SYSTEM BOARD"
+FCT0003 "486 EISA SYSTEM BOARD"
+FIC0000 "LEO 486VE EISA Main Board"
+FIX1516 "15-16MB Memory Hole Patch - Netserver LF/LC 5/66"
+FSI2001 "ESA-200 ATM"
+FSI2002 "ESA-200A ATM"
+FSI2003 "ESA-200E ATM"
+GDT2001 "GDT2000/GDT2020 Fast-SCSI Cache Controller - Rev. 1.0"
+GDT3001 "GDT3000/GDT3020 Dual Channel SCSI Controller - Rev. 1.0"
+GDT3002 "GDT30x0A Cache Controller"
+GDT3003 "GDT3000B/GDT3010A EISA SCSI Cache Controller - Rev. 1.0"
+GIT0000 "G486PEL EISA & LOCAL Bus Mother Board."
+GIT0001 "G486HVL EISA & VESA LOCAL Bus Mother Board."
+HCL0801 "HCL-Hewlett Packard Limited PANTHER System Board"
+HIT0001 "MCC Mini-EISA486 Board"
+HKG0011 "Distributed Signal Conditioning Front-End"
+HMS0000 "HMSI ESIC EVALUATION BOARD"
+HWP0000 "HP Monochrome Plus Video Board (35732A)"
+HWP0010 "HP Multimode Video Adapter (45981A)"
+HWP0020 "HP Multimode Color Adapter Board (45984A)"
+HWP0030 "HP Enhanced Graphics Adapter Board (45983A)"
+HWP0070 "HP Intelligent Graphics Controller 20 (A1083A)"
+HWP0C70 "HP-IB Host Adapter"
+HWP0C80 "SCSI Host Adapter (Cirrus-II) -- 25525A"
+HWP1400 "HP Dual Serial Interface Board (24541B)"
+HWP1410 "HP Internal 2400 Baud Modem (24551A)"
+HWP1420 "HP Internal 1200 Baud Modem (24550A)"
+HWP1440 "HP Terminal Multiplexor Board (D2040A)"
+HWP1450 "HP HP-IB Interface board (82335A)"
+HWP1460 "HP ScanJet Plus Interface (88290A)"
+HWP1461 "HP ScanJet Plus Interface (88290A)"
+HWP1801 "HP StarLAN 10 PC Link II (27240A)"
+HWP1810 "HP ThinLAN Interface Board (27210B)"
+HWP1811 "HP ThinLAN PC Adapter Card (27250A)"
+HWP1820 "HP EtherTwist Adapter Card/8 (27245-60002)"
+HWP1832 "HP EtherTwist PC LAN Adapter/16 TP Plus (27247B)"
+HWP1840 "HP EtherTwist EISA LAN Adapter/32"
+HWP1850 "LAN AdapterCard -- 25567A"
+HWP18A0 "HP EtherTwist PC LAN Adapter/16 TL Plus (27252A)"
+HWP18C0 "HP EtherTwist PC LAN Adapter NC/16 TP (J2405A)"
+HWP18E0 "HP 100Mbps EISA ATM Card"
+HWP1940 "HP 10/100VG Selectable EISA LAN Adapter (J2577A)"
+HWP1980 "ATM Adapter -- J2802A"
+HWP1990 "Hewlett-Packard EISA 100VG AnyLAN adapter card"
+HWP1C00 "HP Serial/Parallel Interface Board (24540B)"
+HWP2002 "HP ScanJet II Interface (C1752A)"
+HWP2051 "EISA Test Adapter Card"
+HWP2080 "HP ScanJet II Interface (C2502A)"
+HWPC000 "Series 700 EISA System Board"
+HWPC010 "Series 700 EISA System Board"
+HWPC051 "Series 700 EISA System Board"
+HWPC091 "EISA System Board"
+HWPC0D1 "EISA System Board"
+HWPC0E1 "EISA System Board"
+IBM0001 "IBM Auto 16/4 Token Ring ISA Adapter"
+IBM1000 "IBM 16/4 Busmaster EISA Adapter"
+IBM1060 "IBM 100/10 ISA Ethernet Adapter"
+IBM1061 "IBM 100/10 ISA Ethernet Adapter"
+ICLA080 "ICL EtherTeam 32 EISA 32-bit Ethernet Controller"
+ICU0010 "Intel SatisFAXtion Modem/400"
+ICU0020 "Intel SatisFAXtion Modem/100"
+ICU0030 "DigiBoard DigiChannel PC/4E Serial Adapter"
+ICU0040 "Western Digital WD1003V-MM2(WITH FIRMWARE) Hard/Floppy Disk Controller"
+ICU0041 "Western Digital WD1003V-MM2(WITHOUT FIRMWARE) Hard/Floppy Disk Controller"
+ICU0050 "Western Digital WD1007A-WA2(WITH BIOS) Hard/Floppy Disk Controller"
+ICU0051 "Western Digital WD1007A-WA2(WITHOUT BIOS) Hard/Floppy Disk Controller"
+ICU0052 "Western Digital WD1007V-SE2 Hard/Floppy Disk Controller"
+ICU0060 "Archive SC402/VP402 QIC-02 Tape Controller"
+ICU0070 "Wangtek PC-36 Tape Controller"
+ICU0080 "Wangtek PC-02 Tape Controller"
+ICU0091 "Adaptec 1542B SCSI/Floppy Disk Controller"
+ICU0092 "Adaptec 1542C SCSI/Floppy Disk Controller"
+ICU00A0 "DPT PM2011B1/9X SCSI Controller"
+ICU00B0 "3COM Etherlink II (3C503) Network Adapter"
+ICU00C0 "3COM Etherlink 16 (3C507) Network Adapter"
+ICU00D0 "SMC PC600WS Network Adapter"
+ICU00E0 "SMC PC130E Network Adapter"
+ICU00F0 "Novell NE2000 Network Adapter"
+ICU0100 "Western Digital WD8003E Network Adapter"
+ICU0110 "Paradise VGA Plus 16 Video Adapter "
+ICU0120 "Paradise VGA 1024 Video Adapter "
+ICU0130 "Orchid Prodesigner IIs Video Adapter"
+ICU0140 "ATI Graphics Ultra Pro Video Adapter"
+ICU0150 "Orchid Fahrenheit 1280 Video Adapter "
+ICU0160 "ATI VGA Wonder XL24 Video Adapter"
+ICU0170 "ATI Graphics Ultra Video Adapter"
+ICU0180 "Sound Blaster Multi-Media Adapter"
+ICU0190 "Sound Blaster Pro Multi-Media Adapter"
+ICU01A0 "Sound Blaster 16ASP Multi-Media Adapter"
+ICU01B0 "Gravis Ultra Sound Multi-Media Adapter"
+ICU01C0 "Logitech Soundman 16 Multi-Media Adapter"
+ICU01D0 "Media Vision Thunderboard Multi-Media Adapter"
+ICU01E0 "Pro Audio Spectrum 16 Multi-Media Adapter"
+ICU01F0 "Microsoft Windows Sound System Multi-Media Adapter"
+ICU0200 "Intel Above Board Plus 8 I/O"
+ICU0210 "Logitech Bus Mouse"
+ICU0220 "Microfield Graphics V8 Video Controller"
+ICU0230 "Accton Ringpair-4/16 (TR1605)"
+ICU0240 "CNet CN600E/680E"
+ICU0250 "CNet CN1000T"
+ICU0260 "CNet CN850E"
+ICU0270 "CNet CN800E/880E"
+ICU0280 "Cogent E/Master II-AT"
+ICU0290 "Cogent E/Master I-AT"
+ICU02A0 "D-Link DE-100"
+ICU02B0 "D-Link DE-200"
+ICU02C0 "Eagle/Novell NE1000 (810-160-00X)"
+ICU02C1 "Eagle/Novell NE1000 (950-054401)"
+ICU02D0 "Eagle/Novell NE1500T"
+ICU02E0 "Eagle/Novell NE2100"
+ICU02F0 "Gateway Ethertwist 16 (Fujitsu Chipset)"
+ICU02F1 "Gateway Ethertwist 16 (National Chipset)"
+ICU0300 "Gateway Ethertwist PC/PC-WS(National Chipset)"
+ICU0310 "Proteon ProNET-4/16 Model p1390"
+ICU0320 "Racal-Datacom InterLan AT"
+ICU0330 "SMC PC330"
+ICU0340 "SMC PC500"
+ICU0350 "SMC PC550"
+ICU0360 "SMC PC650"
+ICU0370 "SMC PC270E"
+ICU0380 "SMC 3008"
+ICU0390 "SMC 3016"
+ICU03A0 "Thomas-Conrad TC5045-2"
+ICU03B0 "Thomas-Conrad TC6042/TC6142/TC6242"
+ICU03C0 "Thomas-Conrad TC6045"
+ICU03D0 "Thomas-Conrad TC6245"
+ICU03E0 "Tiara Lancard 2002/2003"
+ICU03F0 "Tiara Lancard AT"
+ICU0400 "Tiara Lancard PC"
+ICU0410 "Tiara ARCNET Lancard AT"
+ICU0420 "Tiara Ethernet Lancard * 2000"
+ICU0430 "Tiara Ethernet Lancard E2000"
+ICU0440 "Tiara Lancard A-286"
+ICU0450 "Tiara Lancard E"
+ICU0460 "Tiara Lancard E * AT"
+ICU0470 "Tiara Lancard E * AT TP"
+ICU0480 "Tiara Lancard E * PC"
+ICU0490 "Tiara Lancard E * PC10BT"
+ICU04A0 "Tiara Lancard E * PC10TP"
+ICU04B0 "Tiara Token Ring Lancard*16 AT"
+ICU04C0 "Zenith LAN10E-MAT/FAT/FL-AT"
+ICU04D0 "Zenith LAN16TR-AT"
+ICU04E0 "Zenith LAN16TR-XT"
+ICU04F0 "Zenith LAN4TR-AT"
+ICU0500 "Zenith LAN4TR-XT"
+ICU0510 "Zenith OfficeNIC"
+ICU0520 "Zenith XT Lancard"
+ICU0530 "BOCA M1440I 14.4Kbps V.32bis Modem"
+ICU0540 "Always Technology IN-2000 SCSI Controller"
+ICU0550 "Data Technology DTC3180A/DTC3280A SCSI Controller"
+ICU0560 "DTC3150 SCSI Controller"
+ICU0561 "DTC3150B SCSI Controller"
+ICU0570 "Data Technology DTC3250 SCSI Controller"
+ICU0580 "TMC-850M/TMC-850RL SCSI Controller"
+ICU0590 "Future Domain TMC-880/TMC-881 SCSI Controller"
+ICU05A0 "Future Domain TMC-1650/1660/1670/1680 SCSI Controller V5"
+ICU05B0 "Future Domain TMC-1650/1660/1670/1680 SCSI Controller V4"
+ICU05C0 "Promise Technology DC-2030 IDE Controller"
+ICU05D0 "Promise Technology DC-2031 IDE Controller"
+ICU05E0 "Promise Technology DC-2040 SCSI Controller"
+ICU05F0 "Ultrastor ULTRA14F SCSI Controller"
+ICU0600 "Ultrastor ULTRA12C/12F ESDI Controller"
+ICU0610 "Ultrastor ULTRA15C IDE Controller"
+ICU0620 "Longshine LCS-6624/6624G IDE Controller"
+ICU0630 "Longshine LCS-6631/6631F SCSI Controller"
+ICU0640 "Intel EtherExpress TPE Hub Controller"
+ICU0650 "US Robotics Sportster 9600/PC Modem w/V.42BIS"
+ICU0660 "Zoom AFC FAX Modem"
+ICU0680 "DFI DIO-500 Serial/Parallel I/O Card"
+ICU0681 "DFI DIO-200 Serial/Parallel I/O Card"
+ICU0690 "Practical Peripherals PM9600FX Modem/FAX"
+ICU06A0 "Practical Peripherals PM2400 Modem"
+ICU06B0 "Zoom VFP V.32bis FAX Modem"
+ICU06C0 "Zoom VP V.32bis Modem"
+ICU06D0 "Zoom AMC 2400 Modem"
+ICU06E0 "Cardinal MVP96IF 9600 Baud FAX/Modem"
+ICU06F0 "Cardinal MB2296SR 9600 Baud FAX/Modem"
+ICU0700 "Hayes Accura 2400B Modem"
+ICU0710 "US Robotics Sportster 2400/PC Modem"
+ICU0720 "US Robotics Sportster 14,400/PC FAX/Modem"
+ICU0730 "Intel SatisFAXtion Modem/200"
+ICU0740 "Racal InterLan NI5210-10BT"
+ICU0750 "Racal InterLan NI6510-UTP"
+ICU0760 "Intel Smart Video Recorder"
+ICU0770 "Diamond Stealth Pro Accelerator"
+ICU0780 "Diamond SpeedStar 24X VGA adapter"
+ICU0790 "Video Seven WIN.PRO card"
+ICU0800 "Video Seven WIN.VGA card"
+ICU0810 "BOCA Super X Accelerator VGA"
+ICU0820 "Metheus Premier 928"
+ICU0830 "GraphicsENGINE ULTRA Series"
+ICU0840 "Cardinal VIDEO spectrum"
+ICU0850 "SigmaDegins Legend 24LX"
+ICU0860 "Hercules Graphite Card"
+ICU0870 "Focus GUIVGA"
+ICU0880 "AIR AVIEW2V SVGA"
+ICU0890 "NDI Volante Warp Series Warp10"
+ICU0900 "NDI Volante Warp Series Warp10LB and 24LB"
+ICU0910 "Cyber Audio Multi-Media Adapter"
+ICU0920 "Genoa SuperVGA 6000 Series"
+ICU0930 "Acculogic sIDE-1"
+ICU0940 "Acculogic sIDE-1/16"
+ICU0950 "Acculogic sIDE-3/plus"
+ICU0960 "Alpha Research S4251 ISA"
+ICU0970 "CMS Enhancement Universal AT/XT Controller"
+ICU0980 "Eastern IDC-747"
+ICU0990 "Juko D16-X"
+ICU1000 "NCL538/NCL539"
+ICU1010 "NCL538B"
+ICU1020 "NCL538C"
+ICU1030 "easyCACHE IDE/easyCACHEPro IDE"
+ICU1040 "Plus Development HARDCARD II XL"
+ICU1050 "Plus Development HARDCARD II"
+ICU1060 "Seagate ST05A"
+ICU1070 "Seagate ST05X"
+ICU1080 "Silicon ADP60"
+ICU1090 "Silicon ADP65"
+ICU1100 "HP ISA SCSI Host Adapter (D1682A)"
+ICU1101 "HP SCSI-1 Host Adapter for HP CD-ROM (D2886A)"
+ICU1110 "Adaptec AHA-1540A/AHA-1542A"
+ICU1120 "Bustek BT-542B"
+ICU1130 "Bustek BT-542S/BT-542D"
+ICU1140 "Computer Electronik Infosys C5610"
+ICU1150 "Computer Electronik Infosys C5630"
+ICU1160 "Computer Electronik Infosys C5635"
+ICU1170 "Control Concepts HB A8"
+ICU1180 "DPT PM2001B/90,PM2001B/95"
+ICU1190 "Quantum ISA-200S"
+ICU1200 "easyCACHE SCSI/easyCACHEPro SCSI"
+ICU1210 "Procom CC-8 SCSI ENABLER"
+ICU1220 "Procom CC-16 SCSI ENABLER"
+ICU1230 "Procomp S-DCB"
+ICU1240 "Procomp USA, Incoprated S-DCB"
+ICU1250 "Rancho RT10-AT"
+ICU1260 "SMS OMTI-810/812/820/822"
+ICU1270 "SMC 4004-PC"
+ICU1280 "Sumo SPI 200"
+ICU1290 "Trantor T100"
+ICU1300 "IBM Token-Ring 16/4 Adapter"
+ICU1310 "Thomas TC-4045"
+ICU1330 "DPT PM2011/95 SCSI Controller"
+ICU1340 "DPT PM2021 SamrtCacheIII Adapter"
+INP0010 "Barracuda E/4810"
+ICU1360 "SyQuest SQ08  IDE  Controller"
+ICU1370 "SyQuest ST01 SCSI HOST Adapter"
+IDS0100 "EISC960 EISA Caching SCSI Host Adapter"
+IIN0B01 "Intel TokenExpress(tm) ISA/8 Network Adapter"
+IKN1110 "IKON hardcopy boards: 10092, 10097, or 10111"
+IMS1001 "Integrated Micro Solution Inc. 486 EISA System Board"
+ING2040 "HCL-Hewlett Packard Limited PANTHER System Board"
+INP25D0 "Seahawk 4811 FDDI Controller"
+INP5000 "Interphase 4800 EISA->PCI Bridge"
+INT0000 "Mercury/Neptune PCI-EISA Main Board"
+INT0081 "HCL-Hewlett Packard Limited PANTHER System Board"
+INT0701 "Intel TokenExpress(tm) ISA 16/4 Network Adapter"
+INT0703 "Intel TokenExpress(tm) ISA/16s Network Adapter"
+INT0902 "Intel TokenExpress(tm) EISA 16/4 Network Adapter"
+INT0B01 "Intel TokenExpress(tm) ISA/8 Network Adapter"
+INT1000 "Intel EtherExpress 16 Family LAN Adapter"
+INT1010 "Intel EtherExpress(tm) Flash32 Ethernet Adapter"
+INT1030 "Intel EtherExpress(TM) PRO/10 LAN Adapter"
+INT1031 "Intel EtherExpress(TM) PRO/10+ LAN Adapter"
+INT1060 "Intel EtherExpress(tm) PRO/100 LAN Adapter"
+INT1201 "Intel TokenExpress(tm) EISA/32 Network Adapter"
+INT3061 "LP486E System Board"
+INT3079 "X-Series Desktop System Board"
+INT3089 "X-Series Deskside System Board"
+INT30A1 "L486 Series System Board"
+INT30A9 "L486 Series System Board"
+INT30D1 "X-Series System Board"
+INT30F1 "X-Series Premium System Board"
+INT3132 "ECC Memory Module (BXECCMEM0)"
+INT31A0 "System Board"
+ISA0000 "Generic ISA Adapter"
+ISA0001 "Generic Video Card"
+ISA1000 "Serial/Parallel Adapter Board"
+ISA1010 "Generic OSF ISA COM/MODEM/LPT"
+ISA2000 "Microsoft Sound Board ISA Adapter Definition"
+ISA3000 "ISA-PCMCIA Adapter"
+ISA4000 "Dialogic Voice Card Adapter"
+ISA4010 "Dialogic DTI/2xx, DMX, MSI/C Adapter"
+ISA4020 "GammaLink Fax Card Adapter Definitions"
+ISA4030 "Dialogic Antares Card Definitions"
+ISA6400 "ISA ATI MACH64 VGA controller"
+ISA8100 "Attachmate 3270 COAX Adapter (Long Board)"
+ISA8101 "Attachmate Advanced 3270 COAX Adapter (Short Board)"
+ISA8102 "Attachmate SDLC/Autolink Adapter"
+ISA8103 "Attachmate SDLC Adapter"
+ISA8200 "AST 3270/COAX II Rev. X4"
+ISA8201 "AST 5251/11 Enhanced Plus"
+ISA8202 "AST SixPakPlus Version A"
+ISA8203 "AST Rampage 286"
+ISA8204 "AST RAMvantage"
+ISA8300 "IBM Enhanced 5250 Emulator"
+ISA8301 "IBM Enhanced 5250 Emulator Rev B"
+ISA8302 "IBM SDLC (3270 or 5250 Remote)"
+ISA8303 "IBM Advanced 3278/79 Adapter"
+ISA8304 "IBM Serial/Parallel Adapter"
+ISA8305 "IBM PC Network"
+ISA8306 "IBM TOKEN RING Adapter I"
+ISA8307 "IBM TOKEN RING Adapter II"
+ISA8308 "IBM Monochrome Adapter"
+ISA8309 "IBM VGA Display Adapter"
+ISA830A "IBM Token Ring II Short Adapter"
+ISA830B "IBM Token Ring 16/4 Adapter"
+ISA830C "IBM Enhanced Graphics Adapter"
+ISA830D "IBM PGA"
+ISA830E "IBM Realtime Interface Co-Processor Multiport Adapter, Model 2"
+ISA8400 "IDEAssociates IDEAcomm 5250/Remote"
+ISA8401 "IDEAssociates IDEAcomm 5251 Twinax Plus Rev D"
+ISA8402 "IDEAssociates IDEAcomm 5251 Twinax Plus Rev C"
+ISA8403 "IDEAssociates IDEAcomm 5251 Twinax Rev A,B,C"
+ISA8500 "DCA IRMA2 Adapter"
+ISA8501 "DCA IRMA 3278 Emulation"
+ISA8502 "DCA IRMA 3279 Graphics Adapter"
+ISA8503 "DCA IRMA3 Convertible"
+ISA8505 "DCA Smart Alec 5250"
+ISA8506 "DCA IRMA Remote SDLC Adapter"
+ISA8507 "DCA 10-NET Adapter"
+ISA8508 "DCA IRMA2 3279 Graphics Adapter"
+ISA8509 "DCA Intelligent Serial PC Adapter (Long SDLC)"
+ISA8700 "Novell Coax Adapter 3270 Connection"
+ISA8701 "Novell COAX GRAPHICS Rev. A"
+ISA8702 "Novell TWINAX 5250"
+ISA8711 "Novell NE1000 Ethernet Adapter"
+ISA8712 "Novell NE2000 Ethernet Adapter"
+ISA8713 "Novell RX-Net REV B,C,D NIC"
+ISA8714 "Novell RX-Net REV E,F,G NIC"
+ISA8804 "Tecmar EGA Master 480/800"
+ISA8805 "Tecmar Maestro AT"
+ISA8900 "SMC ARCNET PC"
+ISA8901 "SMC ARCNET PC100"
+ISA8902 "SMC ARCNET PC110"
+ISA8903 "SMC Arcnet PC130/E"
+ISA8904 "SMC Arcnet PC220/120"
+ISA8905 "SMC Arcnet PC270/E"
+ISA8906 "SMC Arcnet PC500"
+ISA8907 "SMC Ethernet PC510"
+ISA8A00 "NESTAR ARCNET PLAN 2000"
+ISA8B00 "DEC DEPCA EtherLink Adapter, Rev D1"
+ISA8B01 "DEC DEPCA EtherLink Adapter, Rev E or F"
+ISA8C00 "3COM 3C505-2012 EtherLink Plus 16bit Mode"
+ISA8C01 "3COM EtherLink 3C501 ASM 1221"
+ISA8C02 "3COM EtherLink 3C500B ASM 34-0780"
+ISA8C03 "3COM 3C503 EtherLink II"
+ISA8C04 "3COM 3C603 Tokenlink 16bit"
+ISA8C05 "3COM 3C605-2065 Tokenlink Plus 8bit"
+ISA8C06 "3COM 3C505-2012 EtherLink Plus 8bit Mode"
+ISA8C07 "3COM 3C605-2065 Tokenlink Plus 16bit Mode"
+ISA8C08 "3COM 3C603 Tokenlink 8bit Mode"
+ISA8C09 "3COM 3C507 Etherlink 16"
+ISA8C10 "3COM 3C507TP Etherlink 16"
+ISA8D00 "Tiara LANCARD/A REV B"
+ISA8D01 "Tiara LANCard/E * PC 16"
+ISA8E00 "Microsoft Mouse Controller"
+ISA8E01 "Scanman Plus by Logitech"
+ISA8F00 "AT&T STARLAN Network Adapter"
+ISA8F01 "AT&T Truevision Image Capture Board"
+ISA9000 "Hercules GB222 InColor Card"
+ISA9001 "Hercules Graphics Card Plus"
+ISA9002 "Hercules VGA Card"
+ISA9100 "Quadram QuadEGA+"
+ISA9101 "Quadram QuadVGA Video Adapter"
+ISA9102 "Quadram QUADMEG-AT"
+ISA9103 "QUADEMS+ W/IO"
+ISA9200 "Intel Above Board/AT (no Piggyback)"
+ISA9201 "Intel Above Board/AT With 2MB Piggyback"
+ISA9202 "Intel Above Board 286 (no Piggyback)"
+ISA9203 "Intel Above Board 286 With 2MB Piggyback"
+ISA9204 "Intel Above Board PS/286 (no Piggyback)"
+ISA9205 "Intel Above Board PS/286 With 2MB Piggyback"
+ISA9206 "Intel Above Board Plus 8 (including 6Mb Piggyback)"
+ISA9207 "Intel Visual Edge printing enhancement system"
+ISA9208 "Intel iMX-LAN/586"
+ISA9209 "Intel PC586E"
+ISA9300 "MICOM-Interlan NP600A Ethernet 16bit"
+ISA9302 "MICOM-Interlan NI5210/8 Ethernet"
+ISA9303 "MICOM-Interlan NI5210/16 Ethernet"
+ISA9400 "Gateway G/Ethernet AT"
+ISA9401 "Gateway G/Ethernet 8-bit PC"
+ISA9402 "Gateway G/Token Ring 8-bit "
+ISA9403 "Gateway G/Token Ring AT "
+ISA9404 "Gateway G/Net VS "
+ISA9405 "Gateway G/Net LNIM"
+ISA9500 "Proteon ProNET-4/AT P1344"
+ISA9600 "Madge AT Ring Node"
+ISA9601 "Smart ISA Ringnode"
+ISA9700 "IMC PCnic 16bit NIC"
+ISA9800 "Video Seven V-RAM VGA"
+ISA9801 "Video Seven Vega Deluxe EGA Adapter"
+ISA9802 "Video Seven FastWrite VGA Video Adapter"
+ISA9803 "Video Seven VGA 1024i Video Adapter"
+ISA9900 "Sigma Designs VGA-PC-HP160/162"
+ISA9901 "Sigma Designs SigmaVGA or VGA/HP8"
+ISA9A00 "Verticom M16/M256E"
+ISA9A01 "Verticom MX16/AT & MX256/AT"
+ISA9B00 "HP 82328A Intelligent Graphics Controller"
+ISA9C01 "Matrox PG-1281"
+ISA9C02 "Matrox PG-1024"
+ISA9C03 "Matrox PG-641"
+ISA9D00 "Renaissance GRX Rendition I"
+ISA9D01 "Rendition II Intelligent Graphics Controller"
+ISA9E00 "Pixelworks Micro Clipper Graphics"
+ISA9E01 "Pixelworks Ultra Clipper Graphics"
+ISA9F00 "Genoa Super VGA 16-Bit"
+ISA9F02 "Genoa SuperVGA"
+ISA9F03 "Genoa SuperEGA HiRes+"
+ISA9F04 "Genoa SuperSpectrum Model 4650"
+ISA9F05 "Genoa SuperSpectrum Model 4640"
+ISA9F07 "Genoa Systems QIC-02 Tape Controller"
+ISAA000 "Vermont Page Manager 100"
+ISAA100 "Orchid TurboPGA"
+ISAA101 "Orchid ProDesigner VGA/VGA+"
+ISAA102 "Orchid Enhanced Board OM"
+ISAA103 "Orchid Enhanced Board w/IO"
+ISAA200 "Paradise VGA Professional 16-bit"
+ISAA201 "Paradise VGA Plus 8-bit"
+ISAA202 "Paradise Autoswitch EGA"
+ISAA300 "Truevision ATVista ICB"
+ISAA400 "Excelan EXOS 205E"
+ISAA401 "Excelan EXOS 205T 16-Bit"
+ISAA500 "Pure Data PDI8025 Token Ring"
+ISAA501 "Pure Data PDI508 ArcNet"
+ISAA600 "BICC ISOLAN Ethernet"
+ISAA700 "Control Systems Artist 10"
+ISAA701 "Control Systems Artist XJ10"
+ISAA800 "Codenoll Codenet3051"
+ISAAB00 "Hayes Smartmodem 1200B"
+ISAAB01 "Hayes Smartmodem"
+ISAAB02 "Hayes Smartmodem 2400B"
+ISAAB03 "Hayes Smartmodem 2400Q"
+ISAAC00 "ATI Tech. Inc. EGA WONDER"
+ISAAC01 "ATI Tech. Inc. VGA WONDER"
+ISAAD00 "TOPS FlashCard"
+ISAAE01 "Arnet SMARTPORT Card"
+ISAAE02 "Arnet MODULAR SMARTPORT Card"
+ISAAE03 "Arnet SMARTPORT 16 Card"
+ISAAF00 "Computone INTELLIPORT Multiport Serial Card"
+ISAAF01 "Computone IntelliPort ATCC Cluster Controller"
+ISAB000 "Anvil Designs Stallion Intelligent I/O Controller"
+ISAB100 "Emerald 3XTwin 5250 Twinax"
+ISAB101 "Emerald 3XPlus 5250 Remote"
+ISAB200 "EVEREX Evercom 24 2400 baud modem"
+ISAB300 "Practical Modem 2400"
+ISAB401 "STB Systems EGA Plus"
+ISAB402 "STB Chauffeur HT"
+ISAB403 "STB VGA Extra"
+ISAB404 "STB EGA MultiRes"
+ISAB500 "Banyan Intelligent Communications Adapter"
+ISAB600 "Computer Peripherals Monographic Video"
+ISAB601 "Computer Peripherals VisionMaster VGA"
+ISAB602 "Graphmaster Plus EGA Video Adapter"
+ISAB700 "Iomega Bernoulli PC3B/50 Board"
+ISAB701 "Iomega Bernoulli PC2/50, PC2B/50 Boards"
+ISAB702 "Iomega Bernoulli II Combo Adapter Board"
+ISAB800 "Archive SC499R Tape Controller"
+ISAB801 "Archive VP402 Tape Adapter"
+ISAB900 "DigiBoard DigiCHANNEL PC/Xe"
+ISAB901 "DigiBoard DigiCHANNEL PC/8i"
+ISAB903 "Digiboard Digichannel PC/8e"
+ISAB904 "DigiBoard Com/8s"
+ISAB905 "DigiBoard DigiCHANNEL PC/8"
+ISABA00 "Alloy IMP2 Multiuser Port Controller"
+ISABA01 "Alloy IMP8 Multiuser Port Controller"
+ISABA02 "Alloy PC-HIA XBUS Controller"
+ISABA03 "Alloy FTFA Tape & Floppy Controller"
+ISABB00 "BIT3 403/404/405 Bus Communications Adaptors"
+ISABC00 "Boca Research BOCARAM/AT Plus"
+ISABC01 "Boca Research I/O Master AT"
+ISABD00 "Racal-Interlan NP600A Ethernet 16bit"
+ISABD02 "Racal-Interlan NI5210/8 Ethernet"
+ISABD03 "Racal-Interlan NI5210/16 Ethernet"
+ISABE00 "Qua Tech PXB-1608 Parallel Expansion Board"
+ISABE01 "Qua Tech ES-100 8 Channel Asyncronous"
+ISABE02 "Qua Tech QS-100M 4 Channel Asyncronous"
+ISABE03 "Qua Tech MXI-100 IEEE 488 GPIB"
+ISABE04 "Qua Tech DS-201 Dual Channel RS-422"
+ISABE05 "Qua Tech PXB-721 Parallel Expansion"
+ISABE06 "Qua Tech DSDP-402 Dual Serial/Dual Parallel"
+ISABE07 "Qua Tech WSB-10 Waveform Synthesizer"
+ISABE08 "Qua Tech SmartLynx Multiport Adapter"
+ISABF00 "EOgraph Plus"
+ISAC000 "Corollary 8x4 Mux (Jumpers)"
+ISAC001 "Corollary 8x4 Mux (Rotary Switches)"
+ISAC002 "Corollary 8x4"
+ISAC100 "Bell Technologies' ACE Multiport Serial Card"
+ISAC200 "Micro-Integration PC-STWINAX"
+ISAC201 "Micro-Integration PC-MICOAX"
+ISAC300 "BlueLynx 5251-12"
+ISAC301 "BlueLynx 5250"
+ISAC302 "BlueLynx 3270 Remote"
+ISAC303 "BlueLynx Enhanced 5251-11"
+ISAC304 "BlueLynx 3270 Enhanced Coax"
+ISAC400 "Core CNT-ATP ESDI Internal FD Ctrl"
+ISAC500 "CEC PC 488 IEEE Printer Controller"
+ISAC600 "Vector International SCC Async/BSC/SDLC"
+ISAC700 "LSE Electronics YC808 Color Graphics Printer Adapter"
+ISAC701 "LSE Electronics Platinum VGA16 Card"
+ISAC800 "Street Electronics ECHO PC+ Speech Synthesizer"
+ISAC900 "SIIG ARCLAN-100 Arcnet Network Board."
+ISACA00 "National Instruments GPIB-PCIIA"
+ISACA01 "National Instruments AT-GPIB"
+ISACA02 "National Instruments GPIB-PC"
+ISACB00 "Konan TNT-1050 Caching Disk Controller"
+ISACC00 "Packard Bell PB 3270 Coax"
+ISACD00 "Digital Storage Systems ARC6000"
+ISACE00 "Ideaphone Input Device"
+ISACF00 "Atronics Professional Image Board Plus"
+ISAD000 "Bi-Tech SCSI 2110 HD/TAPE Controller"
+ISAD001 "Bi-Tech SCSI 2200 Controller"
+ISAD100 "Equinox Megaport Board"
+ISAD200 "Comtrol SMART HOSTESS Multiport Serial Card"
+ISAD300 "Emulex MPC-II Comm Controller"
+ISAD301 "Altos Wide Area Network Board /2"
+ISAD400 "Western Digital WD1004A-WX1 Controller"
+ISAD401 "Western Digital WD1006V-MM2 Winchester/Floppy Controller"
+ISAD402 "Western Digital WD1006V-SR2 Winchester/Floppy Controller"
+ISAD403 "Western Digital WD1007A-WAH Winchester Controller"
+ISAD404 "Western Digital WD1007V-SE1 Winchester Controller"
+ISAD500 "GammaLink GammaFax NA"
+ISAD501 "GammaLink GammaFax CP"
+ISAD600 "The Complete FAX/9600"
+ISAD601 "The Complete Page Scanner"
+ISAD602 "Scanman Plus"
+ISAD700 "Hughes 4140 Ethernet Board"
+ISAD701 "Hughes 6130 Broadband Network Card"
+ISAD702 "Hughes(Sytek) 6140 Token Ring Net. Board"
+ISAD800 "AMI SMART PACK 2 W/ PAL 5.1"
+ISAD801 "AMI SMART PACK 2 W/ PAL 6.1"
+ISAD802 "AMI SMART PACK 2 W/ PAL 6.2"
+ISAD900 "NEC Multisync Graphics Board GB-1"
+ISADA00 "Torus Systems Ethernet Adapter"
+ISADA01 "Torus Systems Ethernet Adapter/SB"
+ISADB00 "Rabbit Software RB14 X.25 Adapter"
+ISADB01 "Rabbit Software RB24 Multi-Protocol Comm"
+ISADC00 "Nth Graphics Nth Engine"
+ISADD00 "Chase AT4/AT8/AT16"
+ISADE00 "QMS JetScript"
+ISADF00 "Altos ACPA/AT"
+ISADF01 "SoundBlaster by Creative Labs, Inc."
+ISADF02 "Emerald Systems SCSI Tape Adapter"
+ISADF03 "Weitek Array Processor, Brd #3002-0046-01"
+ISAE000 "Headlands VGA 1024i Video Adapter"
+ISAE100 "Scanman Plus"
+ISAE300 "Overland Data 9-Track Tape TX-8 Controller"
+ISAE401 "Microfield V8 Color Graphics Controller"
+ISAE402 "Microfield T8 Color Graphics Controller"
+ISY0010 "(SYSTEM) VGA Board"
+ISY0020 "(SYSTEM) COM Ports"
+ISY0030 "(SYSTEM) Mother Board PS-2 style Mouse"
+ISY0040 "(SYSTEM) Hard Disk Controller"
+ISY0050 "(SYSTEM) Floppy Drive Controller"
+ISY0060 "(SYSTEM) LPT Ports"
+ISY0070 "(SYSTEM) IRQ9 Cascaded Interrupt"
+ITC0001 "EISA-486C Main Board"
+ITK0011 "ITK ixEins Basic S0/Up0 ISDN-Adapter Version 1.1"
+ITK0012 "ITK ixEins Basic S0/Up0 ISDN-Adapter Version 1.2"
+KCI3201 "ET32EM EISA 32-bit BUS-MASTER Ethernet Adapter"
+KCI3202 "ET-32EM 32-bit EISA Bus Master Ethernet Adapter"
+LEF8000 "LeafNet LAN Adapter"
+MCC0000 "MCC EISA-486 Board"
+MCC0001 "MCCI-486 EISA System Board"
+MCY2501 "Microdyne NE2500/NE5500 Series Ethernet Lan Adapter"
+MDG0002 "Madge Smart 16/4 EISA Ringnode"
+MDG0010 "Madge Smart 16/4 AT Ringnode"
+MDG0020 "Madge Smart 16/4 ISA Client Ringnode"
+MDG2000 "Madge Blue+ 16/4 ISA Token Ring Adapter"
+MDG2010 "Madge Blue+ 16/4 ISA PnP Token Ring Adapter"
+MET1104 "Metheus UGA 1104 Graphics Controller"
+MET1128 "Metheus UGA 1124/1128 Graphics Ctlr."
+MIC0001 "MICRONICS EISA 486 66/50/33/25 System Board"
+MIC0004 "MICRONICS 486 PCI-EISA System Board"
+MIC0005 "MICRONICS M5PE EISA-PCI Pentium System Board"
+MIC0021 "FD-0475 EISA Bus Ethernet LAN Adapter"
+MIC0054 "Micronics M54Pe Dual Pentium PCI-EISA System Board"
+MIC3001 "Micronics EISA3 System Board"
+MIC5402 "Micronics M54E2 Dual Pentium PCI-EISA System Board"
+MINIADP "Adaptec 32-bit SCSI Host Adapter (with floppy)"
+MIR0928 "miroCRYSTAL / miroMAGIC / miroRAINBOW (14-Sep-93) "
+MLX0010 "Mylex LNE390A EISA 32-bit Ethernet LAN Adapter"
+MLX0011 "Mylex LNE390B EISA 32-bit Ethernet LAN Adapter"
+MLX0020 "Mylex DCE376 EISA 32-Bit SCSI Host Adapter"
+MLX0021 "Mylex DCE376 EISA 32-Bit SCSI Host Adapter"
+MLX0022 "Mylex DCE376 EISA 32-Bit SCSI Host Adapter"
+MLX0030 "Mylex LNI390A ISA 16-Bit Ethernet LAN Adapter"
+MLX0040 "Mylex GXE020B or GXE020C EISA 32-Bit Graphics Controller"
+MLX0050 "Mylex GLE(911) EISA Graphics Adapter"
+MLX0070 "Mylex DAC960 EISA Disk Array Controller"
+MLX0071 "Mylex DAC960 EISA Disk Array Controller (3-channel)"
+MLX0072 "Mylex DAC960 EISA Disk Array Controller (3-channel)"
+MLX0073 "Mylex DAC960 EISA Disk Array Controller (2-channel)"
+MLX0074 "Mylex DAC960 EISA Disk Array Controller (1-channel)"
+MLX0075 "Mylex DAC960-A EISA Disk Array Controller (3-channel)"
+MLX0076 "Mylex DAC960-A EISA Disk Array Controller (2-channel)"
+MLX0077 "Mylex DAC960-A EISA Disk Array Controller (1-channel)"
+MLX0101 "Mylex LME596 EISA 32-bit 4 Channel Ethernet LAN Adapter"
+MLXFD01 "Mylex Corporation MDE486 EISA 32-Bit 486 System Board"
+MLXFE01 "Mylex MBE486 EISA 32-Bit 486 System Board"
+MLXFF01 "Mylex MAE486 EISA 32-Bit 486 System Board"
+MLXFF02 "Mylex Corporation MDE486 or MNE486 EISA 32-Bit 486 System Board"
+MTX2040 "MATROX IM-1280/EISA"
+NEC8201 "DPT SCSI Host Bus Adapter w/ Cache (PM2012B/90)"
+NIC0202 "AT-MIO-16 Multi-function Board"
+NIC0301 "AT-DIO-32F Digital I/O Board"
+NIC0400 "PC-DIO-24 Digital I/O Board"
+NIC0501 "LAB-PC/LAB-PC+ Multi-function Board"
+NIC0602 "AT-MIO-16F-5 Multi-function Board"
+NIC0700 "PC-DIO-96 Digital I/O Board"
+NIC0800 "PC-LPM-16 Low Power Multi-function Board"
+NIC0900 "PC-TIO-10 Timing I/O Board"
+NIC1000 "AT-A2150 16-bit 4 Channel A/D Board"
+NIC1100 "AT-DSP2200 DSP Accelerator/Audio I/O Board"
+NIC1200 "AT-AO-6/10 ANALOG OUTPUT BOARD"
+NIC1300 "AT-MIO-16X Multi-function Board"
+NIC1400 "AT-MIO-64F-5 Multi-function Board"
+NIC1500 "AT-MIO-16D Multi-function Board"
+NICC005 "National Instruments AT-GPIB Interface Board"
+NICC105 "National Instruments GPIB-PCIIA Interface Board"
+NICC205 "National Instruments GPIB-PCII Interface Board"
+NICC304 "National Instruments AT-GPIB/TNT"
+NICC502 "National Instruments EISA-GPIB"
+NON0101 "c't Universal 16-Bit Multi I/O Adapter"
+NON0102 "c't Universal 16-Bit Multi I/O Adapter"
+NON0201 "c't Universal 8-Bit Multi I/O Adapter"
+NON0301 "c't Universale Graphic Adapter"
+NON0401 "c't Universal Ethernet Adapter"
+NON0501 "c't Universal 16-Bit Sound Adapter"
+NON0601 "c't Universal 8-Bit Adapter"
+NSS0011 "Newport Systems Solutions WNIC Adapter"
+NVL0701 "Novell NE3200 Bus Master Ethernet"
+NVL0901 "Novell NE2100 Ethernet/Cheapernet Adapter"
+NVL1001 "Novell NMSL (Netware Mirrored Server Link)"
+NVL1201 "Novell NE32HUB 32-bit Base EISA Adapter"
+NVL1301 "Novell NE32HUB 32-bit TPE EISA Adapter"
+NVL1401 "Novell NE32HUB PME ISA Adapter"
+NVL1501 "Novell NE2000PLUS Ethernet Adapter"
+OLC0701 "Olicom ISA 16/4 Token-Ring Network Adapter"
+OLC0702 "Olicom OC-3117, ISA 16/4 Adapter (NIC)"
+OLC0801 "OC-3118 Olicom ISA 16/4 Token-Ring Network Adapter"
+OLC0901 "Olicom EISA 16/4 Token-Ring Network Adapter"
+OLC0902 "Olicom EISA 16/4 Token-Ring Network Adapter"
+OLC0B01 "Olicom PCA 16/4 Token-Ring Network Adapter"
+OLC1201 "Olicom 32 Bit EISA 16/4 Token-Ring Network Adapter"
+OPT0000 "OPTi HUNTER EISA 32-Bit 486 System Board"
+OPT0200 "OPTi LOW_COST EISA 32-Bit 486 System Board"
+OTI0011 "Pro II/EISA"
+PCI0080 "PIONEER 486WB 8 SLOT EISA SYSTEM BOARD"
+PCI0120 "PIONEER 486WB 12 SLOT EISA SYSTEM BOARD"
+PCI2080 "PIONEER 486WB 8 SLOT EISA SYSTEM BOARD"
+PHI8041 "Standard VGA controller"
+PLX1001 "OCEAN EISALink EISA 32-Bit BUS-MASTER Ethernet Controller"
+PRO6000 "Proteon ProNET 4/16 Token Ring Adapter"
+PRO6001 "Proteon ProNET 4/16 Token Ring Adapter"
+PRO6002 "Proteon ProNET 4/16 Token Ring Adapter"
+PTI5401 "Poseidon P6 QUAD PCI-EISA Board"
+RII0101 "Racal InterLan ES3210 Ethernet Controller"
+SEC0010 "SAMSUNG ISA Multifunction Card"
+SEC0020 "SAMSUNG VGA Card (GTI VC-004)"
+SEC0021 "WD 90C31 Local Bus VGA"
+SECFF01 "SAMSUNG MAE486 System Board"
+SECFF02 "OPTi/EISA 32-Bit 486 System Board"
+SGT0101 "AT&T GIS  8/16 Port Serial Controller"
+SIS0000 "4DESD EISA-486 System Board"
+SIS0001 "EISA-486 Demo Board"
+SKD0100 "SK-NET FDDI-FE EISA 32-Bit FDDI LAN Adapter"
+SMC0110 "Standard Microsystems Corp. Elite32 Ethernet"
+SMC03E0 "SMC EtherCard PLUS Family LAN Adapters"
+SMC13E0 "SMC EtherCard PLUS Elite16 Family LAN Adapters"
+SMC8003 "SMC EtherCard PLUS Elite Family LAN Adapters"
+SMC8010 "SMC Ethercard Elite32C Ultra"
+SMC8013 "SMC EtherCard PLUS Elite16 Family LAN Adapters"
+SMC8216 "SMC EtherCard Elite16 ULTRA Family LAN Adapters"
+SMCA010 "SMC Ether 10/100"
+SNIAAA0 "Siemens Nixdorf Ether-Board EISA T"
+SNIAAB0 "Siemens Nixdorf Ether-Board EISA 2"
+SNIABF0 "Siemens Nixdorf ETHER-BOARD-AT105T Ethernet/Cheapernet Adapter"
+SNIACA0 "Siemens Nixdorf ETHER-BOARD-AT10T Ethernet/Twisted Pair Adapter"
+STL0100 "Stallion Technologies - ONboard/E"
+STL0120 "Stallion Technologies - ONboard ISA"
+STL0130 "Stallion Technologies - Brumby ISA"
+STL0200 "Stallion Technologies - EasyIO"
+STL0400 "Stallion Technologies - EC 8/64-EI"
+STL0410 "Stallion Technologies - EC 8/32-AT"
+STL0420 "Stallion Technologies - EC 8/64-AT"
+SUK1022 "SK-NET Token Ring LAN Interface Board"
+SUK1059 "SK-NET G16 LAN Interface Board"
+SUK1072 "SK-FDDI FI LAN Interface Board"
+TCC010C "Thomas-Conrad TC6045 ARC-Card/AT"
+TCC030D "Thomas-Conrad TC6042 ARC-Card/CE"
+TCC040B "Thomas-Conrad TC6142 ARC-Card/CE"
+TCC3047 "Thomas-Conrad TC3047 TCNS Adapter/EISA"
+TCM3190 "3Com 3C319 TokenLink Velocity ISA NIC"
+TCM5030 "3COM EtherLink II Family"
+TCM5070 "3COM 3C507 Etherlink 16 or TP v2.0"
+TCM5090 "3Com 3C509-TP Network Adapter"
+TCM5091 "3Com 3C509 Network Adapter"
+TCM5092 "3Com 3C579-TP EISA Network Adapter"
+TCM5093 "3Com 3C579 EISA Network Adapter"
+TCM5094 "3Com 3C509-Combo Network Adapter"
+TCM5095 "3Com 3C509-TPO Network Adapter"
+TCM5098 "3Com 3C509-TPC Network Adapter"
+TCM5920 "3Com EtherLink III Bus Master EISA (3C592) Network Adapter"
+TCM5970 "3Com Fast EtherLink EISA (3C597-TX) Network Adapter"
+TCM5971 "3C597 Fast Etherlink T4"
+TCM5972 "3C597 Fast Etherlink MII"
+TCM7700 "3Com 3C770 FDDI Adapter"
+TCO010C "Thomas-Conrad TC6045 ARC-Card/AT"
+TCO030D "Thomas-Conrad TC6042 ARC-Card/CE"
+TCO040B "Thomas-Conrad TC6142 ARC-Card/CE"
+TCO050D "Thomas-Conrad TC4035 TOKEN RING Adapter/AT (Rev D)"
+TCO3147 "TC3047 Thomas Conrad Network System (TCNS) EISA Adapter"
+TCO345A "TC3045 Thomas-Conrad Network System (TCNS) AT Adapter"
+TCO345B "TC3045 Thomas-Conrad Network System (TCNS) AT Adapter"
+TEC8000 "Tecmar QIC60 HOST ADAPTER"
+TEC8001 "Tecmar QIC PC36 TAPE CONTROLLER"
+TEC8002 "Tecmar QT HOST ADAPTER"
+TEC8003 "Tecmar QT PC36 TAPE CONTROLLER"
+TRM0001 "EISA-486C SYSTEM BOARD"
+TRM0320 "DC-320 EISA SCSI Host Adapter"
+TRM0620 "DC-620 EISA IDE Cache Controller"
+TRM0820 "DC-820 EISA SCSI Cache Host Adapter"
+TRM320E "DC-320E EISA SCSI Host Adapter"
+TRM820B "DC-820B EISA SCSI Cache Host Adapter"
+TRU0210 "Truevision Image Capture Board"
+TRU0520 "Truevision ATVista (R) VideoGraphics Adapter"
+TRU1100 "Truevision DVR"
+TXN0011 "TACT84500 MODULAR EISA SYSTEM BOARD"
+TYN0000 "Tyan 486 PRO-EISA Board"
+TYN0001 "TYN VL EISA-486  Board"
+TYN0003 "Tyn S1452/S1462 PCI-EISA Main Board"
+UBIA100 "Ungermann-Bass Personal NIU"
+UBIA200 "Ungermann-Bass Personal NIU/ex"
+UBIB100 "Ungermann-Bass NIUpc"
+UBIB200 "Ungermann-Bass 3270 NIUpc"
+UBIC100 "Ungermann-Bass NIC"
+UBID100 "Ungermann-Bass NIUpc/Token Ring"
+USC0120 "UltraStor - ULTRA-12F ISA ESDI Hard Disk Controller"
+USC0125 "UltraStor - ULTRA-12C ESDI Hard Disk Controller"
+USC0140 "UltraStor - ULTRA-14F ISA SCSI Host Adapter"
+USC0220 "UltraStor - U22C"
+USC0225 "UltraStor - ULTRA-22F ESDI Hard Disk Controller"
+USC0240 "UltraStor - ULTRA-24F SCSI Host Adapter"
+USC0340 "UltraStor - ULTRA-34F VESA VL-BUS Host Adapter"
+USR0011 "USROBOTICS 33.6 TELEPHONY MODEM"
+USR3401 "U S Robotics V.34-Ready Fax Modem"
+VMI0201 "Vermont Image Manager 1024"
+VMI0211 "Vermont Cobra"
+VMI0601 "Vermont Image Manager 640"
+VMI0E01 "Vermont Cobra Plus"
+WDC0101 "Western Digital WD1009V-MM1 Winchester Controller"
+WDC0102 "Western Digital WD1009V-SE1 Winchester Controller"
+WDC0300 "Western Digital StarCard PLUS 8003S"
+WDC0301 "Western Digital StarLink PLUS 8003SH"
+WDC03E0 "Western Digital EtherCard PLUS 8003E"
+WDC03E1 "Western Digital EtherCard PLUS w/Boot 8003EBT"
+WDC03E2 "Western Digital EtherCard + 8003EB 61-600245-02"
+WDC03E3 "Western Digital EtherCard PLUS TP 8003WT"
+WDC03E4 "Western Digital EtherCard + 8003EB 61-600090-00"
+WDC0510 "Western Digital TokenCard 8005TR/8005TRWS"
+WDC1009 "Western Digital WD1009V-MM1/MM2 Winchester Controller"
+WDC13E0 "Western Digital EtherCard PLUS 16 8013EBT"
+XTI02B1 "XNET 1800 PARALLEL SWITCH"
diff -Nru a/drivers/hotplug/acpiphp_glue.c b/drivers/hotplug/acpiphp_glue.c
--- a/drivers/hotplug/acpiphp_glue.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/hotplug/acpiphp_glue.c	Thu Jan 16 18:23:05 2003
@@ -712,8 +712,9 @@
 
 
 /* find hot-pluggable slots, and then find P2P bridge */
-static int add_bridges (acpi_handle *handle)
+static int add_bridges(struct acpi_device *device)
 {
+	acpi_handle *handle = device->handle;
 	acpi_status status;
 	unsigned long tmp;
 	int seg, bus;
@@ -767,36 +768,6 @@
 }
 
 
-/* callback routine to enumerate all the bridges in ACPI namespace */
-static acpi_status
-find_host_bridge (acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-	acpi_status status;
-	struct acpi_device_info info;
-	char objname[5];
-	struct acpi_buffer buffer = { .length = sizeof(objname),
-				      .pointer = objname };
-
-	status = acpi_get_object_info(handle, &info);
-	if (ACPI_FAILURE(status)) {
-		dbg("%s: failed to get bridge information\n", __FUNCTION__);
-		return AE_OK;		/* continue */
-	}
-
-	info.hardware_id[sizeof(info.hardware_id)-1] = '\0';
-
-	/* TBD use acpi_get_devices() API */
-	if (info.current_status &&
-	    (info.valid & ACPI_VALID_HID) &&
-	    strcmp(info.hardware_id, ACPI_PCI_HOST_HID) == 0) {
-		acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
-		dbg("checking PCI-hotplug capable bridges under [%s]\n", objname);
-		add_bridges(handle);
-	}
-	return AE_OK;
-}
-
-
 static int power_on_slot (struct acpiphp_slot *slot)
 {
 	acpi_status status;
@@ -1157,6 +1128,14 @@
 	}
 }
 
+static struct acpi_driver acpi_pci_hp_driver = {
+	.name =		"pci_hp",
+	.class =	"",
+	.ids =		ACPI_PCI_HOST_HID,
+	.ops =	{
+		.add =	add_bridges,
+	}
+};
 
 /**
  * acpiphp_glue_init - initializes all PCI hotplug - ACPI glue data structures
@@ -1169,9 +1148,7 @@
 	if (list_empty(&pci_root_buses))
 		return -1;
 
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-				     ACPI_UINT32_MAX, find_host_bridge,
-				     NULL, NULL);
+	status = acpi_bus_register_driver(&acpi_pci_hp_driver);
 
 	if (ACPI_FAILURE(status)) {
 		err("%s: acpi_walk_namespace() failed\n", __FUNCTION__);
diff -Nru a/drivers/ide/Kconfig b/drivers/ide/Kconfig
--- a/drivers/ide/Kconfig	Thu Jan 16 18:23:05 2003
+++ b/drivers/ide/Kconfig	Thu Jan 16 18:23:05 2003
@@ -376,7 +376,7 @@
 config BLK_DEV_IDEDMA
 	bool
 	depends on BLK_DEV_IDE
-	default BLK_DEV_IDEDMA_ICS if ARM
+	default BLK_DEV_IDEDMA_ICS if ARCH_ACORN
 	default BLK_DEV_IDEDMA_PMAC if ALL_PPC && BLK_DEV_IDE_PMAC
 	default BLK_DEV_IDEDMA_PCI if PCI && BLK_DEV_IDEPCI
 
diff -Nru a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
--- a/drivers/input/keyboard/amikbd.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/input/keyboard/amikbd.c	Thu Jan 16 18:23:07 2003
@@ -80,7 +80,7 @@
 	udelay(85);			/* wait until 85 us have expired */
 	ciaa.cra &= ~0x40;		/* switch CIA serial port to input mode */
 
-	down = scancode & 1;		/* lowest bit is release bit */
+	down = !(scancode & 1);		/* lowest bit is release bit */
 	scancode >>= 1;
 
 	if (scancode < 0x78) {		/* scancodes < 0x78 are keys */
diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
--- a/drivers/input/serio/q40kbd.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/input/serio/q40kbd.c	Thu Jan 16 18:23:05 2003
@@ -36,7 +36,6 @@
 #include <linux/serio.h>
 #include <linux/interrupt.h>
 
-#include <asm/keyboard.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -69,33 +68,38 @@
 
 static void q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	if (IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
+	if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
 		if (q40kbd_port.dev)
                          q40kbd_port.dev->interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0);
 
 	master_outb(-1, KEYBOARD_UNLOCK_REG);
 }
 
-void __init q40kbd_init(void)
+static int __init q40kbd_init(void)
 {
 	int maxread = 100;
 
+	if (!MACH_IS_Q40)
+		return -EIO;
+
 	/* allocate the IRQ */
 	request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL);
 
 	/* flush any pending input */
-	while (maxread-- && (IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
+	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
 		master_inb(KEYCODE_REG);
-	
+
 	/* off we go */
 	master_outb(-1,KEYBOARD_UNLOCK_REG);
 	master_outb(1,KEY_IRQ_ENABLE_REG);
 
 	serio_register_port(&q40kbd_port);
 	printk(KERN_INFO "serio: Q40 kbd registered\n");
+
+	return 0;
 }
 
-void __exit q40kbd_exit(void)
+static void __exit q40kbd_exit(void)
 {
 	master_outb(0,KEY_IRQ_ENABLE_REG);
 	master_outb(-1,KEYBOARD_UNLOCK_REG);
diff -Nru a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
--- a/drivers/isdn/hisax/config.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/isdn/hisax/config.c	Thu Jan 16 18:23:06 2003
@@ -2138,7 +2138,7 @@
 }
 
 void
-hisax_resources_release(struct IsdnCardState *cs)
+hisax_release_resources(struct IsdnCardState *cs)
 {
 	resources_release(&cs->rs);
 }
diff -Nru a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c	Thu Jan 16 18:23:06 2003
@@ -58,7 +58,7 @@
 };
 MODULE_DEVICE_TABLE(pci, fcpci_ids);
 
-static struct pnp_card_id fcpnp_ids[] __devinitdata = {
+static struct pnp_card_device_id fcpnp_ids[] __devinitdata = {
 	{ .id = "AVM0900", 
 	  .driver_data = (unsigned long) "Fritz!Card PnP",
 	  .devs = { { "AVM0900" } } }
diff -Nru a/drivers/isdn/i4l/isdn_ppp_ccp.c b/drivers/isdn/i4l/isdn_ppp_ccp.c
--- a/drivers/isdn/i4l/isdn_ppp_ccp.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/isdn/i4l/isdn_ppp_ccp.c	Thu Jan 16 18:23:05 2003
@@ -241,7 +241,7 @@
 	struct ippp_ccp *ccp;
 
 	ccp = kmalloc(sizeof(*ccp), GFP_ATOMIC); // FIXME
-	if (!cpp)
+	if (!ccp)
 		return NULL;
 	memset(ccp, 0, sizeof(*ccp));
 	ccp->mru = 1524;      /* MRU, default 1524 */
diff -Nru a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
--- a/drivers/media/video/cpia.h	Thu Jan 16 18:23:06 2003
+++ b/drivers/media/video/cpia.h	Thu Jan 16 18:23:06 2003
@@ -41,6 +41,7 @@
 
 #include <asm/uaccess.h>
 #include <linux/videodev.h>
+#include <linux/list.h>
 #include <linux/smp_lock.h>
 
 struct cpia_camera_ops
@@ -239,8 +240,7 @@
 #define FRAME_NUM	2	/* double buffering for now */
 
 struct cam_data {
-	struct cam_data **previous;
-	struct cam_data *next;
+	struct list_head cam_data_list;
 
         struct semaphore busy_lock;     /* guard against SMP multithreading */
 	struct cpia_camera_ops *ops;	/* lowlevel driver operations */
@@ -420,28 +420,6 @@
   DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\
       (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
         (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
-
-static inline void cpia_add_to_list(struct cam_data** l, struct cam_data** drv_p)
-{
-	struct cam_data* drv;
-	drv = *drv_p;
-	drv->next = *l;
-	drv->previous = l;
-	*l = drv;
-}
-
-static inline void cpia_remove_from_list(struct cam_data** drv_p)
-{
-	struct cam_data* drv;
-	drv = *drv_p;
-	if (drv->previous != NULL) {
-		if (drv->next != NULL)
-			drv->next->previous = drv->previous;
-		*(drv->previous) = drv->next;
-		drv->previous = NULL;
-		drv->next = NULL;
-	}
-}
 
 #endif /* __KERNEL__ */
 
diff -Nru a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
--- a/drivers/media/video/cpia_pp.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/media/video/cpia_pp.c	Thu Jan 16 18:23:05 2003
@@ -161,8 +161,8 @@
 	THIS_MODULE
 };
 
-static struct cam_data *cam_list;
-static spinlock_t cam_list_lock_pp;
+static LIST_HEAD(cam_list);
+static spinlock_t cam_list_lock_pp = SPIN_LOCK_UNLOCKED;
 
 #ifdef _CPIA_DEBUG_
 #define DEB_PORT(port) { \
@@ -566,7 +566,7 @@
 		return -ENXIO;
 	}
 	spin_lock( &cam_list_lock_pp );
-	cpia_add_to_list(&cam_list, &cpia);
+	list_add( &cpia->cam_data_list, &cam_list );
 	spin_unlock( &cam_list_lock_pp );
 
 	return 0;
@@ -574,14 +574,16 @@
 
 static void cpia_pp_detach (struct parport *port)
 {
+	struct list_head *tmp;
 	struct cam_data *cpia;
+	struct pp_cam_entry *cam;
 
-	for(cpia = cam_list; cpia != NULL; cpia = cpia->next) {
-		struct pp_cam_entry *cam = cpia->lowlevel_data;
+	spin_lock( &cam_list_lock_pp );
+	list_for_each (tmp, &cam_list) {
+		cpia = list_entry(tmp, struct cam_data, cam_data_list);
+		cam = cpia->lowlevel_data;
 		if (cam && cam->port->number == port->number) {
-			spin_lock( &cam_list_lock_pp );
-			cpia_remove_from_list(&cpia);
-			spin_unlock( &cam_list_lock_pp );			
+			list_del(&cpia->cam_data_list);
 			cpia_unregister_camera(cpia);
 			
 			if(cam->open_count > 0) {
@@ -595,6 +597,7 @@
 			break;
 		}
 	}
+	spin_unlock( &cam_list_lock_pp );			
 }
 
 static void cpia_pp_attach (struct parport *port)
@@ -647,9 +650,6 @@
 		return -EIO;
 	}
 	
-	cam_list = NULL;
-	spin_lock_init( &cam_list_lock_pp );
-
 	return 0;
 }
 
diff -Nru a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
--- a/drivers/media/video/cpia_usb.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/media/video/cpia_usb.c	Thu Jan 16 18:23:05 2003
@@ -104,8 +104,8 @@
 	THIS_MODULE
 };
 
-static struct cam_data *cam_list;
-static spinlock_t cam_list_lock_usb;
+static LIST_HEAD(cam_list);
+static spinlock_t cam_list_lock_usb = SPIN_LOCK_UNLOCKED;
 
 static void cpia_usb_complete(struct urb *urb, struct pt_regs *regs)
 {
@@ -549,7 +549,7 @@
 	}
 
 	spin_lock( &cam_list_lock_usb );
-	cpia_add_to_list(&cam_list, &cam);
+	list_add( &cam->cam_data_list, &cam_list );
 	spin_unlock( &cam_list_lock_usb );
 
 	usb_set_intfdata(intf, cam);
@@ -603,7 +603,7 @@
 
 	ucpia = (struct usb_cpia *) cam->lowlevel_data;
 	spin_lock( &cam_list_lock_usb );
-	cpia_remove_from_list(&cam);
+	list_del(&cam->cam_data_list);
 	spin_unlock( &cam_list_lock_usb );
 	
 	/* Don't even try to reset the altsetting if we're disconnected */
@@ -647,8 +647,6 @@
 
 static int __init usb_cpia_init(void)
 {
-	cam_list = NULL;
-	spin_lock_init(&cam_list_lock_usb);
 	return usb_register(&cpia_driver);
 }
 
@@ -667,4 +665,3 @@
 
 module_init (usb_cpia_init);
 module_exit (usb_cpia_cleanup);
-
diff -Nru a/drivers/net/3c501.c b/drivers/net/3c501.c
--- a/drivers/net/3c501.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/3c501.c	Thu Jan 16 18:23:05 2003
@@ -981,10 +981,6 @@
  
 void cleanup_module(void)
 {
-	/*
-	 *	No need to check MOD_IN_USE, as sys_delete_module() checks.
-	 */
-
 	unregister_netdev(&dev_3c501);
 
 	/*
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/3c509.c	Thu Jan 16 18:23:05 2003
@@ -53,11 +53,13 @@
 			- Additional ethtool features
 		v1.19a 28Oct2002 Davud Ruggiero <jdr@farfalle.com>
 			- Increase *read_eeprom udelay to workaround oops with 2 cards.
+		v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
+		    - Introduce driver model for EISA cards.
 */
 
 #define DRV_NAME	"3c509"
-#define DRV_VERSION	"1.19a"
-#define DRV_RELDATE	"28Oct2002"
+#define DRV_VERSION	"1.19b"
+#define DRV_RELDATE	"08Nov2002"
 
 /* A few values that may be tweaked. */
 
@@ -84,6 +86,8 @@
 #include <linux/delay.h>	/* for udelay() */
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
+#include <linux/device.h>
+#include <linux/eisa.h>
 
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
@@ -170,6 +174,9 @@
 #ifdef __ISAPNP__
 	struct pnp_dev *pnpdev;
 #endif
+#ifdef CONFIG_EISA
+	struct eisa_device *edev;
+#endif
 };
 static int id_port __initdata = 0x110;	/* Start with 0x110 to avoid new sound cards.*/
 static struct net_device *el3_root_dev;
@@ -194,6 +201,26 @@
 static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
 #endif
 
+#ifdef CONFIG_EISA
+struct eisa_device_id el3_eisa_ids[] = {
+		{ "TCM5092" },
+		{ "TCM5093" },
+		{ "" }
+};
+
+static int el3_eisa_probe (struct device *device);
+static int el3_eisa_remove (struct device *device);
+
+struct eisa_driver el3_eisa_driver = {
+		.id_table = el3_eisa_ids,
+		.driver   = {
+				.name    = "3c509",
+				.probe   = el3_eisa_probe,
+				.remove  = __devexit_p (el3_eisa_remove)
+		}
+};
+#endif
+
 #ifdef CONFIG_MCA
 struct el3_mca_adapters_struct {
 	char* name;
@@ -240,8 +267,97 @@
 #endif /* __ISAPNP__ */
 static int nopnp;
 
-int __init el3_probe(struct net_device *dev, int card_idx)
+/* With the driver model introduction for EISA devices, both init
+ * and cleanup have been split :
+ * - EISA devices probe/remove starts in el3_eisa_probe/el3_eisa_remove
+ * - MCA/ISA still use el3_probe
+ *
+ * Both call el3_common_init/el3_common_remove. */
+
+static int __init el3_common_init (struct net_device *dev)
+{
+	struct el3_private *lp = dev->priv;
+	short i;
+  
+#ifdef CONFIG_EISA
+	if (!lp->edev)				/* EISA devices are not chained */
+#endif
+	{
+			lp->next_dev = el3_root_dev;
+			el3_root_dev = dev;
+	}
+	spin_lock_init(&lp->lock);
+
+	if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
+		dev->if_port = (dev->mem_start & 0x0f);
+	} else { /* xcvr codes 0/8 */
+		/* use eeprom value, but save user's full-duplex selection */
+		dev->if_port |= (dev->mem_start & 0x08);
+	}
+
+	{
+		const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
+		printk("%s: 3c5x9 at %#3.3lx, %s port, address ",
+			dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)]);
+	}
+
+	/* Read in the station address. */
+	for (i = 0; i < 6; i++)
+		printk(" %2.2x", dev->dev_addr[i]);
+	printk(", IRQ %d.\n", dev->irq);
+
+	if (el3_debug > 0)
+		printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+
+	/* The EL3-specific entries in the device structure. */
+	dev->open = &el3_open;
+	dev->hard_start_xmit = &el3_start_xmit;
+	dev->stop = &el3_close;
+	dev->get_stats = &el3_get_stats;
+	dev->set_multicast_list = &set_multicast_list;
+	dev->tx_timeout = el3_tx_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+	dev->do_ioctl = netdev_ioctl;
+
+#ifdef CONFIG_PM
+	/* register power management */
+	lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
+	if (lp->pmdev) {
+		struct pm_dev *p;
+		p = lp->pmdev;
+		p->data = (struct net_device *)dev;
+	}
+#endif
+
+	return 0;
+}
+
+static void el3_common_remove (struct net_device *dev)
+{
+		struct el3_private *lp = dev->priv;
+
+		(void) lp;				/* Keep gcc quiet... */
+#ifdef CONFIG_MCA		
+		if(lp->mca_slot!=-1)
+			mca_mark_as_unused(lp->mca_slot);
+#endif
+#ifdef CONFIG_PM
+		if (lp->pmdev)
+			pm_unregister(lp->pmdev);
+#endif
+#ifdef __ISAPNP__
+		if (lp->pnpdev)
+			pnp_device_detach(lp->pnpdev);
+#endif
+
+		unregister_netdev (dev);
+		release_region(dev->base_addr, EL3_IO_EXTENT);
+		kfree (dev);
+}
+
+static int __init el3_probe(int card_idx)
 {
+	struct net_device *dev;
 	struct el3_private *lp;
 	short lrs_state = 0xff, i;
 	int ioaddr, irq, if_port;
@@ -253,44 +369,6 @@
 	struct pnp_dev *idev = NULL;
 #endif /* __ISAPNP__ */
 
-	if (dev) SET_MODULE_OWNER(dev);
-
-	/* First check all slots of the EISA bus.  The next slot address to
-	   probe is kept in 'eisa_addr' to support multiple probe() calls. */
-	if (EISA_bus) {
-		static int eisa_addr = 0x1000;
-		while (eisa_addr < 0x9000) {
-			int device_id;
-
-			ioaddr = eisa_addr;
-			eisa_addr += 0x1000;
-
-			/* Check the standard EISA ID register for an encoded '3Com'. */
-			if (inw(ioaddr + 0xC80) != 0x6d50)
-				continue;
-
-			/* Avoid conflict with 3c590, 3c592, 3c597, etc */
-			device_id = (inb(ioaddr + 0xC82)<<8) + inb(ioaddr + 0xC83);
-			if ((device_id & 0xFF00) == 0x5900) {
-				continue;
-			}
-
-			/* Change the register set to the configuration window 0. */
-			outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
-
-			irq = inw(ioaddr + WN0_IRQ) >> 12;
-			if_port = inw(ioaddr + 6)>>14;
-			for (i = 0; i < 3; i++)
-				phys_addr[i] = htons(read_eeprom(ioaddr, i));
-
-			/* Restore the "Product ID" to the EEPROM read register. */
-			read_eeprom(ioaddr, 3);
-
-			/* Was the EISA code an add-on hack?  Nahhhhh... */
-			goto found;
-		}
-	}
-
 #ifdef CONFIG_MCA
 	/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily
 	 * modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca)
@@ -469,6 +547,8 @@
 	}
 	irq = id_read_eeprom(9) >> 12;
 
+#if 0							/* Huh ?
+								   Can someone explain what is this for ? */
 	if (dev) {					/* Set passed-in IRQ or I/O Addr. */
 		if (dev->irq > 1  &&  dev->irq < 16)
 			irq = dev->irq;
@@ -481,6 +561,7 @@
 				return -ENODEV;
 		}
 	}
+#endif
 
 	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
 		return -EBUSY;
@@ -500,79 +581,86 @@
 	/* Free the interrupt so that some other card can use it. */
 	outw(0x0f00, ioaddr + WN0_IRQ);
  found:
+	dev = init_etherdev(NULL, sizeof(struct el3_private));
 	if (dev == NULL) {
-		dev = init_etherdev(dev, sizeof(struct el3_private));
-		if (dev == NULL) {
-			release_region(ioaddr, EL3_IO_EXTENT);
-			return -ENOMEM;
-		}
-		SET_MODULE_OWNER(dev);
+	    release_region(ioaddr, EL3_IO_EXTENT);
+		return -ENOMEM;
 	}
+	SET_MODULE_OWNER(dev);
+
 	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
-
-	if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
-		dev->if_port = (dev->mem_start & 0x0f);
-	} else { /* xcvr codes 0/8 */
-		/* use eeprom value, but save user's full-duplex selection */
-		dev->if_port = (if_port | (dev->mem_start & 0x08) );
-	}
-
-	{
-		const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
-		printk("%s: 3c5x9 at %#3.3lx, %s port, address ",
-			dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)]);
-	}
-
-	/* Read in the station address. */
-	for (i = 0; i < 6; i++)
-		printk(" %2.2x", dev->dev_addr[i]);
-	printk(", IRQ %d.\n", dev->irq);
-
-	/* Make up a EL3-specific-data structure. */
-	if (dev->priv == NULL)
-		dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
-	if (dev->priv == NULL)
-		return -ENOMEM;
-	memset(dev->priv, 0, sizeof(struct el3_private));
-	
+	dev->if_port = if_port;
 	lp = dev->priv;
 #ifdef __ISAPNP__
 	lp->pnpdev = idev;
 #endif
 	lp->mca_slot = mca_slot;
-	lp->next_dev = el3_root_dev;
-	spin_lock_init(&lp->lock);
-	el3_root_dev = dev;
 
-	if (el3_debug > 0)
-		printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+	return el3_common_init (dev);
+}
 
-	/* The EL3-specific entries in the device structure. */
-	dev->open = &el3_open;
-	dev->hard_start_xmit = &el3_start_xmit;
-	dev->stop = &el3_close;
-	dev->get_stats = &el3_get_stats;
-	dev->set_multicast_list = &set_multicast_list;
-	dev->tx_timeout = el3_tx_timeout;
-	dev->watchdog_timeo = TX_TIMEOUT;
-	dev->do_ioctl = netdev_ioctl;
+#ifdef CONFIG_EISA
+static int __init el3_eisa_probe (struct device *device)
+{
+	struct el3_private *lp;
+	short i;
+	int ioaddr, irq, if_port;
+	u16 phys_addr[3];
+	struct net_device *dev = NULL;
+	struct eisa_device *edev;
 
-#ifdef CONFIG_PM
-	/* register power management */
-	lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
-	if (lp->pmdev) {
-		struct pm_dev *p;
-		p = lp->pmdev;
-		p->data = (struct net_device *)dev;
+	/* Yeepee, The driver framework is calling us ! */
+	edev = to_eisa_device (device);
+	ioaddr = edev->base_addr;
+	
+	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
+		return -EBUSY;
+
+	/* Change the register set to the configuration window 0. */
+	outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
+
+	irq = inw(ioaddr + WN0_IRQ) >> 12;
+	if_port = inw(ioaddr + 6)>>14;
+	for (i = 0; i < 3; i++)
+			phys_addr[i] = htons(read_eeprom(ioaddr, i));
+
+	/* Restore the "Product ID" to the EEPROM read register. */
+	read_eeprom(ioaddr, 3);
+
+	dev = init_etherdev(NULL, sizeof(struct el3_private));
+	if (dev == NULL) {
+			release_region(ioaddr, EL3_IO_EXTENT);
+			return -ENOMEM;
 	}
-#endif
 
-	/* Fill in the generic fields of the device structure. */
-	ether_setup(dev);
-	return 0;
+	SET_MODULE_OWNER(dev);
+
+	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
+	dev->base_addr = ioaddr;
+	dev->irq = irq;
+	dev->if_port = if_port;
+	lp = dev->priv;
+	lp->mca_slot = -1;
+	lp->edev = edev;
+	eisa_set_drvdata (edev, dev);
+
+	return el3_common_init (dev);
+}
+
+static int __devexit el3_eisa_remove (struct device *device)
+{
+		struct eisa_device *edev;
+		struct net_device *dev;
+
+		edev = to_eisa_device (device);
+		dev  = eisa_get_drvdata (edev);
+
+		el3_common_remove (dev);
+		return 0;
 }
+#endif
 
 /* Read a word from the EEPROM using the regular EEPROM access register.
    Assume that we are in register window zero.
@@ -982,7 +1070,8 @@
 el3_close(struct net_device *dev)
 {
 	int ioaddr = dev->base_addr;
-
+	struct el3_private *lp = (struct el3_private *)dev->priv;
+	
 	if (el3_debug > 2)
 		printk("%s: Shutting down ethercard.\n", dev->name);
 
@@ -991,8 +1080,12 @@
 	free_irq(dev->irq, dev);
 	/* Switching back to window 0 disables the IRQ. */
 	EL3WINDOW(0);
-	/* But we explicitly zero the IRQ line select anyway. */
-	outw(0x0f00, ioaddr + WN0_IRQ);
+	if (!lp->edev) {
+	    /* But we explicitly zero the IRQ line select anyway. Don't do
+	     * it on EISA cards, it prevents the module from getting an
+	     * IRQ after unload+reload... */
+	    outw(0x0f00, ioaddr + WN0_IRQ);
+	}
 
 	return 0;
 }
@@ -1414,7 +1507,6 @@
 
 #endif /* CONFIG_PM */
 
-#ifdef MODULE
 /* Parameters that may be passed into the module. */
 static int debug = -1;
 static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
@@ -1436,8 +1528,7 @@
 MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B) ISA/PnP ethernet driver");
 MODULE_LICENSE("GPL");
 
-int
-init_module(void)
+static int __init el3_init_module(void)
 {
 	int el3_cards = 0;
 
@@ -1445,7 +1536,7 @@
 		el3_debug = debug;
 
 	el3_root_dev = NULL;
-	while (el3_probe(0, el3_cards) == 0) {
+	while (el3_probe(el3_cards) == 0) {
 		if (irq[el3_cards] > 1)
 			el3_root_dev->irq = irq[el3_cards];
 		if (xcvr[el3_cards] >= 0)
@@ -1453,38 +1544,35 @@
 		el3_cards++;
 	}
 
+#ifdef CONFIG_EISA
+	if (eisa_driver_register (&el3_eisa_driver) < 0) {
+			eisa_driver_unregister (&el3_eisa_driver);
+	}
+	else
+			el3_cards++;				/* Found an eisa card */
+#endif
 	return el3_cards ? 0 : -ENODEV;
 }
 
-void
-cleanup_module(void)
+static void __exit el3_cleanup_module(void)
 {
 	struct net_device *next_dev;
 
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	while (el3_root_dev) {
 		struct el3_private *lp = (struct el3_private *)el3_root_dev->priv;
-#ifdef CONFIG_MCA		
-		if(lp->mca_slot!=-1)
-			mca_mark_as_unused(lp->mca_slot);
-#endif
 
-#ifdef CONFIG_PM
-		if (lp->pmdev)
-			pm_unregister(lp->pmdev);
-#endif
 		next_dev = lp->next_dev;
-		unregister_netdev(el3_root_dev);
-		release_region(el3_root_dev->base_addr, EL3_IO_EXTENT);
-#ifdef __ISAPNP__
-		if (lp->pnpdev)
-			pnp_device_detach(lp->pnpdev);
-#endif
-		kfree(el3_root_dev);
+		el3_common_remove (el3_root_dev);
 		el3_root_dev = next_dev;
 	}
+
+#ifdef CONFIG_EISA
+	eisa_driver_unregister (&el3_eisa_driver);
+#endif
 }
-#endif /* MODULE */
+
+module_init (el3_init_module);
+module_exit (el3_cleanup_module);
 
 /*
  * Local variables:
diff -Nru a/drivers/net/3c515.c b/drivers/net/3c515.c
--- a/drivers/net/3c515.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/3c515.c	Thu Jan 16 18:23:05 2003
@@ -1666,7 +1666,6 @@
 {
 	struct net_device *next_dev;
 
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	while (root_corkscrew_dev) {
 		next_dev =
 		    ((struct corkscrew_private *) root_corkscrew_dev->
diff -Nru a/drivers/net/3c527.c b/drivers/net/3c527.c
--- a/drivers/net/3c527.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/net/3c527.c	Thu Jan 16 18:23:06 2003
@@ -1773,7 +1773,6 @@
 {
 	int slot;
 	
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	unregister_netdev(&this_device);
 
 	/*
diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c
--- a/drivers/net/3c59x.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/3c59x.c	Thu Jan 16 18:23:05 2003
@@ -180,6 +180,9 @@
 
     - See http://www.zip.com.au/~akpm/linux/#3c59x-2.3 for more details.
     - Also see Documentation/networking/vortex.txt
+
+   LK1.1.19 10Nov09 Marc Zyngier <maz@wild-wind.fr.eu.org>
+    - EISA sysfs integration.
 */
 
 /*
@@ -193,8 +196,8 @@
 
 
 #define DRV_NAME	"3c59x"
-#define DRV_VERSION	"LK1.1.18"
-#define DRV_RELDATE	"1 Jul 2002"
+#define DRV_VERSION	"LK1.1.19"
+#define DRV_RELDATE	"10 Nov 2002"
 
 
 
@@ -259,7 +262,7 @@
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 #include <linux/highmem.h>
-
+#include <linux/eisa.h>
 #include <asm/irq.h>			/* For NR_IRQS only. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -768,7 +771,6 @@
 	/* The addresses of transmit- and receive-in-place skbuffs. */
 	struct sk_buff* rx_skbuff[RX_RING_SIZE];
 	struct sk_buff* tx_skbuff[TX_RING_SIZE];
-	struct net_device *next_module;		/* NULL if PCI device */
 	unsigned int cur_rx, cur_tx;		/* The next free ring entry */
 	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
 	struct net_device_stats stats;
@@ -776,7 +778,7 @@
 	dma_addr_t tx_skb_dma;				/* Allocated DMA address for bus master ctrl DMA.   */
 
 	/* PCI configuration space information. */
-	struct pci_dev *pdev;
+	struct device *gendev;
 	char *cb_fn_base;					/* CardBus function status addr space. */
 
 	/* Some values here only for performance evaluation and path-coverage */
@@ -815,6 +817,18 @@
 	u32 power_state[16];
 };
 
+#define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL)
+
+#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)
+
+#ifdef CONFIG_EISA
+#define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL)
+#else
+#define DEVICE_EISA(dev) NULL
+#endif
+
+#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)
+
 /* The action to take with a media selection timer tick.
    Note that we deviate from the 3Com order by checking 10base2 before AUI.
  */
@@ -843,7 +857,7 @@
   { "Default",	 0,			0xFF, XCVR_10baseT, 10000},
 };
 
-static int vortex_probe1(struct pci_dev *pdev, long ioaddr, int irq,
+static int vortex_probe1(struct device *gendev, long ioaddr, int irq,
 				   int chip_idx, int card_idx);
 static void vortex_up(struct net_device *dev);
 static void vortex_down(struct net_device *dev);
@@ -882,11 +896,9 @@
 
 /* #define dev_alloc_skb dev_alloc_skb_debug */
 
-/* A list of all installed Vortex EISA devices, for removing the driver module. */
-static struct net_device *root_vortex_eisa_dev;
-
 /* Variables to work-around the Compaq PCI BIOS32 problem. */
 static int compaq_ioaddr, compaq_irq, compaq_device_id = 0x5900;
+static struct net_device *compaq_net_device;
 
 static int vortex_cards_found;
 
@@ -920,44 +932,89 @@
 
 #endif /* CONFIG_PM */
 
-/* returns count found (>= 0), or negative on error */
-static int __init vortex_eisa_init (void)
+#ifdef CONFIG_EISA
+static struct eisa_device_id vortex_eisa_ids[] = {
+	{ "TCM5920" },
+	{ "TCM5970" },
+	{ "" }
+};
+
+static int vortex_eisa_probe (struct device *device);
+static int vortex_eisa_remove (struct device *device);
+
+static struct eisa_driver vortex_eisa_driver = {
+	.id_table = vortex_eisa_ids,
+	.driver   = {
+		.name    = "3c59x",
+		.probe   = vortex_eisa_probe,
+		.remove  = vortex_eisa_remove
+	}
+};
+
+static int vortex_eisa_probe (struct device *device)
 {
 	long ioaddr;
-	int rc;
-	int orig_cards_found = vortex_cards_found;
+	struct eisa_device *edev;
 
-	/* Now check all slots of the EISA bus. */
-	if (!EISA_bus)
-		return 0;
+	edev = to_eisa_device (device);
+	ioaddr = edev->base_addr;
 
-	for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
-		int device_id;
+	if (!request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME))
+		return -EBUSY;
 
-		if (request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME) == NULL)
-			continue;
+	if (vortex_probe1(device, ioaddr, inw(ioaddr + 0xC88) >> 12,
+					  EISA_TBL_OFFSET, vortex_cards_found)) {
+		release_region (ioaddr, VORTEX_TOTAL_SIZE);
+		return -ENODEV;
+	}
 
-		/* Check the standard EISA ID register for an encoded '3Com'. */
-		if (inw(ioaddr + 0xC80) != 0x6d50) {
-			release_region (ioaddr, VORTEX_TOTAL_SIZE);
-			continue;
-		}
+	vortex_cards_found++;
 
-		/* Check for a product that we support, 3c59{2,7} any rev. */
-		device_id = (inb(ioaddr + 0xC82)<<8) + inb(ioaddr + 0xC83);
-		if ((device_id & 0xFF00) != 0x5900) {
-			release_region (ioaddr, VORTEX_TOTAL_SIZE);
-			continue;
-		}
+	return 0;
+}
 
-		rc = vortex_probe1(NULL, ioaddr, inw(ioaddr + 0xC88) >> 12,
-				   EISA_TBL_OFFSET, vortex_cards_found);
-		if (rc == 0)
-			vortex_cards_found++;
-		else
-			release_region (ioaddr, VORTEX_TOTAL_SIZE);
+static int vortex_eisa_remove (struct device *device)
+{
+	struct eisa_device *edev;
+	struct net_device *dev;
+	struct vortex_private *vp;
+	long ioaddr;
+
+	edev = to_eisa_device (device);
+	dev = eisa_get_drvdata (edev);
+
+	if (!dev) {
+		printk("vortex_eisa_remove called for Compaq device!\n");
+		BUG();
 	}
 
+	vp = dev->priv;
+	ioaddr = dev->base_addr;
+	
+	unregister_netdev (dev);
+	outw (TotalReset|0x14, ioaddr + EL3_CMD);
+	release_region (ioaddr, VORTEX_TOTAL_SIZE);
+
+	kfree (dev);
+	return 0;
+}
+#endif
+
+/* returns count found (>= 0), or negative on error */
+static int __init vortex_eisa_init (void)
+{
+	int orig_cards_found = vortex_cards_found;
+
+	/* Now check all slots of the EISA bus. */
+	if (!EISA_bus)
+		return 0;
+
+#ifdef CONFIG_EISA
+	if (eisa_driver_register (&vortex_eisa_driver) < 0) {
+		eisa_driver_unregister (&vortex_eisa_driver);
+	}
+#endif
+	
 	/* Special code to work-around the Compaq PCI BIOS32 problem. */
 	if (compaq_ioaddr) {
 		vortex_probe1(NULL, compaq_ioaddr, compaq_irq,
@@ -977,8 +1034,8 @@
 	if (pci_enable_device (pdev)) {
 		rc = -EIO;
 	} else {
-		rc = vortex_probe1 (pdev, pci_resource_start (pdev, 0), pdev->irq,
-				    ent->driver_data, vortex_cards_found);
+		rc = vortex_probe1 (&pdev->dev, pci_resource_start (pdev, 0),
+							pdev->irq, ent->driver_data, vortex_cards_found);
 		if (rc == 0)
 			vortex_cards_found++;
 	}
@@ -986,12 +1043,12 @@
 }
 
 /*
- * Start up the PCI device which is described by *pdev.
+ * Start up the PCI/EISA device which is described by *gendev.
  * Return 0 on success.
  *
- * NOTE: pdev can be NULL, for the case of an EISA driver
+ * NOTE: pdev can be NULL, for the case of a Compaq device
  */
-static int __devinit vortex_probe1(struct pci_dev *pdev,
+static int __devinit vortex_probe1(struct device *gendev,
 				   long ioaddr, int irq,
 				   int chip_idx, int card_idx)
 {
@@ -1003,14 +1060,24 @@
 	static int printed_version;
 	int retval, print_info;
 	struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx];
-	char *print_name;
+	char *print_name = "3c59x";
+	struct pci_dev *pdev = NULL;
+	struct eisa_device *edev = NULL;
 
 	if (!printed_version) {
 		printk (version);
 		printed_version = 1;
 	}
 
-	print_name = pdev ? pdev->slot_name : "3c59x";
+	if (gendev) {
+		if ((pdev = DEVICE_PCI(gendev))) {
+			print_name = pdev->slot_name;
+		}
+
+		if ((edev = DEVICE_EISA(gendev))) {
+			print_name = edev->dev.bus_id;
+		}
+	}
 
 	dev = alloc_etherdev(sizeof(*vp));
 	retval = -ENOMEM;
@@ -1063,10 +1130,9 @@
 	vp->io_size = vci->io_size;
 	vp->card_idx = card_idx;
 
-	/* module list only for EISA devices */
-	if (pdev == NULL) {
-		vp->next_module = root_vortex_eisa_dev;
-		root_vortex_eisa_dev = dev;
+	/* module list only for Compaq device */
+	if (gendev == NULL) {
+		compaq_net_device = dev;
 	}
 
 	/* PCI-only startup logic */
@@ -1100,7 +1166,7 @@
 
 	spin_lock_init(&vp->lock);
 	spin_lock_init(&vp->mdio_lock);
-	vp->pdev = pdev;
+	vp->gendev = gendev;
 
 	/* Makes sure rings are at least 16 byte aligned. */
 	vp->rx_ring = pci_alloc_consistent(pdev, sizeof(struct boom_rx_desc) * RX_RING_SIZE
@@ -1117,6 +1183,8 @@
 	 * instead of a module list */	
 	if (pdev)
 		pci_set_drvdata(pdev, dev);
+	if (edev)
+		eisa_set_drvdata (edev, dev);
 
 	vp->media_override = 7;
 	if (option >= 0) {
@@ -1367,7 +1435,7 @@
 	dev->watchdog_timeo = (watchdog * HZ) / 1000;
 	if (pdev && vp->enable_wol) {
 		vp->pm_state_valid = 1;
- 		pci_save_state(vp->pdev, vp->power_state);
+ 		pci_save_state(VORTEX_PCI(vp), vp->power_state);
  		acpi_set_WOL(dev);
 	}
 	retval = register_netdev(dev);
@@ -1422,9 +1490,9 @@
 	unsigned int config;
 	int i;
 
-	if (vp->pdev && vp->enable_wol) {
-		pci_set_power_state(vp->pdev, 0);	/* Go active */
-		pci_restore_state(vp->pdev, vp->power_state);
+	if (VORTEX_PCI(vp) && vp->enable_wol) {
+		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
+		pci_restore_state(VORTEX_PCI(vp), vp->power_state);
 	}
 
 	/* Before initializing select the active media port. */
@@ -1641,7 +1709,7 @@
 				break;			/* Bad news!  */
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 		}
 		if (i != RX_RING_SIZE) {
 			int j;
@@ -1978,7 +2046,7 @@
 	if (vp->bus_master) {
 		/* Set the bus-master controller to transfer the packet. */
 		int len = (skb->len + 3) & ~3;
-		outl(	vp->tx_skb_dma = pci_map_single(vp->pdev, skb->data, len, PCI_DMA_TODEVICE),
+		outl(	vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
 				ioaddr + Wn7_MasterAddr);
 		outw(len, ioaddr + Wn7_MasterLen);
 		vp->tx_skb = skb;
@@ -2057,13 +2125,13 @@
 			vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum | AddUDPChksum);
 
 	if (!skb_shinfo(skb)->nr_frags) {
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data,
+		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 										skb->len, PCI_DMA_TODEVICE));
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len | LAST_FRAG);
 	} else {
 		int i;
 
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data,
+		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 										skb->len-skb->data_len, PCI_DMA_TODEVICE));
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len-skb->data_len);
 
@@ -2071,7 +2139,7 @@
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 			vp->tx_ring[entry].frag[i+1].addr =
-					cpu_to_le32(pci_map_single(vp->pdev,
+					cpu_to_le32(pci_map_single(VORTEX_PCI(vp),
 											   (void*)page_address(frag->page) + frag->page_offset,
 											   frag->size, PCI_DMA_TODEVICE));
 
@@ -2082,7 +2150,7 @@
 		}
 	}
 #else
-	vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data, skb->len, PCI_DMA_TODEVICE));
+	vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
 	vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
 	vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
 #endif
@@ -2170,7 +2238,7 @@
 		if (status & DMADone) {
 			if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
 				outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
-				pci_unmap_single(vp->pdev, vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
+				pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
 				dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
 				if (inw(ioaddr + TxFree) > 1536) {
 					/*
@@ -2291,12 +2359,12 @@
 #if DO_ZEROCOPY					
 					int i;
 					for (i=0; i<=skb_shinfo(skb)->nr_frags; i++)
-							pci_unmap_single(vp->pdev,
+							pci_unmap_single(VORTEX_PCI(vp),
 											 le32_to_cpu(vp->tx_ring[entry].frag[i].addr),
 											 le32_to_cpu(vp->tx_ring[entry].frag[i].length)&0xFFF,
 											 PCI_DMA_TODEVICE);
 #else
-					pci_unmap_single(vp->pdev,
+					pci_unmap_single(VORTEX_PCI(vp),
 						le32_to_cpu(vp->tx_ring[entry].addr), skb->len, PCI_DMA_TODEVICE);
 #endif
 					dev_kfree_skb_irq(skb);
@@ -2383,14 +2451,14 @@
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				if (vp->bus_master &&
 					! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) {
-					dma_addr_t dma = pci_map_single(vp->pdev, skb_put(skb, pkt_len),
+					dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len),
 									   pkt_len, PCI_DMA_FROMDEVICE);
 					outl(dma, ioaddr + Wn7_MasterAddr);
 					outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
 					outw(StartDMAUp, ioaddr + EL3_CMD);
 					while (inw(ioaddr + Wn7_MasterStatus) & 0x8000)
 						;
-					pci_unmap_single(vp->pdev, dma, pkt_len, PCI_DMA_FROMDEVICE);
+					pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);
 				} else {
 					insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
 						 (pkt_len + 3) >> 2);
@@ -2456,7 +2524,7 @@
 			if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != 0) {
 				skb->dev = dev;
 				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-				pci_dma_sync_single(vp->pdev, dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+				pci_dma_sync_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				memcpy(skb_put(skb, pkt_len),
 					   vp->rx_skbuff[entry]->tail,
@@ -2467,7 +2535,7 @@
 				skb = vp->rx_skbuff[entry];
 				vp->rx_skbuff[entry] = NULL;
 				skb_put(skb, pkt_len);
-				pci_unmap_single(vp->pdev, dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+				pci_unmap_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				vp->rx_nocopy++;
 			}
 			skb->protocol = eth_type_trans(skb, dev);
@@ -2504,7 +2572,7 @@
 			}
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 			vp->rx_skbuff[entry] = skb;
 		}
 		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
@@ -2563,8 +2631,8 @@
 	if (vp->full_bus_master_tx)
 		outl(0, ioaddr + DownListPtr);
 
-	if (vp->pdev && vp->enable_wol) {
-		pci_save_state(vp->pdev, vp->power_state);
+	if (VORTEX_PCI(vp) && vp->enable_wol) {
+		pci_save_state(VORTEX_PCI(vp), vp->power_state);
 		acpi_set_WOL(dev);
 	}
 }
@@ -2600,7 +2668,7 @@
 	if (vp->full_bus_master_rx) { /* Free Boomerang bus master Rx buffers. */
 		for (i = 0; i < RX_RING_SIZE; i++)
 			if (vp->rx_skbuff[i]) {
-				pci_unmap_single(	vp->pdev, le32_to_cpu(vp->rx_ring[i].addr),
+				pci_unmap_single(	VORTEX_PCI(vp), le32_to_cpu(vp->rx_ring[i].addr),
 									PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				dev_kfree_skb(vp->rx_skbuff[i]);
 				vp->rx_skbuff[i] = 0;
@@ -2614,12 +2682,12 @@
 				int k;
 
 				for (k=0; k<=skb_shinfo(skb)->nr_frags; k++)
-						pci_unmap_single(vp->pdev,
+						pci_unmap_single(VORTEX_PCI(vp),
 										 le32_to_cpu(vp->tx_ring[i].frag[k].addr),
 										 le32_to_cpu(vp->tx_ring[i].frag[k].length)&0xFFF,
 										 PCI_DMA_TODEVICE);
 #else
-				pci_unmap_single(vp->pdev, le32_to_cpu(vp->tx_ring[i].addr), skb->len, PCI_DMA_TODEVICE);
+				pci_unmap_single(VORTEX_PCI(vp), le32_to_cpu(vp->tx_ring[i].addr), skb->len, PCI_DMA_TODEVICE);
 #endif
 				dev_kfree_skb(skb);
 				vp->tx_skbuff[i] = 0;
@@ -2738,11 +2806,15 @@
 		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
 		strcpy(info.driver, DRV_NAME);
 		strcpy(info.version, DRV_VERSION);
-		if (vp->pdev)
-			strcpy(info.bus_info, vp->pdev->slot_name);
-		else
-			sprintf(info.bus_info, "EISA 0x%lx %d",
-				dev->base_addr, dev->irq);
+		if (VORTEX_PCI(vp))
+			strcpy(info.bus_info, VORTEX_PCI(vp)->slot_name);
+		else {
+			if (VORTEX_EISA(vp))
+				sprintf (info.bus_info, vp->gendev->bus_id);
+			else
+				sprintf(info.bus_info, "EISA 0x%lx %d",
+						dev->base_addr, dev->irq);
+		}
 		if (copy_to_user(useraddr, &info, sizeof(info)))
 			return -EFAULT;
 		return 0;
@@ -2924,8 +2996,8 @@
 	outw(RxEnable, ioaddr + EL3_CMD);
 
 	/* Change the power state to D3; RxEnable doesn't take effect. */
-	pci_enable_wake(vp->pdev, 0, 1);
-	pci_set_power_state(vp->pdev, 3);
+	pci_enable_wake(VORTEX_PCI(vp), 0, 1);
+	pci_set_power_state(VORTEX_PCI(vp), 3);
 }
 
 
@@ -2935,7 +3007,7 @@
 	struct vortex_private *vp;
 
 	if (!dev) {
-		printk("vortex_remove_one called for EISA device!\n");
+		printk("vortex_remove_one called for Compaq device!\n");
 		BUG();
 	}
 
@@ -2949,10 +3021,10 @@
 	/* Should really use issue_and_wait() here */
 	outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
 
-	if (vp->pdev && vp->enable_wol) {
-		pci_set_power_state(vp->pdev, 0);	/* Go active */
+	if (VORTEX_PCI(vp) && vp->enable_wol) {
+		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
 		if (vp->pm_state_valid)
-			pci_restore_state(vp->pdev, vp->power_state);
+			pci_restore_state(VORTEX_PCI(vp), vp->power_state);
 	}
 
 	pci_free_consistent(pdev,
@@ -3000,24 +3072,23 @@
 
 static void __exit vortex_eisa_cleanup (void)
 {
-	struct net_device *dev, *tmp;
 	struct vortex_private *vp;
 	long ioaddr;
 
-	dev = root_vortex_eisa_dev;
-
-	while (dev) {
-		vp = dev->priv;
-		ioaddr = dev->base_addr;
+#ifdef CONFIG_EISA
+	/* Take care of the EISA devices */
+	eisa_driver_unregister (&vortex_eisa_driver);
+#endif
+	
+	if (compaq_net_device) {
+		vp = compaq_net_device->priv;
+		ioaddr = compaq_net_device->base_addr;
 
-		unregister_netdev (dev);
+		unregister_netdev (compaq_net_device);
 		outw (TotalReset, ioaddr + EL3_CMD);
 		release_region (ioaddr, VORTEX_TOTAL_SIZE);
 
-		tmp = dev;
-		dev = vp->next_module;
-
-		kfree (tmp);
+		kfree (compaq_net_device);
 	}
 }
 
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/Space.c	Thu Jan 16 18:23:05 2003
@@ -55,7 +55,6 @@
 extern int hp_plus_probe(struct net_device *dev);
 extern int express_probe(struct net_device *);
 extern int eepro_probe(struct net_device *);
-extern int el3_probe(struct net_device *);
 extern int at1500_probe(struct net_device *);
 extern int at1700_probe(struct net_device *);
 extern int fmv18x_probe(struct net_device *);
@@ -210,9 +209,6 @@
  * look for EISA/PCI/MCA cards in addition to ISA cards).
  */
 static struct devprobe isa_probes[] __initdata = {
-#ifdef CONFIG_EL3		/* ISA, EISA, MCA 3c5x9 */
-	{el3_probe, 0},
-#endif
 #ifdef CONFIG_HP100 		/* ISA, EISA & PCI */
 	{hp100_probe, 0},
 #endif	
diff -Nru a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
--- a/drivers/net/appletalk/cops.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/net/appletalk/cops.c	Thu Jan 16 18:23:06 2003
@@ -1043,7 +1043,6 @@
 
 void cleanup_module(void)
 {
-        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	unregister_netdev(&cops0_dev);
 	kfree(cops0_dev.priv);
 	if(cops0_dev.irq)
diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c
--- a/drivers/net/hamachi.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/net/hamachi.c	Thu Jan 16 18:23:07 2003
@@ -1960,7 +1960,6 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	if (dev) {
 		struct hamachi_private *hmp = dev->priv;
 
diff -Nru a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c
--- a/drivers/net/isa-skeleton.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/net/isa-skeleton.c	Thu Jan 16 18:23:07 2003
@@ -659,7 +659,6 @@
 void
 cleanup_module(void)
 {
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	unregister_netdev(&this_device);
 	/*
 	 * If we don't do this, we can't re-insmod it later.
diff -Nru a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
--- a/drivers/net/myri_sbus.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/myri_sbus.c	Thu Jan 16 18:23:05 2003
@@ -1137,7 +1137,6 @@
 static void __exit myri_sbus_cleanup(void)
 {
 #ifdef MODULE
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	while (root_myri_dev) {
 		struct myri_eth *next = root_myri_dev->next_module;
 
diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
--- a/drivers/net/pcnet32.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/pcnet32.c	Thu Jan 16 18:23:05 2003
@@ -1737,7 +1737,6 @@
 {
     struct net_device *next_dev;
 
-    /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
     while (pcnet32_dev) {
 	struct pcnet32_private *lp = pcnet32_dev->priv;
 	next_dev = lp->next;
diff -Nru a/drivers/net/ptifddi.c b/drivers/net/ptifddi.c
--- a/drivers/net/ptifddi.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/ptifddi.c	Thu Jan 16 18:23:05 2003
@@ -247,7 +247,6 @@
 {
 	struct ptifddi *pp;
 
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	while (root_pti_dev) {
 		pp = root_pti_dev->next_module;
 
diff -Nru a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
--- a/drivers/net/seeq8005.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/net/seeq8005.c	Thu Jan 16 18:23:06 2003
@@ -733,10 +733,6 @@
 
 void cleanup_module(void)
 {
-	/*
-	 *	No need to check MOD_IN_USE, as sys_delete_module() checks.
-	 */
-
 	unregister_netdev(&dev_seeq);
 
 	/*
diff -Nru a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
--- a/drivers/net/sk_mca.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/net/sk_mca.c	Thu Jan 16 18:23:06 2003
@@ -1274,11 +1274,6 @@
 	skmca_priv *priv;
 	int z;
 
-	if (MOD_IN_USE) {
-		printk("cannot unload, module in use\n");
-		return;
-	}
-
 	for (z = 0; z < DEVMAX; z++) {
 		dev = moddevs + z;
 		if (dev->priv != NULL) {
diff -Nru a/drivers/net/smc9194.c b/drivers/net/smc9194.c
--- a/drivers/net/smc9194.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/net/smc9194.c	Thu Jan 16 18:23:06 2003
@@ -1557,7 +1557,6 @@
 
 void cleanup_module(void)
 {
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	unregister_netdev(&devSMC9194);
 
 	free_irq(devSMC9194.irq, &devSMC9194);
diff -Nru a/drivers/net/sundance.c b/drivers/net/sundance.c
--- a/drivers/net/sundance.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/net/sundance.c	Thu Jan 16 18:23:06 2003
@@ -1734,7 +1734,6 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	if (dev) {
 		struct netdev_private *np = dev->priv;
 
diff -Nru a/drivers/net/tc35815.c b/drivers/net/tc35815.c
--- a/drivers/net/tc35815.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/tc35815.c	Thu Jan 16 18:23:05 2003
@@ -1755,7 +1755,6 @@
 {
 	struct net_device *next_dev;
 
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	while (root_tc35815_dev) {
 		struct net_device *dev = root_tc35815_dev;
 		next_dev = ((struct tc35815_local *)dev->priv)->next_module;
diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/tulip/winbond-840.c	Thu Jan 16 18:23:05 2003
@@ -1612,7 +1612,6 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
 	if (dev) {
 		unregister_netdev(dev);
 		pci_release_regions(pdev);
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/net/via-rhine.c	Thu Jan 16 18:23:07 2003
@@ -1239,6 +1239,12 @@
 	/* Calculate the next Tx descriptor entry. */
 	entry = np->cur_tx % TX_RING_SIZE;
 
+	if (skb->len < ETH_ZLEN) {
+		skb = skb_padto(skb, ETH_ZLEN);
+		if (skb == NULL)
+			return 0;
+	}
+
 	np->tx_skbuff[entry] = skb;
 
 	if ((np->drv_flags & ReqTxAlign) &&
diff -Nru a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
--- a/drivers/net/wan/sbni.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/net/wan/sbni.c	Thu Jan 16 18:23:05 2003
@@ -1501,7 +1501,6 @@
 	struct net_device  *dev;
 	int  num;
 
-	/* No need to check MOD_IN_USE, as sys_delete_module( ) checks. */
 	for( num = 0;  num < SBNI_MAX_NUM_CARDS;  ++num )
 		if( (dev = sbni_cards[ num ]) != NULL ) {
 			unregister_netdev( dev );
diff -Nru a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig
--- a/drivers/parisc/Kconfig	Thu Jan 16 18:23:06 2003
+++ b/drivers/parisc/Kconfig	Thu Jan 16 18:23:06 2003
@@ -54,6 +54,8 @@
 	  supports both the Mongoose & Wax EISA adapters.  It is sadly
 	  incomplete and lacks support for card-to-host DMA.
 
+source "drivers/eisa/Kconfig"
+
 config ISA
 	bool
 	depends on EISA
diff -Nru a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
--- a/drivers/pcmcia/cardbus.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/pcmcia/cardbus.c	Thu Jan 16 18:23:05 2003
@@ -285,12 +285,10 @@
 		dev->dev.dma_mask = &dev->dma_mask;
 
 		pci_setup_device(dev);
-		if (pci_enable_device(dev))
-			continue;
 
 		strcpy(dev->dev.bus_id, dev->slot_name);
 
-		/* FIXME: Do we need to enable the expansion ROM? */
+		/* We need to assign resources for expansion ROM. */
 		for (r = 0; r < 7; r++) {
 			struct resource *res = dev->resource + r;
 			if (res->flags)
@@ -299,11 +297,17 @@
 
 		/* Does this function have an interrupt at all? */
 		pci_readb(dev, PCI_INTERRUPT_PIN, &irq_pin);
-		if (irq_pin) {
+		if (irq_pin)
 			dev->irq = irq;
-			pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
-		}
+		
+		/* pci_enable_device needs to be called after pci_assign_resource */
+		/* because it returns an error if (!res->start && res->end).      */
+		if (pci_enable_device(dev))
+			continue;
 
+		if (irq_pin)
+			pci_writeb(dev, PCI_INTERRUPT_LINE, irq);
+		
 		device_register(&dev->dev);
 		pci_insert_device(dev, bus);
 	}
diff -Nru a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
--- a/drivers/s390/cio/chsc.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/s390/cio/chsc.c	Thu Jan 16 18:23:06 2003
@@ -616,13 +616,13 @@
 
 	switch(chp->state) {
 	case CHP_OFFLINE:
-		return snprintf(buf, count, "n/a\n");
+		return sprintf(buf, "n/a\n");
 	case CHP_LOGICALLY_OFFLINE:
-		return snprintf(buf, count, "logically offline\n");
+		return sprintf(buf, "logically offline\n");
 	case CHP_STANDBY:
-		return snprintf(buf, count, "n/a\n");
+		return sprintf(buf, "n/a\n");
 	case CHP_ONLINE:
-		return snprintf(buf, count, "online\n");
+		return sprintf(buf, "online\n");
 	default:
 		return 0;
 	}
diff -Nru a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
--- a/drivers/s390/net/ctcmain.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/s390/net/ctcmain.c	Thu Jan 16 18:23:05 2003
@@ -2762,27 +2762,23 @@
 }
 
 static ssize_t
-ctc_proto_show(struct device *dev, char *buf, size_t count, loff_t off)
+ctc_proto_show(struct device *dev, char *buf)
 {
 	struct ctc_priv *priv;
 
-	if (off)
-		return 0;
 	priv = dev->driver_data;
 	if (!priv)
 		return -ENODEV;
 
-	return snprintf(buf, count, "%d\n", priv->protocol);
+	return sprintf(buf, "%d\n", priv->protocol);
 }
 
 static ssize_t
-ctc_proto_store(struct device *dev, const char *buf, size_t count, loff_t off)
+ctc_proto_store(struct device *dev, const char *buf, size_t count)
 {
 	struct ctc_priv *priv;
 	int value;
 
-	if (off)
-		return 0;
 	priv = dev->driver_data;
 	if (!priv)
 		return -ENODEV;
diff -Nru a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c
--- a/drivers/s390/net/cu3088.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/s390/net/cu3088.c	Thu Jan 16 18:23:05 2003
@@ -63,17 +63,13 @@
 };
 
 static ssize_t
-group_write(struct device_driver *drv, const char *buf, size_t count,
-	    loff_t off)
+group_write(struct device_driver *drv, const char *buf, size_t count)
 {
 	const char *start, *end;
 	char bus_ids[2][BUS_ID_SIZE], *argv[2];
 	int i;
 	int ret;
 	struct ccwgroup_driver *cdrv;
-
-	if (off)
-		return 0;
 
 	cdrv = to_ccwgroupdrv(drv);
 	if (!cdrv)
diff -Nru a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
--- a/drivers/s390/net/netiucv.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/s390/net/netiucv.c	Thu Jan 16 18:23:06 2003
@@ -1473,11 +1473,11 @@
 {
 	netiucv_priv *priv = dev->driver_data;
 	
-	return snprintf(buf, count, "%ld\n", priv->conn->prof.tx_time);
+	return sprintf(buf, "%ld\n", priv->conn->prof.tx_time);
 }
 
 static ssize_t
-txtime_write (struct device *dev, const char *buf)
+txtime_write (struct device *dev, const char *buf, size_t count)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
diff -Nru a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
--- a/drivers/sbus/char/display7seg.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/sbus/char/display7seg.c	Thu Jan 16 18:23:06 2003
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/ioport.h>		/* request_region, check_region */
+#include <asm/atomic.h>
 #include <asm/ebus.h>			/* EBus device					*/
 #include <asm/oplib.h>			/* OpenProm Library 			*/
 #include <asm/uaccess.h>		/* put_/get_user			*/
@@ -86,27 +87,23 @@
 	return ((-1 != prom_getintdefault(opt_node, "d7s-flipped?", -1)) ? 0 : 1);
 }
 
+static atomic_t d7s_users = ATOMIC_INIT(0);
+
 static int d7s_open(struct inode *inode, struct file *f)
 {
 	if (D7S_MINOR != minor(inode->i_rdev))
 		return -ENODEV;
-
-	MOD_INC_USE_COUNT;
+	atomic_inc(&d7s_users);
 	return 0;
 }
 
 static int d7s_release(struct inode *inode, struct file *f)
 {
-	if (D7S_MINOR != minor(inode->i_rdev))
-		return -ENODEV;
-	
-	MOD_DEC_USE_COUNT;
-
 	/* Reset flipped state to OBP default only if
 	 * no other users have the device open and we
 	 * are not operating in solaris-compat mode
 	 */
-	if (0 == MOD_IN_USE && 0 == sol_compat) {
+	if (atomic_dec_and_test(&d7s_users) && !sol_compat) {
 		int regval = 0;
 
 		regval = readb(d7s_regs);
diff -Nru a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
--- a/drivers/scsi/mac_scsi.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/scsi/mac_scsi.c	Thu Jan 16 18:23:05 2003
@@ -25,26 +25,10 @@
  * 1+ (800) 334-5454
  */
 
-
-/*
- * Options :
- *
- * PARITY - enable parity checking.  Not supported.
- *
- * SCSI2 - enable support for SCSI-II tagged queueing.  Untested.
- *
- * USLEEP - enable support for devices that don't disconnect.  Untested.
- */
-
 /*
  * $Log: mac_NCR5380.c,v $
  */
 
-#define AUTOSENSE
-#if 0
-#define PSEUDO_DMA
-#endif
-
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/ctype.h>
@@ -56,6 +40,7 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/blk.h>
+#include <linux/interrupt.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -80,33 +65,28 @@
 #define RESET_BOOT
 #define DRIVER_SETUP
 
-/*
- * BUG can be used to trigger a strange code-size related hang on 2.1 kernels
- */
-#ifdef BUG
-#undef RESET_BOOT
-#undef DRIVER_SETUP
-#endif
-
 #define	ENABLE_IRQ()	mac_enable_irq( IRQ_MAC_SCSI ); 
 #define	DISABLE_IRQ()	mac_disable_irq( IRQ_MAC_SCSI );
 
+extern void via_scsi_clear(void);
+
 #ifdef RESET_BOOT
 static void mac_scsi_reset_boot(struct Scsi_Host *instance);
 #endif
-static char macscsi_read(struct Scsi_Host *instance, int reg);
-static void macscsi_write(struct Scsi_Host *instance, int reg, int value);
 
+static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg);
+static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value);
+
+static int setup_called = 0;
 static int setup_can_queue = -1;
 static int setup_cmd_per_lun = -1;
 static int setup_sg_tablesize = -1;
+static int setup_use_pdma = -1;
 #ifdef SUPPORT_TAGS
 static int setup_use_tagged_queuing = -1;
 #endif
 static int setup_hostid = -1;
 
-static int polled_scsi_on = 0;
-
 /* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
  * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
  * need ten times the standard value... */
@@ -123,44 +103,27 @@
 static volatile unsigned char *mac_scsi_nodrq = NULL;
 
 /*
- * Function : mac_scsi_setup(char *str, int *ints)
+ * Function : mac_scsi_setup(char *str)
  *
  * Purpose : booter command line initialization of the overrides array,
  *
- * Inputs : str - unused, ints - array of integer parameters with ints[0]
- *	equal to the number of ints.
+ * Inputs : str - comma delimited list of options
  *
  */
 
-static int __init mac_scsi_setup(char *str, int *ints) {
-#ifdef DRIVER_SETUP
-	/* Format of mac5380 parameter is:
-	 *   mac5380=<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
-	 * Negative values mean don't change.
-	 */
+static int __init mac_scsi_setup(char *str) {
+#ifdef DRIVER_SETUP	
+	int ints[7];
 	
-	/* Grmbl... the standard parameter parsing can't handle negative numbers
-	 * :-( So let's do it ourselves!
-	 */
-
-	int i = ints[0]+1, fact;
-
-	while( str && (isdigit(*str) || *str == '-') && i <= 10) {
-		if (*str == '-')
-			fact = -1, ++str;
-		else
-			fact = 1;
-		ints[i++] = simple_strtoul( str, NULL, 0 ) * fact;
-		if ((str = strchr( str, ',' )) != NULL)
-			++str;
-	}
-	ints[0] = i-1;
+	(void)get_options( str, ARRAY_SIZE(ints), ints);
 	
-	if (ints[0] < 1) {
-		printk( "mac_scsi_setup: no arguments!\n" );
-		return 0;
+	if (setup_called++ || ints[0] < 1 || ints[0] > 6) {
+	    printk(KERN_WARNING "scsi: <mac5380>"
+		" Usage: mac5380=<can_queue>[,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>,<use_pdma>]\n");
+	    printk(KERN_ALERT "scsi: <mac5380> Bad Penguin parameters?\n");
+	    return 0;
 	}
-
+	    
 	if (ints[0] >= 1) {
 		if (ints[1] > 0)
 			/* no limits on this, just > 0 */
@@ -183,25 +146,31 @@
 		if (ints[4] >= 0 && ints[4] <= 7)
 			setup_hostid = ints[4];
 		else if (ints[4] > 7)
-			printk( "mac_scsi_setup: invalid host ID %d !\n", ints[4] );
+			printk(KERN_WARNING "mac_scsi_setup: invalid host ID %d !\n", ints[4] );
 	}
-#ifdef SUPPORT_TAGS
+#ifdef SUPPORT_TAGS	
 	if (ints[0] >= 5) {
 		if (ints[5] >= 0)
 			setup_use_tagged_queuing = !!ints[5];
 	}
+	
+	if (ints[0] == 6) {
+	    if (ints[6] >= 0)
+		setup_use_pdma = ints[6];
+	}
+#else
+	if (ints[0] == 5) {
+	    if (ints[5] >= 0)
+		setup_use_pdma = ints[5];
+	}
 #endif
+	
 #endif
-	return 1; 
+	return 1;
 }
 
 __setup("mac5380=", mac_scsi_setup);
 
-#if 0
-#define MAC_ADDRESS(card) (ecard_address((card), ECARD_IOC, ECARD_SLOW) + 0x800)
-#define MAC_IRQ(card)     ((card)->irq)
-#endif
-
 /*
  * XXX: status debug
  */
@@ -221,93 +190,89 @@
  
 int macscsi_detect(Scsi_Host_Template * tpnt)
 {
-    int count = 0;
     static int called = 0;
+    int flags = 0;
     struct Scsi_Host *instance;
 
     if (!MACH_IS_MAC || called)
 	return( 0 );
 
     if (macintosh_config->scsi_type != MAC_SCSI_OLD)
-	 return( 0 );
-
-    tpnt->proc_name = "mac5380";
+	return( 0 );
 
     /* setup variables */
     tpnt->can_queue =
-      (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE;
+	(setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE;
     tpnt->cmd_per_lun =
-      (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN;
+	(setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN;
     tpnt->sg_tablesize = 
-      (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE;
+	(setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE;
 
     if (setup_hostid >= 0)
-      tpnt->this_id = setup_hostid;
+	tpnt->this_id = setup_hostid;
     else {
-      /* use 7 as default */
-      tpnt->this_id = 7;
+	/* use 7 as default */
+	tpnt->this_id = 7;
     }
 
 #ifdef SUPPORT_TAGS
-	if (setup_use_tagged_queuing < 0)
-		setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING;
-#endif
-
-#if 0	/* loop over multiple adapters (Powerbooks ??) */
-    for (count = 0; count < mac_num_scsi; count++) {
+    if (setup_use_tagged_queuing < 0)
+	setup_use_tagged_queuing = USE_TAGGED_QUEUING;
 #endif
-        instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
-        if(instance == NULL)
-        	continue;
-	default_instance = instance;
-
-	if (macintosh_config->ident == MAC_MODEL_IIFX) {
-		mac_scsi_regp  = via1+0x8000;
-		mac_scsi_drq   = via1+0xE000;
-		mac_scsi_nodrq = via1+0xC000;
-	} else {
-		mac_scsi_regp  = via1+0x10000;
-		mac_scsi_drq   = via1+0x6000;
-		mac_scsi_nodrq = via1+0x12000;
-	}
 
+    /* Once we support multiple 5380s (e.g. DuoDock) we'll do
+       something different here */
+    instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
+    default_instance = instance;
+    
+    if (macintosh_config->ident == MAC_MODEL_IIFX) {
+	mac_scsi_regp  = via1+0x8000;
+	mac_scsi_drq   = via1+0xE000;
+	mac_scsi_nodrq = via1+0xC000;
+	/* The IIFX should be able to do true DMA, but pseudo-dma doesn't work */
+	flags = FLAG_NO_PSEUDO_DMA;
+    } else {
+	mac_scsi_regp  = via1+0x10000;
+	mac_scsi_drq   = via1+0x6000;
+	mac_scsi_nodrq = via1+0x12000;
+    }
 
-        instance->io_port = (unsigned long) mac_scsi_regp;
-	instance->irq = IRQ_MAC_SCSI;
+    if (! setup_use_pdma)
+	flags = FLAG_NO_PSEUDO_DMA;
+	
+    instance->io_port = (unsigned long) mac_scsi_regp;
+    instance->irq = IRQ_MAC_SCSI;
 
-#ifdef RESET_BOOT
-	mac_scsi_reset_boot(instance);
+#ifdef RESET_BOOT   
+    mac_scsi_reset_boot(instance);
 #endif
+    
+    NCR5380_init(instance, flags);
 
-	NCR5380_init(instance, 0);
+    instance->n_io_port = 255;
 
-	instance->n_io_port = 255;
+    ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0;
 
-        ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0;
+    if (instance->irq != IRQ_NONE)
+	if (request_irq(instance->irq, NCR5380_intr, IRQ_FLG_SLOW, 
+		"ncr5380", NCR5380_intr)) {
+	    printk(KERN_WARNING "scsi%d: IRQ%d not free, interrupts disabled\n",
+		   instance->host_no, instance->irq);
+	    instance->irq = IRQ_NONE;
+	}
 
-	if (instance->irq != IRQ_NONE)
-	    if (request_irq(instance->irq, NCR5380_intr, IRQ_FLG_SLOW, "ncr5380", NCR5380_intr)) {
-		printk("scsi%d: IRQ%d not free, interrupts disabled\n",
-		    instance->host_no, instance->irq);
-		instance->irq = IRQ_NONE;
-	    }
-
-	printk("scsi%d: generic 5380 at port %lX irq", instance->host_no, instance->io_port);
-	if (instance->irq == IRQ_NONE)
-	    printk ("s disabled");
-	else
-	    printk (" %d", instance->irq);
-	printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
-	    instance->can_queue, instance->cmd_per_lun, MACSCSI_PUBLIC_RELEASE);
-	printk("\nscsi%d:", instance->host_no);
-	NCR5380_print_options(instance);
-	printk("\n");
-#if 0	/* multiple adapters */
-    }
-#endif
+    printk(KERN_INFO "scsi%d: generic 5380 at port %lX irq", instance->host_no, instance->io_port);
+    if (instance->irq == IRQ_NONE)
+	printk (KERN_INFO "s disabled");
+    else
+	printk (KERN_INFO " %d", instance->irq);
+    printk(KERN_INFO " options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
+	   instance->can_queue, instance->cmd_per_lun, MACSCSI_PUBLIC_RELEASE);
+    printk(KERN_INFO "\nscsi%d:", instance->host_no);
+    NCR5380_print_options(instance);
+    printk("\n");
     called = 1;
     return 1;
-
 }
 
 int macscsi_release (struct Scsi_Host *shpnt)
@@ -335,10 +300,10 @@
 	 * with the queues, interrupts, or locks necessary here.
 	 */
 
-	printk( "Macintosh SCSI: resetting the SCSI bus..." );
+	printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
 
 	/* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
-       	mac_disable_irq(IRQ_MAC_SCSI);
+	mac_disable_irq(IRQ_MAC_SCSI);
 
 	/* get in phase */
 	NCR5380_write( TARGET_COMMAND_REG,
@@ -356,207 +321,22 @@
 		barrier();
 
 	/* switch on SCSI IRQ again */
-       	mac_enable_irq(IRQ_MAC_SCSI);
+	mac_enable_irq(IRQ_MAC_SCSI);
 
-	printk( " done\n" );
+	printk(KERN_INFO " done\n" );
 }
 #endif
 
 const char * macscsi_info (struct Scsi_Host *spnt) {
-    return "";
-}
-
-void restore_irq(struct pt_regs *regs)
-{
-	unsigned long flags;
-
-	local_save_flags(flags);
-	flags = (flags & ~0x0700) | (regs->sr & 0x0700);
-	local_irq_restore(flags);
-}
-
-/*
- * pseudo-DMA transfer functions, copied and modified from Russel King's
- * ARM 5380 driver (cumana_1)
- *
- * Work in progress (sort of), didn't work last time I checked, don't use!
- */
-
-#ifdef NOT_EFFICIENT
-#define CTRL(p,v)     outb(*ctrl = (v), (p) - 577)
-#define STAT(p)       inb((p)+1)
-#define IN(p)         inb((p))
-#define OUT(v,p)      outb((v), (p))
-#else
-#if 0
-#define CTRL(p,v)	(p[-2308] = (*ctrl = (v)))
-#else
-#define CTRL(p,v)	(*ctrl = (v))
-#endif
-#define STAT(p)		(p[1<<4])
-#define IN(p)		(*(p))
-#define IN2(p)		((unsigned short)(*(volatile unsigned long *)(p)))
-#define OUT(v,p)	(*(p) = (v))
-#define OUT2(v,p)	(*((volatile unsigned long *)(p)) = (v))
-#endif
-#define L(v)		(((v)<<16)|((v) & 0x0000ffff))
-#define H(v)		(((v)>>16)|((v) & 0xffff0000))
-#define ioaddr(v)	(v)
-
-static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
-              int len)
-{
-  int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
-  int oldctrl = *ctrl;
-  unsigned long *laddr;
-#ifdef NOT_EFFICIENT
-  int iobase = instance->io_port;
-  int dma_io = mac_scsi_nodrq;
-#else
-  volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port);
-  volatile unsigned char *dma_io = (unsigned char *)(mac_scsi_nodrq);
-#endif
-
-  if(!len) return 0;
-
-  CTRL(iobase, 0x02);
-  laddr = (unsigned long *)addr;
-  while(len >= 32)
-  {
-    int status;
-    unsigned long v;
-    status = STAT(iobase);
-    if(status & 0x80)
-      goto end;
-    if(!(status & 0x40))
-      continue;
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    len -= 32;
-    if(len == 0)
-      break;
-  }
-
-  addr = (unsigned char *)laddr;
-  CTRL(iobase, 0x12);
-  while(len > 0)
-  {
-    int status;
-    status = STAT(iobase);
-    if(status & 0x80)
-      goto end;
-    if(status & 0x40)
-    {
-      OUT(*addr++, dma_io);
-      if(--len == 0)
-        break;
-    }
-
-    status = STAT(iobase);
-    if(status & 0x80)
-      goto end;
-    if(status & 0x40)
-    {
-      OUT(*addr++, dma_io);
-      if(--len == 0)
-        break;
-    }
-  }
-end:
-  CTRL(iobase, oldctrl|0x40);
-  return len;
+	return "";
 }
 
-static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
-              int len)
-{
-  int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
-  int oldctrl = *ctrl;
-  unsigned long *laddr;
-#ifdef NOT_EFFICIENT
-  int iobase = instance->io_port;
-  int dma_io = mac_scsi_nodrq;
-#else
-  volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port);
-  volatile unsigned char *dma_io = (unsigned char *)((int)mac_scsi_nodrq);
-#endif
-
-  if(!len) return 0;
-
-  CTRL(iobase, 0x00);
-  laddr = (unsigned long *)addr;
-  while(len >= 32)
-  {
-    int status;
-    status = STAT(iobase);
-    if(status & 0x80)
-      goto end;
-    if(!(status & 0x40))
-      continue;
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    len -= 32;
-    if(len == 0)
-      break;
-  }
-
-  addr = (unsigned char *)laddr;
-  CTRL(iobase, 0x10);
-  while(len > 0)
-  {
-    int status;
-    status = STAT(iobase);
-    if(status & 0x80)
-      goto end;
-    if(status & 0x40)
-    {
-      *addr++ = IN(dma_io);
-      if(--len == 0)
-        break;
-    }
-
-    status = STAT(iobase);
-    if(status & 0x80)
-      goto end;
-    if(status & 0x40)
-    {
-      *addr++ = IN(dma_io);
-      if(--len == 0)
-        break;
-    }
-  }
-end:
-  CTRL(iobase, oldctrl|0x40);
-  return len;
-}
-
-#undef STAT
-#undef CTRL
-#undef IN
-#undef OUT
-
 /*
  * NCR 5380 register access functions
  */
 
-#ifdef ORIG
-#if 0
-#define CTRL(p,v) outb(*ctrl = (v), (p) - 577)
-#else
+/* Debug versions
 #define CTRL(p,v) (*ctrl = (v))
-#endif
 
 static char macscsi_read(struct Scsi_Host *instance, int reg)
 {
@@ -565,11 +345,7 @@
   int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
 
   CTRL(iobase, 0);
-#if 0
-  i = inb(iobase + 64 + reg);
-#else
-  i = inb(iobase + reg<<4);
-#endif
+  i = in_8(iobase + (reg<<4));
   CTRL(iobase, 0x40);
 
   return i;
@@ -581,86 +357,244 @@
   int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
 
   CTRL(iobase, 0);
-#if 0
-  outb(value, iobase + 64 + reg);
-#else
-  outb(value, iobase + reg<<4);
-#endif
+  out_8(value, iobase + (reg<<4));
   CTRL(iobase, 0x40);
 }
+*/
 
-#undef CTRL
-
-#else
-static char macscsi_read(struct Scsi_Host *instance, int reg)
+/* Fast versions */
+static __inline__ char macscsi_read(struct Scsi_Host *instance, int reg)
 {
-	return( mac_scsi_regp[reg << 4] );
+  return in_8(instance->io_port + (reg<<4));
 }
 
-static void macscsi_write(struct Scsi_Host *instance, int reg, int value)
-{
-	mac_scsi_regp[reg << 4] = value;
+static __inline__ void macscsi_write(struct Scsi_Host *instance, int reg, int value)
+{
+  out_8(value, instance->io_port + (reg<<4));
+}
+
+
+/* 
+   Pseudo-DMA: (Ove Edlund)
+   The code attempts to catch bus errors that occur if one for example
+   "trips over the cable".
+   XXX: Since bus errors in the PDMA routines never happen on my 
+   computer, the bus error code is untested. 
+   If the code works as intended, a bus error results in Pseudo-DMA 
+   beeing disabled, meaning that the driver switches to slow handshake. 
+   If bus errors are NOT extremely rare, this has to be changed. 
+*/
+
+#define CP_IO_TO_MEM(s,d,len)				\
+__asm__ __volatile__					\
+    ("    cmp.w  #4,%2\n"				\
+     "    bls    8f\n"					\
+     "    move.w %1,%%d0\n"				\
+     "    neg.b  %%d0\n"				\
+     "    and.w  #3,%%d0\n"				\
+     "    sub.w  %%d0,%2\n"				\
+     "    bra    2f\n"					\
+     " 1: move.b (%0),(%1)+\n"				\
+     " 2: dbf    %%d0,1b\n"				\
+     "    move.w %2,%%d0\n"				\
+     "    lsr.w  #5,%%d0\n"				\
+     "    bra    4f\n"					\
+     " 3: move.l (%0),(%1)+\n"				\
+     "31: move.l (%0),(%1)+\n"				\
+     "32: move.l (%0),(%1)+\n"				\
+     "33: move.l (%0),(%1)+\n"				\
+     "34: move.l (%0),(%1)+\n"				\
+     "35: move.l (%0),(%1)+\n"				\
+     "36: move.l (%0),(%1)+\n"				\
+     "37: move.l (%0),(%1)+\n"				\
+     " 4: dbf    %%d0,3b\n"				\
+     "    move.w %2,%%d0\n"				\
+     "    lsr.w  #2,%%d0\n"				\
+     "    and.w  #7,%%d0\n"				\
+     "    bra    6f\n"					\
+     " 5: move.l (%0),(%1)+\n"				\
+     " 6: dbf    %%d0,5b\n"				\
+     "    and.w  #3,%2\n"				\
+     "    bra    8f\n"					\
+     " 7: move.b (%0),(%1)+\n"				\
+     " 8: dbf    %2,7b\n"				\
+     "    moveq.l #0, %2\n"				\
+     " 9: \n"						\
+     ".section .fixup,\"ax\"\n"				\
+     "    .even\n"					\
+     "90: moveq.l #1, %2\n"				\
+     "    jra 9b\n"					\
+     ".previous\n"					\
+     ".section __ex_table,\"a\"\n"			\
+     "   .align 4\n"					\
+     "   .long  1b,90b\n"				\
+     "   .long  3b,90b\n"				\
+     "   .long 31b,90b\n"				\
+     "   .long 32b,90b\n"				\
+     "   .long 33b,90b\n"				\
+     "   .long 34b,90b\n"				\
+     "   .long 35b,90b\n"				\
+     "   .long 36b,90b\n"				\
+     "   .long 37b,90b\n"				\
+     "   .long  5b,90b\n"				\
+     "   .long  7b,90b\n"				\
+     ".previous"					\
+     : "=a"(s), "=a"(d), "=d"(len)			\
+     : "0"(s), "1"(d), "2"(len)				\
+     : "d0")
+
+
+static int macscsi_pread (struct Scsi_Host *instance,
+			  unsigned char *dst, int len)
+{
+   unsigned char *d;
+   volatile unsigned char *s;
+
+   NCR5380_local_declare();
+   NCR5380_setup(instance);
+
+   s = mac_scsi_drq+0x60;
+   d = dst;
+
+/* These conditions are derived from MacOS */
+
+   while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) 
+         && !(NCR5380_read(STATUS_REG) & SR_REQ))
+      ;
+   if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) 
+         && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
+      printk(KERN_ERR "Error in macscsi_pread\n");
+      return -1;
+   }
+
+   CP_IO_TO_MEM(s, d, len);
+   
+   if (len != 0) {
+      printk(KERN_NOTICE "Bus error in macscsi_pread\n");
+      return -1;
+   }
+   
+   return 0;
+}
+
+
+#define CP_MEM_TO_IO(s,d,len)				\
+__asm__ __volatile__					\
+    ("    cmp.w  #4,%2\n"				\
+     "    bls    8f\n"					\
+     "    move.w %0,%%d0\n"				\
+     "    neg.b  %%d0\n"				\
+     "    and.w  #3,%%d0\n"				\
+     "    sub.w  %%d0,%2\n"				\
+     "    bra    2f\n"					\
+     " 1: move.b (%0)+,(%1)\n"				\
+     " 2: dbf    %%d0,1b\n"				\
+     "    move.w %2,%%d0\n"				\
+     "    lsr.w  #5,%%d0\n"				\
+     "    bra    4f\n"					\
+     " 3: move.l (%0)+,(%1)\n"				\
+     "31: move.l (%0)+,(%1)\n"				\
+     "32: move.l (%0)+,(%1)\n"				\
+     "33: move.l (%0)+,(%1)\n"				\
+     "34: move.l (%0)+,(%1)\n"				\
+     "35: move.l (%0)+,(%1)\n"				\
+     "36: move.l (%0)+,(%1)\n"				\
+     "37: move.l (%0)+,(%1)\n"				\
+     " 4: dbf    %%d0,3b\n"				\
+     "    move.w %2,%%d0\n"				\
+     "    lsr.w  #2,%%d0\n"				\
+     "    and.w  #7,%%d0\n"				\
+     "    bra    6f\n"					\
+     " 5: move.l (%0)+,(%1)\n"				\
+     " 6: dbf    %%d0,5b\n"				\
+     "    and.w  #3,%2\n"				\
+     "    bra    8f\n"					\
+     " 7: move.b (%0)+,(%1)\n"				\
+     " 8: dbf    %2,7b\n"				\
+     "    moveq.l #0, %2\n"				\
+     " 9: \n"						\
+     ".section .fixup,\"ax\"\n"				\
+     "    .even\n"					\
+     "90: moveq.l #1, %2\n"				\
+     "    jra 9b\n"					\
+     ".previous\n"					\
+     ".section __ex_table,\"a\"\n"			\
+     "   .align 4\n"					\
+     "   .long  1b,90b\n"				\
+     "   .long  3b,90b\n"				\
+     "   .long 31b,90b\n"				\
+     "   .long 32b,90b\n"				\
+     "   .long 33b,90b\n"				\
+     "   .long 34b,90b\n"				\
+     "   .long 35b,90b\n"				\
+     "   .long 36b,90b\n"				\
+     "   .long 37b,90b\n"				\
+     "   .long  5b,90b\n"				\
+     "   .long  7b,90b\n"				\
+     ".previous"					\
+     : "=a"(s), "=a"(d), "=d"(len)			\
+     : "0"(s), "1"(d), "2"(len)				\
+     : "d0")
+
+static int macscsi_pwrite (struct Scsi_Host *instance,
+				  unsigned char *src, int len)
+{
+   unsigned char *s;
+   volatile unsigned char *d;
+
+   NCR5380_local_declare();
+   NCR5380_setup(instance);
+
+   s = src;
+   d = mac_scsi_drq;
+   
+/* These conditions are derived from MacOS */
+
+   while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) 
+         && (!(NCR5380_read(STATUS_REG) & SR_REQ) 
+            || (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))) 
+      ;
+   if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)) {
+      printk(KERN_ERR "Error in macscsi_pwrite\n");
+      return -1;
+   }
+
+   CP_MEM_TO_IO(s, d, len);   
+
+   if (len != 0) {
+      printk(KERN_NOTICE "Bus error in macscsi_pwrite\n");
+      return -1;
+   }
+   
+   return 0;
 }
 
-#endif
-
-#include "NCR5380.c"
-
-/*
- * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; 
- * reentering NCR5380_print_status seems to have ugly side effects
- */
-
-void scsi_mac_debug (void)
-{
-	unsigned long flags;
-	NCR5380_local_declare();
-
-	if (default_instance) {
-#if 0
-		NCR5380_setup(default_instance);
-		if(NCR5380_read(BUS_AND_STATUS_REG)&BASR_IRQ)
-#endif
-			local_irq_save(flags);
-			NCR5380_print_status(default_instance);
-			local_irq_restore(flags);
-	}
-#if 0
-	polled_scsi_on = 1;
-#endif
-}
-/*
- * Helper function for interrupt trouble. More ugly side effects here.
- */
 
-void scsi_mac_polled (void)
-{
-	unsigned long flags;
-	NCR5380_local_declare();
-	struct Scsi_Host *instance;
-	
-#if 0
-	for (instance = first_instance; instance && (instance->hostt == 
-	    the_template); instance = instance->next)
-	    if (instance->irq == IRQ_MAC_SCSI && polled_scsi_on) {
-#else
-		instance = default_instance;
-#endif
-		NCR5380_setup(instance);
-		if(NCR5380_read(BUS_AND_STATUS_REG)&BASR_IRQ)
-		{
-			printk("SCSI poll\n");
-			local_irq_save(flags);
-			NCR5380_intr(IRQ_MAC_SCSI, instance, NULL);
-			local_irq_restore(flags);
-		}
-#if 0
-	    }
-#endif
-}
+/* These control the behaviour of the generic 5380 core */
+#define AUTOSENSE
+#define PSEUDO_DMA
 
+#include "NCR5380.c"
 
+static Scsi_Host_Template driver_template = {
+	.proc_name			= "Mac5380",
+	.proc_info			= macscsi_proc_info,
+	.name				= "Macintosh NCR5380 SCSI",
+	.detect				= macscsi_detect,
+	.release			= macscsi_release,
+	.info				= macscsi_info,
+	.queuecommand			= macscsi_queue_command,
+	.eh_abort_handler		= macscsi_abort,
+	.eh_bus_reset_handler		= macscsi_bus_reset,
+	.eh_device_reset_handler	= macscsi_device_reset,
+	.eh_host_reset_handler		= macscsi_host_reset,
+	.can_queue			= CAN_QUEUE,
+	.this_id			= 7,
+	.sg_tablesize			= SG_ALL,
+	.cmd_per_lun			= CMD_PER_LUN,
+	.unchecked_isa_dma		= 0,
+	.use_clustering			= DISABLE_CLUSTERING
+};
 
-static Scsi_Host_Template driver_template = MAC_NCR5380;
 
 #include "scsi_module.c"
diff -Nru a/drivers/scsi/mac_scsi.h b/drivers/scsi/mac_scsi.h
--- a/drivers/scsi/mac_scsi.h	Thu Jan 16 18:23:06 2003
+++ b/drivers/scsi/mac_scsi.h	Thu Jan 16 18:23:06 2003
@@ -29,16 +29,9 @@
 #ifndef MAC_NCR5380_H
 #define MAC_NCR5380_H
 
-#define MACSCSI_PUBLIC_RELEASE 1
-
+#define MACSCSI_PUBLIC_RELEASE 2
 
 #ifndef ASM
-int macscsi_abort (Scsi_Cmnd *);
-int macscsi_detect (Scsi_Host_Template *);
-int macscsi_release (struct Scsi_Host *);
-const char *macscsi_info (struct Scsi_Host *);
-int macscsi_reset(Scsi_Cmnd *, unsigned int);
-int macscsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 int macscsi_proc_info (char *buffer, char **start, off_t offset,
 			int length, int hostno, int inout);
 
@@ -64,22 +57,6 @@
 
 #include <scsi/scsicam.h>
 
-#define MAC_NCR5380 {						\
-.name			= "Macintosh NCR5380 SCSI",			\
-.detect			= macscsi_detect,					\
-.release		= macscsi_release,	/* Release */		\
-.info			= macscsi_info,					\
-.queuecommand		= macscsi_queue_command,				\
-.abort			= macscsi_abort,			 		\
-.reset			= macscsi_reset,					\
-.can_queue		= CAN_QUEUE,		/* can queue */		\
-.this_id		= 7,			/* id */		\
-.sg_tablesize		= SG_ALL,			/* sg_tablesize */	\
-.cmd_per_lun		= CMD_PER_LUN,		/* cmd per lun */	\
-.unchecked_isa_dma	= 0,			/* unchecked_isa_dma */	\
-.use_clustering		= DISABLE_CLUSTERING				\
-	}
-
 #ifndef HOSTS_C
 
 #define NCR5380_implementation_fields \
@@ -94,10 +71,15 @@
 #define NCR5380_read(reg) macscsi_read(_instance, reg)
 #define NCR5380_write(reg, value) macscsi_write(_instance, reg, value)
 
+#define NCR5380_pread 	macscsi_pread
+#define NCR5380_pwrite 	macscsi_pwrite
+	
 #define NCR5380_intr macscsi_intr
 #define NCR5380_queue_command macscsi_queue_command
 #define NCR5380_abort macscsi_abort
-#define NCR5380_reset macscsi_reset
+#define NCR5380_bus_reset macscsi_bus_reset
+#define NCR5380_device_reset macscsi_device_reset
+#define NCR5380_host_reset macscsi_host_reset
 #define NCR5380_proc_info macscsi_proc_info
 
 #define BOARD_NORMAL	0
diff -Nru a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
--- a/drivers/scsi/pcmcia/aha152x_stub.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/scsi/pcmcia/aha152x_stub.c	Thu Jan 16 18:23:06 2003
@@ -350,12 +350,15 @@
 
     DEBUG(0, "aha152x_release_cs(0x%p)\n", link);
 
+#warning This doesn't protect you.  You need some real fix for your races.
+#if 0
     if (GET_USE_COUNT(driver_template.module) != 0) {
 	DEBUG(1, "aha152x_cs: release postponed, "
 	      "device still open\n");
 	link->state |= DEV_STALE_CONFIG;
 	return;
     }
+#endif
 
     scsi_unregister_host(&driver_template);
     link->dev = NULL;
diff -Nru a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
--- a/drivers/scsi/pcmcia/fdomain_stub.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/scsi/pcmcia/fdomain_stub.c	Thu Jan 16 18:23:06 2003
@@ -313,12 +313,15 @@
 
     DEBUG(0, "fdomain_release(0x%p)\n", link);
 
+#warning This doesn't protect you.  You need some real fix for your races.
+#if 0
     if (GET_USE_COUNT(&__this_module) != 0) {
 	DEBUG(1, "fdomain_cs: release postponed, "
 	      "device still open\n");
 	link->state |= DEV_STALE_CONFIG;
 	return;
     }
+#endif
 
     scsi_unregister_host(&driver_template);
     link->dev = NULL;
diff -Nru a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
--- a/drivers/scsi/pcmcia/qlogic_stub.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/scsi/pcmcia/qlogic_stub.c	Thu Jan 16 18:23:06 2003
@@ -329,11 +329,14 @@
 
 	DEBUG(0, "qlogic_release(0x%p)\n", link);
 
+#warning This doesn't protect you.  You need some real fix for your races.
+#if 0
 	if (GET_USE_COUNT(&__this_module) != 0) {
 		DEBUG(0, "qlogic_cs: release postponed, device still open\n");
 		link->state |= DEV_STALE_CONFIG;
 		return;
 	}
+#endif
 
 	scsi_unregister_host(&driver_template);
 	link->dev = NULL;
diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/scsi/scsi_debug.c	Thu Jan 16 18:23:06 2003
@@ -1192,20 +1192,17 @@
 	return len;
 }
 
-static ssize_t sdebug_delay_read(struct device_driver * ddp, char * buf, 
-				 size_t count, loff_t off)
+static ssize_t sdebug_delay_read(struct device_driver * ddp, char * buf)
 {
-        return off ? 0 : snprintf(buf, count, "%d\n", scsi_debug_delay);
+        return sprintf(buf, "%d\n", scsi_debug_delay);
 }
 
 static ssize_t sdebug_delay_write(struct device_driver * ddp, 
-				  const char * buf, size_t count, loff_t off)
+				  const char * buf, size_t count)
 {
         int delay;
 	char work[20];
 
-        if (off)
-                return 0;
         if (1 == sscanf(buf, "%10s", work)) {
 		if ((1 == sscanf(work, "%d", &delay)) && (delay >= 0)) {
 			scsi_debug_delay = delay;
@@ -1217,20 +1214,17 @@
 DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_read, 
 	    sdebug_delay_write)
 
-static ssize_t sdebug_opts_read(struct device_driver * ddp, char * buf, 
-				size_t count, loff_t off)
+static ssize_t sdebug_opts_read(struct device_driver * ddp, char * buf)
 {
-        return off ? 0 : snprintf(buf, count, "0x%x\n", scsi_debug_opts);
+        return sprintf(buf, "0x%x\n", scsi_debug_opts);
 }
 
 static ssize_t sdebug_opts_write(struct device_driver * ddp, 
-				 const char * buf, size_t count, loff_t off)
+				 const char * buf, size_t count)
 {
         int opts;
 	char work[20];
 
-        if (off)
-                return 0;
         if (1 == sscanf(buf, "%10s", work)) {
 		if (0 == strnicmp(work,"0x", 2)) {
 			if (1 == sscanf(&work[2], "%x", &opts))
@@ -1248,55 +1242,47 @@
 DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_read, 
 	    sdebug_opts_write)
 
-static ssize_t sdebug_num_devs_read(struct device_driver * ddp, char * buf, 
-				    size_t count, loff_t off)
+static ssize_t sdebug_num_devs_read(struct device_driver * ddp, char * buf)
 {
-        return off ? 0 : snprintf(buf, count, "%d\n", scsi_debug_num_devs);
+        return sprintf(buf, "%d\n", scsi_debug_num_devs);
 }
 DRIVER_ATTR(num_devs, S_IRUGO, sdebug_num_devs_read, NULL) 
 
-static ssize_t sdebug_dev_size_mb_read(struct device_driver * ddp, char * buf, 
-				       size_t count, loff_t off)
+static ssize_t sdebug_dev_size_mb_read(struct device_driver * ddp, char * buf)
 {
-        return off ? 0 : snprintf(buf, count, "%d\n", scsi_debug_dev_size_mb);
+        return sprintf(buf, "%d\n", scsi_debug_dev_size_mb);
 }
 DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_read, NULL) 
 
-static ssize_t sdebug_every_nth_read(struct device_driver * ddp, char * buf, 
-				     size_t count, loff_t off)
+static ssize_t sdebug_every_nth_read(struct device_driver * ddp, char * buf)
 {
-        return off ? 0 : snprintf(buf, count, "%d\n", scsi_debug_every_nth);
+        return sprintf(buf, "%d\n", scsi_debug_every_nth);
 }
 DRIVER_ATTR(every_nth, S_IRUGO, sdebug_every_nth_read, NULL) 
 
-static ssize_t sdebug_max_luns_read(struct device_driver * ddp, char * buf, 
-				    size_t count, loff_t off)
+static ssize_t sdebug_max_luns_read(struct device_driver * ddp, char * buf)
 {
-        return off ? 0 : snprintf(buf, count, "%d\n", scsi_debug_max_luns);
+        return sprintf(buf, "%d\n", scsi_debug_max_luns);
 }
 DRIVER_ATTR(max_luns, S_IRUGO, sdebug_max_luns_read, NULL) 
 
-static ssize_t sdebug_scsi_level_read(struct device_driver * ddp, char * buf, 
-				      size_t count, loff_t off)
+static ssize_t sdebug_scsi_level_read(struct device_driver * ddp, char * buf)
 {
-        return off ? 0 : snprintf(buf, count, "%d\n", scsi_debug_scsi_level);
+        return sprintf(buf, "%d\n", scsi_debug_scsi_level);
 }
 DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_read, NULL) 
 
-static ssize_t sdebug_add_host_read(struct device_driver * ddp, char * buf, 
-				    size_t count, loff_t off)
+static ssize_t sdebug_add_host_read(struct device_driver * ddp, char * buf)
 {
-        return off ? 0 : snprintf(buf, count, "%d\n", scsi_debug_add_host);
+        return sprintf(buf, "%d\n", scsi_debug_add_host);
 }
 
 static ssize_t sdebug_add_host_write(struct device_driver * ddp, 
-				  const char * buf, size_t count, loff_t off)
+				  const char * buf, size_t count)
 {
         int delta_hosts, k;
 	char work[20];
 
-        if (off)
-                return 0;
         if (1 != sscanf(buf, "%10s", work))
 		return -EINVAL;
 	{	/* temporary hack around sscanf() problem with -ve nums */
diff -Nru a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
--- a/drivers/serial/sunsab.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/serial/sunsab.c	Thu Jan 16 18:23:05 2003
@@ -768,7 +768,7 @@
 {
 	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
 	unsigned long flags;
-	int baud = uart_get_baud_rate(port, termios);
+	int baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
 
 	spin_lock_irqsave(&up->port.lock, flags);
 	sunsab_convert_to_sab(up, termios->c_cflag, termios->c_iflag, baud);
diff -Nru a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c
--- a/drivers/usb/class/bluetty.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/usb/class/bluetty.c	Thu Jan 16 18:23:06 2003
@@ -1107,20 +1107,17 @@
 		return -EIO;
 	}
 
-	MOD_INC_USE_COUNT;
 	info("USB Bluetooth converter detected");
 
 	for (minor = 0; minor < BLUETOOTH_TTY_MINORS && bluetooth_table[minor]; ++minor)
 		;
 	if (bluetooth_table[minor]) {
 		err("No more free Bluetooth devices");
-		MOD_DEC_USE_COUNT;
 		return -ENODEV;
 	}
 
 	if (!(bluetooth = kmalloc(sizeof(struct usb_bluetooth), GFP_KERNEL))) {
 		err("Out of memory");
-		MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
 
@@ -1236,7 +1233,6 @@
 
 	/* free up any memory that we allocated */
 	kfree (bluetooth);
-	MOD_DEC_USE_COUNT;
 	return -EIO;
 }
 
@@ -1295,13 +1291,12 @@
 	} else {
 		info("device disconnected");
 	}
-
-	MOD_DEC_USE_COUNT;
 }
 
 
 static struct tty_driver bluetooth_tty_driver = {
 	.magic =		TTY_DRIVER_MAGIC,
+	.owner =		THIS_MODULE,
 	.driver_name =		"usb-bluetooth",
 	.name =			"usb/ttub/%d",
 	.major =		BLUETOOTH_TTY_MAJOR,
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/usb/class/cdc-acm.c	Thu Jan 16 18:23:06 2003
@@ -320,8 +320,6 @@
 	tty->driver_data = acm;
 	acm->tty = tty;
 
-	MOD_INC_USE_COUNT;
-
         lock_kernel();
 
 	if (acm->used++) {
@@ -369,7 +367,6 @@
 			kfree(acm);
 		}
 	}
-	MOD_DEC_USE_COUNT;
 }
 
 static int acm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
@@ -724,6 +721,7 @@
 
 static struct tty_driver acm_tty_driver = {
 	.magic =		TTY_DRIVER_MAGIC,
+	.owner =		THIS_MODULE,
 	.driver_name =		"acm",
 	.name =			"usb/acm/%d",
 	.major =		ACM_TTY_MAJOR,
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/usb/core/hcd.c	Thu Jan 16 18:23:06 2003
@@ -1001,7 +1001,7 @@
 	spin_lock_irqsave (&hcd_data_lock, flags);
 	if (HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_QUIESCING) {
 		usb_get_dev (urb->dev);
-		list_add (&urb->urb_list, &dev->urb_list);
+		list_add_tail (&urb->urb_list, &dev->urb_list);
 		status = 0;
 	} else {
 		INIT_LIST_HEAD (&urb->urb_list);
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h	Thu Jan 16 18:23:05 2003
+++ b/drivers/usb/core/hcd.h	Thu Jan 16 18:23:05 2003
@@ -353,9 +353,6 @@
 extern void usb_bus_get (struct usb_bus *bus);
 extern void usb_bus_put (struct usb_bus *bus);
 
-extern struct usb_interface *usb_ifnum_to_if (struct usb_device *dev,
-	unsigned ifnum);
-
 extern int usb_find_interface_driver (struct usb_device *dev,
 	struct usb_interface *interface);
 
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/usb/core/usb.c	Thu Jan 16 18:23:06 2003
@@ -1484,6 +1484,7 @@
 EXPORT_SYMBOL(usb_driver_release_interface);
 EXPORT_SYMBOL(usb_match_id);
 EXPORT_SYMBOL(usb_find_interface);
+EXPORT_SYMBOL(usb_ifnum_to_if);
 
 EXPORT_SYMBOL(usb_new_device);
 EXPORT_SYMBOL(usb_reset_device);
diff -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c
--- a/drivers/usb/misc/speedtouch.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/usb/misc/speedtouch.c	Thu Jan 16 18:23:07 2003
@@ -82,7 +82,7 @@
 #endif
 
 #define DRIVER_AUTHOR	"Johan Verrept, Johan.Verrept@advalvas.be"
-#define DRIVER_DESC	"Driver for the Alcatel Speed Touch USB ADSL modem"
+#define DRIVER_DESC	"Driver for the Alcatel SpeedTouch USB ADSL modem"
 #define DRIVER_VERSION	"1.5A"
 
 #define SPEEDTOUCH_VENDORID		0x06b9
@@ -158,7 +158,7 @@
 static DECLARE_MUTEX(udsl_usb_ioctl_lock);
 
 #ifdef DEBUG_PACKET
-int udsl_print_packet (const unsigned char *data, int len);
+static int udsl_print_packet (const unsigned char *data, int len);
 #endif
 
 /*
@@ -169,8 +169,8 @@
 static void udsl_atm_close (struct atm_vcc *vcc);
 static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
 static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
-int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page);
-void udsl_atm_processqueue (unsigned long data);
+static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page);
+static void udsl_atm_processqueue (unsigned long data);
 
 static struct atmdev_ops udsl_atm_devops = {
 	.open =		udsl_atm_open,
@@ -190,7 +190,7 @@
 static int udsl_usb_probe (struct usb_interface *intf,
 			   const struct usb_device_id *id);
 static void udsl_usb_disconnect (struct usb_interface *intf);
-int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc,
+static int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc,
 			struct sk_buff *skb);
 static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data);
 static int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *vcc);
@@ -213,8 +213,7 @@
 *
 ****************************************************************************/
 
-struct atm_dev *udsl_atm_startdevice (struct udsl_instance_data *instance,
-				      struct atmdev_ops *devops)
+static struct atm_dev *udsl_atm_startdevice (struct udsl_instance_data *instance, struct atmdev_ops *devops)
 {
 	MOD_INC_USE_COUNT;
 	instance->atm_dev = atm_dev_register (udsl_driver_name, devops, -1, 0);
@@ -231,7 +230,7 @@
 	return instance->atm_dev;
 }
 
-void udsl_atm_stopdevice (struct udsl_instance_data *instance)
+static void udsl_atm_stopdevice (struct udsl_instance_data *instance)
 {
 	struct atm_vcc *walk;
 	struct sk_buff *skb;
@@ -257,7 +256,7 @@
 	MOD_DEC_USE_COUNT;
 }
 
-void udsl_atm_set_mac (struct udsl_instance_data *instance, const char mac[6])
+static void udsl_atm_set_mac (struct udsl_instance_data *instance, const char mac[6])
 {
 	if (!instance->atm_dev)
 		return;
@@ -270,7 +269,7 @@
 * ATM helper functions
 *
 ****************************************************************************/
-struct sk_buff *udsl_atm_alloc_tx (struct atm_vcc *vcc, unsigned int size)
+static struct sk_buff *udsl_atm_alloc_tx (struct atm_vcc *vcc, unsigned int size)
 {
 	struct atmsar_vcc_data *atmsar_vcc =
 	    ((struct udsl_atm_dev_data *) vcc->dev_data)->atmsar_vcc;
@@ -282,13 +281,13 @@
 	return NULL;
 }
 
-int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page)
+static int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page)
 {
 	struct udsl_instance_data *instance = atm_dev->dev_data;
 	int left = *pos;
 
 	if (!left--)
-		return sprintf (page, "Speed Touch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+		return sprintf (page, "SpeedTouch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
 				instance->usb_dev->bus->bus_name, instance->usb_dev->devpath,
 				atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2],
 				atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]);
@@ -317,7 +316,7 @@
 * ATM DATA functions
 *
 ****************************************************************************/
-int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
+static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
 {
 	struct udsl_atm_dev_data *dev_data = vcc->dev_data;
 	struct udsl_instance_data *instance = vcc->dev->dev_data;
@@ -361,7 +360,7 @@
 };
 
 
-void udsl_atm_processqueue (unsigned long data)
+static void udsl_atm_processqueue (unsigned long data)
 {
 	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
 	struct atmsar_vcc_data *atmsar_vcc = NULL;
@@ -420,7 +419,7 @@
 * SAR driver entries
 *
 ****************************************************************************/
-int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
+static int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
 {
 	struct udsl_atm_dev_data *dev_data;
 	struct udsl_instance_data *instance = vcc->dev->dev_data;
@@ -458,7 +457,7 @@
 	return 0;
 }
 
-void udsl_atm_close (struct atm_vcc *vcc)
+static void udsl_atm_close (struct atm_vcc *vcc)
 {
 	struct udsl_atm_dev_data *dev_data = vcc->dev_data;
 	struct udsl_instance_data *instance = vcc->dev->dev_data;
@@ -485,7 +484,7 @@
 	return;
 };
 
-int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
+static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg)
 {
 	switch (cmd) {
 	case ATM_QUERYLOOP:
@@ -538,7 +537,7 @@
 		ctx->skb, ctx->skb->len, err);
 }
 
-int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *vcc)
+static int udsl_usb_cancelsends (struct udsl_instance_data *instance, struct atm_vcc *vcc)
 {
 	int i;
 
@@ -558,7 +557,7 @@
 }
 
 /**** send ******/
-int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc,
+static int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc,
 			struct sk_buff *skb)
 {
 	int err, i;
@@ -622,7 +621,7 @@
 }
 
 /********* receive *******/
-void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
+static void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
 {
 	struct udsl_data_ctx *ctx;
 	struct udsl_instance_data *instance;
@@ -676,7 +675,7 @@
 	return;
 };
 
-int udsl_usb_data_init (struct udsl_instance_data *instance)
+static int udsl_usb_data_init (struct udsl_instance_data *instance)
 {
 	int i, succes;
 
@@ -775,6 +774,8 @@
 		ctx->skb = NULL;
 	}
 
+	tasklet_kill (&instance->recvqueue_tasklet);
+
 	for (i = 0; i < UDSL_NUMBER_SND_URBS; i++) {
 		struct udsl_usb_send_data_context *ctx = &(instance->send_ctx[i]);
 
@@ -926,7 +927,7 @@
 *
 *******************************************************************************/
 
-int udsl_print_packet (const unsigned char *data, int len)
+static int udsl_print_packet (const unsigned char *data, int len)
 {
 	unsigned char buffer[256];
 	int i = 0, j = 0;
diff -Nru a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
--- a/drivers/usb/serial/bus.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/usb/serial/bus.c	Thu Jan 16 18:23:07 2003
@@ -23,6 +23,17 @@
 
 #include "usb-serial.h"
 
+static ssize_t show_dev (struct device *dev, char *buf)
+{
+	struct usb_serial_port *port= to_usb_serial_port(dev);
+	dev_t base;
+
+	port = to_usb_serial_port(dev);
+
+	base = MKDEV(SERIAL_TTY_MAJOR, port->number);
+	return sprintf(buf, "%04x\n", base);
+}
+static DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
 
 static int usb_serial_device_match (struct device *dev, struct device_driver *drv)
 {
@@ -79,6 +90,8 @@
 	minor = port->number;
 
 	tty_register_device (&usb_serial_tty_driver, minor);
+	device_create_file (dev, &dev_attr_dev);
+
 	dev_info(&port->serial->dev->dev, 
 		 "%s converter now attached to ttyUSB%d (or usb/tts/%d for devfs)\n",
 		 driver->name, minor, minor);
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/usb/serial/usb-serial.c	Thu Jan 16 18:23:05 2003
@@ -1257,6 +1257,7 @@
 
 struct tty_driver usb_serial_tty_driver = {
 	.magic =		TTY_DRIVER_MAGIC,
+	.owner =		THIS_MODULE,
 	.driver_name =		"usbserial",
 #ifndef CONFIG_DEVFS_FS
 	.name =			"ttyUSB",
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/usb/storage/scsiglue.c	Thu Jan 16 18:23:06 2003
@@ -88,8 +88,12 @@
 	/* register the host */
 	us->host = scsi_register(sht, sizeof(us));
 	if (us->host) {
+		struct usb_interface *iface;
 		us->host->hostdata[0] = (unsigned long)us;
 		us->host_no = us->host->host_no;
+		iface = usb_ifnum_to_if(us->pusb_dev, us->ifnum);
+		if (iface)
+			scsi_set_device(us->host, &iface->dev);
 		return 1;
 	}
 
diff -Nru a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/Kconfig	Thu Jan 16 18:23:05 2003
@@ -295,7 +295,7 @@
 	  vga16fb.o.
 
 config FB_STI
-	bool "HP STI frame buffer device support"
+	tristate "HP STI frame buffer device support"
 	depends on FB && PARISC
 	default y
 	---help---
diff -Nru a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/Makefile	Thu Jan 16 18:23:05 2003
@@ -18,7 +18,7 @@
 obj-$(CONFIG_PPC)                 += macmodes.o
 endif
 
-obj-$(CONFIG_FB_ACORN)            += acornfb.o
+obj-$(CONFIG_FB_ACORN)            += acornfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_AMIGA)            += amifb.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
 obj-$(CONFIG_FB_PM3)		  += pm3fb.o
@@ -38,14 +38,14 @@
 obj-$(CONFIG_FB_CYBER)            += cyberfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
 obj-$(CONFIG_FB_SGIVW)            += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_3DFX)             += tdfxfb.o
+obj-$(CONFIG_FB_3DFX)             += tdfxfb.o cfbimgblt.o
 obj-$(CONFIG_FB_MAC)              += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_HP300)            += hpfb.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_OF)               += offb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
 obj-$(CONFIG_FB_IMSTT)            += imsttfb.o
 obj-$(CONFIG_FB_RETINAZ3)         += retz3fb.o
 obj-$(CONFIG_FB_CLGEN)            += clgenfb.o
-obj-$(CONFIG_FB_TRIDENT)	  += tridentfb.o
+obj-$(CONFIG_FB_TRIDENT)	  += tridentfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
 obj-$(CONFIG_FB_S3TRIO)           += S3triofb.o
 obj-$(CONFIG_FB_TGA)              += tgafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_VESA)             += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
@@ -69,16 +69,15 @@
 obj-$(CONFIG_FB_TX3912)           += tx3912fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 
 obj-$(CONFIG_FB_MATROX)		  += matrox/
-obj-$(CONFIG_FB_RIVA)		  += riva/ cfbfillrect.o cfbcopyarea.o \
-	                             cfbimgblt.o vgastate.o
+obj-$(CONFIG_FB_RIVA)		  += riva/ cfbimgblt.o vgastate.o 
 obj-$(CONFIG_FB_SIS)		  += sis/
-obj-$(CONFIG_FB_ATY)		  += aty/ cfbimgblt.o
+obj-$(CONFIG_FB_ATY)		  += aty/ cfbimgblt.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_I810)             += i810/ cfbfillrect.o cfbcopyarea.o \
 	                             cfbimgblt.o vgastate.o
 
 obj-$(CONFIG_FB_SUN3)             += sun3fb.o
 obj-$(CONFIG_FB_HGA)              += hgafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
-obj-$(CONFIG_FB_SA1100)           += sa1100fb.o
+obj-$(CONFIG_FB_SA1100)           += sa1100fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_HIT)              += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_E1355)            += epson1355fb.o
diff -Nru a/drivers/video/acornfb.c b/drivers/video/acornfb.c
--- a/drivers/video/acornfb.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/video/acornfb.c	Thu Jan 16 18:23:07 2003
@@ -12,6 +12,9 @@
  * NOTE: Most of the modes with X!=640 will disappear shortly.
  * NOTE: Startup setting of HS & VS polarity not supported.
  *       (do we need to support it if we're coming up in 640x480?)
+ *
+ * FIXME: (things broken by the "new improved" FBCON API)
+ *  - Blanking 8bpp displays with VIDC
  */
 
 #include <linux/config.h>
@@ -33,14 +36,6 @@
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
 
-#include <video/fbcon.h>
-#include <video/fbcon-mfb.h>
-#include <video/fbcon-cfb2.h>
-#include <video/fbcon-cfb4.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb32.h>
-
 #include "acornfb.h"
 
 /*
@@ -58,25 +53,7 @@
  */
 #define DEFAULT_XRES	640
 #define DEFAULT_YRES	480
-/*
- * The order here defines which BPP we
- * pick depending on which resolutions
- * we have configured.
- */
-#if   defined(FBCON_HAS_CFB4)
-# define DEFAULT_BPP	4
-#elif defined(FBCON_HAS_CFB8)
-# define DEFAULT_BPP	8
-#elif defined(FBCON_HAS_CFB16)
-# define DEFAULT_BPP	16
-#elif defined(FBCON_HAS_CFB2)
-# define DEFAULT_BPP	2
-#elif defined(FBCON_HAS_MFB)
-# define DEFAULT_BPP	1
-#else
-#error No suitable framebuffers configured
-#endif
-
+#define DEFAULT_BPP	4
 
 /*
  * define this to debug the video mode selection
@@ -99,13 +76,10 @@
 	{ 30000, 70000, 60, 60, 0 }
 };
 
-static struct display global_disp;
 static struct fb_info fb_info;
 static struct acornfb_par current_par;
 static struct vidc_timing current_vidc;
-static struct fb_var_screeninfo __initdata init_var = {};
 
-extern int acornfb_depth;	/* set by setup.c */
 extern unsigned int vram_size;	/* set by setup.c */
 
 #ifdef HAS_VIDC
@@ -333,34 +307,26 @@
 #endif
 }
 
-static inline void
-acornfb_palette_write(u_int regno, union palette pal)
-{
-	vidc_writel(pal.p);
-}
-
-static inline union palette
-acornfb_palette_encode(u_int regno, u_int red, u_int green, u_int blue,
-		       u_int trans)
+static int
+acornfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+		  u_int trans, struct fb_info *info)
 {
 	union palette pal;
 
+	if (regno >= current_par.palette_size)
+		return 1;
+
 	pal.p = 0;
 	pal.vidc.reg   = regno;
 	pal.vidc.red   = red >> 12;
 	pal.vidc.green = green >> 12;
 	pal.vidc.blue  = blue >> 12;
-	return pal;
-}
 
-static void
-acornfb_palette_decode(u_int regno, u_int *red, u_int *green, u_int *blue,
-		       u_int *trans)
-{
-	*red   = EXTEND4(current_par.palette[regno].vidc.red);
-	*green = EXTEND4(current_par.palette[regno].vidc.green);
-	*blue  = EXTEND4(current_par.palette[regno].vidc.blue);
-	*trans = current_par.palette[regno].vidc.trans ? -1 : 0;
+	current_par.palette[regno] = pal;
+
+	vidc_writel(pal.p);
+
+	return 0;
 }
 #endif
 
@@ -513,34 +479,66 @@
 #endif
 }
 
-static inline void
-acornfb_palette_write(u_int regno, union palette pal)
-{
-	vidc_writel(0x10000000 | regno);
-	vidc_writel(pal.p);
-}
-
-static inline union palette
-acornfb_palette_encode(u_int regno, u_int red, u_int green, u_int blue,
-		       u_int trans)
+/*
+ * We have to take note of the VIDC20's 16-bit palette here.
+ * The VIDC20 looks up a 16 bit pixel as follows:
+ *
+ *   bits   111111
+ *          5432109876543210
+ *   red            ++++++++  (8 bits,  7 to 0)
+ *  green       ++++++++      (8 bits, 11 to 4)
+ *   blue   ++++++++          (8 bits, 15 to 8)
+ *
+ * We use a pixel which looks like:
+ *
+ *   bits   111111
+ *          5432109876543210
+ *   red               +++++  (5 bits,  4 to  0)
+ *  green         +++++       (5 bits,  9 to  5)
+ *   blue    +++++            (5 bits, 14 to 10)
+ */
+static int
+acornfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+		  u_int trans, struct fb_info *info)
 {
 	union palette pal;
+	int bpp = info->var.bits_per_pixel;
+
+	if (regno >= current_par.palette_size)
+		return 1;
 
 	pal.p = 0;
 	pal.vidc20.red   = red >> 8;
 	pal.vidc20.green = green >> 8;
 	pal.vidc20.blue  = blue >> 8;
-	return pal;
-}
 
-static void
-acornfb_palette_decode(u_int regno, u_int *red, u_int *green, u_int *blue,
-		       u_int *trans)
-{
-	*red   = EXTEND8(current_par.palette[regno].vidc20.red);
-	*green = EXTEND8(current_par.palette[regno].vidc20.green);
-	*blue  = EXTEND8(current_par.palette[regno].vidc20.blue);
-	*trans = EXTEND4(current_par.palette[regno].vidc20.ext);
+	current_par.palette[regno] = pal;
+
+	if (bpp == 32 && regno < 16) {
+		current_par.cmap.cfb32[regno] =
+				regno | regno << 8 | regno << 16;
+	}
+	if (bpp == 16 && regno < 16) {
+		int i;
+
+		current_par.cmap.cfb16[regno] =
+				regno | regno << 5 | regno << 10;
+
+		pal.p = 0;
+		vidc_writel(0x10000000);
+		for (i = 0; i < 256; i += 1) {
+			pal.vidc20.red   = current_par.palette[ i       & 31].vidc20.red;
+			pal.vidc20.green = current_par.palette[(i >> 1) & 31].vidc20.green;
+			pal.vidc20.blue  = current_par.palette[(i >> 2) & 31].vidc20.blue;
+			vidc_writel(pal.p);
+			/* Palette register pointer auto-increments */
+		}
+	} else {
+		vidc_writel(0x10000000 | regno);
+		vidc_writel(pal.p);
+	}
+
+	return 0;
 }
 #endif
 
@@ -549,12 +547,9 @@
  * the resolution to fit the rules.
  */
 static int
-acornfb_adjust_timing(struct fb_info *info, struct fb_var_screeninfo *var, int con)
+acornfb_adjust_timing(struct fb_info *info, struct fb_var_screeninfo *var, u_int fontht)
 {
-	u_int font_line_len;
-	u_int fontht;
-	u_int sam_size, min_size, size;
-	u_int nr_y;
+	u_int font_line_len, sam_size, min_size, size, nr_y;
 
 	/* xres must be even */
 	var->xres = (var->xres + 1) & ~1;
@@ -565,17 +560,6 @@
 	var->xres_virtual = var->xres;
 	var->xoffset = 0;
 
-	/*
-	 * Find the font height
-	 */
-	if (con == -1)
-		fontht = fontheight(&global_disp);
-	else
-		fontht = fontheight(fb_display + con);
-
-	if (fontht == 0)
-		fontht = 8;
-
 	if (current_par.using_vram)
 		sam_size = current_par.vram_half_sam * 2;
 	else
@@ -693,8 +677,8 @@
 static inline void
 acornfb_update_dma(struct fb_info *info, struct fb_var_screeninfo *var)
 {
-	int off = (var->yoffset * var->xres_virtual *
-		   var->bits_per_pixel) >> 3;
+	u_int off = (var->yoffset * var->xres_virtual *
+		     var->bits_per_pixel) >> 3;
 
 #if defined(HAS_MEMC)
 	memc_write(VDMA_INIT, off >> 2);
@@ -704,130 +688,27 @@
 }
 
 static int
-acornfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-		  u_int *trans, struct fb_info *info)
-{
-	if (regno >= current_par.palette_size)
-		return 1;
-
-	acornfb_palette_decode(regno, red, green, blue, trans);
-
-	return 0;
-}
-
-/*
- * We have to take note of the VIDC20's 16-bit palette here.
- * The VIDC20 looks up a 16 bit pixel as follows:
- *
- *   bits   111111
- *          5432109876543210
- *   red            ++++++++  (8 bits,  7 to 0)
- *  green       ++++++++      (8 bits, 11 to 4)
- *   blue   ++++++++          (8 bits, 15 to 8)
- *
- * We use a pixel which looks like:
- *
- *   bits   111111
- *          5432109876543210
- *   red               +++++  (5 bits,  4 to  0)
- *  green         +++++       (5 bits,  9 to  5)
- *   blue    +++++            (5 bits, 14 to 10)
- */
-static int
-acornfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-		  u_int trans, struct fb_info *info)
-{
-	union palette pal;
-	int bpp = fb_display[info->currcon].var.bits_per_pixel;
-
-	if (regno >= current_par.palette_size)
-		return 1;
-
-	pal = acornfb_palette_encode(regno, red, green, blue, trans);
-	current_par.palette[regno] = pal;
-
-#ifdef FBCON_HAS_CFB32
-	if (bpp == 32 && regno < 16) {
-		current_par.cmap.cfb32[regno] =
-				regno | regno << 8 | regno << 16;
-	}
-#endif
-#ifdef FBCON_HAS_CFB16
-	if (bpp == 16 && regno < 16) {
-		int i;
-
-		current_par.cmap.cfb16[regno] =
-				regno | regno << 5 | regno << 10;
-
-		pal.p = 0;
-		vidc_writel(0x10000000);
-		for (i = 0; i < 256; i += 1) {
-			pal.vidc20.red   = current_par.palette[ i       & 31].vidc20.red;
-			pal.vidc20.green = current_par.palette[(i >> 1) & 31].vidc20.green;
-			pal.vidc20.blue  = current_par.palette[(i >> 2) & 31].vidc20.blue;
-			vidc_writel(pal.p);
-			/* Palette register pointer auto-increments */
-		}
-	} else
-#endif
-		acornfb_palette_write(regno, pal);
-
-	return 0;
-}
-
-static int
-acornfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-		 struct fb_info *info)
-{
-	int err = 0;
-
-	if (con == info->currcon)
-		err = fb_get_cmap(cmap, kspc, acornfb_getcolreg, info);
-	else if (fb_display[con].cmap.len)
-		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-	else
-		fb_copy_cmap(fb_default_cmap(current_par.palette_size),
-			     cmap, kspc ? 0 : 2);
-	return err;
-}
-
-static int
-acornfb_decode_var(struct fb_info *info, struct fb_var_screeninfo *var, int con)
+acornfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
+	u_int fontht;
 	int err;
 
-#if defined(HAS_VIDC20)
-	var->red.offset    = 0;
-	var->red.length    = 8;
-	var->green         = var->red;
-	var->blue          = var->red;
-	var->transp.offset = 0;
-	var->transp.length = 4;
-#elif defined(HAS_VIDC)
-	var->red.length	   = 4;
-	var->green         = var->red;
-	var->blue          = var->red;
-	var->transp.length = 1;
-#endif
+	/*
+	 * FIXME: Find the font height
+	 */
+	fontht = 8;
 
 	switch (var->bits_per_pixel) {
-#ifdef FBCON_HAS_MFB
-	case 1:
-		break;
-#endif
-#ifdef FBCON_HAS_CFB2
-	case 2:
-		break;
-#endif
-#ifdef FBCON_HAS_CFB4
-	case 4:
-		break;
-#endif
-#ifdef FBCON_HAS_CFB8
-	case 8:
+	case 1:	case 2:	case 4:	case 8:
+		var->red.offset    = 0;
+		var->red.length    = var->bits_per_pixel;
+		var->green         = var->red;
+		var->blue          = var->red;
+		var->transp.offset = 0;
+		var->transp.length = 0;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB16
+
+#ifdef HAS_VIDC20
 	case 16:
 		var->red.offset    = 0;
 		var->red.length    = 5;
@@ -838,8 +719,7 @@
 		var->transp.offset = 15;
 		var->transp.length = 1;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB32
+
 	case 32:
 		var->red.offset    = 0;
 		var->red.length    = 8;
@@ -865,7 +745,7 @@
 	 * Validate and adjust the resolution to
 	 * match the video generator hardware.
 	 */
-	err = acornfb_adjust_timing(info, var, con);
+	err = acornfb_adjust_timing(info, var, fontht);
 	if (err)
 		return err;
 
@@ -873,137 +753,61 @@
 	 * Validate the timing against the
 	 * monitor hardware.
 	 */
-	return acornfb_validate_timing(var, &fb_info.monspecs);
+	return acornfb_validate_timing(var, &info->monspecs);
 }
 
-static int
-acornfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+static int acornfb_set_par(struct fb_info *info)
 {
-	struct display *display;
-	unsigned int visual, chgvar = 0;
-	int err;
-
-	if (con >= 0)
-		display = fb_display + con;
-	else
-		display = &global_disp;
-
-	err = acornfb_decode_var(info, var, con);
-	if (err)
-		return err;
-
-	switch (var->activate & FB_ACTIVATE_MASK) {
-	case FB_ACTIVATE_TEST:
-		return 0;
-
-	case FB_ACTIVATE_NXTOPEN:
-	case FB_ACTIVATE_NOW:
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	if (con >= 0) {
-		if (display->var.xres != var->xres)
-			chgvar = 1;
-		if (display->var.yres != var->yres)
-			chgvar = 1;
-		if (display->var.xres_virtual != var->xres_virtual)
-			chgvar = 1;
-		if (display->var.yres_virtual != var->yres_virtual)
-			chgvar = 1;
-		if (memcmp(&display->var.red, &var->red, sizeof(var->red)))
-			chgvar = 1;
-		if (memcmp(&display->var.green, &var->green, sizeof(var->green)))
-			chgvar = 1;
-		if (memcmp(&display->var.blue, &var->blue, sizeof(var->blue)))
-			chgvar = 1;
-	}
-
-	display->var = *var;
-	display->var.activate &= ~FB_ACTIVATE_ALL;
-
-	if (var->activate & FB_ACTIVATE_ALL)
-		global_disp.var = display->var;
-
-	switch (display->var.bits_per_pixel) {
-#ifdef FBCON_HAS_MFB
+	switch (info->var.bits_per_pixel) {
 	case 1:
 		current_par.palette_size = 2;
-		display->dispsw = &fbcon_mfb;
-		visual = FB_VISUAL_MONO10;
+		info->fix.visual = FB_VISUAL_MONO10;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB2
 	case 2:
 		current_par.palette_size = 4;
-		display->dispsw = &fbcon_cfb2;
-		visual = FB_VISUAL_PSEUDOCOLOR;
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB4
 	case 4:
 		current_par.palette_size = 16;
-		display->dispsw = &fbcon_cfb4;
-		visual = FB_VISUAL_PSEUDOCOLOR;
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB8
 	case 8:
 		current_par.palette_size = VIDC_PALETTE_SIZE;
-		display->dispsw = &fbcon_cfb8;
 #ifdef HAS_VIDC
-		visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
+		info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
 #else
-		visual = FB_VISUAL_PSEUDOCOLOR;
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
 #endif
 		break;
-#endif
-#ifdef FBCON_HAS_CFB16
+#ifdef HAS_VIDC20
 	case 16:
 		current_par.palette_size = 32;
-		display->dispsw = &fbcon_cfb16;
-		display->dispsw_data = current_par.cmap.cfb16;
-		visual = FB_VISUAL_DIRECTCOLOR;
+		info->pseudo_palette = current_par.cmap.cfb16;
+		info->fix.visual = FB_VISUAL_DIRECTCOLOR;
 		break;
-#endif
-#ifdef FBCON_HAS_CFB32
 	case 32:
 		current_par.palette_size = VIDC_PALETTE_SIZE;
-		display->dispsw = &fbcon_cfb32;
-		display->dispsw_data = current_par.cmap.cfb32;
-		visual = FB_VISUAL_TRUECOLOR;
+		info->pseudo_palette = current_par.cmap.cfb32;
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
 		break;
 #endif
 	default:
-		display->dispsw = &fbcon_dummy;
-		visual = FB_VISUAL_MONO10;
-		break;
+		BUG();
 	}
 
-	display->next_line      = (var->xres * var->bits_per_pixel) / 8;
-	display->can_soft_blank	= visual == FB_VISUAL_PSEUDOCOLOR ? 1 : 0;
-	display->inverse	= 0;
-
-	if (chgvar && info && info->changevar)
-		info->changevar(con);
-
-	if (con == info->currcon) {
-		struct fb_cmap *cmap;
-		unsigned long start, size;
-		int control;
-
-		info->fix.visual = visual;
+	info->fix.line_length	= (info->var.xres * info->var.bits_per_pixel) / 8;
 
 #if defined(HAS_MEMC)
-		start   = 0;
-		size    = info->fix.smem_len - VDMA_XFERSIZE;
-		control = 0;
+	{
+		unsigned long size = info->fix.smem_len - VDMA_XFERSIZE;
 
-		memc_write(VDMA_START, start);
+		memc_write(VDMA_START, 0);
 		memc_write(VDMA_END, size >> 2);
+	}
 #elif defined(HAS_IOMD)
+	{
+		unsigned long start, size;
+		u_int control;
 
 		start = info->fix.smem_start;
 		size  = current_par.screen_end;
@@ -1019,80 +823,27 @@
 		iomd_writel(start,   IOMD_VIDSTART);
 		iomd_writel(size,    IOMD_VIDEND);
 		iomd_writel(control, IOMD_VIDCR);
+	}
 #endif
-		acornfb_update_dma(info, var);
-		acornfb_set_timing(info, var);
 
-		if (display->cmap.len)
-			cmap = &display->cmap;
-		else
-			cmap = fb_default_cmap(current_par.palette_size);
+	acornfb_update_dma(info, &info->var);
+	acornfb_set_timing(info, &info->var);
 
-		fb_set_cmap(cmap, 1, info);
-	}
 	return 0;
 }
 
 static int
-acornfb_pan_display(struct fb_var_screeninfo *var, int con,
-		    struct fb_info *info)
+acornfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	u_int y_bottom;
-
-	if (var->xoffset)
-		return -EINVAL;
-
-	y_bottom = var->yoffset;
+	u_int y_bottom = var->yoffset;
 
 	if (!(var->vmode & FB_VMODE_YWRAP))
 		y_bottom += var->yres;
 
-	if (y_bottom > fb_display[con].var.yres_virtual)
-		return -EINVAL;
+	BUG_ON(y_bottom > var->yres_virtual);
 
 	acornfb_update_dma(info, var);
 
-	fb_display[con].var.yoffset = var->yoffset;
-	if (var->vmode & FB_VMODE_YWRAP)
-		fb_display[con].var.vmode |= FB_VMODE_YWRAP;
-	else
-		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
-
-	return 0;
-}
-
-static int 
-acornfb_blank(int blank, struct fb_info *info)
-{
-	union palette p;
-	int i, bpp = fb_display[info->currcon].var.bits_per_pixel;
-
-#ifdef FBCON_HAS_CFB16
-	if (bpp == 16) {
-		p.p = 0;
-
-		for (i = 0; i < 256; i++) {
-			if (blank)
-				p = acornfb_palette_encode(i, 0, 0, 0, 0);
-			else {
-				p.vidc20.red   = current_par.palette[ i       & 31].vidc20.red;
-				p.vidc20.green = current_par.palette[(i >> 1) & 31].vidc20.green;
-				p.vidc20.blue  = current_par.palette[(i >> 2) & 31].vidc20.blue;
-			}
-			acornfb_palette_write(i, current_par.palette[i]);
-		}
-	} else
-#endif
-	{
-		for (i = 0; i < current_par.palette_size; i++) {
-			if (blank)
-				p = acornfb_palette_encode(i, 0, 0, 0, 0);
-			else
-				p = current_par.palette[i];
-
-			acornfb_palette_write(i, p);
-		}
-	}
 	return 0;
 }
 
@@ -1137,45 +888,16 @@
 
 static struct fb_ops acornfb_ops = {
 	.owner		= THIS_MODULE,
-	.fb_set_var	= acornfb_set_var,
-	.fb_get_cmap	= acornfb_get_cmap,
-	.fb_set_cmap	= gen_set_cmap,
+	.fb_check_var	= acornfb_check_var,
+	.fb_set_par	= acornfb_set_par,
 	.fb_setcolreg	= acornfb_setcolreg,
 	.fb_pan_display	= acornfb_pan_display,
-	.fb_blank	= acornfb_blank,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
 	.fb_mmap	= acornfb_mmap,
 };
 
-static int
-acornfb_updatevar(int con, struct fb_info *info)
-{
-	if (con == info->currcon)
-		acornfb_update_dma(info, &fb_display[con].var);
-
-	return 0;
-}
-
-static int
-acornfb_switch(int con, struct fb_info *info)
-{
-	struct fb_cmap *cmap;
-
-	if (info->currcon >= 0) {
-		cmap = &fb_display[info->currcon].cmap;
-
-		if (cmap->len)
-			fb_get_cmap(cmap, 1, acornfb_getcolreg, info);
-	}
-
-	info->currcon = con;
-
-	fb_display[con].var.activate = FB_ACTIVATE_NOW;
-
-	acornfb_set_var(&fb_display[con].var, con, info);
-
-	return 0;
-}
-
 /*
  * Everything after here is initialisation!!!
  */
@@ -1248,8 +970,7 @@
 	.vmode =	FB_VMODE_NONINTERLACED
 };
 
-static void __init
-acornfb_init_fbinfo(void)
+static void __init acornfb_init_fbinfo(void)
 {
 	static int first = 1;
 
@@ -1257,15 +978,8 @@
 		return;
 	first = 0;
 
-	strcpy(fb_info.modename, "Acorn");
-	strcpy(fb_info.fontname, "Acorn8x8");
-
 	fb_info.node		= NODEV;
 	fb_info.fbops		= &acornfb_ops;
-	fb_info.disp		= &global_disp;
-	fb_info.changevar	= NULL;
-	fb_info.switch_con	= acornfb_switch;
-	fb_info.updatevar	= acornfb_updatevar;
 	fb_info.flags		= FBINFO_FLAG_DEFAULT;
 
 	strcpy(fb_info.fix.id, "Acorn");
@@ -1277,28 +991,26 @@
 	fb_info.fix.line_length	= 0;
 	fb_info.fix.accel	= FB_ACCEL_NONE;
 
-	global_disp.dispsw	= &fbcon_dummy;
-
 	/*
 	 * setup initial parameters
 	 */
-	memset(&init_var, 0, sizeof(init_var));
+	memset(&fb_info.var, 0, sizeof(fb_info.var));
 
 #if defined(HAS_VIDC20)
-	init_var.red.length	   = 8;
-	init_var.transp.length	   = 4;
+	fb_info.var.red.length	   = 8;
+	fb_info.var.transp.length  = 4;
 #elif defined(HAS_VIDC)
-	init_var.red.length	   = 4;
-	init_var.transp.length	   = 1;
+	fb_info.var.red.length	   = 4;
+	fb_info.var.transp.length  = 1;
 #endif
-	init_var.green		   = init_var.red;
-	init_var.blue		   = init_var.red;
-	init_var.nonstd		   = 0;
-	init_var.activate	   = FB_ACTIVATE_NOW;
-	init_var.height		   = -1;
-	init_var.width		   = -1;
-	init_var.vmode		   = FB_VMODE_NONINTERLACED;
-	init_var.accel_flags	   = FB_ACCELF_TEXT;
+	fb_info.var.green	   = fb_info.var.red;
+	fb_info.var.blue	   = fb_info.var.red;
+	fb_info.var.nonstd	   = 0;
+	fb_info.var.activate	   = FB_ACTIVATE_NOW;
+	fb_info.var.height	   = -1;
+	fb_info.var.width	   = -1;
+	fb_info.var.vmode	   = FB_VMODE_NONINTERLACED;
+	fb_info.var.accel_flags	   = FB_ACCELF_TEXT;
 
 	current_par.dram_size	   = 0;
 	current_par.montype	   = -1;
@@ -1308,9 +1020,6 @@
 /*
  * setup acornfb options:
  *
- *  font:fontname
- *	Set fontname
- *
  *  mon:hmin-hmax:vmin-vmax:dpms:width:height
  *	Set monitor parameters:
  *		hmin   = horizontal minimum frequency (Hz)
@@ -1338,12 +1047,6 @@
  *	MB or KB respectively.
  */
 static void __init
-acornfb_parse_font(char *opt)
-{
-	strcpy(fb_info.fontname, opt);
-}
-
-static void __init
 acornfb_parse_mon(char *opt)
 {
 	char *p = opt;
@@ -1373,12 +1076,12 @@
 	if (*p != ':')
 		goto check_values;
 
-	init_var.width = simple_strtoul(p + 1, &p, 0);
+	fb_info.var.width = simple_strtoul(p + 1, &p, 0);
 
 	if (*p != ':')
 		goto check_values;
 
-	init_var.height = simple_strtoul(p + 1, NULL, 0);
+	fb_info.var.height = simple_strtoul(p + 1, NULL, 0);
 
 check_values:
 	if (fb_info.monspecs.hfmax < fb_info.monspecs.hfmin ||
@@ -1460,7 +1163,6 @@
 	char *name;
 	void (*parse)(char *opt);
 } opt_table[] __initdata = {
-	{ "font",    acornfb_parse_font    },
 	{ "mon",     acornfb_parse_mon     },
 	{ "montype", acornfb_parse_montype },
 	{ "dram",    acornfb_parse_dram    },
@@ -1658,7 +1360,7 @@
 	 * the resolution, so we disable this feature.
 	 */
 	do {
-		rc = fb_find_mode(&init_var, &fb_info, NULL, modedb,
+		rc = fb_find_mode(&fb_info.var, &fb_info, NULL, modedb,
 				 sizeof(modedb) / sizeof(*modedb),
 				 &acornfb_default_mode, DEFAULT_BPP);
 		/*
@@ -1667,7 +1369,7 @@
 		if (rc == 1)
 			break;
 
-		rc = fb_find_mode(&init_var, &fb_info, NULL, NULL, 0,
+		rc = fb_find_mode(&fb_info.var, &fb_info, NULL, NULL, 0,
 				  &acornfb_default_mode, DEFAULT_BPP);
 		/*
 		 * If we found an exact match, all ok.
@@ -1675,13 +1377,13 @@
 		if (rc == 1)
 			break;
 
-		rc = fb_find_mode(&init_var, &fb_info, NULL, modedb,
+		rc = fb_find_mode(&fb_info.var, &fb_info, NULL, modedb,
 				 sizeof(modedb) / sizeof(*modedb),
 				 &acornfb_default_mode, DEFAULT_BPP);
 		if (rc)
 			break;
 
-		rc = fb_find_mode(&init_var, &fb_info, NULL, NULL, 0,
+		rc = fb_find_mode(&fb_info.var, &fb_info, NULL, NULL, 0,
 				  &acornfb_default_mode, DEFAULT_BPP);
 	} while (0);
 
@@ -1694,17 +1396,17 @@
 		return -EINVAL;
 	}
 
-	h_sync = 1953125000 / init_var.pixclock;
-	h_sync = h_sync * 512 / (init_var.xres + init_var.left_margin +
-		 init_var.right_margin + init_var.hsync_len);
-	v_sync = h_sync / (init_var.yres + init_var.upper_margin +
-		 init_var.lower_margin + init_var.vsync_len);
+	h_sync = 1953125000 / fb_info.var.pixclock;
+	h_sync = h_sync * 512 / (fb_info.var.xres + fb_info.var.left_margin +
+		 fb_info.var.right_margin + fb_info.var.hsync_len);
+	v_sync = h_sync / (fb_info.var.yres + fb_info.var.upper_margin +
+		 fb_info.var.lower_margin + fb_info.var.vsync_len);
 
 	printk(KERN_INFO "Acornfb: %dkB %cRAM, %s, using %dx%d, "
 		"%d.%03dkHz, %dHz\n",
 		fb_info.fix.smem_len / 1024,
 		current_par.using_vram ? 'V' : 'D',
-		VIDC_NAME, init_var.xres, init_var.yres,
+		VIDC_NAME, fb_info.var.xres, fb_info.var.yres,
 		h_sync / 1000, h_sync % 1000, v_sync);
 
 	printk(KERN_INFO "Acornfb: Monitor: %d.%03d-%d.%03dkHz, %d-%dHz%s\n",
@@ -1713,7 +1415,7 @@
 		fb_info.monspecs.vfmin, fb_info.monspecs.vfmax,
 		fb_info.monspecs.dpms ? ", DPMS" : "");
 
-	if (acornfb_set_var(&init_var, -1, &fb_info))
+	if (fb_set_var(&fb_info.var, &fb_info))
 		printk(KERN_ERR "Acornfb: unable to set display parameters\n");
 
 	if (register_framebuffer(&fb_info) < 0)
diff -Nru a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
--- a/drivers/video/aty/atyfb.h	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/aty/atyfb.h	Thu Jan 16 18:23:06 2003
@@ -79,6 +79,7 @@
 	u8 ram_type;
 	u8 mem_refresh_rate;
 	u8 blitter_may_be_busy;
+	u32 accel_flags;
 #ifdef __sparc__
 	struct pci_mmap_map *mmap_map;
 	u8 mmaped;
diff -Nru a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
--- a/drivers/video/aty/atyfb_base.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/aty/atyfb_base.c	Thu Jan 16 18:23:06 2003
@@ -173,9 +173,6 @@
 			   struct crtc *crtc);
 static int aty_crtc_to_var(const struct crtc *crtc,
 			   struct fb_var_screeninfo *var);
-static int atyfb_encode_var(struct fb_var_screeninfo *var,
-			    const struct atyfb_par *par,
-			    const struct fb_info *info);
 static void set_off_pitch(struct atyfb_par *par,
 			  const struct fb_info *info);
 #ifdef CONFIG_PPC
@@ -772,11 +769,17 @@
 static int atyfb_set_par(struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	int accelmode;
+	struct fb_var_screeninfo *var = &info->var;
 	u8 tmp;
 	u32 i;
+	int err;
 
-	accelmode = info->var.accel_flags;	/* hack */
+	if ((err = aty_var_to_crtc(info, var, &par->crtc)) ||
+	    (err = par->pll_ops->var_to_pll(info, var->pixclock,
+					var->bits_per_pixel, &par->pll)))
+		return err;
+
+	par->accel_flags = var->accel_flags;	/* hack */
 
 	if (par->blitter_may_be_busy)
 		wait_for_idle(par);
@@ -786,13 +789,14 @@
 	/* better call aty_StrobeClock ?? */
 	aty_st_8(CLOCK_CNTL + par->clk_wr_offset, CLOCK_STROBE, par);
 
-	par->dac_ops->set_dac(info, &par->pll, info->var.bits_per_pixel, accelmode);
+	par->dac_ops->set_dac(info, &par->pll, var->bits_per_pixel,
+			      par->accel_flags);
 	par->pll_ops->set_pll(info, &par->pll);
 
 	if (!M64_HAS(INTEGRATED)) {
 		/* Don't forget MEM_CNTL */
 		i = aty_ld_le32(MEM_CNTL, par) & 0xf0ffffff;
-		switch (info->var.bits_per_pixel) {
+		switch (var->bits_per_pixel) {
 		case 8:
 			i |= 0x02000000;
 			break;
@@ -808,7 +812,7 @@
 		i = aty_ld_le32(MEM_CNTL, par) & 0xf00fffff;
 		if (!M64_HAS(MAGIC_POSTDIV))
 			i |= par->mem_refresh_rate << 20;
-		switch (info->var.bits_per_pixel) {
+		switch (var->bits_per_pixel) {
 		case 8:
 		case 24:
 			i |= 0x00000000;
@@ -841,20 +845,20 @@
 	}
 	aty_st_8(DAC_MASK, 0xff, par);
 
-	info->fix.line_length = info->var.xres_virtual * info->var.bits_per_pixel/8;
-	info->fix.visual = info->var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+	info->fix.line_length = var->xres_virtual * var->bits_per_pixel/8;
+	info->fix.visual = var->bits_per_pixel <= 8 ?
+		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
 
 	/* Initialize the graphics engine */
-	if (info->var.accel_flags & FB_ACCELF_TEXT)
+	if (par->accel_flags & FB_ACCELF_TEXT)
 		aty_init_engine(par, info);
 
 #ifdef CONFIG_BOOTX_TEXT
 	btext_update_display(info->fix.smem_start,
-			     (((par->crtc.h_tot_disp >> 16) & 0xff) +
-			      1) * 8,
+			     (((par->crtc.h_tot_disp >> 16) & 0xff) + 1) * 8,
 			     ((par->crtc.v_tot_disp >> 16) & 0x7ff) + 1,
-			     info->var.bits_per_pixel,
-			     par->crtc.vxres * info->var.bits_per_pixel / 8);
+			     var->bits_per_pixel,
+			     par->crtc.vxres * var->bits_per_pixel / 8);
 #endif				/* CONFIG_BOOTX_TEXT */
 	return 0;
 }
@@ -863,41 +867,24 @@
 			   struct fb_info *info)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
+	struct crtc crtc;
+	union aty_pll pll;
 	int err;
 
-	if ((err = aty_var_to_crtc(info, var, &par->crtc)) ||
-	    (err =
-	     par->pll_ops->var_to_pll(info, var->pixclock, var->bits_per_pixel,
-				       &par->pll)))
+	if ((err = aty_var_to_crtc(info, var, &crtc)) ||
+	    (err = par->pll_ops->var_to_pll(info, var->pixclock,
+					var->bits_per_pixel, &pll)))
 		return err;
 
-#if 0				/* fbmon is not done. uncomment for 2.5.x -brad */
+#if 0	/* fbmon is not done. uncomment for 2.5.x -brad */
 	if (!fbmon_valid_timings(var->pixclock, htotal, vtotal, info))
 		return -EINVAL;
 #endif
-	atyfb_encode_var(var, par, info);
-	return 0;
-}
-
-static int atyfb_encode_var(struct fb_var_screeninfo *var,
-			    const struct atyfb_par *par,
-			    const struct fb_info *info)
-{
-	int err;
-
-	memset(var, 0, sizeof(struct fb_var_screeninfo));
-
-	if ((err = aty_crtc_to_var(&par->crtc, var)))
-		return err;
-	var->pixclock = par->pll_ops->pll_to_var(info, &par->pll);
-
-	var->height = -1;
-	var->width = -1;
+	aty_crtc_to_var(&crtc, var);
+	var->pixclock = par->pll_ops->pll_to_var(info, &pll);
 	return 0;
 }
 
-
-
 static void set_off_pitch(struct atyfb_par *par,
 			  const struct fb_info *info)
 {
@@ -976,7 +963,6 @@
 						var.yres_virtual =
 						    var.yres;
 				}
-				fb_set_var(&var, -1, info);
 			}
 		}
 	} 
@@ -1410,7 +1396,7 @@
 	for (info = first_display; info != NULL; info = par->next) {
 		int nb;
 
-		par = (struct atyfb_par *) info->fb.par;
+		par = (struct atyfb_par *) info->par;
 		nb = info->var.yres * info->fix.line_length;
 
 		switch (when) {
@@ -1429,7 +1415,7 @@
 			if (par->blitter_may_be_busy)
 				wait_for_idle(par);
 			/* Stop accel engine (stop bus mastering) */
-			if (info->accel_flags & FB_ACCELF_TEXT)
+			if (par->accel_flags & FB_ACCELF_TEXT)
 				aty_reset_engine(par);
 
 			/* Backup fb content */
@@ -2306,9 +2292,7 @@
 
 #ifdef CONFIG_PMAC_PBOOK
 			if (first_display == NULL)
-				pmu_register_sleep_notifier
-				    (&aty_sleep_notifier);
-			/* FIXME info->next = first_display; */
+				pmu_register_sleep_notifier(&aty_sleep_notifier);
 			default_par->next = first_display;
 #endif
 		}
@@ -2346,7 +2330,7 @@
 		info->fix.smem_start = info->screen_base;	/* Fake! */
 		default_par->ati_regbase = (unsigned long)ioremap(phys_guiregbase[m64_num],
 							  0x10000) + 0xFC00ul;
-		info->fix.mmio_start = par->ati_regbase; /* Fake! */
+		info->fix.mmio_start = default_par->ati_regbase; /* Fake! */
 
 		aty_st_le32(CLOCK_CNTL, 0x12345678, default_par);
 		clock_r = aty_ld_le32(CLOCK_CNTL, default_par);
@@ -2544,6 +2528,7 @@
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
 	int i, scale;
+	u32 *pal = info->pseudo_palette;
 
 	if (regno > 255)
 		return 1;
@@ -2570,17 +2555,14 @@
 	if (regno < 16)
 		switch (info->var.bits_per_pixel) {
 		case 16:
-			((u16 *) (info->pseudo_palette))[regno] =
-			    (regno << 10) | (regno << 5) | regno;
+			pal[regno] = (regno << 10) | (regno << 5) | regno;
 			break;
 		case 24:
-			((u32 *) (info->pseudo_palette))[regno] =
-			    (regno << 16) | (regno << 8) | regno;
+			pal[regno] = (regno << 16) | (regno << 8) | regno;
 			break;
 		case 32:
 			i = (regno << 8) | regno;
-			((u32 *) (info->pseudo_palette))[regno] =
-			    (i << 16) | i;
+			pal[regno] = (i << 16) | i;
 			break;
 		}
 	return 0;
@@ -2605,8 +2587,8 @@
 	if (info->screen_base)
 		iounmap((void *) info->screen_base);
 #ifdef __BIG_ENDIAN
-	if (info->cursor && info->cursor->ram)
-		iounmap(info->cursor->ram);
+	if (info->cursor && par->cursor->ram)
+		iounmap(par->cursor->ram);
 #endif
 #endif
 	if (info->cursor)
diff -Nru a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
--- a/drivers/video/aty/mach64_accel.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/aty/mach64_accel.c	Thu Jan 16 18:23:05 2003
@@ -179,6 +179,12 @@
 
 	if (!area->width || !area->height)
 		return;
+	if (!par->accel_flags) {
+		if (par->blitter_may_be_busy)
+			wait_for_idle(par);
+		cfb_copyarea(info, area);
+		return;
+	}
 
 	pitch_value = info->var.xres_virtual;
 	if (info->var.bits_per_pixel == 24) {
@@ -216,6 +222,12 @@
 
 	if (!rect->width || !rect->height)
 		return;
+	if (!par->accel_flags) {
+		if (par->blitter_may_be_busy)
+			wait_for_idle(par);
+		cfb_fillrect(info, rect);
+		return;
+	}
 
 	rect->color |= (rect->color << 8);
 	rect->color |= (rect->color << 16);
diff -Nru a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
--- a/drivers/video/cfbcopyarea.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/cfbcopyarea.c	Thu Jan 16 18:23:06 2003
@@ -65,13 +65,15 @@
 			// Single word
 			if (last)
 				first &= last;
-			FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+			FB_WRITEL((*src & first) | (FB_READL(dst) & ~first),
+				  dst);
 		} else {
 			// Multiple destination words
 			// Leading bits
 			if (first) {
 				
-				FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL((*src & first) | (FB_READL(dst) & 
+							    ~first), dst);
 				dst++;
 				src++;
 				n -= BITS_PER_LONG-dst_idx;
@@ -94,7 +96,8 @@
 				FB_WRITEL(*src++, dst++);
 			// Trailing bits
 			if (last)
-				FB_WRITEL((*src & last) | (FB_READL(dst) & ~last), dst);
+				FB_WRITEL((*src & last) | (FB_READL(dst) & 
+							   ~last), dst);
 		}
 	} else {
 		// Different alignment for source and dest
@@ -108,15 +111,18 @@
 				first &= last;
 			if (shift > 0) {
 				// Single source word
-				FB_WRITEL(((*src >> right) & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL(((*src >> right) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 			} else if (src_idx+n <= BITS_PER_LONG) {
 				// Single source word
-				FB_WRITEL(((*src << left) & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL(((*src << left) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 			} else {
 				// 2 source words
 				d0 = *src++;
 				d1 = *src;
-				FB_WRITEL(((d0 << left | d1 >> right) & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL(((d0<<left | d1>>right) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 			}
 		} else {
 			// Multiple destination words
@@ -124,13 +130,15 @@
 			// Leading bits
 			if (shift > 0) {
 				// Single source word
-				FB_WRITEL(((d0 >> right) & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL(((d0 >> right) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 				dst++;
 				n -= BITS_PER_LONG-dst_idx;
 			} else {
 				// 2 source words
 				d1 = *src++;
-				FB_WRITEL(((d0 << left | d1 >> right) & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL(((d0<<left | d1>>right) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 				d0 = d1;
 				dst++;
 				n -= BITS_PER_LONG-dst_idx;
@@ -164,11 +172,15 @@
 			if (last) {
 				if (m <= right) {
 					// Single source word
-					FB_WRITEL(((d0 << left) & last) | (FB_READL(dst) & ~last), dst);
+					FB_WRITEL(((d0 << left) & last) | 
+						  (FB_READL(dst) & ~last), 
+						  dst);
 				} else {
 					// 2 source words
 					d1 = *src;
-					FB_WRITEL(((d0 << left | d1 >> right) & last) | (FB_READL(dst) & ~last), dst);
+					FB_WRITEL(((d0<<left | d1>>right) & 
+						   last) | (FB_READL(dst) & 
+							    ~last), dst);
 				}
 			}
 		}
@@ -208,12 +220,14 @@
 			// Single word
 			if (last)
 				first &= last;
-			FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+			FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), 
+				  dst);
 		} else {
 			// Multiple destination words
 			// Leading bits
 			if (first) {
-				FB_WRITEL((*src & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL((*src & first) | (FB_READL(dst) & 
+							    ~first), dst);
 				dst--;
 				src--;
 				n -= dst_idx+1;
@@ -237,7 +251,8 @@
 			
 			// Trailing bits
 			if (last)
-				FB_WRITEL((*src & last) | (FB_READL(dst) & ~last), dst);
+				FB_WRITEL((*src & last) | (FB_READL(dst) & 
+							   ~last), dst);
 		}
 	} else {
 		// Different alignment for source and dest
@@ -251,15 +266,18 @@
 				first &= last;
 			if (shift < 0) {
 				// Single source word
-				FB_WRITEL((*src << left & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL((*src << left & first) | 
+					  (FB_READL(dst) & ~first), dst);
 			} else if (1+(unsigned long)src_idx >= n) {
 				// Single source word
-				FB_WRITEL(((*src >> right) & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL(((*src >> right) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 			} else {
 				// 2 source words
 				d0 = *src--;
 				d1 = *src;
-				FB_WRITEL(((d0 >> right | d1 << left) & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL(((d0>>right | d1<<left) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 			}
 		} else {
 			// Multiple destination words
@@ -267,13 +285,15 @@
 			// Leading bits
 			if (shift < 0) {
 				// Single source word
-				FB_WRITEL(((d0 << left) & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL(((d0 << left) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 				dst--;
 				n -= dst_idx+1;
 			} else {
 				// 2 source words
 				d1 = *src--;
-				FB_WRITEL(((d0 >> right | d1 << left) & first) | (FB_READL(dst) & ~first), dst);
+				FB_WRITEL(((d0>>right | d1<<left) & first) | 
+					  (FB_READL(dst) & ~first), dst);
 				d0 = d1;
 				dst--;
 				n -= dst_idx+1;
@@ -307,12 +327,15 @@
 			if (last) {
 				if (m <= left) {
 					// Single source word
-					FB_WRITEL(((d0 >> right) & last) | (FB_READL(dst) & ~last), dst);
+					FB_WRITEL(((d0 >> right) & last) | 
+						  (FB_READL(dst) & ~last), 
+						  dst);
 				} else {
 					// 2 source words
 					d1 = *src;
-					FB_WRITEL(((d0 >> right | d1 << left) & last) |
-						  (FB_READL(dst) & ~last), dst);
+					FB_WRITEL(((d0>>right | d1<<left) & 
+						   last) | (FB_READL(dst) & 
+							    ~last), dst);
 				}
 			}
 		}
@@ -363,18 +386,22 @@
 	    (area->sx + area->width) > vxres ||
 	    (area->sy + area->height) > vyres)
 		return;
-	
-	if (area->dy > area->sy || (area->dy == area->sy && area->dx > area->sx)) {
+
+	if ((area->dy == area->sy && area->dx > area->sx) ||	
+	    (area->dy > area->sy)) { 
 		area->dy += area->height;
 		area->sy += area->height;
 		rev_copy = 1;
 	}
 
-	dst = src = (unsigned long *)((unsigned long)p->screen_base & ~(BYTES_PER_LONG-1));
+	dst = src = (unsigned long *)((unsigned long)p->screen_base & 
+				      ~(BYTES_PER_LONG-1));
 	dst_idx = src_idx = (unsigned long)p->screen_base & (BYTES_PER_LONG-1);
 	dst_idx += area->dy*next_line*8 + area->dx*p->var.bits_per_pixel;
 	src_idx += area->sy*next_line*8 + area->sx*p->var.bits_per_pixel;
 	
+	if (p->fbops->fb_sync)
+		p->fbops->fb_sync(p);
 	if (rev_copy) {
 		while (area->height--) {
 			dst_idx -= next_line*8;
@@ -383,8 +410,9 @@
 			dst_idx &= (BYTES_PER_LONG-1);
 			src += src_idx >> SHIFT_PER_LONG;
 			src_idx &= (BYTES_PER_LONG-1);
-			bitcpy_rev((unsigned long*)dst, dst_idx, (unsigned long *)src,
-					src_idx, area->width*p->var.bits_per_pixel);
+			bitcpy_rev((unsigned long*)dst, dst_idx, 
+				   (unsigned long *)src, src_idx, 
+				   area->width*p->var.bits_per_pixel);
 		}	
 	} else {
 		while (area->height--) {
@@ -392,8 +420,9 @@
 			dst_idx &= (BYTES_PER_LONG-1);
 			src += src_idx >> SHIFT_PER_LONG;
 			src_idx &= (BYTES_PER_LONG-1);
-			bitcpy((unsigned long*)dst, dst_idx, (unsigned long *)src,
-				   src_idx, area->width*p->var.bits_per_pixel);
+			bitcpy((unsigned long*)dst, dst_idx, 
+			       (unsigned long *)src, src_idx, 
+			       area->width*p->var.bits_per_pixel);
 			dst_idx += next_line*8;
 			src_idx += next_line*8;
 		}	
diff -Nru a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
--- a/drivers/video/cfbfillrect.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/cfbfillrect.c	Thu Jan 16 18:23:06 2003
@@ -99,7 +99,8 @@
      *  the correct start position
      */
 
-static inline unsigned long pixel_to_pat(const struct fb_info *p, pixel_t pixel, int left)
+static inline unsigned long pixel_to_pat(const struct fb_info *p, 
+					 pixel_t pixel, int left)
 {
     unsigned long pat = pixel;
     u32 bpp = p->var.bits_per_pixel;
@@ -373,7 +374,8 @@
 	vxres = p->var.xres_virtual;
 	vyres = p->var.yres_virtual;
 
-	if (!rect->width || !rect->height || rect->dx > vxres || rect->dy > vyres)
+	if (!rect->width || !rect->height || 
+	    rect->dx > vxres || rect->dy > vyres)
 		return;
 
 	/* We could use hardware clipping but on many cards you get around
@@ -392,14 +394,18 @@
 	else
 		fg = rect->color;
 	
-	dst = (unsigned long *)((unsigned long)p->screen_base & ~(BYTES_PER_LONG-1));
+	dst = (unsigned long *)((unsigned long)p->screen_base & 
+				~(BYTES_PER_LONG-1));
 	dst_idx = ((unsigned long)p->screen_base & (BYTES_PER_LONG-1))*8;
 	dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp;
 	/* FIXME For now we support 1-32 bpp only */
 	left = BITS_PER_LONG % bpp;
+	if (p->fbops->fb_sync)
+		p->fbops->fb_sync(p);
 	if (!left) {
 		u32 pat = pixel_to_pat32(p, fg);
-		void (*fill_op32)(unsigned long *dst, int dst_idx, u32 pat, u32 n) = NULL;
+		void (*fill_op32)(unsigned long *dst, int dst_idx, u32 pat, 
+				  u32 n) = NULL;
 		
 		switch (rect->rop) {
 		case ROP_XOR:
@@ -420,8 +426,9 @@
 		unsigned long pat = pixel_to_pat(p, fg, (left-dst_idx) % bpp);
 		int right = bpp-left;
 		int r;
-		void (*fill_op)(unsigned long *dst, int dst_idx, unsigned long pat, 
-				int left, int right, u32 n) = NULL;
+		void (*fill_op)(unsigned long *dst, int dst_idx, 
+				unsigned long pat, int left, int right, 
+				u32 n) = NULL;
 		
 		switch (rect->rop) {
 		case ROP_XOR:
@@ -435,7 +442,8 @@
 		while (height--) {
 			dst += dst_idx >> SHIFT_PER_LONG;
 			dst_idx &= (BITS_PER_LONG-1);
-			fill_op(dst, dst_idx, pat, left, right, rect->width*bpp);
+			fill_op(dst, dst_idx, pat, left, right, 
+				rect->width*bpp);
 			r = (p->fix.line_length*8) % bpp;
 			pat = pat << (bpp-r) | pat >> r;
 			dst_idx += p->fix.line_length*8;
diff -Nru a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
--- a/drivers/video/cfbimgblt.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/cfbimgblt.c	Thu Jan 16 18:23:06 2003
@@ -19,10 +19,6 @@
  *  up to the nearest byte. For example a bitmap 12 bits wide must be two 
  *  bytes width. 
  *
- *  FIXME
- *  The code for 24 bit is horrible. It copies byte by byte size instead of
- *  longs like the other sizes. Needs to be optimized.
- *  
  *  Tony: 
  *  Incorporate mask tables similar to fbcon-cfb*.c in 2.4 API.  This speeds 
  *  up the code significantly.
@@ -32,7 +28,6 @@
  *
  *  Also need to add code to deal with cards endians that are different than
  *  the native cpu endians. I also need to deal with MSB position in the word.
- *
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -98,8 +93,9 @@
 #define SHIFT_LOW(val, bits)   ((val) >> (bits))
 #endif
 
-static inline void color_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1, 
-				   unsigned long start_index, unsigned long pitch_index)
+static inline void color_imageblit(struct fb_image *image, struct fb_info *p, 
+				   u8 *dst1, unsigned long start_index,
+				   unsigned long pitch_index)
 {
 	/* Draw the penguin */
 	unsigned long *dst, *dst2, color = 0, val, shift;
@@ -116,8 +112,8 @@
 		val = 0;
 		
 		if (start_index) {
-			unsigned long start_mask = ~(SHIFT_HIGH(~0UL, start_index));
-
+			unsigned long start_mask = ~(SHIFT_HIGH(~0UL,
+								start_index));
 			val = FB_READL(dst) & start_mask;
 			shift = start_index;
 		}
@@ -131,10 +127,9 @@
 			val |= SHIFT_HIGH(color, shift);
 			if (shift >= null_bits) {
 				FB_WRITEL(val, dst++);
-				if (shift == null_bits)
-					val = 0;
-				else
-					val = SHIFT_LOW(color, BITS_PER_LONG - shift);
+	
+				val = (shift == null_bits) ? 0 : 
+					SHIFT_LOW(color,BITS_PER_LONG - shift);
 			}
 			shift += bpp;
 			shift &= (BITS_PER_LONG - 1);
@@ -157,60 +152,62 @@
 	}
 }
 
-static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1,
-				  unsigned long fgcolor, unsigned long bgcolor, 
-				  unsigned long start_index, unsigned long pitch_index)
+static inline void slow_imageblit(struct fb_image *image, struct fb_info *p, 
+				  u8 *dst1, unsigned long fgcolor,
+				  unsigned long bgcolor, 
+				  unsigned long start_index,
+				  unsigned long pitch_index)
 {
-	unsigned long i, j, l = 8;
-	unsigned long shift, color, bpp = p->var.bits_per_pixel;
+	unsigned long shift, color = 0, bpp = p->var.bits_per_pixel;
 	unsigned long *dst, *dst2, val, pitch = p->fix.line_length;
 	unsigned long null_bits = BITS_PER_LONG - bpp;
-	u8 *src = image->data;
+	unsigned long spitch = (image->width+7)/8;
+	u8 *src = image->data, *s;
+	unsigned long i, j, l;
 	
 	dst2 = (unsigned long *) dst1;
 
 	for (i = image->height; i--; ) {
-		shift = 0;
-		val = 0;
+		shift = val = 0;
+		l = 8;
 		j = image->width;
 		dst = (unsigned long *) dst1;
+		s = src;
 
 		/* write leading bits */
 		if (start_index) {
-			unsigned long start_mask = ~(SHIFT_HIGH(~0UL, start_index));
-
+			unsigned long start_mask = ~(SHIFT_HIGH(~0UL,
+								start_index));
 			val = FB_READL(dst) & start_mask;
 			shift = start_index;
 		}
+
 		while (j--) {
 			l--;
-			if (*src & (1 << l)) 
-				color = fgcolor;
-			else 
-				color = bgcolor;
+			color = (*s & (1 << l)) ? fgcolor : bgcolor;
 			color <<= LEFT_POS(bpp);
 			val |= SHIFT_HIGH(color, shift);
 			
 			/* Did the bitshift spill bits to the next long? */
 			if (shift >= null_bits) {
 				FB_WRITEL(val, dst++);
-				if (shift == null_bits)
-					val = 0;
-				else
-					val = SHIFT_LOW(color, BITS_PER_LONG - shift);
+				val = (shift == null_bits) ? 0 :
+					 SHIFT_LOW(color,BITS_PER_LONG - shift);
 			}
 			shift += bpp;
 			shift &= (BITS_PER_LONG - 1);
-			if (!l) { l = 8; src++; };
+			if (!l) { l = 8; s++; };
 		}
+
 		/* write trailing bits */
  		if (shift) {
 			unsigned long end_mask = SHIFT_HIGH(~0UL, shift);
 
 			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
 		}
-		dst1 += pitch;	
-
+		
+		dst1 += pitch;
+		src += spitch;	
 		if (pitch_index) {
 			dst2 += pitch;
 			dst1 = (char *) dst2;
@@ -223,26 +220,34 @@
 	}
 }
 
-static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, u8 *dst1, 
-				  unsigned long fgcolor, unsigned long bgcolor) 
+/*
+ * fast_imageblit - optimized monochrome color expansion
+ *
+ * Only if:  bits_per_pixel == 8, 16, or 32
+ *           image->width is divisible by pixel/dword (ppw);
+ *           fix->line_legth is divisible by 4;
+ *           beginning and end of a scanline is dword aligned
+ */
+static inline void fast_imageblit(struct fb_image *image, struct fb_info *p, 
+				  u8 *dst1, unsigned long fgcolor, 
+				  unsigned long bgcolor) 
 {
-	int i, j, k, l = 8, n;
-	unsigned long bit_mask, end_mask, eorx; 
-	unsigned long fgx = fgcolor, bgx = bgcolor, pad, bpp = p->var.bits_per_pixel;
-	unsigned long tmp = (1 << bpp) - 1;
-	unsigned long ppw = BITS_PER_LONG/bpp, ppos;
+	unsigned long fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
+	unsigned long ppw = BITS_PER_LONG/bpp, spitch = (image->width + 7)/8;
+	unsigned long bit_mask, end_mask, eorx, shift;
+	char *s = image->data, *src;
 	unsigned long *dst;
 	u32 *tab = NULL;
-	char *src = image->data;
+	int i, j, k;
 		
-	switch (ppw) {
-	case 4:
+	switch (bpp) {
+	case 8:
 		tab = cfb_tab8;
 		break;
-	case 2:
+	case 16:
 		tab = cfb_tab16;
 		break;
-	case 1:
+	case 32:
 		tab = cfb_tab32;
 		break;
 	}
@@ -254,56 +259,39 @@
 		bgx |= bgcolor;
 	}
 	
-	n = ((image->width + 7) / 8);
-	pad = (n * 8) - image->width;
-	n = image->width % ppw;
-	
 	bit_mask = (1 << ppw) - 1;
 	eorx = fgx ^ bgx;
-
 	k = image->width/ppw;
 
 	for (i = image->height; i--; ) {
-		dst = (unsigned long *) dst1;
+		dst = (unsigned long *) dst1, shift = 8; src = s;
 		
 		for (j = k; j--; ) {
-			l -= ppw;
-			end_mask = tab[(*src >> l) & bit_mask]; 
-			FB_WRITEL((end_mask & eorx)^bgx, dst++);
-			if (!l) { l = 8; src++; }
-		}
-		if (n) {
-			end_mask = 0;	
-			ppos = LEFT_POS(bpp);
-			for (j = n; j > 0; j--) {
-				l--;
-				if (*src & (1 << l))
-					end_mask |= tmp << ppos;
-				NEXT_POS(ppos, bpp);
-				if (!l) { l = 8; src++; }
-			}
+			shift -= ppw;
+			end_mask = tab[(*src >> shift) & bit_mask];
 			FB_WRITEL((end_mask & eorx)^bgx, dst++);
+			if (!shift) { shift = 8; src++; }		
 		}
-		l -= pad;		
-		dst1 += p->fix.line_length;	
+		dst1 += p->fix.line_length;
+		s += spitch;
 	}
 }	
 	
 void cfb_imageblit(struct fb_info *p, struct fb_image *image)
 {
-	int x2, y2, vxres, vyres;
 	unsigned long fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
 	unsigned long bpl = sizeof(unsigned long), bpp = p->var.bits_per_pixel;
+	int x2, y2, vxres, vyres;
 	u8 *dst1;
 
 	vxres = p->var.xres_virtual;
 	vyres = p->var.yres_virtual;
 	/* 
-	 * We could use hardware clipping but on many cards you get around hardware
-	 * clipping by writing to framebuffer directly like we are doing here. 
+	 * We could use hardware clipping but on many cards you get around
+	 * hardware clipping by writing to framebuffer directly like we are
+	 * doing here. 
 	 */
-	if (image->dx > vxres ||
-	    image->dy > vyres)
+	if (image->dx > vxres || image->dy > vyres)
 		return;
 
 	x2 = image->dx + image->width;
@@ -323,18 +311,22 @@
 	bitstart &= ~(bpl - 1);
 	dst1 = p->screen_base + bitstart;
 
+	if (p->fbops->fb_sync)
+		p->fbops->fb_sync(p);
+
 	if (image->depth == 1) {
 		if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
 		    p->fix.visual == FB_VISUAL_DIRECTCOLOR) {
-			fgcolor = ((u32 *)(p->pseudo_palette))[image->fg_color];
-			bgcolor = ((u32 *)(p->pseudo_palette))[image->bg_color];
+			fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color];
+			bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color];
 		} else {
 			fgcolor = image->fg_color;
 			bgcolor = image->bg_color;
 		}	
 		
 		if (BITS_PER_LONG % bpp == 0 && !start_index && !pitch_index && 
-		    bpp >= 8 && bpp <= 32 && (image->width & 7) == 0) 
+		    ((image->width & (BITS_PER_LONG/bpp-1)) == 0) &&
+		    bpp >= 8 && bpp <= 32) 			
 			fast_imageblit(image, p, dst1, fgcolor, bgcolor);
 		else 
 			slow_imageblit(image, p, dst1, fgcolor, bgcolor, start_index, pitch_index);
diff -Nru a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
--- a/drivers/video/console/Kconfig	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/console/Kconfig	Thu Jan 16 18:23:05 2003
@@ -66,25 +66,25 @@
 
 #  bool 'IODC console' CONFIG_IODC_CONSOLE
 config STI_CONSOLE
-        bool "STI text console"
+        tristate "STI text console" 
         depends on PARISC
         default y
-	help
+        help
           The STI console is the builtin display/keyboard on HP-PARISC
           machines.  Say Y here to build support for it into your kernel.
           The alternative is to use your primary serial port as a console.
 
 config DUMMY_CONSOLE_COLUMNS
-        int "Initial number of STI console screen columns" if STI_CONSOLE
-        depends on STI_CONSOLE || FB_STI
+        int "Initial number of console screen columns" if STI_CONSOLE
+        depends on PARISC
         default "160"
         help
           The default value is 160, which should fit a 1280x1024 monitor.
           Select 80 if you use a 640x480 resolution by default.
 
 config DUMMY_CONSOLE_ROWS
-        int "Initial number of STI console screen rows" if STI_CONSOLE
-        depends on STI_CONSOLE || FB_STI
+        int "Initial number of console screen rows" if STI_CONSOLE
+        depends on PARISC
         default "64"
         help
           The default value is 64, which should fit a 1280x1024 monitor.
@@ -99,7 +99,7 @@
 
 config DUMMY_CONSOLE
 	bool
-	depends on !PROM_CONSOLE=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y || !IODC_CONSOLE && GSC_PS2
+	depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y
 	default y
 
 config FRAMEBUFFER_CONSOLE
diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
--- a/drivers/video/console/fbcon.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/console/fbcon.c	Thu Jan 16 18:23:06 2003
@@ -378,6 +378,7 @@
 	info->fbops->fb_fillrect(info, &region);
 }	
 
+#define FB_PIXMAPSIZE 8192
 void accel_putcs(struct vc_data *vc, struct display *p,
 			const unsigned short *s, int count, int yy, int xx)
 {
@@ -387,7 +388,7 @@
 	unsigned int cellsize = vc->vc_font.height * width;
 	struct fb_image image;
 	u16 c = scr_readw(s);
-	static u8 pixmap[8192];
+	static u8 pixmap[FB_PIXMAPSIZE];
 	
 	image.fg_color = attr_fgcol(p, c);
 	image.bg_color = attr_bgcol(p, c);
@@ -396,43 +397,48 @@
 	image.height = vc->vc_font.height;
 	image.depth = 1;
 
-/*	pixmap = kmalloc((info->var.bits_per_pixel + 7) >> 3 *
-				vc->vc_font.height, GFP_KERNEL); 
-*/
-				
-	if (!(vc->vc_font.width & 7) && pixmap != NULL) {
-		unsigned int pitch = width * count, i, j;
+	if (!(vc->vc_font.width & 7)) {
+		unsigned int pitch, cnt, i, j, k;
+		unsigned int maxcnt = FB_PIXMAPSIZE/(vc->vc_font.height * width);
 		char *src, *dst, *dst0;
 
-		dst0 = pixmap;
-		image.width = vc->vc_font.width * count;
 		image.data = pixmap;
-		while (count--) {
-			src = p->fontdata + (scr_readw(s++) & charmask) * cellsize;
-			dst = dst0;
-			for (i = image.height; i--; ) {
-				for (j = 0; j < width; j++) 
-					dst[j] = *src++;
-				dst += pitch;
-			}
-			dst0 += width;
-		}
-		info->fbops->fb_imageblit(info, &image);
-		if (info->fbops->fb_sync)
-			info->fbops->fb_sync(info);
+		while (count) {
+			if (count > maxcnt) 
+				cnt = k = maxcnt;
+			else
+				cnt = k = count;
+			
+			dst0 = pixmap;
+			pitch = width * cnt;
+			image.width = vc->vc_font.width * cnt;
+			while (k--) {
+				src = p->fontdata + (scr_readw(s++)&charmask)*
+					cellsize;
+				dst = dst0;
+				for (i = image.height; i--; ) {
+					for (j = 0; j < width; j++) 
+						dst[j] = *src++;
+					dst += pitch;
+				}
+				dst0 += width;
+			}
+
+			info->fbops->fb_imageblit(info, &image);
+			image.dx += cnt * vc->vc_font.width;
+			count -= cnt;
+		}
 	} else {
 		image.width = vc->vc_font.width;
 		while (count--) {
 			image.data = p->fontdata + 
-				(scr_readw(s++) & charmask) * vc->vc_font.height * width;
+				(scr_readw(s++) & charmask) * cellsize;
 			info->fbops->fb_imageblit(info, &image);
 			image.dx += vc->vc_font.width;
 		}	
 	}
-	/*
-	if (pixmap);
-		kfree(pixmap);
-	*/	
+	if (info->fbops->fb_sync)
+		info->fbops->fb_sync(info);
 }
 
 void accel_clear_margins(struct vc_data *vc, struct display *p,
@@ -1271,16 +1277,9 @@
 
 int update_var(int con, struct fb_info *info)
 {
-	int err;
+	if (con == info->currcon) 
+		return fb_pan_display(&info->var, info);
 
-	if (con == info->currcon) {
-		if (info->fbops->fb_pan_display) {
-			if ((err =
-			     info->fbops->fb_pan_display(&info->var,
-							 info)))
-				return err;
-		}
-	}
 	return 0;
 }
 
@@ -1871,6 +1870,25 @@
 }
 
 
+static int fbcon_resize(struct vc_data *vc, unsigned int width, 
+			unsigned int height)
+{
+	struct display *p = &fb_display[vc->vc_num];
+	struct fb_info *info = p->fb_info;
+	struct fb_var_screeninfo var = info->var;
+	int err;
+
+	var.xres = width * vc->vc_font.width;
+	var.yres = height * vc->vc_font.height;
+	var.activate = FB_ACTIVATE_NOW;
+
+	err = fb_set_var(&var, info);
+	return  (err || var.xres != info->var.xres ||
+		 var.yres != info->var.yres) ?
+		-EINVAL : 0;
+	  
+}
+
 static int fbcon_switch(struct vc_data *vc)
 {
 	int unit = vc->vc_num;
@@ -1920,8 +1938,10 @@
 
 	info->currcon = unit;
 	
+        fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
 	update_var(unit, info);
-	
+	fbcon_set_palette(vc, color_table); 	
+
 	if (vt_cons[unit]->vc_mode == KD_TEXT)
 		accel_clear_margins(vc, p, 0);
 	if (logo_shown == -2) {
@@ -2537,6 +2557,7 @@
 	.con_invert_region 	= fbcon_invert_region,
 	.con_screen_pos 	= fbcon_screen_pos,
 	.con_getxy 		= fbcon_getxy,
+	.con_resize             = fbcon_resize,
 };
 
 int __init fb_console_init(void)
diff -Nru a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
--- a/drivers/video/console/sticon.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/console/sticon.c	Thu Jan 16 18:23:06 2003
@@ -43,6 +43,7 @@
 #include <linux/vt_kern.h>
 #include <linux/kd.h>
 #include <linux/selection.h>
+#include <linux/module.h>
 
 #include <asm/io.h>
 
@@ -52,17 +53,16 @@
 #define BLANK 0
 static int vga_is_gfx;
 
+/* this is the sti_struct used for this console */
+static struct sti_struct *sticon_sti;
 
 /* Software scrollback */
-
 static unsigned long softback_buf, softback_curr;
 static unsigned long softback_in;
 static unsigned long /* softback_top, */ softback_end;
 static int softback_lines;
 
-
 /* software cursor */
-
 static int cursor_drawn;
 #define CURSOR_DRAW_DELAY		(1)
 #define DEFAULT_CURSOR_BLINK_RATE	(20)
@@ -75,7 +75,6 @@
     cursor_drawn = 0;
 }
 
-
 static const char *__init sticon_startup(void)
 {
     return "STI console";
@@ -108,7 +107,7 @@
     }
 #endif
 
-    sti_putc(default_sti, c, ypos, xpos);
+    sti_putc(sticon_sti, c, ypos, xpos);
 
     if (redraw_cursor)
 	    vbl_cursor_cnt = CURSOR_DRAW_DELAY;
@@ -135,7 +134,7 @@
 #endif
 
     while (count--) {
-	sti_putc(default_sti, scr_readw(s++), ypos, xpos++);
+	sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++);
     }
 
     if (redraw_cursor)
@@ -149,7 +148,7 @@
     car1 = conp->vc_screenbuf[conp->vc_x + conp->vc_y * conp->vc_cols];
     switch (mode) {
     case CM_ERASE:
-	sti_putc(default_sti, car1, conp->vc_y, conp->vc_x);
+	sti_putc(sticon_sti, car1, conp->vc_y, conp->vc_x);
 	break;
     case CM_MOVE:
     case CM_DRAW:
@@ -159,7 +158,7 @@
 	case CUR_LOWER_HALF:
 	case CUR_TWO_THIRDS:
 	case CUR_BLOCK:
-	    sti_putc(default_sti, (car1 & 255) + (0 << 8) + (7 << 11),
+	    sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11),
 		     conp->vc_y, conp->vc_x);
 	    break;
 	}
@@ -167,10 +166,9 @@
     }
 }
 
-static int
-sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+static int sticon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
 {
-    struct sti_struct *sti = default_sti;
+    struct sti_struct *sti = sticon_sti;
 
     if (vga_is_gfx)
         return 0;
@@ -192,9 +190,8 @@
     return 0;
 }
 
-static void
-sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
-	     int height, int width)
+static void sticon_bmove(struct vc_data *conp, int sy, int sx, 
+	int dy, int dx, int height, int width)
 {
     if (!width || !height)
 	    return;
@@ -206,12 +203,12 @@
 		sticon_cursor(p, CM_ERASE /*|CM_SOFTBACK*/);
 #endif
 
-    sti_bmove(default_sti, sy, sx, dy, dx, height, width);
+    sti_bmove(sticon_sti, sy, sx, dy, dx, height, width);
 }
 
 static void sticon_init(struct vc_data *c, int init)
 {
-    struct sti_struct *sti = default_sti;
+    struct sti_struct *sti = sticon_sti;
     int vc_cols, vc_rows;
 
     sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
@@ -240,7 +237,7 @@
     if (!height || !width)
 	return;
 
-    sti_clear(default_sti, sy, sx, height, width, conp->vc_video_erase_char);
+    sti_clear(sticon_sti, sy, sx, height, width, conp->vc_video_erase_char);
 }
 
 static int sticon_switch(struct vc_data *conp)
@@ -265,10 +262,10 @@
 	if (vga_is_gfx)
 		return 0;
 	sticon_set_origin(c);
-	sti_clear(default_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
+	sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
 	return 1;
     case -1:		/* Entering graphic mode */
-	sti_clear(default_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
+	sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
 	vga_is_gfx = 1;
 	return 1;
     }
@@ -344,7 +341,7 @@
     return attr;
 }
 
-void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
+static void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
 {
     int col = 1; /* vga_can_do_color; */
 
@@ -360,45 +357,51 @@
     }
 }
 
-void sticon_save_screen(struct vc_data *conp)
+static void sticon_save_screen(struct vc_data *conp)
 {
 }
 
-struct consw sti_con = {
-    con_startup:	sticon_startup,
-    con_init:		sticon_init,
-    con_deinit:		sticon_deinit,
-    con_clear:		sticon_clear,
-    con_putc:		sticon_putc,
-    con_putcs:		sticon_putcs,
-    con_cursor:		sticon_cursor,
-    con_scroll:		sticon_scroll,
-    con_bmove:		sticon_bmove,
-    con_switch:		sticon_switch,
-    con_blank:		sticon_blank,
-    con_font_op:	sticon_font_op,
-    con_set_palette:	sticon_set_palette,
-    con_scrolldelta:	sticon_scrolldelta,
-    con_set_origin:	sticon_set_origin,
-    con_save_screen:	sticon_save_screen, 
-    con_build_attr:	sticon_build_attr,
-    con_invert_region:	sticon_invert_region, 
-    con_screen_pos:	sticon_screen_pos,
-    con_getxy:		sticon_getxy,
+static struct consw sti_con = {
+	.con_startup		= sticon_startup,
+	.con_init		= sticon_init,
+	.con_deinit		= sticon_deinit,
+	.con_clear		= sticon_clear,
+	.con_putc		= sticon_putc,
+	.con_putcs		= sticon_putcs,
+	.con_cursor		= sticon_cursor,
+	.con_scroll		= sticon_scroll,
+	.con_bmove		= sticon_bmove,
+	.con_switch		= sticon_switch,
+	.con_blank		= sticon_blank,
+	.con_font_op		= sticon_font_op,
+	.con_set_palette	= sticon_set_palette,
+	.con_scrolldelta	= sticon_scrolldelta,
+	.con_set_origin		= sticon_set_origin,
+	.con_save_screen	= sticon_save_screen, 
+	.con_build_attr		= sticon_build_attr,
+	.con_invert_region	= sticon_invert_region, 
+	.con_screen_pos		= sticon_screen_pos,
+	.con_getxy		= sticon_getxy,
 };
 
 
 
 int __init sticonsole_init(void)
 {
-    if (sti_init_roms()) {
-	if (conswitchp == &dummy_con) {
-        	printk(KERN_INFO "sticon: Initializing STI text console.\n");
-		take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1);
-	}
-	return 0;
-    } else
+    /* already initialized ? */
+    if (sticon_sti)
+	 return 0;
+
+    sticon_sti = sti_get_rom(0);
+    if (!sticon_sti)
 	return -ENODEV;
+
+    if (conswitchp == &dummy_con) {
+	printk(KERN_INFO "sticon: Initializing STI text console.\n");
+	take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1);
+    }
+    return 0;
 }
 
 module_init(sticonsole_init);
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
--- a/drivers/video/console/sticore.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/console/sticore.c	Thu Jan 16 18:23:05 2003
@@ -3,14 +3,13 @@
  *	core code for console driver using HP's STI firmware
  *
  *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- *	Portions Copyright (C) 2001-2002 Helge Deller <deller@gmx.de>
- *	Portions Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+ *	Copyright (C) 2001-2003 Helge Deller <deller@gmx.de>
+ *	Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
  * 
  * TODO:
  * - call STI in virtual mode rather than in real mode
  * - screen blanking with state_mgmt() in text mode STI ? 
  * - try to make it work on m68k hp workstations ;)
- * - clean up the cache flushing functions
  * 
  */
 
@@ -25,10 +24,12 @@
 
 #include <asm/pgalloc.h>
 #include <asm/hardware.h>
+#include <asm/parisc-device.h>
+#include <asm/cacheflush.h>
 
 #include "../sticore.h"
 
-#define STI_DRIVERVERSION "0.9"
+#define STI_DRIVERVERSION "Version 0.9a"
 
 struct sti_struct *default_sti;
 
@@ -73,8 +74,8 @@
 {
 	struct sti_init_inptr_ext inptr_ext = { 0, };
 	struct sti_init_inptr inptr = {
-		3,	/* # of text planes (3 is maximum for STI) */ 
-		STI_PTR(&inptr_ext)
+		.text_planes	= 3, /* # of text planes (max 3 for STI) */
+		.ext_ptr	= STI_PTR(&inptr_ext)
 	};
 	struct sti_init_outptr outptr = { 0, };
 	unsigned long flags;
@@ -97,13 +98,13 @@
 }
 
 static const struct sti_conf_flags default_conf_flags = {
-		wait:	STI_WAIT,
-	};
+	.wait	= STI_WAIT,
+};
 
 void
 sti_inq_conf(struct sti_struct *sti)
 {
-	struct sti_conf_inptr inptr = { 0 };
+	struct sti_conf_inptr inptr = { 0, };
 	unsigned long flags;
 	s32 ret;
 
@@ -118,17 +119,20 @@
 }
 
 static const struct sti_font_flags default_font_flags = {
-		wait:	STI_WAIT,
-		non_text: 0,
+	.wait		= STI_WAIT,
+	.non_text	= 0,
 };
 
 void
 sti_putc(struct sti_struct *sti, int c, int y, int x)
 {
 	struct sti_font_inptr inptr = {
-		STI_PTR(sti->font->raw),
-		c_index(sti, c), c_fg(sti, c), c_bg(sti, c),
-		x * sti->font_width, y * sti->font_height, 0
+		.font_start_addr= STI_PTR(sti->font->raw),
+		.index		= c_index(sti, c),
+		.fg_color	= c_fg(sti, c),
+		.bg_color	= c_bg(sti, c),
+		.dest_x		= x * sti->font_width,
+		.dest_y		= y * sti->font_height,
 	};
 	struct sti_font_outptr outptr = { 0, };
 	s32 ret;
@@ -153,11 +157,14 @@
 	int height, int width, u8 color)
 {
 	struct sti_blkmv_inptr inptr = {
-		color, color,
-		src_x, src_y ,
-		src_x, src_y ,
-		width, height,
-		0
+		.fg_color	= color,
+		.bg_color	= color,
+		.src_x		= src_x,
+		.src_y		= src_y,
+		.dest_x		= src_x,
+		.dest_y		= src_y,
+		.width		= width,
+		.height		= height,
 	};
 	struct sti_blkmv_outptr outptr = { 0, };
 	s32 ret;
@@ -176,11 +183,14 @@
 	  int height, int width, int c)
 {
 	struct sti_blkmv_inptr inptr = {
-		c_fg(sti, c), c_bg(sti, c),
-		src_x * sti->font_width, src_y * sti->font_height,
-		src_x * sti->font_width, src_y * sti->font_height,
-		width * sti->font_width, height* sti->font_height,
-		0
+		.fg_color	= c_fg(sti, c),
+		.bg_color	= c_bg(sti, c),
+		.src_x		= src_x * sti->font_width,
+		.src_y		= src_y * sti->font_height,
+		.dest_x		= src_x * sti->font_width,
+		.dest_y		= src_y * sti->font_height,
+		.width		= width * sti->font_width,
+		.height		= height* sti->font_height,
 	};
 	struct sti_blkmv_outptr outptr = { 0, };
 	s32 ret;
@@ -195,7 +205,7 @@
 }
 
 static const struct sti_blkmv_flags default_blkmv_flags = {
-	.wait	= STI_WAIT, 
+	.wait = STI_WAIT, 
 };
 
 void
@@ -203,11 +213,12 @@
 	  int dst_y, int dst_x, int height, int width)
 {
 	struct sti_blkmv_inptr inptr = {
-		0, 0,
-		src_x * sti->font_width, src_y * sti->font_height,
-		dst_x * sti->font_width, dst_y * sti->font_height,
-		width * sti->font_width, height* sti->font_height,
-		0
+		.src_x		= src_x * sti->font_width,
+		.src_y		= src_y * sti->font_height,
+		.dest_x		= dst_x * sti->font_width,
+		.dest_y		= dst_y * sti->font_height,
+		.width		= width * sti->font_width,
+		.height		= height* sti->font_height,
 	};
 	struct sti_blkmv_outptr outptr = { 0, };
 	s32 ret;
@@ -222,6 +233,14 @@
 }
 
 
+/* FIXME: Do we have another solution for this ? */
+static void sti_flush(unsigned long from, unsigned long len)
+{
+	flush_data_cache();
+	flush_kernel_dcache_range(from, len);
+	flush_icache_range(from, from+len);
+}
+
 void __init
 sti_rom_copy(unsigned long base, unsigned long count, void *dest)
 {
@@ -242,7 +261,7 @@
 		dest++;
 	}
 
-	sti_flush(dest_start, dest_len); /* XXX */
+	sti_flush(dest_start, dest_len);
 }
 
 
@@ -250,8 +269,8 @@
 
 static char default_sti_path[21];
 
-static int __init 
-sti_setup(char *str)
+#ifndef MODULE
+static int __init sti_setup(char *str)
 {
 	if (str)
 		strncpy (default_sti_path, str, sizeof (default_sti_path));
@@ -266,6 +285,7 @@
  *	STI screen.
  */
 __setup("sti=", sti_setup);
+#endif
 
 
 
@@ -273,7 +293,7 @@
 static int __initdata	font_index[MAX_STI_ROMS], 
 			font_height[MAX_STI_ROMS],
 			font_width[MAX_STI_ROMS];
-
+#ifndef MODULE
 static int __init sti_font_setup(char *str)
 {
 	char *x;
@@ -323,10 +343,11 @@
  *		found, sticon will use the default 8x8 font.
  */
 __setup("sti_font=", sti_font_setup);
+#endif
 
 
 	
-void __init
+static void __init
 sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, unsigned int sti_mem_request)
 {
 	struct sti_glob_cfg_ext *cfg;
@@ -366,7 +387,7 @@
 		cfg->sti_mem_addr, sti_mem_request));
 }
 
-void __init
+static void __init
 sti_dump_outptr(struct sti_struct *sti)
 {
 	DPRINTK((KERN_INFO
@@ -380,7 +401,7 @@
 		 sti->outptr.attributes));
 }
 
-int __init
+static int __init
 sti_init_glob_cfg(struct sti_struct *sti,
 	    unsigned long rom_address, unsigned long hpa)
 {
@@ -399,8 +420,13 @@
 	save_addr = kmalloc(save_addr_size, GFP_KERNEL);
 	sti_mem_addr = kmalloc(sti->sti_mem_request, GFP_KERNEL);
 
-	if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr))
+	if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) {
+		kfree(glob_cfg);
+		kfree(glob_cfg_ext);
+		kfree(save_addr);
+		kfree(sti_mem_addr);
 		return -ENOMEM;
+	}
 
 	memset(glob_cfg, 0, sizeof(*glob_cfg));
 	memset(glob_cfg_ext, 0, sizeof(*glob_cfg_ext));
@@ -659,10 +685,10 @@
 		base += 4;
 		dest++;
 	}
-	sti_flush(dest_start, dest_len); /* XXX */
+	sti_flush(dest_start, dest_len);
 }
 
-struct sti_rom * __init
+static struct sti_rom * __init
 sti_get_bmode_rom (unsigned long address)
 {
 	struct sti_rom *raw;
@@ -889,7 +915,7 @@
 	return NULL;
 }
 
-static void __init sticore_check_for_default_sti (struct sti_struct *sti, char *path)
+static void __init sticore_check_for_default_sti(struct sti_struct *sti, char *path)
 {
 	if (strcmp (path, default_sti_path) == 0)
 		default_sti = sti;
@@ -977,14 +1003,12 @@
 }
 
 
-#define PCI_DEVICE_ID_VISUALIZE_EG	0x1005
-#define PCI_DEVICE_ID_VISUALIZE_FX	0x1008
-#define PCI_DEVICE_ID_VISUALIZE_FX_NEW	0x108b
-
 static struct pci_device_id sti_pci_tbl[] __devinitdata = {
-	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_VISUALIZE_EG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_VISUALIZE_FX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_VISUALIZE_FX_NEW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_EG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FXE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ 0, } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, sti_pci_tbl);
@@ -1002,58 +1026,53 @@
 	{ 0, }
 };
 
-struct parisc_driver pa_sti_driver = {
+static struct parisc_driver pa_sti_driver = {
 	.name		= "sti (native)",
 	.id_table	= sti_pa_tbl,
 	.probe		= sticore_pa_init,
 };
 
-struct sti_struct * __init sti_init_roms(void)
+
+/*
+ * sti_init_roms() - detects all STI ROMs and stores them in sti_roms[]
+ */
+
+static int sticore_initialized;
+
+static void __init sti_init_roms(void)
 {
-	static int initialized;
+	if (sticore_initialized)
+		return;
 
-	if (initialized)
-		goto out;
+	sticore_initialized = 1;
 
-	printk(KERN_INFO "STI GSC/PCI graphics driver version %s\n",
-			STI_DRIVERVERSION);
+	printk(KERN_INFO "STI GSC/PCI core graphics driver "
+			STI_DRIVERVERSION "\n");
 
 	/* Register drivers for native & PCI cards */
 	register_parisc_driver(&pa_sti_driver);
-	pci_module_init (&pci_sti_driver);
+	pci_module_init(&pci_sti_driver);
 
 	/* if we didn't find the given default sti, take the first one */
 	if (!default_sti)
 		default_sti = sti_roms[0];
 
-out:
-	/* return default STI if available */
-	if (num_sti_roms && default_sti && default_sti->init_graph) {
-		initialized = 1;
-		return default_sti;
-	}
-	return NULL;
 }
 
 /*
  * index = 0 gives default sti
  * index > 0 gives other stis in detection order
  */
-struct sti_struct * __init sti_get_rom(int index)
+struct sti_struct * sti_get_rom(unsigned int index)
 {
-	int i;
-	
+	if (!sticore_initialized)
+		sti_init_roms();
+
 	if (index == 0)
 		return default_sti;
 
-	i = -1;
-	while (index > 0) {
-		i++;
-		if (i > num_sti_roms)
-			return NULL;
-		if (sti_roms[i] == default_sti)
-			continue;
-		index--;
-	}
-	return sti_roms[i];
+	if (index > num_sti_roms)
+		return NULL;
+
+	return sti_roms[index-1];
 }
diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c
--- a/drivers/video/fbmem.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/fbmem.c	Thu Jan 16 18:23:05 2003
@@ -501,7 +501,7 @@
 int fb_show_logo(struct fb_info *info)
 {
 	unsigned char *fb = info->screen_base, *logo_new = NULL;
-	u32 *palette = NULL, *saved_palette = NULL;
+	u32 *palette = NULL, *saved_pseudo_palette = NULL;
 	int needs_directpalette = 0;
 	int needs_truepalette = 0;
 	int needs_cmapreset = 0;
@@ -578,7 +578,7 @@
 		else
 			fb_set_logo_directpalette(info, palette);
 
-		saved_palette = info->pseudo_palette;
+		saved_pseudo_palette = info->pseudo_palette;
 		info->pseudo_palette = palette;
 	}
 
@@ -587,8 +587,8 @@
 		if (logo_new == NULL) {
 			if (palette)
 				kfree(palette);
-			if (saved_palette)
-				info->pseudo_palette = saved_palette;
+			if (saved_pseudo_palette)
+				info->pseudo_palette = saved_pseudo_palette;
 			return 1;
 		}
 
@@ -609,8 +609,8 @@
 
 	if (palette != NULL)
 		kfree(palette);
-	if (saved_palette != NULL)
-		info->pseudo_palette = saved_palette;
+	if (saved_pseudo_palette != NULL)
+		info->pseudo_palette = saved_pseudo_palette;
 	if (logo_new != NULL)
 		kfree(logo_new);
 	return 0;
@@ -656,6 +656,8 @@
 	    count = info->fix.smem_len;
 	if (count + p > info->fix.smem_len)
 		count = info->fix.smem_len - p;
+	if (info->fbops->fb_sync)
+		info->fbops->fb_sync(info);
 	if (count) {
 	    char *base_addr;
 
@@ -692,6 +694,8 @@
 	    count = info->fix.smem_len - p;
 	    err = -ENOSPC;
 	}
+	if (info->fbops->fb_sync)
+		info->fbops->fb_sync(info);
 	if (count) {
 	    char *base_addr;
 
@@ -1189,5 +1193,6 @@
 EXPORT_SYMBOL(fb_show_logo);
 EXPORT_SYMBOL(fb_set_var);
 EXPORT_SYMBOL(fb_blank);
+EXPORT_SYMBOL(fb_pan_display);
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/fbmon.c b/drivers/video/fbmon.c
--- a/drivers/video/fbmon.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/fbmon.c	Thu Jan 16 18:23:06 2003
@@ -289,7 +289,390 @@
 }
 #endif
 
+/* 
+ * VESA Generalized Timing Formula (GTF) 
+ */
+
+#define FLYBACK                     550
+#define V_FRONTPORCH                1
+#define H_OFFSET                    40
+#define H_SCALEFACTOR               20
+#define H_BLANKSCALE                128
+#define H_GRADIENT                  600
+#define C_VAL                       30
+#define M_VAL                       300
+
+struct __fb_timings {
+	u32 dclk;
+	u32 hfreq;
+	u32 vfreq;
+	u32 hactive;
+	u32 vactive;
+	u32 hblank;
+	u32 vblank;
+	u32 htotal;
+	u32 vtotal;
+};
+
+/*
+ * a simple function to get the square root of integers 
+ */
+static u32 fb_sqrt(int x)
+{
+	register int op, res, one;
+
+	op = x;
+	res = 0;
+
+	one = 1 << 30;
+	while (one > op) one >>= 2;
+
+	while (one != 0) {
+		if (op >= res + one) {
+			op = op - (res + one);
+			res = res +  2 * one;
+		}
+		res /= 2;
+		one /= 4;
+	}
+	return((u32) res);
+}
+
+/**
+ * fb_get_vblank - get vertical blank time
+ * @hfreq: horizontal freq
+ *
+ * DESCRIPTION:
+ * vblank = right_margin + vsync_len + left_margin 
+ *
+ *    given: right_margin = 1 (V_FRONTPORCH)
+ *           vsync_len    = 3
+ *           flyback      = 550
+ *
+ *                          flyback * hfreq
+ *           left_margin  = --------------- - vsync_len
+ *                           1000000
+ */
+static u32 fb_get_vblank(u32 hfreq)
+{
+	u32 vblank;
+
+	vblank = (hfreq * FLYBACK)/1000; 
+	vblank = (vblank + 500)/1000;
+	return (vblank + V_FRONTPORCH);
+}
+
+/** 
+ * fb_get_hblank_by_freq - get horizontal blank time given hfreq
+ * @hfreq: horizontal freq
+ * @xres: horizontal resolution in pixels
+ *
+ * DESCRIPTION:
+ *
+ *           xres * duty_cycle
+ * hblank = ------------------
+ *           100 - duty_cycle
+ *
+ * duty cycle = percent of htotal assigned to inactive display
+ * duty cycle = C - (M/Hfreq)
+ *
+ * where: C = ((offset - scale factor) * blank_scale)
+ *            -------------------------------------- + scale factor
+ *                        256 
+ *        M = blank_scale * gradient
+ *
+ */
+static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres)
+{
+	u32 c_val, m_val, duty_cycle, hblank;
+
+	c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 + 
+		 H_SCALEFACTOR) * 1000;
+	m_val = (H_BLANKSCALE * H_GRADIENT)/256;
+	m_val = (m_val * 1000000)/hfreq;
+	duty_cycle = c_val - m_val;
+	hblank = (xres * duty_cycle)/(100000 - duty_cycle);
+	return (hblank);
+}
+
+/** 
+ * fb_get_hblank_by_dclk - get horizontal blank time given pixelclock
+ * @dclk: pixelclock in Hz
+ * @xres: horizontal resolution in pixels
+ *
+ * DESCRIPTION:
+ *
+ *           xres * duty_cycle
+ * hblank = ------------------
+ *           100 - duty_cycle
+ *
+ * duty cycle = percent of htotal assigned to inactive display
+ * duty cycle = C - (M * h_period)
+ * 
+ * where: h_period = SQRT(100 - C + (0.4 * xres * M)/dclk) + C - 100
+ *                   -----------------------------------------------
+ *                                    2 * M
+ *        M = 300;
+ *        C = 30;
+
+ */
+static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres)
+{
+	u32 duty_cycle, h_period, hblank;;
+
+	dclk /= 1000;
+	h_period = 100 - C_VAL;
+	h_period *= h_period;
+	h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk);
+	h_period *=10000; 
+
+	h_period = fb_sqrt((int) h_period);
+	h_period -= (100 - C_VAL) * 100;
+	h_period *= 1000; 
+	h_period /= 2 * M_VAL;
+
+	duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100;
+	hblank = (xres * duty_cycle)/(100000 - duty_cycle) + 8;
+	hblank &= ~15;
+	return (hblank);
+}
+	
+/**
+ * fb_get_hfreq - estimate hsync
+ * @vfreq: vertical refresh rate
+ * @yres: vertical resolution
+ *
+ * DESCRIPTION:
+ *
+ *          (yres + front_port) * vfreq * 1000000
+ * hfreq = -------------------------------------
+ *          (1000000 - (vfreq * FLYBACK)
+ * 
+ */
+
+static u32 fb_get_hfreq(u32 vfreq, u32 yres)
+{
+	u32 divisor, hfreq;
+	
+	divisor = (1000000 - (vfreq * FLYBACK))/1000;
+	hfreq = (yres + V_FRONTPORCH) * vfreq  * 1000;
+	return (hfreq/divisor);
+}
+
+static void fb_timings_vfreq(struct __fb_timings *timings)
+{
+	timings->hfreq = fb_get_hfreq(timings->vfreq, timings->vactive);
+	timings->vblank = fb_get_vblank(timings->hfreq);
+	timings->vtotal = timings->vactive + timings->vblank;
+	timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, 
+						 timings->hactive);
+	timings->htotal = timings->hactive + timings->hblank;
+	timings->dclk = timings->htotal * timings->hfreq;
+}
+
+static void fb_timings_hfreq(struct __fb_timings *timings)
+{
+	timings->vblank = fb_get_vblank(timings->hfreq);
+	timings->vtotal = timings->vactive + timings->vblank;
+	timings->vfreq = timings->hfreq/timings->vtotal;
+	timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, 
+						 timings->hactive);
+	timings->htotal = timings->hactive + timings->hblank;
+	timings->dclk = timings->htotal * timings->hfreq;
+}
+
+static void fb_timings_dclk(struct __fb_timings *timings)
+{
+	timings->hblank = fb_get_hblank_by_dclk(timings->dclk, 
+						timings->hactive);
+	timings->htotal = timings->hactive + timings->hblank;
+	timings->hfreq = timings->dclk/timings->htotal;
+	timings->vblank = fb_get_vblank(timings->hfreq);
+	timings->vtotal = timings->vactive + timings->vblank;
+	timings->vfreq = timings->hfreq/timings->vtotal;
+}
+
+/*
+ * fb_get_mode - calculates video mode using VESA GTF
+ * @flags: if: 0 - maximize vertical refresh rate
+ *             1 - vrefresh-driven calculation;
+ *             2 - hscan-driven calculation;
+ *             3 - pixelclock-driven calculation;
+ * @val: depending on @flags, ignored, vrefresh, hsync or pixelclock
+ * @var: pointer to fb_var_screeninfo
+ * @info: pointer to fb_info
+ *
+ * DESCRIPTION:
+ * Calculates video mode based on monitor specs using VESA GTF. 
+ * The GTF is best for VESA GTF compliant monitors but is 
+ * specifically formulated to work for older monitors as well.
+ *
+ * If @flag==0, the function will attempt to maximize the 
+ * refresh rate.  Otherwise, it will calculate timings based on
+ * the flag and accompanying value.  
+ *
+ * If FB_IGNOREMON bit is set in @flags, monitor specs will be 
+ * ignored and @var will be filled with the calculated timings.
+ *
+ * All calculations are based on the VESA GTF Spreadsheet
+ * available at VESA's public ftp (http://www.vesa.org).
+ * 
+ * NOTES:
+ * The timings generated by the GTF will be different from VESA
+ * DMT.  It might be a good idea to keep a table of standard
+ * VESA modes as well.  The GTF may also not work for some displays,
+ * such as, and especially, analog TV.
+ *   
+ * REQUIRES:
+ * A valid info->monspecs, otherwise 'safe numbers' will be used.
+ */ 
+int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	struct __fb_timings timings;
+	u32 interlace = 1, dscan = 1;
+	u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax;
+
+	/* 
+	 * If monspecs are invalid, use values that are enough
+	 * for 640x480@60
+	 */
+	if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
+	    !info->monspecs.dclkmax ||
+	    info->monspecs.hfmax < info->monspecs.hfmin ||
+	    info->monspecs.vfmax < info->monspecs.vfmin ||
+	    info->monspecs.dclkmax < info->monspecs.dclkmin) {
+		hfmin = 29000; hfmax = 30000;
+		vfmin = 60; vfmax = 60;
+		dclkmin = 0; dclkmax = 25000000;
+	} else {
+		hfmin = info->monspecs.hfmin;
+		hfmax = info->monspecs.hfmax;
+		vfmin = info->monspecs.vfmin;
+		vfmax = info->monspecs.vfmax;
+		dclkmin = info->monspecs.dclkmin;
+		dclkmax = info->monspecs.dclkmax;
+	}
+
+	memset(&timings, 0, sizeof(struct __fb_timings));
+	timings.hactive = var->xres;
+	timings.vactive = var->yres;
+	if (var->vmode & FB_VMODE_INTERLACED) { 
+		timings.vactive /= 2;
+		interlace = 2;
+	}
+	if (var->vmode & FB_VMODE_DOUBLE) {
+		timings.vactive *= 2;
+		dscan = 2;
+	}
+
+	switch (flags & ~FB_IGNOREMON) {
+	case FB_MAXTIMINGS: /* maximize refresh rate */
+		timings.hfreq = hfmax;
+		fb_timings_hfreq(&timings);
+		if (timings.vfreq > vfmax) {
+			timings.vfreq = vfmax;
+			fb_timings_vfreq(&timings);
+		}
+		break;
+	case FB_VSYNCTIMINGS: /* vrefresh driven */
+		timings.vfreq = val;
+		fb_timings_vfreq(&timings);
+		break;
+	case FB_HSYNCTIMINGS: /* hsync driven */
+		timings.hfreq = val;
+		fb_timings_hfreq(&timings);
+		break;
+	case FB_DCLKTIMINGS: /* pixelclock driven */
+		timings.dclk = PICOS2KHZ(val) * 1000;
+		fb_timings_dclk(&timings);
+		break;
+	default:
+		return -EINVAL;
+		
+	} 
+	
+	if (!(flags & FB_IGNOREMON) && 
+	    (timings.vfreq < vfmin || timings.vfreq > vfmax || 
+	     timings.hfreq < hfmin || timings.hfreq > hfmax ||
+	     timings.dclk < dclkmin || timings.dclk > dclkmax))
+		return -EINVAL;
+
+	var->pixclock = KHZ2PICOS(timings.dclk/1000);
+	var->hsync_len = (timings.htotal * 8)/100;
+	var->right_margin = (timings.hblank/2) - var->hsync_len;
+	var->left_margin = timings.hblank - var->right_margin - var->hsync_len;
+	
+	var->vsync_len = (3 * interlace)/dscan;
+	var->lower_margin = (1 * interlace)/dscan;
+	var->upper_margin = (timings.vblank * interlace)/dscan - 
+		(var->vsync_len + var->lower_margin);
+	
+	return 0;
+}
+	
+/*
+ * fb_validate_mode - validates var against monitor capabilities
+ * @var: pointer to fb_var_screeninfo
+ * @info: pointer to fb_info
+ *
+ * DESCRIPTION:
+ * Validates video mode against monitor capabilities specified in
+ * info->monspecs.
+ *
+ * REQUIRES:
+ * A valid info->monspecs.
+ */
+int fb_validate_mode(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	u32 hfreq, vfreq, htotal, vtotal, pixclock;
+	u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax;
+
+	/* 
+	 * If monspecs are invalid, use values that are enough
+	 * for 640x480@60
+	 */
+	if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
+	    !info->monspecs.dclkmax ||
+	    info->monspecs.hfmax < info->monspecs.hfmin ||
+	    info->monspecs.vfmax < info->monspecs.vfmin ||
+	    info->monspecs.dclkmax < info->monspecs.dclkmin) {
+		hfmin = 29000; hfmax = 30000;
+		vfmin = 60; vfmax = 60;
+		dclkmin = 0; dclkmax = 25000000;
+	} else {
+		hfmin = info->monspecs.hfmin;
+		hfmax = info->monspecs.hfmax;
+		vfmin = info->monspecs.vfmin;
+		vfmax = info->monspecs.vfmax;
+		dclkmin = info->monspecs.dclkmin;
+		dclkmax = info->monspecs.dclkmax;
+	}
+
+	if (!var->pixclock)
+		return -EINVAL;
+	pixclock = PICOS2KHZ(var->pixclock) * 1000;
+	   
+	htotal = var->xres + var->right_margin + var->hsync_len + 
+		var->left_margin;
+	vtotal = var->yres + var->lower_margin + var->vsync_len + 
+		var->upper_margin;
+
+	if (var->vmode & FB_VMODE_INTERLACED)
+		vtotal /= 2;
+	if (var->vmode & FB_VMODE_DOUBLE)
+		vtotal *= 2;
+
+	hfreq = pixclock/htotal;
+	vfreq = hfreq/vtotal;
+
+	return (vfreq < vfmin || vfreq > vfmax || 
+		hfreq < hfmin || hfreq > hfmax) ?
+		-EINVAL : 0;
+}
+
 EXPORT_SYMBOL(parse_edid);
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL(get_EDID);
 #endif
+EXPORT_SYMBOL(fb_get_mode);
+EXPORT_SYMBOL(fb_validate_mode);
diff -Nru a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
--- a/drivers/video/i810/i810.h	Thu Jan 16 18:23:07 2003
+++ b/drivers/video/i810/i810.h	Thu Jan 16 18:23:07 2003
@@ -212,9 +212,7 @@
 
 struct gtt_data {
 	agp_memory *i810_fb_memory;
-	agp_memory *i810_iring_memory;
 	agp_memory *i810_cursor_memory;
-	agp_memory *i810_pixmap_memory;
 };
 
 struct mode_registers {
diff -Nru a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c
--- a/drivers/video/i810/i810_accel.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/i810/i810_accel.c	Thu Jan 16 18:23:05 2003
@@ -27,7 +27,6 @@
 }                                                                      
 
 extern inline void flush_cache(void);
-extern int reinit_agp(struct fb_info *info);
 
 /************************************************************/
 
@@ -343,7 +342,7 @@
 	dy = rect->dy;
 	height = rect->height;
 
-	dest = p->fix.smem_start +  (dy * p->fix.line_length) + dx;
+	dest = p->fix.smem_start + (dy * p->fix.line_length) + dx;
 	color_blit(width, height, p->fix.line_length, dest, rop, color, 
 		   par->blit_bpp, par);
 }
@@ -394,11 +393,6 @@
 			 PAT_COPY_ROP, par->blit_bpp, par);
 }
 
-/*
- * Blitting is done at 8x8 pixel-array at a time.  If map is not 
- * monochrome or not a multiple of 8x8 pixels, cfb_imageblit will
- * be called instead.  
- */
 void i810fb_imageblit(struct fb_info *p, struct fb_image *image)
 {
 	struct i810fb_par *par = (struct i810fb_par *) p->par;
@@ -422,9 +416,6 @@
 		bg = image->bg_color;
 		break;
 	case 16:
-		fg = ((u32 *)(p->pseudo_palette))[image->fg_color];
-		bg = ((u32 *)(p->pseudo_palette))[image->bg_color];
-		break;
 	case 24:
 		fg = ((u32 *)(p->pseudo_palette))[image->fg_color];
 		bg = ((u32 *)(p->pseudo_palette))[image->bg_color];
diff -Nru a/drivers/video/i810/i810_dvt.c b/drivers/video/i810/i810_dvt.c
--- a/drivers/video/i810/i810_dvt.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/i810/i810_dvt.c	Thu Jan 16 18:23:06 2003
@@ -218,7 +218,7 @@
 	u32 diff = 0, diff_best = 0xFFFFFFFF, i = 0, i_best = 0; 
 	u8 hfl;
 
-	hfl =  (u8) ((xres >> 3) - 1);
+	hfl = (u8) ((xres >> 3) - 1);
 	for (i = 0; i < ARRAY_SIZE(std_modes); i++) { 
 		if (std_modes[i].cr01 == hfl) { 
 			if (std_modes[i].pixclock <= par->regs.pixclock)
diff -Nru a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
--- a/drivers/video/i810/i810_main.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/i810/i810_main.c	Thu Jan 16 18:23:05 2003
@@ -1221,7 +1221,7 @@
 
     	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 
-    	strcpy(fix->id, i810fb_name);
+    	strcpy(fix->id, "I810");
     	fix->smem_start = par->fb.physical;
     	fix->smem_len = par->fb.size;
     	fix->type = FB_TYPE_PACKED_PIXELS;
@@ -1519,15 +1519,9 @@
 	struct i810fb_par *par = (struct i810fb_par *) info->par;
 	u32 total;
 	u8 *mmio = par->mmio_start_virtual;
-	int xoffset = var->xoffset, yoffset = var->yoffset;
 	
-	if (xoffset < 0 ||
-	    xoffset+var->xres > var->xres_virtual ||
-	    yoffset < 0 ||
-	    yoffset+var->yres > var->yres_virtual) 
-		return -EINVAL;
-
-	total = xoffset * par->depth + yoffset * info->fix.line_length;
+	total = var->xoffset * par->depth + 
+		var->yoffset * info->fix.line_length;
 	i810_writel(DPLYBASE, mmio, par->fb.physical + total);
 
 	return 0;
@@ -1575,6 +1569,7 @@
 {
 	struct i810fb_par *par = (struct i810fb_par *) info->par;
 
+	decode_var(&info->var, par, info);
 	i810_load_regs(par);
 	i810_init_cursor(par);
 	par->cursor_reset = 1;
@@ -1586,7 +1581,6 @@
 static int i810fb_check_var(struct fb_var_screeninfo *var, 
 			    struct fb_info *info)
 {
-	struct i810fb_par *par = (struct i810fb_par *) info->par;
 	int err;
 
 	if (IS_DVT) {
@@ -1604,7 +1598,6 @@
 
 	i810fb_fill_var_timings(var);
 	set_color_bitfields(var);
-	decode_var(&info->var, par, info);
 	return 0;
 }
 
@@ -1699,13 +1692,14 @@
     .fb_copyarea =       i810fb_copyarea,
     .fb_imageblit =      i810fb_imageblit,
     .fb_cursor =         i810fb_cursor,
+    .fb_sync =           i810fb_sync,
 };
 
 /***********************************************************************
  *                  AGP resource allocation                            *
  ***********************************************************************/
   
-static void __devinit i810_fix_pointers(struct i810fb_par *par)
+static void __init i810_fix_pointers(struct i810fb_par *par)
 {
       	par->fb.physical = par->aperture.physical+(par->fb.offset << 12);
 	par->fb.virtual = par->aperture.virtual+(par->fb.offset << 12);
@@ -1721,7 +1715,7 @@
 		(par->pixmap.offset << 12);
 }
 
-static void __devinit i810_fix_offsets(struct i810fb_par *par)
+static void __init i810_fix_offsets(struct i810fb_par *par)
 {
 	if (vram + 1 > par->aperture.size >> 20)
 		vram = (par->aperture.size >> 20) - 1;
@@ -1744,7 +1738,7 @@
 	par->cursor_heap.size = 4096;
 }
 
-static int __devinit i810_alloc_agp_mem(struct fb_info *info)
+static int __init i810_alloc_agp_mem(struct fb_info *info)
 {
 	struct i810fb_par *par = (struct i810fb_par *) info->par;
 	int size;
@@ -1809,7 +1803,7 @@
  * Sets the the user monitor's horizontal and vertical
  * frequency limits
  */
-static void __devinit i810_init_monspecs(struct fb_info *info)
+static void __init i810_init_monspecs(struct fb_info *info)
 {
 	if (!hsync1)
 		hsync1 = HFMIN;
@@ -1837,8 +1831,8 @@
  * @par: pointer to i810fb_par structure
  * @info: pointer to current fb_info structure
  */
-static void __devinit i810_init_defaults(struct i810fb_par *par, 
-					 struct fb_info *info)
+static void __init i810_init_defaults(struct i810fb_par *par, 
+				      struct fb_info *info)
 {
 	if (voffset) {
 		v_offset_default = voffset;
@@ -1866,16 +1860,16 @@
 		vyres = (vram << 20)/(xres*bpp >> 3);
 
 	par->i810fb_ops = i810fb_ops;
-	i810fb_default.xres = xres;
-	i810fb_default.yres = yres;
-	i810fb_default.yres_virtual = vyres;
-	i810fb_default.bits_per_pixel = bpp;
+	info->var.xres = xres;
+	info->var.yres = yres;
+	info->var.yres_virtual = vyres;
+	info->var.bits_per_pixel = bpp;
 	
 	if (dcolor)
-		i810fb_default.nonstd = 1;
+		info->var.nonstd = 1;
 
 	if (par->dev_flags & HAS_ACCELERATION) 
-		i810fb_default.accel_flags = 1;
+		info->var.accel_flags = 1;
 
 	i810_init_monspecs(info);
 }
@@ -1884,7 +1878,7 @@
  * i810_init_device - initialize device
  * @par: pointer to i810fb_par structure
  */
-static void __devinit i810_init_device(struct i810fb_par *par)
+static void __init i810_init_device(struct i810fb_par *par)
 {
 	u8 reg, *mmio = par->mmio_start_virtual;
 
@@ -1905,7 +1899,7 @@
 	i810fb_init_ringbuffer(par);
 }
 
-static int __devinit 
+static int __init 
 i810_allocate_pci_resource(struct i810fb_par *par, 
 			   const struct pci_device_id *entry)
 {
@@ -2014,7 +2008,7 @@
 	return 0;
 }
 
-static int __devinit i810fb_init_pci (struct pci_dev *dev, 
+static int __init i810fb_init_pci (struct pci_dev *dev, 
 				      const struct pci_device_id *entry)
 {
 	struct fb_info    *info;
@@ -2061,7 +2055,6 @@
 	
 	fb_alloc_cmap(&info->cmap, 256, 0);
 
-	info->var = i810fb_default;
 	if ((err = info->fbops->fb_check_var(&info->var, info))) {
 		i810fb_release_resource(info, par);
 		return err;
@@ -2082,6 +2075,7 @@
 			  info->var.hsync_len + info->var.right_margin);
 	vfreq = hfreq/(info->var.yres + info->var.upper_margin +
 		       info->var.vsync_len + info->var.lower_margin);
+
       	printk("fb: %s v%d.%d.%d%s, Tony Daplas\n"
       	       "     Video RAM      : %dK\n" 
 	       "     Mode           : %dx%d-%dbpp@%dHz\n"
@@ -2098,7 +2092,6 @@
 	       (ext_vga) ? "en" : "dis", (IS_DVT) ? 
 	       "Intel(R) DVT" : "VESA GTF (US)");
 
-	
 	return 0;
 }
 
@@ -2144,7 +2137,7 @@
 		kfree(info);
 }
 
-static void __devexit i810fb_remove_pci(struct pci_dev *dev)
+static void __exit i810fb_remove_pci(struct pci_dev *dev)
 {
 	struct fb_info *info = pci_get_drvdata(dev);
 	struct i810fb_par *par = (struct i810fb_par *) info->par;
diff -Nru a/drivers/video/i810/i810_main.h b/drivers/video/i810/i810_main.h
--- a/drivers/video/i810/i810_main.h	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/i810/i810_main.h	Thu Jan 16 18:23:06 2003
@@ -14,9 +14,8 @@
 #ifndef __I810_MAIN_H__
 #define __I810_MAIN_H__
 
-
 /* PCI */
-static const char *i810_pci_list[] __devinitdata = {
+static const char *i810_pci_list[] __initdata = {
 	"Intel(R) 810 Framebuffer Device"                                 ,
 	"Intel(R) 810-DC100 Framebuffer Device"                           ,
 	"Intel(R) 810E Framebuffer Device"                                ,
@@ -25,7 +24,7 @@
 	"Intel(R) 815 (Internal Graphics with AGP) Framebuffer Device"  
 };
 
-static struct pci_device_id i810fb_pci_tbl[] __devinitdata = {
+static struct pci_device_id i810fb_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1, 
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3,
@@ -41,64 +40,32 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }
 };	  
 	             
-static int  __devinit i810fb_init_pci (struct pci_dev *dev, 
+static int  __init i810fb_init_pci (struct pci_dev *dev, 
 				       const struct pci_device_id *entry);
-static void __devexit i810fb_remove_pci(struct pci_dev *dev);
+static void __exit i810fb_remove_pci(struct pci_dev *dev);
 
 static struct pci_driver i810fb_driver = {
 	.name     =	"i810fb",
 	.id_table =	i810fb_pci_tbl,
 	.probe    =	i810fb_init_pci,
-	.remove   =	__devexit_p(i810fb_remove_pci),
+	.remove   =	__exit_p(i810fb_remove_pci),
 };	
 
-static int i810_init  __devinitdata = 0;
-static int vram       __devinitdata = 4;
-static int bpp        __devinitdata = 8;
-static int mtrr       __devinitdata = 0;
-static int accel      __devinitdata = 0;
-static int hsync1     __devinitdata = 0;
-static int hsync2     __devinitdata = 0;
-static int vsync1     __devinitdata = 0;
-static int vsync2     __devinitdata = 0;
-static int xres       __devinitdata = 640;
-static int yres       __devinitdata = 480;
-static int vyres      __devinitdata = 0;
-static int sync       __devinitdata = 0;
-static int ext_vga    __devinitdata = 0;
-static int dcolor     __devinitdata = 0;
-
-/* "use once" vars */
-static char i810fb_name[16]  = "i810fb";
-static struct fb_var_screeninfo i810fb_default __devinitdata = {
-	/* 640x480, 8 bpp */
-	.xres           = 640, 
-	.yres           = 480, 
-	.xres_virtual   = 640, 
-	.yres_virtual   = 480,
-	.xoffset        = 0, 
-	.yoffset        = 0, 
-	.bits_per_pixel = 8, 
-	.grayscale      = 0,
-	.red            = {0, 8, 0}, 
-	.green          = {0, 8, 0}, 
-	.blue           = {0, 8, 0}, 
-	.transp         = {0, 0, 0},
-	.nonstd         = 0, 
-	.activate       = 0, 
-	.height         = -1, 
-	.width          = -1, 
-	.accel_flags    = 0, 
-	.pixclock       = 20000, 
-	.left_margin    = 64, 
-	.right_margin   = 64, 
-	.upper_margin   = 32, 
-	.lower_margin   = 32, 
-	.hsync_len      = 64, 
-	.vsync_len      = 2,
-	.sync           = 0, 
-	.vmode          = FB_VMODE_NONINTERLACED
-};
+static int i810_init  __initdata = 0;
+static int vram       __initdata = 4;
+static int bpp        __initdata = 8;
+static int mtrr       __initdata = 0;
+static int accel      __initdata = 0;
+static int hsync1     __initdata = 0;
+static int hsync2     __initdata = 0;
+static int vsync1     __initdata = 0;
+static int vsync2     __initdata = 0;
+static int xres       __initdata = 640;
+static int yres       __initdata = 480;
+static int vyres      __initdata = 0;
+static int sync       __initdata = 0;
+static int ext_vga    __initdata = 0;
+static int dcolor     __initdata = 0;
 
 /*
  * voffset - framebuffer offset in MiB from aperture start address.  In order for
@@ -124,8 +91,8 @@
  * 
  * Experiment with v_offset to find out which works best for you.
  */
-static u32 v_offset_default __devinitdata; /* For 32 MiB Aper size, 8 should be the default */
-static u32 voffset          __devinitdata = 0;
+static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */
+static u32 voffset          __initdata = 0;
 
 static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor);
 
@@ -173,7 +140,7 @@
 
 #ifdef CONFIG_MTRR
 #define KERNEL_HAS_MTRR 1
-static inline void __devinit set_mtrr(struct i810fb_par *par)
+static inline void __init set_mtrr(struct i810fb_par *par)
 {
 	par->mtrr_reg = mtrr_add((u32) par->aperture.physical, 
 		 par->aperture.size, MTRR_TYPE_WRCOMB, 1);
diff -Nru a/drivers/video/riva/Makefile b/drivers/video/riva/Makefile
--- a/drivers/video/riva/Makefile	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/riva/Makefile	Thu Jan 16 18:23:05 2003
@@ -4,4 +4,4 @@
 
 obj-$(CONFIG_FB_RIVA) += rivafb.o
 
-rivafb-objs := fbdev.o riva_hw.o
+rivafb-objs := fbdev.o riva_hw.o nv_driver.o
diff -Nru a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
--- a/drivers/video/riva/fbdev.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/riva/fbdev.c	Thu Jan 16 18:23:06 2003
@@ -14,6 +14,8 @@
  *
  *	Jindrich Makovicka:  Accel code help, hw cursor, mtrr
  *
+ *	Paul Richards:  Bug fixes, updates
+ *
  * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven
  * Includes riva_hw.c from nVidia, see copyright below.
  * KGI code provided the basis for state storage, init, and mode switching.
@@ -36,6 +38,7 @@
 #include <linux/tty.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #ifdef CONFIG_MTRR
@@ -50,7 +53,7 @@
 #endif
 
 /* version number of this driver */
-#define RIVAFB_VERSION "0.9.4"
+#define RIVAFB_VERSION "0.9.5b"
 
 /* ------------------------------------------------------------------------- *
  *
@@ -84,16 +87,8 @@
 #define Set8Bits(value)		((value)&0xff)
 
 /* HW cursor parameters */
-#define DEFAULT_CURSOR_BLINK_RATE	(40)
-#define CURSOR_HIDE_DELAY		(20)
-#define CURSOR_SHOW_DELAY		(3)
-
-#define CURSOR_COLOR		0x7fff
-#define TRANSPARENT_COLOR	0x0000
 #define MAX_CURS		32
 
-
-
 /* ------------------------------------------------------------------------- *
  *
  * prototypes
@@ -102,8 +97,6 @@
 
 static int rivafb_blank(int blank, struct fb_info *info);
 
-extern inline void wait_for_idle(struct riva_par *par);
-
 /* ------------------------------------------------------------------------- *
  *
  * card identification
@@ -165,17 +158,17 @@
 	{ "RIVA-VTNT2", NV_ARCH_04 },
 	{ "RIVA-UVTNT2", NV_ARCH_04 },
 	{ "RIVA-ITNT2", NV_ARCH_04 },
-	{ "GeForce-SDR", NV_ARCH_10},
-	{ "GeForce-DDR", NV_ARCH_10},
-	{ "Quadro", NV_ARCH_10},
-	{ "GeForce2-MX", NV_ARCH_10},
-	{ "GeForce2-MX", NV_ARCH_10},
-        { "GeForce2-Go", NV_ARCH_10},
-	{ "Quadro2-MXR", NV_ARCH_10},
-	{ "GeForce2-GTS", NV_ARCH_10},
-	{ "GeForce2-GTS", NV_ARCH_10},
-	{ "GeForce2-ULTRA", NV_ARCH_10},
-	{ "Quadro2-PRO", NV_ARCH_10},
+	{ "GeForce-SDR", NV_ARCH_10 },
+	{ "GeForce-DDR", NV_ARCH_10 },
+	{ "Quadro", NV_ARCH_10 },
+	{ "GeForce2-MX", NV_ARCH_10 },
+	{ "GeForce2-MX", NV_ARCH_10 },
+	{ "GeForce2-GO", NV_ARCH_10 },
+	{ "Quadro2-MXR", NV_ARCH_10 },
+	{ "GeForce2-GTS", NV_ARCH_10 },
+	{ "GeForce2-GTS", NV_ARCH_10 },
+	{ "GeForce2-ULTRA", NV_ARCH_10 },
+	{ "Quadro2-PRO", NV_ARCH_10 },
 	{ "GeForce4-MX-460", NV_ARCH_20 },
 	{ "GeForce4-MX-440", NV_ARCH_20 },
 	{ "GeForce4-MX-420", NV_ARCH_20 },
@@ -188,10 +181,10 @@
 	{ "Quadro4-550-XGL", NV_ARCH_20 },
 	{ "Quadro4-500-GOGL", NV_ARCH_20 },
 	{ "GeForce2", NV_ARCH_20 },
-	{ "GeForce3", NV_ARCH_20}, 
-        { "GeForce3 Ti 200", NV_ARCH_20},
-        { "GeForce3 Ti 500", NV_ARCH_20},
-        { "Quadro DDC", NV_ARCH_20},
+	{ "GeForce3", NV_ARCH_20 }, 
+	{ "GeForce3 Ti 200", NV_ARCH_20 },
+	{ "GeForce3 Ti 500", NV_ARCH_20 },
+	{ "Quadro DDC", NV_ARCH_20 },
 	{ "GeForce4 Ti 4600", NV_ARCH_20 },
 	{ "GeForce4 Ti 4400", NV_ARCH_20 },
 	{ "GeForce4 Ti 4200", NV_ARCH_20 },
@@ -275,10 +268,10 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4400 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4200 },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL,
+ 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_900XGL },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL,
- 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_750XGL },
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_750XGL },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_700XGL },
 	{ 0, } /* terminate list */
@@ -292,7 +285,10 @@
  * ------------------------------------------------------------------------- */
 
 /* command line data, set in rivafb_setup() */
-static u32  pseudo_palette[17];
+static u32 pseudo_palette[17];
+static int noblink = 0;
+static int flatpanel __initdata = -1; /* Autodetect later */
+static int forceCRTC __initdata = -1;
 #ifdef CONFIG_MTRR
 static int nomtrr __initdata = 0;
 #endif
@@ -313,19 +309,15 @@
 	yres:		480,
 	xres_virtual:	640,
 	yres_virtual:	480,
-	xoffset:	0,
-	yoffset:	0,
 	bits_per_pixel:	8,
-	grayscale:	0,
 	red:		{0, 6, 0},
 	green:		{0, 6, 0},
 	blue:		{0, 6, 0},
 	transp:		{0, 0, 0},
-	nonstd:		0,
-	activate:	0,
+	activate:	FB_ACTIVATE_NOW,
 	height:		-1,
 	width:		-1,
-	accel_flags:	 FB_ACCELF_TEXT, 
+	accel_flags:	FB_ACCELF_TEXT,
 	pixclock:	39721,
 	left_margin:	40,
 	right_margin:	24,
@@ -333,7 +325,6 @@
 	lower_margin:	11,
 	hsync_len:	96,
 	vsync_len:	2,
-	sync:		0,
 	vmode:		FB_VMODE_NONINTERLACED
 };
 
@@ -358,8 +349,6 @@
 	0xEB							/* MISC */
 };
 
-
-
 /* ------------------------------------------------------------------------- *
  *
  * MMIO access macros
@@ -432,8 +421,6 @@
 	return (VGA_RD08(par->riva.PVIO, 0x3cc));
 }
 
-
-
 /* ------------------------------------------------------------------------- *
  *
  * cursor stuff
@@ -453,26 +440,25 @@
  * DESCRIPTiON:
  * Loads cursor image based on a monochrome source and mask bitmap.  The
  * mask bit determines if the image pixel is to be written to the framebuffer
- * or not.  The imaage bits determines the color of the pixel, 0 for 
- * background, 1 for foreground.  Only the affected region (as determined 
+ * or not.  The imaage bits determines the color of the pixel, 0 for
+ * background, 1 for foreground.  Only the affected region (as determined
  * by @w and @h parameters) will be updated.
  *
  * CALLED FROM:
  * rivafb_cursor()
  */
-static void rivafb_load_cursor_image(u8 *data, u8 *mask, struct riva_par *par, 
-				     int w, int h, u16 bg, u16 fg)
+static void rivafb_load_cursor_image(u8 *data, u8 *mask, struct riva_par *par,
+                                     int w, int h, u16 bg, u16 fg)
 {
 	int i, j, k = 0;
 	u32 b, m, tmp;
-       
 
 	for (i = 0; i < h; i++) {
 		b = *((u32 *)data)++;
 		m = *((u32 *)mask)++;
 		for (j = 0; j < w/2; j++) {
 			tmp = 0;
-#if defined (__BIG_ENDIAN__) 
+#if defined (__BIG_ENDIAN__)
 			if (m & (1 << 31))
 				tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
 			b <<= 1;
@@ -537,7 +523,7 @@
  * Saves current chip state to @regs.
  *
  * CALLED FROM:
- * rivafb_init_one()
+ * rivafb_probe()
  */
 /* from GGI */
 static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
@@ -550,21 +536,17 @@
 
 	regs->misc_output = MISCin(par);
 
-	for (i = 0; i < NUM_CRT_REGS; i++) {
+	for (i = 0; i < NUM_CRT_REGS; i++)
 		regs->crtc[i] = CRTCin(par, i);
-	}
 
-	for (i = 0; i < NUM_ATC_REGS; i++) {
+	for (i = 0; i < NUM_ATC_REGS; i++)
 		regs->attr[i] = ATTRin(par, i);
-	}
 
-	for (i = 0; i < NUM_GRC_REGS; i++) {
+	for (i = 0; i < NUM_GRC_REGS; i++)
 		regs->gra[i] = GRAin(par, i);
-	}
 
-	for (i = 0; i < NUM_SEQ_REGS; i++) {
+	for (i = 0; i < NUM_SEQ_REGS; i++)
 		regs->seq[i] = SEQin(par, i);
-	}
 }
 
 /**
@@ -577,8 +559,8 @@
  *
  * CALLED FROM:
  * riva_load_video_mode()
- * rivafb_init_one()
- * rivafb_remove_one()
+ * rivafb_probe()
+ * rivafb_remove()
  */
 /* from GGI */
 static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
@@ -604,29 +586,25 @@
 		}
 	}
 
-	for (i = 0; i < NUM_ATC_REGS; i++) {
+	for (i = 0; i < NUM_ATC_REGS; i++)
 		ATTRout(par, i, regs->attr[i]);
-	}
 
-	for (i = 0; i < NUM_GRC_REGS; i++) {
+	for (i = 0; i < NUM_GRC_REGS; i++)
 		GRAout(par, i, regs->gra[i]);
-	}
 
-	for (i = 0; i < NUM_SEQ_REGS; i++) {
+	for (i = 0; i < NUM_SEQ_REGS; i++)
 		SEQout(par, i, regs->seq[i]);
-	}
 }
 
 /**
  * riva_load_video_mode - calculate timings
  * @info: pointer to fb_info object containing info for current riva board
- * @video_mode: video mode to set
  *
  * DESCRIPTION:
  * Calculate some timings and then send em off to riva_load_state().
  *
  * CALLED FROM:
- * rivafb_set_var()
+ * rivafb_set_par()
  */
 static void riva_load_video_mode(struct fb_info *info)
 {
@@ -635,9 +613,8 @@
 	int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
 	struct riva_par *par = (struct riva_par *) info->par;
 	struct riva_regs newmode;
-
+	
 	/* time to calculate */
-
 	rivafb_blank(1, info);
 
 	bpp = info->var.bits_per_pixel;
@@ -676,7 +653,7 @@
 		hBlankEnd = hTotal + 4;
 	}
 
-	newmode.crtc[0x0] = Set8Bits (hTotal);
+	newmode.crtc[0x0] = Set8Bits (hTotal); 
 	newmode.crtc[0x1] = Set8Bits (hDisplay);
 	newmode.crtc[0x2] = Set8Bits (hBlankStart);
 	newmode.crtc[0x3] = SetBitField (hBlankEnd, 4: 0, 4:0) | SetBit (7);
@@ -707,22 +684,28 @@
 		| SetBitField(vStart,10:10,2:2)
 		| SetBitField(vDisplay,10:10,1:1)
 		| SetBitField(vTotal,10:10,0:0);
-	newmode.ext.horiz  = SetBitField(hTotal,8:8,0:0)
+	newmode.ext.horiz  = SetBitField(hTotal,8:8,0:0) 
 		| SetBitField(hDisplay,8:8,1:1)
 		| SetBitField(hBlankStart,8:8,2:2)
 		| SetBitField(hStart,8:8,3:3);
 	newmode.ext.extra  = SetBitField(vTotal,11:11,0:0)
 		| SetBitField(vDisplay,11:11,2:2)
 		| SetBitField(vStart,11:11,4:4)
-		| SetBitField(vBlankStart,11:11,6:6);
+		| SetBitField(vBlankStart,11:11,6:6); 
 
-	newmode.ext.bpp = bpp;
-	newmode.ext.width = width;
-	newmode.ext.height = height;
 	newmode.ext.interlace = 0xff; /* interlace off */
 
+	if (par->riva.Architecture >= NV_ARCH_10)
+		par->riva.CURSOR = (U032 *)(info->screen_base + par->riva.CursorStart);
+
 	par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
 				  hDisplaySize, height, dotClock);
+
+	newmode.ext.scale = par->riva.PRAMDAC[0x00000848/4] & 0xfff000ff;
+	if (par->FlatPanel == 1) {
+		newmode.ext.pixel |= (1 << 7);
+		newmode.ext.scale |= (1 << 8);
+	}
 	if (par->SecondCRTC) {
 		newmode.ext.head  = par->riva.PCRTC0[0x00000860/4] & ~0x00001000;
 		newmode.ext.head2 = par->riva.PCRTC0[0x00002860/4] | 0x00001000;
@@ -735,10 +718,9 @@
 		newmode.ext.crtcOwner = 0;
 		newmode.ext.vpll2 = par->riva.PRAMDAC0[0x00000520/4];
 	}
-
 	if (par->FlatPanel == 1) {
 		newmode.ext.pixel |= (1 << 7);
-		newmode.ext.scale |= (1 << 8) ;
+		newmode.ext.scale |= (1 << 8);
 	}
 	newmode.ext.cursorConfig = 0x02000100;
 	par->current_state = newmode;
@@ -762,7 +744,7 @@
  * 
  *
  * CALLED FROM:
- * rivafb_set_var()
+ * rivafb_check_var()
  */
 static int rivafb_do_maximize(struct fb_info *info,
 			      struct fb_var_screeninfo *var,
@@ -870,342 +852,9 @@
 	par->riva.Clip->TopLeft     = 0x0;
 	par->riva.Clip->WidthHeight = 0x80008000;
 	riva_setup_ROP(par);
-}
-
-/**
- * rivafb_fillrect - hardware accelerated color fill function
- * @info: pointer to fb_info structure
- * @rect: pointer to fb_fillrect structure
- * 
- * DESCRIPTION:
- * This function fills up a region of framebuffer memory with a solid
- * color with a choice of two different ROP's, copy or invert.
- *
- * CALLED FROM:
- * framebuffer hook
- */
-static void rivafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
-{
-	struct riva_par *par = (struct riva_par *) info->par;
-	u_int color, rop = 0;
-
-	if (info->var.bits_per_pixel == 8)
-		color = rect->color;
-	else
-		color = par->riva_palette[rect->color];
-
-	switch (rect->rop) {
-	case ROP_XOR:
-		rop = 0x66;
-		break;
-	case ROP_COPY:
-	default:
-		rop = 0xCC;
-		break;
-	}
-
-	RIVA_FIFO_FREE(par->riva, Rop, 1);
-	par->riva.Rop->Rop3 = rop;
-
-	RIVA_FIFO_FREE(par->riva, Bitmap, 1);
-	par->riva.Bitmap->Color1A = color;
-
-	RIVA_FIFO_FREE(par->riva, Bitmap, 2);
-	par->riva.Bitmap->UnclippedRectangle[0].TopLeft = 
-		(rect->dx << 16) | rect->dy;
-	par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
-		(rect->width << 16) | rect->height;
-}
-
-/**
- * rivafb_copyarea - hardware accelerated blit function
- * @info: pointer to fb_info structure
- * @region: pointer to fb_copyarea structure
- *
- * DESCRIPTION:
- * This copies an area of pixels from one location to another
- *
- * CALLED FROM:
- * framebuffer hook
- */
-static void rivafb_copyarea(struct fb_info *info, struct fb_copyarea *region)
-{
-	struct riva_par *par = (struct riva_par *) info->par;
-
-	RIVA_FIFO_FREE(par->riva, Blt, 3);
-	par->riva.Blt->TopLeftSrc  = (region->sy << 16) | region->sx;
-	par->riva.Blt->TopLeftDst  = (region->dy << 16) | region->dx;
-	par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
 	wait_for_idle(par);
 }
 
-static u8 byte_rev[256] = {
-	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 
-	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
-	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 
-	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
-	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 
-	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
-	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 
-	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
-	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 
-	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
-	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 
-	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
-	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 
-	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
-	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 
-	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
-	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 
-	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
-	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 
-	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
-	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 
-	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
-	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 
-	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
-	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
-	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
-	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
-	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
-	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
-	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
-	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
-	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
-};
-
-/**
- * rivafb_imageblit: hardware accelerated color expand function
- * @info: pointer to fb_info structure
- * @image: pointer to fb_image structure
- *
- * DESCRIPTION:
- * If the source is a monochrome bitmap, the function fills up a a region
- * of framebuffer memory with pixels whose color is determined by the bit
- * setting of the bitmap, 1 - foreground, 0 - background.
- *
- * If the source is not a monochrome bitmap, color expansion is not done.
- * In this case, it is channeled to a software function.
- *
- * CALLED FROM:
- * framebuffer hook
- */
-static void rivafb_imageblit(struct fb_info *info, struct fb_image *image)
-{
-	struct riva_par *par = (struct riva_par *) info->par;
-	u8 *cdat = image->data, *dat;
-	int w, h, dx, dy;
-	volatile u32 *d;
-	u32 fgx = 0, bgx = 0, size, width, mod;
-	int i, j;
-
-	if (image->depth != 1) {
-		wait_for_idle(par);
-		cfb_imageblit(info, image);
-		return;
-	}
-
-	w = image->width;
-	h = image->height;
-	dx = image->dx;
-	dy = image->dy;
-
-	width = (w + 7)/8;
-
-	size = width * h;
-	dat = cdat;
-
-	for (i = 0; i < size; i++) {
-		*dat = byte_rev[*dat];
-		dat++;
-	}
-
-	switch (info->var.bits_per_pixel) {
-	case 8:
-		fgx = image->fg_color;
-		bgx = image->bg_color;
-		
-		break;
-	case 16:
-	case 32:
-		fgx |= par->riva_palette[image->fg_color];
-		bgx |= par->riva_palette[image->bg_color];
-		break;
-	}
-
-        RIVA_FIFO_FREE(par->riva, Bitmap, 7);
-        par->riva.Bitmap->ClipE.TopLeft     = (dy << 16) | (dx & 0xFFFF);
-        par->riva.Bitmap->ClipE.BottomRight = (((dy + h) << 16) | 
-					       ((dx + w) & 0xffff));
-        par->riva.Bitmap->Color0E           = bgx;
-        par->riva.Bitmap->Color1E           = fgx;
-        par->riva.Bitmap->WidthHeightInE    = (h << 16) | ((w + 31) & ~31);
-        par->riva.Bitmap->WidthHeightOutE   = (h << 16) | ((w + 31) & ~31);
-        par->riva.Bitmap->PointE            = (dy << 16) | (dx & 0xFFFF);
-	
-	d = &par->riva.Bitmap->MonochromeData01E;
-
-	mod = width % 4;
-
-	if (width >= 4) {
-		while (h--) {
-			size = width / 4;
-			while (size >= 16) {
-				RIVA_FIFO_FREE(par->riva, Bitmap, 16);
-				for (i = 0; i < 16; i++)
-					d[i] = *((u32 *)cdat)++;
-				size -= 16;
-			}
-			
-			if (size) {
-				RIVA_FIFO_FREE(par->riva, Bitmap, size);
-				for (i = 0; i < size; i++)
-					d[i] = *((u32 *) cdat)++;
-			}
-			
-			if (mod) {
-				u32 tmp;
-				RIVA_FIFO_FREE(par->riva, Bitmap, 1);
-				for (i = 0; i < mod; i++) 
-					((u8 *)&tmp)[i] = *cdat++;
-				d[i] = tmp;
-			}
-		}
-	}
-	else {
-		u32 k, tmp;
-
-		for (i = h; i > 0; i-=16) {
-			if (i >= 16)
-				size = 16;
-			else
-				size = i;
-			RIVA_FIFO_FREE(par->riva, Bitmap, size);
-			for (j = 0; j < size; j++) {
-				for (k = 0; k < width; k++)
-					((u8 *)&tmp)[k] = *cdat++;
-				d[j] = tmp;
-			}
-		}
-	}
-}
-
-/**
- * rivafb_cursor - hardware cursor function
- * @info: pointer to info structure
- * @cursor: pointer to fbcursor structure
- *
- * DESCRIPTION:
- * A cursor function that supports displaying a cursor image via hardware.
- * Within the kernel, copy and invert rops are supported.  If exported
- * to user space, only the copy rop will be supported.
- *
- * CALLED FROM
- * framebuffer hook
- */
-static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) 
-{
-	static u8 data[MAX_CURS*MAX_CURS/8], mask[MAX_CURS*MAX_CURS/8];
-	struct riva_par *par = (struct riva_par *) info->par;
-	int i, j, d_idx = 0, s_idx = 0;
-	u16 flags = cursor->set, fg, bg;
-
-	/*
-	 * Can't do invert if one of the operands (dest) is missing,
-	 * ie, only opaque cursor supported.  This should be
-	 * standard for GUI apps.
-	 */
-	if (cursor->dest == NULL && cursor->rop == ROP_XOR)
-		return 1;
-
-	if (par->cursor_reset) {
-		flags = FB_CUR_SETALL;
-		par->cursor_reset = 0;
-	}
-
-	par->riva.ShowHideCursor(&par->riva, 0);
-
-	if (flags & FB_CUR_SETPOS) {
-		u32 xx, yy, temp;
-	
-		yy = cursor->image.dy - info->var.yoffset;
-		xx = cursor->image.dx - info->var.xoffset;
-		temp = xx & 0xFFFF;
-		temp |= yy << 16;
-
-		par->riva.PRAMDAC[0x0000300/4] = temp;
-	}
-
-	if (flags & FB_CUR_SETSIZE) {
-		memset(data, 0, MAX_CURS * MAX_CURS/8);
-		memset(mask, 0, MAX_CURS * MAX_CURS/8);
-		memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
-	}
-
-	if (flags & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETDEST)) { 
-		int bg_idx = cursor->image.bg_color;
-		int fg_idx = cursor->image.fg_color;
-
-		switch (cursor->rop) {
-		case ROP_XOR:
-			for (i = 0; i < cursor->image.height; i++) {
-				for (j = 0; j < (cursor->image.width + 7)/8;
-				     j++) {
-					d_idx = i * MAX_CURS/8  + j;
-					data[d_idx] =  byte_rev[((u8 *)cursor->image.data)[s_idx] ^
-							       ((u8 *)cursor->dest)[s_idx]];
-					mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
-					s_idx++;
-				}
-			}
-			break;
-		case ROP_COPY:
-		default:
-			for (i = 0; i < cursor->image.height; i++) {
-				for (j = 0; j < (cursor->image.width + 7)/8; j++) {
-					d_idx = i * MAX_CURS/8 + j;
-					data[d_idx] = byte_rev[((u8 *)cursor->image.data)[s_idx]];
-					mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
-					s_idx++;
-				}
-			}
-			break;
-		}
-			
-		bg = ((par->cmap[bg_idx].red & 0xf8) << 7) | 
-			((par->cmap[bg_idx].green & 0xf8) << 2) |
-			((par->cmap[bg_idx].blue & 0xf8) >> 3) | 1 << 15;
-		
-		fg = ((par->cmap[fg_idx].red & 0xf8) << 7) | 
-			((par->cmap[fg_idx].green & 0xf8) << 2) |
-			((par->cmap[fg_idx].blue & 0xf8) >> 3) | 1 << 15;
-
-		par->riva.LockUnlock(&par->riva, 0);
-		rivafb_load_cursor_image(data, mask, par, cursor->image.width, 
-					 cursor->image.height, bg, fg);
-	}
-	
-	if (cursor->enable)
-		par->riva.ShowHideCursor(&par->riva, 1);
-
-	return 0;
-}
-
-static int rivafb_sync(struct fb_info *info)
-{
-	struct riva_par *par = (struct riva_par *) info->par;
-
-	wait_for_idle(par);
-	
-	return 0;
-}
-
-/* ------------------------------------------------------------------------- *
- *
- * internal fb_ops helper functions
- *
- * ------------------------------------------------------------------------- */
-
 /**
  * riva_get_cmap_len - query current color map length
  * @var: standard kernel fb changeable data
@@ -1217,29 +866,29 @@
  * Length of color map
  *
  * CALLED FROM:
- * riva_getcolreg()
  * rivafb_setcolreg()
- * rivafb_get_cmap()
- * rivafb_set_cmap()
  */
 static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
 {
 	int rc = 16;		/* reasonable default */
 
-	assert(var != NULL);
-
-	switch (var->green.length) {
-	case 5:
-		rc = 32;	/* fix for 15 bpp depths on Riva 128 based cards */
+	switch (var->bits_per_pixel) {
+	case 8:
+		rc = 256;	/* pseudocolor... 256 entries HW palette */
 		break;
-	case 6:
-		rc = 64;	/* directcolor... 16 entries SW palette */
+	case 15:
+		rc = 15;	/* fix for 15 bpp depths on Riva 128 based cards */
+		break;
+	case 16:
+		rc = 16;	/* directcolor... 16 entries SW palette */
+		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
+	case 32:
+		rc = 16;	/* directcolor... 16 entries SW palette */
 		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
 	default:
-		rc = 256;	/* pseudocolor... 256 entries HW palette */
+		/* should not occur */
 		break;
 	}
-
 	return rc;
 }
 
@@ -1248,6 +897,7 @@
  * framebuffer operations
  *
  * ------------------------------------------------------------------------- */
+
 static int rivafb_open(struct fb_info *info, int user)
 {
 	struct riva_par *par = (struct riva_par *) info->par;
@@ -1261,13 +911,13 @@
 			par->state.flags |= VGA_SAVE_CMAP;
 		save_vga(&par->state);
 
-		RivaGetConfig(&par->riva, par->Chipset);	
-		CRTCout(par, 0x11, 0xFF);	/* vgaHWunlock() + riva unlock (0x7F) */
+		RivaGetConfig(&par->riva, par->Chipset);
+		/* vgaHWunlock() + riva unlock (0x7F) */
+		CRTCout(par, 0x11, 0xFF);
 		par->riva.LockUnlock(&par->riva, 0);
-
+	
 		riva_save_state(par, &par->initial_state);
 	}
-	
 	atomic_inc(&par->ref_count);
 	return 0;
 }
@@ -1286,41 +936,26 @@
 		restore_vga(&par->state);
 		par->riva.LockUnlock(&par->riva, 1);
 	}
-
 	atomic_dec(&par->ref_count);
-
 	return 0;
 }
 
-static int rivafb_check_var(struct fb_var_screeninfo *var,
-                            struct fb_info *info)
+static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	struct riva_par *par = (struct riva_par *) info->par;
 	int nom, den;		/* translating from pixels->bytes */
 	
-	if (par->riva.Architecture == NV_ARCH_03 &&
-	    var->bits_per_pixel == 16)
-		var->bits_per_pixel = 15;
-
 	switch (var->bits_per_pixel) {
 	case 1 ... 8:
+		var->red.offset = var->green.offset = var->blue.offset = 0;
+		var->red.length = var->green.length = var->blue.length = 8;
 		var->bits_per_pixel = 8;
-		nom = 1;
-		den = 1;
-		var->red.offset = 0;
-		var->red.length = 8;
-		var->green.offset = 0;
-		var->green.length = 8;
-		var->blue.offset = 0;
-		var->blue.length = 8;
+		nom = den = 1;
 		break;
 	case 9 ... 15:
 		var->green.length = 5;
 		/* fall through */
 	case 16:
 		var->bits_per_pixel = 16;
-		nom = 2;
-		den = 1;
 		if (var->green.length == 5) {
 			/* 0rrrrrgg gggbbbbb */
 			var->red.offset = 10;
@@ -1338,17 +973,17 @@
 			var->green.length = 6;
 			var->blue.length = 5;
 		}
+		nom = 2;
+		den = 1;
 		break;
 	case 17 ... 32:
+		var->red.length = var->green.length = var->blue.length = 8;
 		var->bits_per_pixel = 32;
-		nom = 4;
-		den = 1;
 		var->red.offset = 16;
 		var->green.offset = 8;
 		var->blue.offset = 0;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
+		nom = 4;
+		den = 1;
 		break;
 	default:
 		printk(KERN_ERR PFX
@@ -1373,7 +1008,7 @@
 	if (var->yoffset > var->yres_virtual - var->yres)
 		var->yoffset = var->yres_virtual - var->yres - 1;
 
-	var->red.msb_right =
+	var->red.msb_right = 
 	    var->green.msb_right =
 	    var->blue.msb_right =
 	    var->transp.offset = var->transp.length = var->transp.msb_right = 0;
@@ -1385,24 +1020,10 @@
 	struct riva_par *par = (struct riva_par *) info->par;
 
 	riva_load_video_mode(info);
-	if (info->var.accel_flags) {
-		riva_setup_accel(par);
-		info->fbops->fb_fillrect  = rivafb_fillrect;
-		info->fbops->fb_copyarea  = rivafb_copyarea;
-		info->fbops->fb_imageblit = rivafb_imageblit;
-		info->fbops->fb_cursor    = rivafb_cursor;
-		info->fbops->fb_sync      = rivafb_sync;
-	}
-	else {
-		info->fbops->fb_fillrect  = cfb_fillrect;
-		info->fbops->fb_copyarea  = cfb_copyarea;
-		info->fbops->fb_imageblit = cfb_imageblit;
-		info->fbops->fb_cursor    = soft_cursor;
-		info->fbops->fb_sync      = NULL;
-	}
-
+	riva_setup_accel(par);
+	
 	info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
-	info->fix.visual = (info->var.bits_per_pixel == 8) ? 
+	info->fix.visual = (info->var.bits_per_pixel == 8) ?
 				FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
 	return 0;
 }
@@ -1411,7 +1032,7 @@
  * rivafb_pan_display
  * @var: standard kernel fb changeable data
  * @con: TODO
- * @info: pointer to rivafb_info object containing info for current riva board
+ * @info: pointer to fb_info object containing info for current riva board
  *
  * DESCRIPTION:
  * Pan (or wrap, depending on the `vmode' field) the display using the
@@ -1423,9 +1044,9 @@
 static int rivafb_pan_display(struct fb_var_screeninfo *var,
 			      struct fb_info *info)
 {
-	struct riva_par *par = (struct riva_par *) info->par;
+	struct riva_par *par = (struct riva_par *)info->par;
 	unsigned int base;
-	
+
 	if (var->xoffset > (var->xres_virtual - var->xres))
 		return -EINVAL;
 	if (var->yoffset > (var->yres_virtual - var->yres))
@@ -1445,29 +1066,27 @@
 
 	par->riva.SetStartAddress(&par->riva, base);
 
-	info->var.xoffset = var->xoffset;
-	info->var.yoffset = var->yoffset;
-
-	if (var->vmode & FB_VMODE_YWRAP)
-		info->var.vmode |= FB_VMODE_YWRAP;
-	else
-		info->var.vmode &= ~FB_VMODE_YWRAP;
-
 	/*
 	 * HACK: The hardware cursor occasionally disappears during fast scrolling.
 	 *       We just reset the cursor each time we change the start address.
-	 *       This also has a beneficial side effect of restoring the cursor 
+	 *       This also has a beneficial side effect of restoring the cursor
 	 *       image when switching from X.
 	 */
 	par->cursor_reset = 1;
 
-	DPRINTK("EXIT, returning 0\n");
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
+
+	if (var->vmode & FB_VMODE_YWRAP)
+		info->var.vmode |= FB_VMODE_YWRAP;
+	else
+		info->var.vmode &= ~FB_VMODE_YWRAP;
 	return 0;
 }
 
 static int rivafb_blank(int blank, struct fb_info *info)
 {
-	struct riva_par *par = (struct riva_par *) info->par;
+	struct riva_par *par= (struct riva_par *)info->par;
 	unsigned char tmp, vesa;
 
 	tmp = SEQin(par, 0x01) & ~0x20;	/* screen on/off */
@@ -1489,11 +1108,8 @@
 			break;
 		}
 	}
-
 	SEQout(par, 0x01, tmp);
 	CRTCout(par, 0x1a, vesa);
-
-	DPRINTK("EXIT\n");
 	return 0;
 }
 
@@ -1504,7 +1120,7 @@
  * @green: green component
  * @blue: blue component
  * @transp: transparency
- * @info: pointer to rivafb_info object containing info for current riva board
+ * @info: pointer to fb_info object containing info for current riva board
  *
  * DESCRIPTION:
  * Set a single color register. The values supplied have a 16 bit
@@ -1514,22 +1130,14 @@
  * Return != 0 for invalid regno.
  *
  * CALLED FROM:
- * rivafb_set_cmap()
  * fbcmap.c:fb_set_cmap()
- *	fbgen.c:fbgen_get_cmap()
- *	fbgen.c:do_install_cmap()
- *		fbgen.c:fbgen_set_var()
- *		fbgen.c:fbgen_switch()
- *		fbgen.c:fbgen_blank()
- *	fbgen.c:fbgen_blank()
  */
 static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
-			    unsigned blue, unsigned transp,
-			    struct fb_info *info)
+			  unsigned blue, unsigned transp,
+			  struct fb_info *info)
 {
-	struct riva_par *par = (struct riva_par *) info->par;
+	struct riva_par *par = (struct riva_par *)info->par;
 	RIVA_HW_INST *chip = &par->riva;
-	int i;
 
 	if (regno >= riva_get_cmap_len(&info->var))
 		return -EINVAL;
@@ -1540,75 +1148,375 @@
 		    (red * 77 + green * 151 + blue * 28) >> 8;
 	}
 
-	if (!regno) {
-		for (i = 0; i < 256; i++) {
-			par->cmap[i].red = 0;
-			par->cmap[i].green = 0;
-			par->cmap[i].blue = 0;
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		/* "transparent" stuff is completely ignored. */
+		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
+		break;
+	case 16:
+		if (info->var.green.length == 5) {
+			/* 0rrrrrgg gggbbbbb */
+			((u16 *)(info->pseudo_palette))[regno] =
+					((red & 0xf800) >> 1) |
+					((green & 0xf800) >> 6) |
+					((blue & 0xf800) >> 11);
+		} else {
+			/* rrrrrggg gggbbbbb */
+			((u16 *)(info->pseudo_palette))[regno] =
+					((red & 0xf800) >> 0) |
+					((green & 0xf800) >> 5) |
+					((blue & 0xf800) >> 11);
 		}
+		break;
+	case 32:
+		((u32 *) (info->pseudo_palette))[regno] =
+		    		((red & 0xff00) << 8) |
+		    		((green & 0xff00)) | ((blue & 0xff00) >> 8);
+		break;
+	default:
+		/* do nothing */
+		break;
 	}
-	par->cmap[regno].red   = (u8) red;
-	par->cmap[regno].green = (u8) green;
-	par->cmap[regno].blue  = (u8) blue;
-	
-	if (info->var.green.length == 5) {
-		 /* RGB555: all components have 32 entries, 8 indices apart */
-		for (i = 0; i < 8; i++)
-			riva_wclut(chip, (regno*8)+i, (u8) red, (u8) green, (u8) blue);
-	}
-	else if (info->var.green.length == 6) {
-		/* 
-		 * RGB 565: red and blue have 32 entries, 8 indices apart, while
-		 *          green has 64 entries, 4 indices apart
-		 */
-		if (regno < 32) {
-			for (i = 0; i < 8; i++) {
-				riva_wclut(chip, (regno*8)+i, (u8) red, 
-					   par->cmap[regno*2].green,
-					   (u8) blue);
+	return 0;
+}
+
+/**
+ * rivafb_fillrect - hardware accelerated color fill function
+ * @info: pointer to fb_info structure
+ * @rect: pointer to fb_fillrect structure
+ *
+ * DESCRIPTION:
+ * This function fills up a region of framebuffer memory with a solid
+ * color with a choice of two different ROP's, copy or invert.
+ *
+ * CALLED FROM:
+ * framebuffer hook
+ */
+static void rivafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+{
+	struct riva_par *par = (struct riva_par *) info->par;
+	u_int color, rop = 0;
+
+	if (info->var.bits_per_pixel == 8)
+		color = rect->color;
+	else
+		color = ((u32 *)(info->pseudo_palette))[rect->color];
+
+	switch (rect->rop) {
+	case ROP_XOR:
+		rop = 0x66;
+		break;
+	case ROP_COPY:
+	default:
+		rop = 0xCC;
+		break;
+	}
+
+	RIVA_FIFO_FREE(par->riva, Rop, 1);
+	par->riva.Rop->Rop3 = rop;
+
+	RIVA_FIFO_FREE(par->riva, Bitmap, 1);
+	par->riva.Bitmap->Color1A = color;
+
+	RIVA_FIFO_FREE(par->riva, Bitmap, 2);
+	par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
+			(rect->dx << 16) | rect->dy;
+	par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
+			(rect->width << 16) | rect->height;
+	RIVA_FIFO_FREE(par->riva, Rop, 1);
+	par->riva.Rop->Rop3 = 0xCC;	// back to COPY
+}
+
+/**
+ * rivafb_copyarea - hardware accelerated blit function
+ * @info: pointer to fb_info structure
+ * @region: pointer to fb_copyarea structure
+ *
+ * DESCRIPTION:
+ * This copies an area of pixels from one location to another
+ *
+ * CALLED FROM:
+ * framebuffer hook
+ */
+static void rivafb_copyarea(struct fb_info *info, struct fb_copyarea *region)
+{
+	struct riva_par *par = (struct riva_par *) info->par;
+
+	RIVA_FIFO_FREE(par->riva, Blt, 3);
+	par->riva.Blt->TopLeftSrc  = (region->sy << 16) | region->sx;
+	par->riva.Blt->TopLeftDst  = (region->dy << 16) | region->dx;
+	par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
+	wait_for_idle(par);
+}
+
+static u8 byte_rev[256] = {
+	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
+
+static inline void reverse_order(u32 *l)
+{
+	u8 *a = (u8 *)l;
+	*a = byte_rev[*a], a++;
+	*a = byte_rev[*a];
+}
+
+static inline void convert_bgcolor_16(u32 *col)
+{
+	*col = ((*col & 0x00007C00) << 9)
+		| ((*col & 0x000003E0) << 6)
+		| ((*col & 0x0000001F) << 3)
+		|	   0xFF000000;
+}
+
+/**
+ * rivafb_imageblit: hardware accelerated color expand function
+ * @info: pointer to fb_info structure
+ * @image: pointer to fb_image structure
+ *
+ * DESCRIPTION:
+ * If the source is a monochrome bitmap, the function fills up a a region
+ * of framebuffer memory with pixels whose color is determined by the bit
+ * setting of the bitmap, 1 - foreground, 0 - background.
+ *
+ * If the source is not a monochrome bitmap, color expansion is not done.
+ * In this case, it is channeled to a software function.
+ *
+ * CALLED FROM:
+ * framebuffer hook
+ */
+static void rivafb_imageblit(struct fb_info *info, struct fb_image *image)
+{
+	struct riva_par *par = (struct riva_par *) info->par;
+	u32 fgx = 0, bgx = 0, width, mod;
+	u8 *cdat = image->data, *dat;
+	volatile u32 *d;
+	int i, j, size;
+
+	if (image->depth != 1) {
+		wait_for_idle(par);
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	width = (image->width + 7)/8;
+
+	size = image->width * image->height;
+	dat = cdat;
+/*
+	for (i = 0; i < size; i++) {
+		*dat = byte_rev[*dat];
+		dat++;
+	}
+*/
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		fgx = image->fg_color;
+		bgx = image->bg_color;
+		break;
+	case 16:
+		fgx |= ((u16 *) (info->pseudo_palette))[image->fg_color];
+		bgx |= ((u16 *) (info->pseudo_palette))[image->bg_color];
+		if (info->var.green.length == 6)
+			convert_bgcolor_16(&bgx);	
+		break;
+	case 32:
+		fgx |= ((u32 *) (info->pseudo_palette))[image->fg_color];
+		bgx |= ((u32 *) (info->pseudo_palette))[image->bg_color];
+		break;
+	}
+
+	RIVA_FIFO_FREE(par->riva, Bitmap, 7);
+	par->riva.Bitmap->ClipE.TopLeft     = (image->dy << 16) | (image->dx & 0xFFFF);
+	par->riva.Bitmap->ClipE.BottomRight = (((image->dy + image->height) << 16) |
+                                       		((image->dx + image->width) & 0xffff));
+	par->riva.Bitmap->Color0E           = bgx;
+	par->riva.Bitmap->Color1E           = fgx;
+	par->riva.Bitmap->WidthHeightInE    = (image->height << 16) | ((image->width + 31) & ~31);
+	par->riva.Bitmap->WidthHeightOutE   = (image->height << 16) | ((image->width + 31) & ~31);
+	par->riva.Bitmap->PointE            = (image->dy << 16) | (image->dx & 0xFFFF);
+
+	d = &par->riva.Bitmap->MonochromeData01E;
+
+	mod = width % 4;
+
+	if (width >= 4) {
+		while (image->height--) {
+			size = width / 4;
+			while (size >= 16) {
+				RIVA_FIFO_FREE(par->riva, Bitmap, 16);
+				for (i = 0; i < 16; i++)
+					d[i] = *((u32 *)cdat)++;
+				size -= 16;
+			}
+
+			if (size) {
+				RIVA_FIFO_FREE(par->riva, Bitmap, size);
+				for (i = 0; i < size; i++)
+					d[i] = *((u32 *) cdat)++;
+			}
+
+			if (mod) {
+				u32 tmp;
+				RIVA_FIFO_FREE(par->riva, Bitmap, 1);
+				for (i = 0; i < mod; i++)
+					((u8 *)&tmp)[i] = *cdat++;
+				d[i] = tmp;
 			}
 		}
-		for (i = 0; i < 4; i++) {
-			riva_wclut(chip, (regno*4)+i, par->cmap[regno/2].red,
-				   (u8) green, par->cmap[regno/2].blue);
-		
+	} else {
+		u32 tmp;
+
+		for (i = image->height; i > 0; i-=16) {
+			if (i >= 16)
+				size = 16;
+			else
+				size = i;
+			RIVA_FIFO_FREE(par->riva, Bitmap, size);
+			for (j = 0; j < size; j++) {
+				if (image->width <= 8)
+					tmp = *cdat++;
+				else
+					tmp = *((u16 *)cdat)++;
+				reverse_order(&tmp);
+				d[j] = tmp;
+			}
 		}
 	}
-	else {
-		riva_wclut(chip, regno, (u8) red, (u8) green, (u8) blue);
+}
+
+/**
+ * rivafb_cursor - hardware cursor function
+ * @info: pointer to info structure
+ * @cursor: pointer to fbcursor structure
+ *
+ * DESCRIPTION:
+ * A cursor function that supports displaying a cursor image via hardware.
+ * Within the kernel, copy and invert rops are supported.  If exported
+ * to user space, only the copy rop will be supported.
+ *
+ * CALLED FROM
+ * framebuffer hook
+ */
+static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+	static u8 data[MAX_CURS*MAX_CURS/8], mask[MAX_CURS*MAX_CURS/8];
+	struct riva_par *par = (struct riva_par *) info->par;
+	int i, j, d_idx = 0, s_idx = 0;
+	u16 flags = cursor->set, fg, bg;
+
+	/*
+	 * Can't do invert if one of the operands (dest) is missing,
+	 * ie, only opaque cursor supported.  This should be
+	 * standard for GUI apps.
+	 */
+	if (cursor->dest == NULL && cursor->rop == ROP_XOR)
+		return 1;
+
+	if (par->cursor_reset) {
+		flags = FB_CUR_SETALL;
+		par->cursor_reset = 0;
 	}
 
-	if (regno < 16) {
-		switch (info->var.bits_per_pixel) {
-		case 16:
-			if (info->var.green.length == 5) {
-				/* 0rrrrrgg gggbbbbb */
-				((u32 *)(info->pseudo_palette))[regno] =
-					(regno << 10) | (regno << 5) | regno;
-				par->riva_palette[regno] = 
-					((red & 0xf800) >> 1) |
-					((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);
+	par->riva.ShowHideCursor(&par->riva, 0);
 
-			} else {
-				/* rrrrrggg gggbbbbb */
-				((u32 *)(info->pseudo_palette))[regno] =
-					(regno << 11) | (regno << 6) | regno;
-				par->riva_palette[regno] = ((red & 0xf800) >> 0) |
-					((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
+	if (flags & FB_CUR_SETPOS) {
+		u32 xx, yy, temp;
+
+		yy = cursor->image.dy - info->var.yoffset;
+		xx = cursor->image.dx - info->var.xoffset;
+		temp = xx & 0xFFFF;
+		temp |= yy << 16;
+
+		par->riva.PRAMDAC[0x0000300/4] = temp;
+	}
+
+	if (flags & FB_CUR_SETSIZE) {
+		memset(data, 0, MAX_CURS * MAX_CURS/8);
+		memset(mask, 0, MAX_CURS * MAX_CURS/8);
+		memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
+	}
+
+	if (flags & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETDEST)) {
+		int bg_idx = cursor->image.bg_color;
+		int fg_idx = cursor->image.fg_color;
+
+		switch (cursor->rop) {
+		case ROP_XOR:
+			for (i = 0; i < cursor->image.height; i++) {
+				for (j = 0; j < (cursor->image.width + 7)/8; j++) {
+					d_idx = i * MAX_CURS/8  + j;
+					data[d_idx] =  byte_rev[((u8 *)cursor->image.data)[s_idx] ^ ((u8 *)cursor->dest)[s_idx]]; 	
+					mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
+					s_idx++;
+				}
 			}
 			break;
-		case 32:
-			((u32 *)(info->pseudo_palette))[regno] =
-				(regno << 16) | (regno << 8) | regno;
-			par->riva_palette[regno] =
-				((red & 0xff00) << 8) |
-				((green & 0xff00)) | ((blue & 0xff00) >> 8);
-			break;
+		case ROP_COPY:
 		default:
-			/* do nothing */
+			for (i = 0; i < cursor->image.height; i++) {
+				for (j = 0; j < (cursor->image.width + 7)/8; j++) {
+					d_idx = i * MAX_CURS/8 + j;
+					data[d_idx] = byte_rev[((u8 *)cursor->image.data)[s_idx]];
+					mask[d_idx] = byte_rev[((u8 *)cursor->mask)[s_idx]];
+					s_idx++;
+				}
+			}
 			break;
 		}
+/*
+		bg = ((par->cmap[bg_idx].red & 0xf8) << 7) |
+		     ((par->cmap[bg_idx].green & 0xf8) << 2) |
+		     ((par->cmap[bg_idx].blue & 0xf8) >> 3) | 1 << 15;
+
+		fg = ((par->cmap[fg_idx].red & 0xf8) << 7) |
+		     ((par->cmap[fg_idx].green & 0xf8) << 2) |
+		     ((par->cmap[fg_idx].blue & 0xf8) >> 3) | 1 << 15;
+*/
+		par->riva.LockUnlock(&par->riva, 0);
+		rivafb_load_cursor_image(data, mask, par, cursor->image.width,
+		cursor->image.height, bg, fg);
 	}
+	if (cursor->enable)
+		par->riva.ShowHideCursor(&par->riva, 1);
+	return 0;
+}
+
+static int rivafb_sync(struct fb_info *info)
+{
+	struct riva_par *par = (struct riva_par *)info->par;
+
+	wait_for_idle(par);
 	return 0;
 }
 
@@ -1620,153 +1528,168 @@
 
 /* kernel interface */
 static struct fb_ops riva_fb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_open =      rivafb_open,
-	.fb_release =   rivafb_release,
-	.fb_check_var =	rivafb_check_var,
-	.fb_set_par =	rivafb_set_par,
-	.fb_setcolreg =	rivafb_setcolreg,
-	.fb_pan_display=rivafb_pan_display,
-	.fb_blank =	rivafb_blank,
-	.fb_fillrect =	rivafb_fillrect,
-	.fb_copyarea =	rivafb_copyarea,
-	.fb_imageblit =	rivafb_imageblit,
-	.fb_cursor =    rivafb_cursor,
-	.fb_sync =      rivafb_sync,
+	.owner 		= THIS_MODULE,
+	.fb_open	= rivafb_open,
+	.fb_release	= rivafb_release,
+	.fb_check_var 	= rivafb_check_var,
+	.fb_set_par 	= rivafb_set_par,
+	.fb_setcolreg 	= rivafb_setcolreg,
+	.fb_pan_display	= rivafb_pan_display,
+	.fb_blank 	= rivafb_blank,
+	.fb_fillrect 	= rivafb_fillrect,
+	.fb_copyarea 	= rivafb_copyarea,
+	.fb_imageblit 	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,	
+	.fb_sync 	= rivafb_sync,
 };
 
 static int __devinit riva_set_fbinfo(struct fb_info *info)
 {
+	struct riva_par *par = (struct riva_par *) info->par;
 	unsigned int cmap_len;
 
 	info->node = NODEV;
 	info->flags = FBINFO_FLAG_DEFAULT;
-	info->fbops = &riva_fb_ops;
 	info->var = rivafb_default_var;
 	info->fix = rivafb_fix;
-
-	/* FIXME: set monspecs to what??? */
-	info->display_fg = NULL;
+	info->fbops = &riva_fb_ops;
 	info->pseudo_palette = pseudo_palette;
-
+	
 #ifndef MODULE
 	if (mode_option)
 		fb_find_mode(&info->var, info, mode_option,
 			     NULL, 0, NULL, 8);
 #endif
-	cmap_len = riva_get_cmap_len(&info->var);
-	fb_alloc_cmap(&info->cmap, cmap_len, 0);
+	if (par->use_default_var)
+		/* We will use the modified default var */
+		info->var = rivafb_default_var;
 
+	cmap_len = riva_get_cmap_len(&info->var);
+	fb_alloc_cmap(&info->cmap, cmap_len, 0);	
 	return 0;
 }
 
-/* ------------------------------------------------------------------------- *
- *
- * PCI bus
- *
- * ------------------------------------------------------------------------- */
+#ifdef CONFIG_ALL_PPC
+static int riva_get_EDID_OF(struct riva_par *par, struct pci_dev *pd)
+{
+	struct device_node *dp;
+	unsigned char *pedid = NULL;
+
+	dp = pci_device_to_OF_node(pd);
+	pedid = (unsigned char *)get_property(dp, "EDID,B", 0);
 
-static void __devinit rivafb_get_mem_len(struct riva_par *par,
-					 struct fb_fix_screeninfo *fix)
+	if (pedid) {
+		par->EDID = pedid;
+		return 1;
+	} else
+		return 0;
+}
+#endif /* CONFIG_ALL_PPC */
+
+static int riva_dfp_parse_EDID(struct riva_par *par)
 {
-	RIVA_HW_INST *chip = &par->riva;
+	unsigned char *block = par->EDID;
 
-	switch (chip->Architecture) {
-	case NV_ARCH_03:
-		if (chip->PFB[0x00000000/4] & 0x00000020) {
-			if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
-			    && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) {   
-				/*
-				 * SDRAM 128 ZX.
-				 */
-				switch (chip->PFB[0x00000000/4] & 0x03) {
-				case 2:
-					fix->smem_len = 1024 * 1024 * 4;
-					break;
-				case 1:
-					fix->smem_len = 1024 * 1024 * 2;
-					break;
-				default:
-					fix->smem_len = 1024 * 1024 * 8;
-					break;
-				}
-			}            
-			else  {
-				fix->smem_len = 1024 * 1024 * 8;
-			}            
-		}
-		else {
-			/*
-			 * SGRAM 128.
-			 */
-			switch (chip->PFB[0x00000000/4] & 0x00000003) {
-			case 0:
-				fix->smem_len = 1024 * 1024 * 8;
-				break;
-			case 2:
-				fix->smem_len = 1024 * 1024 * 4;
-				break;
-			default:
-				fix->smem_len = 1024 * 1024 * 2;
-				break;
-			}
-		}
-		break;
-	case NV_ARCH_04:
-		if (chip->PFB[0x00000000/4] & 0x00000100) {
-			fix->smem_len = (((chip->PFB[0x00000000/4] >> 12)
-					 & 0x0F) * 1024 * 2 + 1024 * 2) * 1024;
-		}
-		else {
-			switch (chip->PFB[0x00000000/4] & 0x00000003) {
-			case 0:
-				fix->smem_len = 1024 * 1024 * 32;
-				break;
-			case 1:
-				fix->smem_len = 1024 * 1024 * 4;
-				break;
-			case 2:
-				fix->smem_len = 1024 * 1024 * 8;
-				break;
-			case 3:
-			default:
-				fix->smem_len = 1024 * 1024 * 16;
-				break;
-			}
-		}
-		break;
-	case NV_ARCH_10:
-	case NV_ARCH_20:
-		switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF) {
-		case 0x02:
-			fix->smem_len = 1024 * 1024 * 2;
-			break;
-		case 0x04:
-			fix->smem_len = 1024 * 1024 * 4;
-			break;
-		case 0x08:
-			fix->smem_len = 1024 * 1024 * 8;
-			break;
-		case 0x10:
-			fix->smem_len = 1024 * 1024 * 16;
-			break;
-		case 0x20:
-			fix->smem_len = 1024 * 1024 * 32;
-			break;
-		case 0x40:
-			fix->smem_len = 1024 * 1024 * 64;
-			break;
-		case 0x80:
-			fix->smem_len = 1024 * 1024 * 128;
-			break;
-		default:
-			fix->smem_len = 1024 * 1024 * 16;
-			break;
-		}
+	if (!block)
+		return 0;
+
+	/* jump to detailed timing block section */
+	block += 54;
+
+	par->clock = (block[0] + (block[1] << 8));
+	par->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
+	par->hblank = (block[3] + ((block[4] & 0x0f) << 8));
+	par->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
+	par->vblank = (block[6] + ((block[7] & 0x0f) << 8));
+	par->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
+	par->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
+	par->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
+	par->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
+	par->interlaced = ((block[17] & 0x80) >> 7);
+	par->synct = ((block[17] & 0x18) >> 3);
+	par->misc = ((block[17] & 0x06) >> 1);
+	par->hAct_high = par->vAct_high = 0;
+	if (par->synct == 3) {
+		if (par->misc & 2)
+			par->hAct_high = 1;
+		if (par->misc & 1)
+			par->vAct_high = 1;
 	}
+
+	printk(KERN_INFO PFX
+			"detected DFP panel size from EDID: %dx%d\n", 
+			par->panel_xres, par->panel_yres);
+	par->got_dfpinfo = 1;
+	return 1;
 }
 
-static int __devinit rivafb_init_one(struct pci_dev *pd,
+static void riva_update_default_var(struct fb_info *info)
+{
+	struct fb_var_screeninfo *var = &rivafb_default_var;
+	struct riva_par *par = (struct riva_par *) info->par;
+
+        var->xres = par->panel_xres;
+        var->yres = par->panel_yres;
+        var->xres_virtual = par->panel_xres;
+        var->yres_virtual = par->panel_yres;
+        var->xoffset = var->yoffset = 0;
+        var->bits_per_pixel = 8;
+        var->pixclock = 100000000 / par->clock;
+        var->left_margin = (par->hblank - par->hOver_plus - par->hSync_width);
+        var->right_margin = par->hOver_plus;
+        var->upper_margin = (par->vblank - par->vOver_plus - par->vSync_width);
+        var->lower_margin = par->vOver_plus;
+        var->hsync_len = par->hSync_width;
+        var->vsync_len = par->vSync_width;
+        var->sync = 0;
+
+        if (par->synct == 3) {
+                if (par->hAct_high)
+                        var->sync |= FB_SYNC_HOR_HIGH_ACT;
+                if (par->vAct_high)
+                        var->sync |= FB_SYNC_VERT_HIGH_ACT;
+        }
+ 
+        var->vmode = 0;
+        if (par->interlaced)
+                var->vmode |= FB_VMODE_INTERLACED;
+
+	var->accel_flags |= FB_ACCELF_TEXT;
+        
+        par->use_default_var = 1;
+}
+
+
+static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
+{
+#ifdef CONFIG_ALL_PPC
+	if (!riva_get_EDID_OF(info, pdev))
+		printk("rivafb: could not retrieve EDID from OF\n");
+#else
+	/* XXX use other methods later */
+#endif
+}
+
+
+static void riva_get_dfpinfo(struct fb_info *info)
+{
+	struct riva_par *par = (struct riva_par *) info->par;
+
+	if (riva_dfp_parse_EDID(par))
+		riva_update_default_var(info);
+
+	/* if user specified flatpanel, we respect that */
+	if (par->got_dfpinfo == 1)
+		par->FlatPanel = 1;
+}
+
+/* ------------------------------------------------------------------------- *
+ *
+ * PCI bus
+ *
+ * ------------------------------------------------------------------------- */
+
+static int __devinit rivafb_probe(struct pci_dev *pd,
 				     const struct pci_device_id *ent)
 {
 	struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
@@ -1781,7 +1704,7 @@
 		goto err_out;
 
 	default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL);
-	if (!default_par) 
+	if (!default_par)
 		goto err_out_kfree;
 
 	memset(info, 0, sizeof(struct fb_info));
@@ -1789,12 +1712,27 @@
 
 	strcat(rivafb_fix.id, rci->name);
 	default_par->riva.Architecture = rci->arch_rev;
-	default_par->riva.Chipset = pd->device;
+
+	default_par->Chipset = (pd->vendor << 16) | pd->device;
+	printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
+	
+	default_par->FlatPanel = flatpanel;
+	if (flatpanel == 1)
+		printk(KERN_INFO PFX "flatpanel support enabled\n");
+	default_par->forceCRTC = forceCRTC;
 	
-	printk(KERN_INFO PFX "nVidia device/chipset %X\n", pd->device);	
 	rivafb_fix.mmio_len = pci_resource_len(pd, 0);
 	rivafb_fix.smem_len = pci_resource_len(pd, 1);
 
+	{
+		/* enable IO and mem if not already done */
+		unsigned short cmd;
+
+		pci_read_config_word(pd, PCI_COMMAND, &cmd);
+		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+		pci_write_config_word(pd, PCI_COMMAND, cmd);
+	}
+	
 	rivafb_fix.mmio_start = pci_resource_start(pd, 0);
 	rivafb_fix.smem_start = pci_resource_start(pd, 1);
 
@@ -1805,100 +1743,72 @@
 	}
 
 	default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
-				   rivafb_fix.mmio_len);
+					 rivafb_fix.mmio_len);
 	if (!default_par->ctrl_base) {
 		printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
-		goto err_out_free_base1;
+		goto err_out_free_base0;
 	}
-	
-	default_par->riva.EnableIRQ = 0;
-	default_par->riva.PRAMDAC = (unsigned *)(default_par->ctrl_base + 
-						 0x00680000);
-	default_par->riva.PFB = (unsigned *)(default_par->ctrl_base + 
-					     0x00100000);
-	default_par->riva.PFIFO = (unsigned *)(default_par->ctrl_base + 
-					       0x00002000);
-	default_par->riva.PGRAPH = (unsigned *)(default_par->ctrl_base + 
-						0x00400000);
-	default_par->riva.PEXTDEV = (unsigned *)(default_par->ctrl_base +
-						 0x00101000);
-	default_par->riva.PTIMER = (unsigned *)(default_par->ctrl_base + 
-						0x00009000);
-	default_par->riva.PMC = (unsigned *)(default_par->ctrl_base + 
-					     0x00000000);
-	default_par->riva.FIFO = (unsigned *)(default_par->ctrl_base + 
-					      0x00800000);
-	default_par->riva.PCIO = (U008 *)(default_par->ctrl_base + 0x00601000);
-	default_par->riva.PDIO = (U008 *)(default_par->ctrl_base + 0x00681000);
-	default_par->riva.PVIO = (U008 *)(default_par->ctrl_base + 0x000C0000);
-	default_par->riva.IO = (MISCin(default_par) & 0x01) ? 0x3D0 : 0x3B0;
 
-	if (default_par->riva.Architecture == NV_ARCH_03) {
-		/*
-		 * We have to map the full BASE_1 aperture for Riva128's
-		 * because they use the PRAMIN set in "framebuffer" space
-		 */
-		if (!request_mem_region(rivafb_fix.smem_start,
-					rivafb_fix.smem_len, "rivafb")) {
-			printk(KERN_ERR PFX "cannot reserve FB region\n");
-			goto err_out_free_base0;
-		}
-	
-		info->screen_base = ioremap(rivafb_fix.smem_start,
-					 rivafb_fix.smem_len);
-		if (!info->screen_base) {
-			printk(KERN_ERR PFX "cannot ioremap FB base\n");
-			goto err_out_iounmap_ctrl;
-		}
-	}
+	info->par = default_par;
+
+	riva_get_EDID(info, pd);
+
+	riva_get_dfpinfo(info);
 
 	switch (default_par->riva.Architecture) {
 	case NV_ARCH_03:
-		default_par->riva.PRAMIN = (unsigned *)(info->screen_base + 
-							0x00C00000);
-		default_par->dclk_max = 256000000;
+		/* Riva128's PRAMIN is in the "framebuffer" space
+		 * Since these cards were never made with more than 8 megabytes
+		 * we can safely allocate this seperately.
+		 */
+		if (!request_mem_region(rivafb_fix.smem_start + 0x00C00000,
+					 0x00008000, "rivafb")) {
+			printk(KERN_ERR PFX "cannot reserve PRAMIN region\n");
+			goto err_out_iounmap_ctrl;
+		}
+		default_par->riva.PRAMIN = ioremap(rivafb_fix.smem_start + 0x00C00000, 0x00008000);
+		if (!default_par->riva.PRAMIN) {
+			printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n");
+			goto err_out_free_nv3_pramin;
+		}
 		rivafb_fix.accel = FB_ACCEL_NV3;
 		break;
 	case NV_ARCH_04:
 	case NV_ARCH_10:
 	case NV_ARCH_20:
-		default_par->riva.PCRTC = (unsigned *)(default_par->ctrl_base 
-						       + 0x00600000);
-		default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base
-							+ 0x00710000);
-		default_par->dclk_max = 250000000;
+		default_par->riva.PCRTC0 = (unsigned *)(default_par->ctrl_base + 0x00600000);
+		default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base + 0x00710000);
 		rivafb_fix.accel = FB_ACCEL_NV4;
 		break;
 	}
 
-	rivafb_get_mem_len(default_par, &rivafb_fix);
+	riva_common_setup(default_par);
 
-	info->par = default_par;
+	if (default_par->riva.Architecture == NV_ARCH_03) {
+		default_par->riva.PCRTC = default_par->riva.PCRTC0 = default_par->riva.PGRAPH;
+	}
 
-	if (default_par->riva.Architecture != NV_ARCH_03) {
-		/*
-		 * Now the _normal_ chipsets can just map the amount of
-		 * real physical ram instead of the whole aperture
-		 */
-		if (!request_mem_region(rivafb_fix.smem_start,
-					rivafb_fix.smem_len, "rivafb")) {
-			printk(KERN_ERR PFX "cannot reserve FB region\n");
-			goto err_out_free_base0;
-		}
+	rivafb_fix.smem_len = default_par->riva.RamAmountKBytes * 1024;
+	default_par->dclk_max = default_par->riva.MaxVClockFreqKHz * 1000;
+
+	if (!request_mem_region(rivafb_fix.smem_start,
+				rivafb_fix.smem_len, "rivafb")) {
+		printk(KERN_ERR PFX "cannot reserve FB region\n");
+		goto err_out_iounmap_nv3_pramin;
+	}
 	
-		info->screen_base = ioremap(rivafb_fix.smem_start,
-					    rivafb_fix.smem_len);
-		if (!info->screen_base) {
-			printk(KERN_ERR PFX "cannot ioremap FB base\n");
-			goto err_out_iounmap_ctrl;
-		}
+	info->screen_base = ioremap(rivafb_fix.smem_start,
+				    rivafb_fix.smem_len);
+	if (!info->screen_base) {
+		printk(KERN_ERR PFX "cannot ioremap FB base\n");
+		goto err_out_free_base1;
 	}
 
 #ifdef CONFIG_MTRR
 	if (!nomtrr) {
 		default_par->mtrr.vram = mtrr_add(rivafb_fix.smem_start,
-					    rivafb_fix.smem_len,
-					    MTRR_TYPE_WRCOMB, 1);
+					   	  rivafb_fix.smem_len,
+					    	  MTRR_TYPE_WRCOMB, 1);
 		if (default_par->mtrr.vram < 0) {
 			printk(KERN_ERR PFX "unable to setup MTRR\n");
 		} else {
@@ -1909,9 +1819,15 @@
 	}
 #endif /* CONFIG_MTRR */
 
+	/* unlock io */
+	CRTCout(default_par, 0x11, 0xFF);/* vgaHWunlock() + riva unlock (0x7F) */
+	default_par->riva.LockUnlock(&default_par->riva, 0);
+
+	riva_save_state(default_par, &default_par->initial_state);
+
 	if (riva_set_fbinfo(info) < 0) {
 		printk(KERN_ERR PFX "error setting initial video mode\n");
-		goto err_out_cursor;
+		goto err_out_load_state;
 	}
 
 	if (register_framebuffer(info) < 0) {
@@ -1920,7 +1836,7 @@
 		goto err_out_load_state;
 	}
 
-	pci_set_drvdata(pd,info);
+	pci_set_drvdata(pd, info);
 
 	printk(KERN_INFO PFX
 		"PCI nVidia NV%x framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
@@ -1929,26 +1845,31 @@
 		info->fix.id,
 		info->fix.smem_len / (1024 * 1024),
 		info->fix.smem_start);
-
 	return 0;
 
 err_out_load_state:
-err_out_cursor:
+	riva_load_state(default_par, &default_par->initial_state);
 /* err_out_iounmap_fb: */
 	iounmap(info->screen_base);
+err_out_free_base1:
+	release_mem_region(rivafb_fix.smem_start, rivafb_fix.smem_len);
+err_out_iounmap_nv3_pramin:
+	if (default_par->riva.Architecture == NV_ARCH_03) 
+		iounmap((caddr_t)default_par->riva.PRAMIN);
+err_out_free_nv3_pramin:
+	if (default_par->riva.Architecture == NV_ARCH_03)
+		release_mem_region(rivafb_fix.smem_start + 0x00C00000, 0x00008000);
 err_out_iounmap_ctrl:
 	iounmap(default_par->ctrl_base);
-err_out_free_base1:
-	release_mem_region(info->fix.smem_start, info->fix.smem_len);
 err_out_free_base0:
-	release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
+	release_mem_region(rivafb_fix.mmio_start, rivafb_fix.mmio_len);
 err_out_kfree:
 	kfree(info);
 err_out:
 	return -ENODEV;
 }
 
-static void __devexit rivafb_remove_one(struct pci_dev *pd)
+static void __devexit rivafb_remove(struct pci_dev *pd)
 {
 	struct fb_info *info = pci_get_drvdata(pd);
 	struct riva_par *par = (struct riva_par *) info->par;
@@ -1956,6 +1877,8 @@
 	if (!info)
 		return;
 
+	riva_load_state(par, &par->initial_state);
+
 	unregister_framebuffer(info);
 
 #ifdef CONFIG_MTRR
@@ -1971,6 +1894,12 @@
 			   info->fix.mmio_len);
 	release_mem_region(info->fix.smem_start,
 			   info->fix.smem_len);
+
+	if (par->riva.Architecture == NV_ARCH_03) {
+		iounmap((caddr_t)par->riva.PRAMIN);
+		release_mem_region(info->fix.smem_start + 0x00C00000, 0x00008000);
+	}
+	kfree(par);
 	kfree(info);
 	pci_set_drvdata(pd, NULL);
 }
@@ -1992,11 +1921,23 @@
 	while ((this_opt = strsep(&options, ",")) != NULL) {
 		if (!*this_opt)
 			continue;
+		if (!strncmp(this_opt, "noblink", 7)) {
+			noblink = 1;
 #ifdef CONFIG_MTRR
-		if (!strncmp(this_opt, "nomtrr", 6)) {
+		} else if (!strncmp(this_opt, "nomtrr", 6)) {
 			nomtrr = 1;
-		} else
 #endif
+		} else if (!strncmp(this_opt, "forceCRTC", 9)) {
+			char *p;
+			
+			p = this_opt + 9;
+			if (!*p || !*(++p)) continue; 
+			forceCRTC = *p - '0';
+			if (forceCRTC < 0 || forceCRTC > 1) 
+				forceCRTC = -1;
+		} else if (!strncmp(this_opt, "flatpanel", 9)) {
+			flatpanel = 1;
+		} else
 			mode_option = this_opt;
 	}
 	return 0;
@@ -2006,8 +1947,8 @@
 static struct pci_driver rivafb_driver = {
 	name:		"rivafb",
 	id_table:	rivafb_pci_tbl,
-	probe:		rivafb_init_one,
-	remove:		__devexit_p(rivafb_remove_one),
+	probe:		rivafb_probe,
+	remove:		__devexit_p(rivafb_remove),
 };
 
 
@@ -2021,10 +1962,10 @@
 int __init rivafb_init(void)
 {
 	int err;
-
 	err = pci_module_init(&rivafb_driver);
 	if (err)
 		return err;
+	pci_register_driver(&rivafb_driver);
 	return 0;
 }
 
@@ -2038,10 +1979,13 @@
 module_init(rivafb_init);
 module_exit(rivafb_exit);
 
-MODULE_PARM(font, "s");
-MODULE_PARM_DESC(font, "Specifies one of the compiled-in fonts (default=none)");
-MODULE_PARM(noaccel, "i");
-MODULE_PARM_DESC(noaccel, "Disables hardware acceleration (0 or 1=disabled) (default=0)");
+MODULE_PARM(noblink, "i");
+MODULE_PARM_DESC(noblink, "Disables hardware cursor blinking (0 or 1=disabled) (default=0)");
+MODULE_PARM(flatpanel, "i");
+MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
+MODULE_PARM(forceCRTC, "i");
+MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");
+
 #ifdef CONFIG_MTRR
 MODULE_PARM(nomtrr, "i");
 MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
@@ -2049,5 +1993,5 @@
 #endif /* MODULE */
 
 MODULE_AUTHOR("Ani Joshi, maintainer");
-MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2");
+MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2, and the GeForce series");
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/riva/nv_driver.c b/drivers/video/riva/nv_driver.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/video/riva/nv_driver.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,212 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997  David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * GPL licensing note -- nVidia is allowing a liberal interpretation of
+ * the documentation restriction above, to merely say that this nVidia's
+ * copyright and disclaimer should be included with all code derived
+ * from this source.  -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 
+ */
+
+/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
+   <jpaana@s2.org> */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.18 2002/08/0
+5 20:47:06 mvojkovi Exp $ */
+
+#include <linux/delay.h>
+#include <linux/pci_ids.h>
+#include "nv_type.h"
+#include "rivafb.h"
+#include "nvreg.h"
+
+
+#ifndef CONFIG_PCI		/* sanity check */
+#error This driver requires PCI support.
+#endif
+
+#define PFX "rivafb: "
+
+static inline unsigned char MISCin(struct riva_par *par)
+{
+	return (VGA_RD08(par->riva.PVIO, 0x3cc));
+}
+
+static Bool 
+riva_is_connected(struct riva_par *par, Bool second)
+{
+	volatile U032 *PRAMDAC = par->riva.PRAMDAC0;
+	U032 reg52C, reg608;
+	Bool present;
+
+	if(second) PRAMDAC += 0x800;
+
+	reg52C = PRAMDAC[0x052C/4];
+	reg608 = PRAMDAC[0x0608/4];
+
+	PRAMDAC[0x0608/4] = reg608 & ~0x00010000;
+
+	PRAMDAC[0x052C/4] = reg52C & 0x0000FEEE;
+	mdelay(1); 
+	PRAMDAC[0x052C/4] |= 1;
+
+	par->riva.PRAMDAC0[0x0610/4] = 0x94050140;
+	par->riva.PRAMDAC0[0x0608/4] |= 0x00001000;
+
+	mdelay(1);
+
+	present = (PRAMDAC[0x0608/4] & (1 << 28)) ? TRUE : FALSE;
+
+	par->riva.PRAMDAC0[0x0608/4] &= 0x0000EFFF;
+
+	PRAMDAC[0x052C/4] = reg52C;
+	PRAMDAC[0x0608/4] = reg608;
+
+	return present;
+}
+
+static void
+riva_override_CRTC(struct riva_par *par)
+{
+	printk(KERN_INFO PFX
+		"Detected CRTC controller %i being used\n",
+		par->SecondCRTC ? 1 : 0);
+
+	if(par->forceCRTC != -1) {
+		printk(KERN_INFO PFX
+			"Forcing usage of CRTC %i\n", par->forceCRTC);
+		par->SecondCRTC = par->forceCRTC;
+	}
+}
+
+static void
+riva_is_second(struct riva_par *par)
+{
+	if (par->FlatPanel == 1) {
+		switch(par->Chipset) {
+		case NV_CHIP_GEFORCE4_440_GO:
+		case NV_CHIP_GEFORCE4_440_GO_M64:
+		case NV_CHIP_GEFORCE4_420_GO:
+		case NV_CHIP_GEFORCE4_420_GO_M32:
+		case NV_CHIP_QUADRO4_500_GOGL:
+			par->SecondCRTC = TRUE;
+			break;
+		default:
+			par->SecondCRTC = FALSE;
+			break;
+		}
+	} else {
+		if(riva_is_connected(par, 0)) {
+			if(par->riva.PRAMDAC0[0x0000052C/4] & 0x100)
+				par->SecondCRTC = TRUE;
+			else
+				par->SecondCRTC = FALSE;
+		} else 
+		if (riva_is_connected(par, 1)) {
+			if(par->riva.PRAMDAC0[0x0000252C/4] & 0x100)
+				par->SecondCRTC = TRUE;
+			else
+				par->SecondCRTC = FALSE;
+		} else /* default */
+			par->SecondCRTC = FALSE;
+	}
+	riva_override_CRTC(par);
+}
+
+void
+riva_common_setup(struct riva_par *par)
+{
+	par->riva.EnableIRQ = 0;
+	par->riva.PRAMDAC0 = (unsigned *)(par->ctrl_base + 0x00680000);
+	par->riva.PFB = (unsigned *)(par->ctrl_base + 0x00100000);
+	par->riva.PFIFO = (unsigned *)(par->ctrl_base + 0x00002000);
+	par->riva.PGRAPH = (unsigned *)(par->ctrl_base + 0x00400000);
+	par->riva.PEXTDEV = (unsigned *)(par->ctrl_base + 0x00101000);
+	par->riva.PTIMER = (unsigned *)(par->ctrl_base + 0x00009000);
+	par->riva.PMC = (unsigned *)(par->ctrl_base + 0x00000000);
+	par->riva.FIFO = (unsigned *)(par->ctrl_base + 0x00800000);
+	par->riva.PCIO0 = (U008 *)(par->ctrl_base + 0x00601000);
+	par->riva.PDIO0 = (U008 *)(par->ctrl_base + 0x00681000);
+	par->riva.PVIO = (U008 *)(par->ctrl_base + 0x000C0000);
+
+	par->riva.IO = (MISCin(par) & 0x01) ? 0x3D0 : 0x3B0;
+	
+	if (par->FlatPanel == -1) {
+		switch (par->Chipset) {
+		case NV_CHIP_GEFORCE4_440_GO:
+		case NV_CHIP_GEFORCE4_440_GO_M64:
+		case NV_CHIP_GEFORCE4_420_GO:
+		case NV_CHIP_GEFORCE4_420_GO_M32:
+		case NV_CHIP_QUADRO4_500_GOGL:
+		case NV_CHIP_GEFORCE2_GO:
+			printk(KERN_INFO PFX 
+				"On a laptop.  Assuming Digital Flat Panel\n");
+			par->FlatPanel = 1;
+			break;
+		default:
+			break;
+		}
+	}
+	
+	switch (par->Chipset & 0x0ff0) {
+	case 0x0110:
+		if (par->Chipset == NV_CHIP_GEFORCE2_GO)
+			par->SecondCRTC = TRUE; 
+#if defined(__powerpc__)
+		if (par->FlatPanel == 1)
+			par->SecondCRTC = TRUE;
+#endif
+		riva_override_CRTC(par);
+		break;
+	case 0x0170:
+	case 0x0180:
+	case 0x01F0:
+	case 0x0250:
+	case 0x0280:
+		riva_is_second(par);
+		break;
+	default:
+		break;
+	}
+
+	if (par->SecondCRTC) {
+		par->riva.PCIO = par->riva.PCIO0 + 0x2000;
+		par->riva.PCRTC = par->riva.PCRTC0 + 0x800;
+		par->riva.PRAMDAC = par->riva.PRAMDAC0 + 0x800;
+		par->riva.PDIO = par->riva.PDIO0 + 0x2000;
+	} else {
+		par->riva.PCIO = par->riva.PCIO0;
+		par->riva.PCRTC = par->riva.PCRTC0;
+		par->riva.PRAMDAC = par->riva.PRAMDAC0;
+		par->riva.PDIO = par->riva.PDIO0;
+	}
+
+	RivaGetConfig(&par->riva, par->Chipset);
+
+	if (par->FlatPanel == -1) {
+		/* Fix me, need x86 DDC code */
+		par->FlatPanel = 0;
+	}
+	par->riva.flatPanel = (par->FlatPanel > 0) ? TRUE : FALSE;
+}
+
diff -Nru a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
--- a/drivers/video/riva/riva_hw.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/riva/riva_hw.c	Thu Jan 16 18:23:05 2003
@@ -44,10 +44,10 @@
  * from this source.  -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99 
  */
 
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c,v 1.8 2000/02/08 17:19:11 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c,v 1.33 2002/08/05 20:47:06 mvojkovi Exp $ */
 
-#include <linux/pci_ids.h>
 #include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include "riva_hw.h"
 #include "riva_tbl.h"
 #include "nv_type.h"
@@ -81,13 +81,13 @@
 static void vgaLockUnlock
 (
     RIVA_HW_INST *chip,
-    int		  Lock
+    int           Lock
 )
 {
     U008 cr11;
     VGA_WR08(chip->PCIO, 0x3D4, 0x11);
     cr11 = VGA_RD08(chip->PCIO, 0x3D5);
-    if(Lock) cr11 |= 0x80;				
+    if(Lock) cr11 |= 0x80;
     else cr11 &= ~0x80;
     VGA_WR08(chip->PCIO, 0x3D5, cr11);
 }
@@ -99,7 +99,7 @@
 {
     VGA_WR08(chip->PVIO, 0x3C4, 0x06);
     VGA_WR08(chip->PVIO, 0x3C5, Lock ? 0x99 : 0x57);
-    vgaLockUnlock(chip, Lock);	
+    vgaLockUnlock(chip, Lock);
 }
 static void nv4LockUnlock
 (
@@ -109,7 +109,7 @@
 {
     VGA_WR08(chip->PCIO, 0x3D4, 0x1F);
     VGA_WR08(chip->PCIO, 0x3D5, Lock ? 0x99 : 0x57);
-    vgaLockUnlock(chip, Lock);	
+    vgaLockUnlock(chip, Lock);
 }
 
 static int ShowHideCursor
@@ -121,7 +121,7 @@
     int cursor;
     cursor                      =  chip->CurrentState->cursor1;
     chip->CurrentState->cursor1 = (chip->CurrentState->cursor1 & 0xFE) |
-	                          (ShowHide & 0x01);
+                                  (ShowHide & 0x01);
     VGA_WR08(chip->PCIO, 0x3D4, 0x31);
     VGA_WR08(chip->PCIO, 0x3D5, chip->CurrentState->cursor1);
     return (cursor & 0x01);
@@ -615,7 +615,7 @@
     nv3_sim_state sim_data;
     unsigned int M, N, P, pll, MClk;
     
-    pll = chip->PRAMDAC[0x00000504/4];
+    pll = chip->PRAMDAC0[0x00000504/4]; 
     M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
     MClk = (N * chip->CrystalFreqKHz / M) >> P;
     sim_data.pix_bpp        = (char)pixelDepth;
@@ -802,10 +802,10 @@
     nv4_sim_state sim_data;
     unsigned int M, N, P, pll, MClk, NVClk, cfg1;
 
-    pll = chip->PRAMDAC[0x00000504/4];
+    pll = chip->PRAMDAC0[0x00000504/4];
     M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
     MClk  = (N * chip->CrystalFreqKHz / M) >> P;
-    pll = chip->PRAMDAC[0x00000500/4];
+    pll = chip->PRAMDAC0[0x00000500/4];
     M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
     NVClk  = (N * chip->CrystalFreqKHz / M) >> P;
     cfg1 = chip->PFB[0x00000204/4];
@@ -1063,10 +1063,10 @@
     nv10_sim_state sim_data;
     unsigned int M, N, P, pll, MClk, NVClk, cfg1;
 
-    pll = chip->PRAMDAC[0x00000504/4];
+    pll = chip->PRAMDAC0[0x00000504/4];
     M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
     MClk  = (N * chip->CrystalFreqKHz / M) >> P;
-    pll = chip->PRAMDAC[0x00000500/4];
+    pll = chip->PRAMDAC0[0x00000500/4];
     M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
     NVClk  = (N * chip->CrystalFreqKHz / M) >> P;
     cfg1 = chip->PFB[0x00000204/4];
@@ -1092,6 +1092,57 @@
     }
 }
 
+static void nForceUpdateArbitrationSettings
+(
+    unsigned      VClk,
+    unsigned      pixelDepth,
+    unsigned     *burst,
+    unsigned     *lwm,
+    RIVA_HW_INST *chip
+)
+{
+    nv10_fifo_info fifo_data;
+    nv10_sim_state sim_data;
+    unsigned int M, N, P, pll, MClk, NVClk;
+    unsigned int uMClkPostDiv;
+    struct pci_dev *dev;
+
+    dev = pci_find_slot(0, 3);
+    pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
+    uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
+
+    if(!uMClkPostDiv) uMClkPostDiv = 4;
+    MClk = 400000 / uMClkPostDiv;
+
+    pll = chip->PRAMDAC0[0x00000500/4];
+    M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
+    NVClk  = (N * chip->CrystalFreqKHz / M) >> P;
+    sim_data.pix_bpp        = (char)pixelDepth;
+    sim_data.enable_video   = 0;
+    sim_data.enable_mp      = 0;
+
+    dev = pci_find_slot(0, 1);
+    pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
+    sim_data.memory_type    = (sim_data.memory_type >> 12) & 1;
+
+    sim_data.memory_width   = 64;
+    sim_data.mem_latency    = 3;
+    sim_data.mem_aligned    = 1;
+    sim_data.mem_page_miss  = 10;
+    sim_data.gr_during_vid  = 0;
+    sim_data.pclk_khz       = VClk;
+    sim_data.mclk_khz       = MClk;
+    sim_data.nvclk_khz      = NVClk;
+    nv10CalcArbitration(&fifo_data, &sim_data);
+    if (fifo_data.valid)
+    {
+        int  b = fifo_data.graphics_burst_size >> 4;
+        *burst = 0;
+        while (b >>= 1) (*burst)++;
+        *lwm   = fifo_data.graphics_lwm >> 3;
+    }
+}
+
 /****************************************************************************\
 *                                                                            *
 *                          RIVA Mode State Routines                          *
@@ -1140,8 +1191,8 @@
             for (M = lowM; M <= highM; M++)
             {
                 N    = (VClk << P) * M / chip->CrystalFreqKHz;
-		if(N <= 255) {
-               	Freq = (chip->CrystalFreqKHz * N / M) >> P;
+                if(N <= 255) {
+                Freq = (chip->CrystalFreqKHz * N / M) >> P;
                 if (Freq > VClk)
                     DeltaNew = Freq - VClk;
                 else
@@ -1179,7 +1230,7 @@
     /*
      * Save mode parameters.
      */
-    state->bpp    = bpp;
+    state->bpp    = bpp;    /* this is not bitsPerPixel, it's 8,15,16,32 */
     state->width  = width;
     state->height = height;
     /*
@@ -1221,20 +1272,36 @@
             state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
             break;
         case NV_ARCH_10:
-            nv10UpdateArbitrationSettings(VClk, 
+        case NV_ARCH_20:
+            if((chip->Chipset == NV_CHIP_IGEFORCE2) ||
+               (chip->Chipset == NV_CHIP_0x01F0))
+            {
+                nForceUpdateArbitrationSettings(VClk,
+                                          pixelDepth * 8,
+                                         &(state->arbitration0),
+                                         &(state->arbitration1),
+                                          chip);
+            } else {
+                nv10UpdateArbitrationSettings(VClk, 
                                           pixelDepth * 8, 
                                          &(state->arbitration0),
                                          &(state->arbitration1),
                                           chip);
-            state->cursor0  = 0x00; 
-            state->cursor1  = 0xFC; 
-            state->cursor2  = 0x00000000; 
+            }
+            state->cursor0  = 0x80 | (chip->CursorStart >> 17);
+            state->cursor1  = (chip->CursorStart >> 11) << 2;
+            state->cursor2  = chip->CursorStart >> 24;
             state->pllsel   = 0x10000700;
             state->config   = chip->PFB[0x00000200/4];
             state->general  = bpp == 16 ? 0x00101100 : 0x00100100;
             state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
             break;
     }
+
+    /* Paul Richards: below if block borks things in kernel for some reason */
+    /* if((bpp != 8) && (chip->Architecture != NV_ARCH_03))
+    state->general |= 0x00000030; */
+
     state->vpll     = (p << 16) | (n << 8) | m;
     state->repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3;
     state->pixel    = pixelDepth > 2   ? 3    : pixelDepth;
@@ -1280,7 +1347,7 @@
             chip->Tri05 = (RivaTexturedTriangle05 *)&(chip->FIFO[0x0000E000/4]);
             break;
         case NV_ARCH_10:
-	case NV_ARCH_20:
+        case NV_ARCH_20:
             /*
              * Initialize state for the RivaTriangle3D05 routines.
              */
@@ -1389,6 +1456,13 @@
             chip->PGRAPH[0x0000067C/4] = state->pitch3;
             break;
         case NV_ARCH_10:
+        case NV_ARCH_20:
+            if(chip->twoHeads) {
+               VGA_WR08(chip->PCIO, 0x03D4, 0x44);
+               VGA_WR08(chip->PCIO, 0x03D5, state->crtcOwner);
+               chip->LockUnlock(chip, 0);
+            }
+
             LOAD_FIXED_STATE(nv10,PFIFO);
             LOAD_FIXED_STATE(nv10,PRAMIN);
             LOAD_FIXED_STATE(nv10,PGRAPH);
@@ -1417,15 +1491,54 @@
                     chip->Tri03 = 0L;
                     break;
             }
-            chip->PGRAPH[0x00000640/4] = state->offset0;
-            chip->PGRAPH[0x00000644/4] = state->offset1;
-            chip->PGRAPH[0x00000648/4] = state->offset2;
-            chip->PGRAPH[0x0000064C/4] = state->offset3;
-            chip->PGRAPH[0x00000670/4] = state->pitch0;
-            chip->PGRAPH[0x00000674/4] = state->pitch1;
-            chip->PGRAPH[0x00000678/4] = state->pitch2;
-            chip->PGRAPH[0x0000067C/4] = state->pitch3;
-            chip->PGRAPH[0x00000680/4] = state->pitch3;
+
+            if(chip->Architecture == NV_ARCH_10) {
+                chip->PGRAPH[0x00000640/4] = state->offset0;
+                chip->PGRAPH[0x00000644/4] = state->offset1;
+                chip->PGRAPH[0x00000648/4] = state->offset2;
+                chip->PGRAPH[0x0000064C/4] = state->offset3;
+                chip->PGRAPH[0x00000670/4] = state->pitch0;
+                chip->PGRAPH[0x00000674/4] = state->pitch1;
+                chip->PGRAPH[0x00000678/4] = state->pitch2;
+                chip->PGRAPH[0x0000067C/4] = state->pitch3;
+                chip->PGRAPH[0x00000680/4] = state->pitch3;
+        } else {
+        chip->PGRAPH[0x00000820/4] = state->offset0;
+        chip->PGRAPH[0x00000824/4] = state->offset1;
+        chip->PGRAPH[0x00000828/4] = state->offset2;
+        chip->PGRAPH[0x0000082C/4] = state->offset3;
+        chip->PGRAPH[0x00000850/4] = state->pitch0;
+        chip->PGRAPH[0x00000854/4] = state->pitch1;
+        chip->PGRAPH[0x00000858/4] = state->pitch2;
+        chip->PGRAPH[0x0000085C/4] = state->pitch3;
+        chip->PGRAPH[0x00000860/4] = state->pitch3;
+        chip->PGRAPH[0x00000864/4] = state->pitch3;
+        chip->PGRAPH[0x000009A4/4] = chip->PFB[0x00000200/4];
+        chip->PGRAPH[0x000009A8/4] = chip->PFB[0x00000204/4];
+        }
+            if(chip->twoHeads) {
+               chip->PCRTC0[0x00000860/4] = state->head;
+               chip->PCRTC0[0x00002860/4] = state->head2;
+            }
+            chip->PRAMDAC[0x00000404/4] |= (1 << 25);
+
+            chip->PMC[0x00008704/4] = 1;
+            chip->PMC[0x00008140/4] = 0;
+            chip->PMC[0x00008920/4] = 0;
+            chip->PMC[0x00008924/4] = 0;
+            chip->PMC[0x00008908/4] = 0x01ffffff;
+            chip->PMC[0x0000890C/4] = 0x01ffffff;
+            chip->PMC[0x00001588/4] = 0;
+
+            chip->PFB[0x00000240/4] = 0;
+            chip->PFB[0x00000244/4] = 0;
+            chip->PFB[0x00000248/4] = 0;
+            chip->PFB[0x0000024C/4] = 0;
+            chip->PFB[0x00000250/4] = 0;
+            chip->PFB[0x00000254/4] = 0;
+            chip->PFB[0x00000258/4] = 0;
+            chip->PFB[0x0000025C/4] = 0;
+
             chip->PGRAPH[0x00000B00/4] = chip->PFB[0x00000240/4];
             chip->PGRAPH[0x00000B04/4] = chip->PFB[0x00000244/4];
             chip->PGRAPH[0x00000B08/4] = chip->PFB[0x00000248/4];
@@ -1499,7 +1612,27 @@
             chip->PGRAPH[0x00000F50/4] = 0x00000040;
             for (i = 0; i < 4; i++)
                 chip->PGRAPH[0x00000F54/4] = 0x00000000;
-    	    break;
+
+            chip->PCRTC[0x00000810/4] = state->cursorConfig;
+
+            if(chip->flatPanel) {
+               if((chip->Chipset & 0x0ff0) == 0x0110) {
+                   chip->PRAMDAC[0x0528/4] = state->dither;
+               } else 
+               if((chip->Chipset & 0x0ff0) >= 0x0170) {
+                   chip->PRAMDAC[0x083C/4] = state->dither;
+               }
+            
+               VGA_WR08(chip->PCIO, 0x03D4, 0x53);
+               VGA_WR08(chip->PCIO, 0x03D5, 0);
+               VGA_WR08(chip->PCIO, 0x03D4, 0x54);
+               VGA_WR08(chip->PCIO, 0x03D5, 0);
+               VGA_WR08(chip->PCIO, 0x03D4, 0x21);
+               VGA_WR08(chip->PCIO, 0x03D5, 0xfa);
+            }
+
+            VGA_WR08(chip->PCIO, 0x03D4, 0x41);
+            VGA_WR08(chip->PCIO, 0x03D5, state->extra);
     }
     LOAD_FIXED_STATE(Riva,FIFO);
     UpdateFifoState(chip);
@@ -1524,11 +1657,21 @@
     VGA_WR08(chip->PCIO, 0x03D5, state->cursor0);
     VGA_WR08(chip->PCIO, 0x03D4, 0x31);
     VGA_WR08(chip->PCIO, 0x03D5, state->cursor1);
-    chip->PRAMDAC[0x00000300/4]  = state->cursor2;
-    chip->PRAMDAC[0x00000508/4]  = state->vpll;
-    chip->PRAMDAC[0x0000050C/4]  = state->pllsel;
+    VGA_WR08(chip->PCIO, 0x03D4, 0x2F);
+    VGA_WR08(chip->PCIO, 0x03D5, state->cursor2);
+    VGA_WR08(chip->PCIO, 0x03D4, 0x39);
+    VGA_WR08(chip->PCIO, 0x03D5, state->interlace);
+
+    if(!chip->flatPanel) {
+       chip->PRAMDAC0[0x00000508/4] = state->vpll;
+       chip->PRAMDAC0[0x0000050C/4] = state->pllsel;
+       if(chip->twoHeads)
+          chip->PRAMDAC0[0x00000520/4] = state->vpll2;
+    }  else {
+       chip->PRAMDAC[0x00000848/4]  = state->scale;
+    }  
     chip->PRAMDAC[0x00000600/4]  = state->general;
-    	
+
     /*
      * Turn off VBlank enable and reset.
      */
@@ -1576,10 +1719,15 @@
     state->cursor0      = VGA_RD08(chip->PCIO, 0x03D5);
     VGA_WR08(chip->PCIO, 0x03D4, 0x31);
     state->cursor1      = VGA_RD08(chip->PCIO, 0x03D5);
-    state->cursor2      = chip->PRAMDAC[0x00000300/4];
-    state->vpll         = chip->PRAMDAC[0x00000508/4];
-    state->pllsel       = chip->PRAMDAC[0x0000050C/4];
+    VGA_WR08(chip->PCIO, 0x03D4, 0x2F);
+    state->cursor2      = VGA_RD08(chip->PCIO, 0x03D5);
+    VGA_WR08(chip->PCIO, 0x03D4, 0x39);
+    state->interlace    = VGA_RD08(chip->PCIO, 0x03D5);
+    state->vpll         = chip->PRAMDAC0[0x00000508/4];
+    state->vpll2        = chip->PRAMDAC0[0x00000520/4];
+    state->pllsel       = chip->PRAMDAC0[0x0000050C/4];
     state->general      = chip->PRAMDAC[0x00000600/4];
+    state->scale        = chip->PRAMDAC[0x00000848/4];
     state->config       = chip->PFB[0x00000200/4];
     switch (chip->Architecture)
     {
@@ -1604,6 +1752,7 @@
             state->pitch3   = chip->PGRAPH[0x0000067C/4];
             break;
         case NV_ARCH_10:
+        case NV_ARCH_20:
             state->offset0  = chip->PGRAPH[0x00000640/4];
             state->offset1  = chip->PGRAPH[0x00000644/4];
             state->offset2  = chip->PGRAPH[0x00000648/4];
@@ -1612,6 +1761,22 @@
             state->pitch1   = chip->PGRAPH[0x00000674/4];
             state->pitch2   = chip->PGRAPH[0x00000678/4];
             state->pitch3   = chip->PGRAPH[0x0000067C/4];
+            if(chip->twoHeads) {
+               state->head     = chip->PCRTC0[0x00000860/4];
+               state->head2    = chip->PCRTC0[0x00002860/4];
+               VGA_WR08(chip->PCIO, 0x03D4, 0x44);
+               state->crtcOwner = VGA_RD08(chip->PCIO, 0x03D5);
+            }
+            VGA_WR08(chip->PCIO, 0x03D4, 0x41);
+            state->extra = VGA_RD08(chip->PCIO, 0x03D5);
+            state->cursorConfig = chip->PCRTC[0x00000810/4];
+
+            if((chip->Chipset & 0x0ff0) == 0x0110) {
+                state->dither = chip->PRAMDAC[0x0528/4];
+            } else 
+            if((chip->Chipset & 0x0ff0) >= 0x0170) {
+                state->dither = chip->PRAMDAC[0x083C/4];
+            }
             break;
     }
 }
@@ -1621,6 +1786,15 @@
     unsigned      start
 )
 {
+    chip->PCRTC[0x800/4] = start;
+}
+
+static void SetStartAddress3
+(
+    RIVA_HW_INST *chip,
+    unsigned      start
+)
+{
     int offset = start >> 2;
     int pan    = (start & 3) << 1;
     unsigned char tmp;
@@ -1801,7 +1975,7 @@
                 break;
         }
     }        
-    chip->CrystalFreqKHz   = (chip->PEXTDEV[0x00000000/4] & 0x00000020) ? 14318 : 13500;
+    chip->CrystalFreqKHz   = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
     chip->CURSOR           = &(chip->PRAMIN[0x00008000/4 - 0x0800/4]);
     chip->VBlankBit        = 0x00000100;
     chip->MaxVClockFreqKHz = 256000;
@@ -1813,7 +1987,7 @@
     chip->CalcStateExt    = CalcStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
-    chip->SetStartAddress = SetStartAddress;
+    chip->SetStartAddress = SetStartAddress3;
     chip->SetSurfaces2D   = nv3SetSurfaces2D;
     chip->SetSurfaces3D   = nv3SetSurfaces3D;
     chip->LockUnlock      = nv3LockUnlock;
@@ -1879,7 +2053,7 @@
 static void nv10GetConfig
 (
     RIVA_HW_INST *chip,
-    unsigned int chipset	
+    unsigned int chipset
 )
 {
     struct pci_dev* dev;
@@ -1888,7 +2062,7 @@
 #ifdef __BIG_ENDIAN
     /* turn on big endian register access */
     chip->PMC[0x00000004/4] = 0x01000001;
-#endif		
+#endif
 
     /*
      * Fill in chip configuration.
@@ -1902,33 +2076,33 @@
         pci_read_config_dword(dev, 0x84, &amt);
         chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
     } else {
-    switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF)
-    {
-        case 0x02:
-            chip->RamAmountKBytes = 1024 * 2;
-            break;
-        case 0x04:
-            chip->RamAmountKBytes = 1024 * 4;
-            break;
-        case 0x08:
-            chip->RamAmountKBytes = 1024 * 8;
-            break;
-        case 0x10:
-            chip->RamAmountKBytes = 1024 * 16;
-            break;
-        case 0x20:
-            chip->RamAmountKBytes = 1024 * 32;
-            break;
-        case 0x40:
-            chip->RamAmountKBytes = 1024 * 64;
-            break;
-        case 0x80:
-            chip->RamAmountKBytes = 1024 * 128;
-            break;
-        default:
-            chip->RamAmountKBytes = 1024 * 16;
-            break;
-    }
+        switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF)
+        {
+            case 0x02:
+                chip->RamAmountKBytes = 1024 * 2;
+                break;
+            case 0x04:
+                chip->RamAmountKBytes = 1024 * 4;
+                break;
+            case 0x08:
+                chip->RamAmountKBytes = 1024 * 8;
+                break;
+            case 0x10:
+                chip->RamAmountKBytes = 1024 * 16;
+                break;
+            case 0x20:
+                chip->RamAmountKBytes = 1024 * 32;
+                break;
+            case 0x40:
+                chip->RamAmountKBytes = 1024 * 64;
+                break;
+            case 0x80:
+                chip->RamAmountKBytes = 1024 * 128;
+                break;
+            default:
+                chip->RamAmountKBytes = 1024 * 16;
+                break;
+        }
     }
     switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
     {
@@ -1939,8 +2113,24 @@
             chip->RamBandwidthKBytesPerSec = 1000000;
             break;
     }
-    chip->CrystalFreqKHz   = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
-    chip->CURSOR           = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]);
+    chip->CrystalFreqKHz = (chip->PEXTDEV[0x0000/4] & (1 << 6)) ? 14318 :
+                                                                  13500;
+
+    switch (chipset & 0x0ff0) {
+    case 0x0170:
+    case 0x0180:
+    case 0x01F0:
+    case 0x0250:
+    case 0x0280:
+       if(chip->PEXTDEV[0x0000/4] & (1 << 22))
+           chip->CrystalFreqKHz = 27000;
+       break;
+    default:
+       break;
+    }
+
+    chip->CursorStart      = (chip->RamAmountKBytes - 128) * 1024;
+    chip->CURSOR           = NULL;  /* can't set this here */
     chip->VBlankBit        = 0x00000001;
     chip->MaxVClockFreqKHz = 350000;
     /*
@@ -1955,11 +2145,25 @@
     chip->SetSurfaces2D   = nv10SetSurfaces2D;
     chip->SetSurfaces3D   = nv10SetSurfaces3D;
     chip->LockUnlock      = nv4LockUnlock;
+
+    switch(chipset & 0x0ff0) {
+    case 0x0110:
+    case 0x0170:
+    case 0x0180:
+    case 0x01F0:
+    case 0x0250:
+    case 0x0280:
+        chip->twoHeads = TRUE;
+        break;
+    default:
+        chip->twoHeads = FALSE;
+        break;
+    }
 }
 int RivaGetConfig
 (
     RIVA_HW_INST *chip,
-    unsigned int chipset 	
+    unsigned int chipset
 )
 {
     /*
@@ -1978,13 +2182,13 @@
             nv4GetConfig(chip);
             break;
         case NV_ARCH_10:
-	case NV_ARCH_20:
+        case NV_ARCH_20:
             nv10GetConfig(chip, chipset);
             break;
         default:
             return (-1);
     }
-    chip->Chipset = chipset;	
+    chip->Chipset = chipset;
     /*
      * Fill in FIFO pointers.
      */
diff -Nru a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
--- a/drivers/video/riva/rivafb.h	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/riva/rivafb.h	Thu Jan 16 18:23:05 2003
@@ -23,10 +23,6 @@
 	RIVA_HW_STATE ext;
 };
 
-typedef struct {
-	unsigned char red, green, blue, transp;
-} riva_cfb8_cmap_t;
-
 struct riva_par {
 	RIVA_HW_INST riva;	/* interface to riva_hw.c */
 
@@ -37,11 +33,18 @@
 	struct riva_regs current_state;
 	struct vgastate state;
 	atomic_t ref_count;
-	riva_cfb8_cmap_t cmap[256];	/* VGA DAC palette cache */
-	u32 riva_palette[16];
 	u32 cursor_data[32 * 32/4];
 	int cursor_reset;
 	unsigned char *EDID;
+
+	int panel_xres, panel_yres;
+	int hOver_plus, hSync_width, hblank;
+	int vOver_plus, vSync_width, vblank;
+	int hAct_high, vAct_high, interlaced;
+	int synct, misc, clock;
+
+	int use_default_var;
+	int got_dfpinfo;
 	unsigned int Chipset;
 	int forceCRTC;
 	Bool SecondCRTC;
diff -Nru a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h
--- a/drivers/video/sa1100fb.h	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/sa1100fb.h	Thu Jan 16 18:23:05 2003
@@ -103,9 +103,6 @@
 	wait_queue_head_t	ctrlr_wait;
 	struct work_struct	task;
 
-#ifdef CONFIG_PM
-	struct pm_dev		*pm;
-#endif
 #ifdef CONFIG_CPU_FREQ
 	struct notifier_block	freq_transition;
 	struct notifier_block	freq_policy;
@@ -128,6 +125,7 @@
 #define C_REENABLE		(4)
 #define C_DISABLE_PM		(5)
 #define C_ENABLE_PM		(6)
+#define C_STARTUP		(7)
 
 #define SA1100_NAME	"SA1100"
 
diff -Nru a/drivers/video/sstfb.c b/drivers/video/sstfb.c
--- a/drivers/video/sstfb.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/sstfb.c	Thu Jan 16 18:23:06 2003
@@ -15,14 +15,16 @@
  *	(enable driver on big-endian machines (hppa), ioctl fixes)
  * 12/2002 Helge Deller    <deller@gmx.de>
  *	(port driver to new frambuffer infrastructure)
+ * 01/2003 Helge Deller    <deller@gmx.de>
+ *	(initial work on fb hardware acceleration for voodoo2)
  *
  */
 
 /*
  * The voodoo1 has the following memory mapped adress space:
- * 0x000000 - 0x3fffff : registers              (4Mb)
- * 0x400000 - 0x7fffff : linear frame buffer    (4Mb)
- * 0x800000 - 0xffffff : texture memory         (8Mb)
+ * 0x000000 - 0x3fffff : registers              (4MB)
+ * 0x400000 - 0x7fffff : linear frame buffer    (4MB)
+ * 0x800000 - 0xffffff : texture memory         (8MB)
  */
 
 /*
@@ -34,13 +36,11 @@
       the one ...
 -TODO: in  set_var check the validity of timings (hsync vsync)...
 -TODO: check and recheck the use of sst_wait_idle : we dont flush the fifo via
-       a nop command . so it's ok as long as the commands we pass don't go
+       a nop command. so it's ok as long as the commands we pass don't go
        through the fifo. warning: issuing a nop command seems to need pci_fifo
 -FIXME: in case of failure in the init sequence, be sure we return to a safe
         state.
 -FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
--ASK: I stole "inverse" but seems it doesn't work... check what it realy does...
--TODO: change struct fb_info fb_info from static to array/dynamic
  */
 
 /*
@@ -106,13 +106,11 @@
 
 /* initialized by setup */
 
-static int inverse;		/* invert colormap */
 static int vgapass;		/* enable Vga passthrough cable */
-static int mem;			/* mem size in Mb , 0 = autodetect */
+static int mem;			/* mem size in MB, 0 = autodetect */
 static int clipping = 1;	/* use clipping (slower, safer) */
 static int gfxclk;		/* force FBI freq in Mhz . Dangerous */
 static int slowpci;		/* slow PCI settings */
-static int dev = -2;		/* specify device (0..n) -2=all -1=none*/
 
 static char *mode_option __devinitdata;
 
@@ -121,7 +119,7 @@
 	ID_VOODOO2 = 1,
 };
 
-#define IS_VOODOO2(par) ((par)->type == ID_VOODOO2 )
+#define IS_VOODOO2(par) ((par)->type == ID_VOODOO2)
 
 static struct sst_spec voodoo_spec[] __devinitdata = {
  { .name = "Voodoo Graphics", .default_gfx_clock = 50000, .max_gfxclk = 60 },
@@ -166,84 +164,12 @@
  * debug functions
  */
 
-static void sstfb_test16(struct fb_info *info);
-#if EN_24_32_BPP
-static void sstfb_test32(struct fb_info *info);
-#endif
-
-#if 0
-static void __Dump_regs (struct sstfb_info *sst_info)
-{
-	struct { u32 reg ; char * reg_name;}  pci_regs [] =  {
-		{ PCI_INIT_ENABLE, "initenable"},
-		{ PCI_VCLK_ENABLE, "enable vclk"},
-		{ PCI_VCLK_DISABLE, "disable vclk"},
-	};
-
-	struct { u32 reg ; char * reg_name;}  sst_regs [] =  {
-		{FBIINIT0,"fbiinit0"},
-		{FBIINIT1,"fbiinit1"},
-		{FBIINIT2,"fbiinit2"},
-		{FBIINIT3,"fbiinit3"},
-		{FBIINIT4,"fbiinit4"},
-		{FBIINIT5,"fbiinit5"},
-		{FBIINIT6,"fbiinit6"},
-		{FBIINIT7,"fbiinit7"},
-		{LFBMODE,"lfbmode"},
-		{FBZMODE,"fbzmode"},
-	};
-	int pci_s = sizeof(pci_regs)/sizeof(*pci_regs);
-	int sst_s = sizeof(sst_regs)/sizeof(*sst_regs);
-	u32 pci_res[pci_s];
-	u32 sst_res[sst_s];
-
-	struct pci_dev * dev = sst_info->dev;
-
-	int i;
+static void sstfb_drawdebugimage(struct fb_info *info);
+static int sstfb_dump_regs(struct fb_info *info);
 
-	for (i=0; i < pci_s ; i++ ) {
-		pci_read_config_dword ( dev, pci_regs[i].reg , &pci_res[i]) ;
-	}
-	for (i=0; i < sst_s ; i++ ) {
-		sst_res[i]=sst_read(sst_regs[i].reg);
-	}
-
-	dprintk ("Dump regs\n");
-	for (i=0; i < pci_s ; i++ ) {
-		dprintk("%s = %0#10x\n", pci_regs[i].reg_name , pci_res[i]) ;
-	}
-	for (i=0; i < sst_s ; i++ ) {
-		dprintk("%s = %0#10x\n", sst_regs[i].reg_name , sst_res[i]) ;
-	}
-}
-#endif
-
-#if (SST_DEBUG_VAR > 0)
-/* debug info / dump a fb_var_screeninfo */
-static void sst_dbg_print_var(struct fb_var_screeninfo *var) {
-	dprintk(" {%d, %d, %d, %d, %d, %d, %d, %d,\n",
-	        var->xres, var->yres, var->xres_virtual, var->yres_virtual,
-	        var->xoffset, var->yoffset,
-	        var->bits_per_pixel, var->grayscale);
-	dprintk(" {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d},\n",
-	        var->red.offset, var->red.length, var->red.msb_right,
-	        var->green.offset, var->green.length, var->green.msb_right,
-	        var->blue.offset, var->blue.length, var->blue.msb_right,
-	        var->transp.offset, var->transp.length,
-	        var->transp.msb_right);
-	dprintk(" %d, %d, %d, %d, %d,\n",
-	        var->nonstd, var->activate,
-	        var->height, var->width, var->accel_flags);
-	dprintk(" %d, %d, %d, %d, %d, %d, %d,\n",
-	        var->pixclock, var->left_margin, var->right_margin,
-	        var->upper_margin, var->lower_margin,
-	        var->hsync_len, var->vsync_len);
-	dprintk(" %#x, %#x}\n",var->sync, var->vmode);
-}
-#endif /* (SST_DEBUG_VAR > 0) */
 
 #if (SST_DEBUG_REG > 0)
-static void sst_dbg_print_read_reg (u32 reg, u32 val) {
+static void sst_dbg_print_read_reg(u32 reg, u32 val) {
 	const char *regname;
 	switch (reg) {
 	case FBIINIT0:	regname = "FbiInit0"; break;
@@ -261,7 +187,7 @@
 		r_dprintk(" sst_read(%s): %#x\n", regname, val);
 }
 
-static void sst_dbg_print_write_reg (u32 reg, u32 val) {
+static void sst_dbg_print_write_reg(u32 reg, u32 val) {
 	const char *regname;
 	switch (reg) {
 	case FBIINIT0:	regname = "FbiInit0"; break;
@@ -329,13 +255,14 @@
  * in a row a "idle" answer to our requests
  */
 
-#define sst_wait_idle()  __sst_wait_idle(par->mmio_vbase)
+#define sst_wait_idle() __sst_wait_idle(par->mmio_vbase)
 
 static int __sst_wait_idle(u_long vbase)
 {
 	int count = 0;
 
-	f_ddprintk("sst_wait_idle\n");
+	/* if (doFBINOP) __sst_write(vbase, NOPCMD, 0); */
+
 	while(1) {
 		if (__sst_read(vbase, STATUS) & STATUS_FBI_BUSY) {
 			f_dddprintk("status: busy\n");
@@ -359,29 +286,19 @@
 {
 	u8 ret;
 
-#ifdef SST_DEBUG
-	if ((reg & 0x07) != reg) {
-		dprintk("bug line %d: register adress '%d' is too high\n",
-		         __LINE__,reg);
-	}
-#endif
 	reg &= 0x07;
 	__sst_write(vbase, DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD );
 	__sst_wait_idle(vbase);
 	/* udelay(10); */
 	ret = __sst_read(vbase, DAC_READ) & 0xff;
 	r_dprintk("sst_dac_read(%#x): %#x\n", reg, ret);
+
 	return ret;
 }
 
 static void __sst_dac_write(u_long vbase, u8 reg, u8 val)
 {
 	r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val);
-#ifdef SST_DEBUG
-	if ((reg & 0x07) != reg)
-		dprintk("bug line %d: register adress '%d' is too high\n",
-		         __LINE__,reg);
-#endif
 	reg &= 0x07;
 	__sst_write(vbase, DAC_DATA,(((u32)reg << 8)) | (u32)val);
 }
@@ -420,7 +337,6 @@
 	int best_n = -1;
 	int best_m = -1;
 
-	f_dprintk("sst_calc_pll(%dKhz)\n", freq);
 	best_err = freq;
 	p = 3;
 	/* f * 2^P = vco should be less than VCOmax ~ 250 MHz for ics*/
@@ -456,7 +372,19 @@
 }
 
 /*
- * Frame buffer API
+ * clear lfb screen
+ */
+static void sstfb_clear_screen(struct fb_info *info)
+{
+	/* clear screen */
+	fb_memset(info->screen_base, 0, info->fix.smem_len);
+}
+
+
+/**
+ *      sstfb_check_var - Optional function.  Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
  */
 static int sstfb_check_var(struct fb_var_screeninfo *var,
 		struct fb_info *info)
@@ -464,14 +392,14 @@
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
 	int hSyncOff   = var->xres + var->right_margin + var->left_margin;
 	int vSyncOff   = var->yres + var->lower_margin + var->upper_margin;
-	int vBackPorch = var->left_margin, yDim = var->yres, vSyncOn = var->vsync_len;
+	int vBackPorch = var->left_margin, yDim = var->yres;
+	int vSyncOn    = var->vsync_len;
 	int tiles_in_X, real_length;
 	unsigned int freq;
 
-	f_dprintk("sstfb_check_var()\n");
-	
 	if (sst_calc_pll(PICOS2KHZ(var->pixclock), &freq, &par->pll)) {
-		eprintk("Pixclock at %ld KHZ out of range\n", PICOS2KHZ(var->pixclock));
+		eprintk("Pixclock at %ld KHZ out of range\n",
+				PICOS2KHZ(var->pixclock));
 		return -EINVAL;
 	}
 	var->pixclock = KHZ2PICOS(freq);
@@ -500,7 +428,6 @@
 	default :
 		eprintk("Unsupported bpp %d\n", var->bits_per_pixel);
 		return -EINVAL;
-		break;
 	}
 	
 	/* validity tests */
@@ -574,10 +501,10 @@
 
 	var->sync &= (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);
 	var->vmode &= (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE);
-	var->xoffset		= 0;
-	var->yoffset		= 0;
-	var->height		= -1;
-	var->width		= -1;
+	var->xoffset = 0;
+	var->yoffset = 0;
+	var->height  = -1;
+	var->width   = -1;
 
 	/*
 	 * correct the color bit fields
@@ -611,12 +538,15 @@
 		break;
 #endif
 	default:
-		BUG();
 		return -EINVAL;
 	}
 	return 0;
 }
 
+/**
+ *      sstfb_set_par - Optional function.  Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ */
 static int sstfb_set_par(struct fb_info *info)
 {
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
@@ -647,21 +577,20 @@
 	if (IS_VOODOO2(par)) {
 		/* voodoo2 has 32 pixel wide tiles , BUT stange things
 		   happen with odd number of tiles */
-		par->tiles_in_X= (info->var.xres + 63 ) / 64 * 2;
+		par->tiles_in_X = (info->var.xres + 63 ) / 64 * 2;
 	} else {
 		/* voodoo1 has 64 pixels wide tiles. */
-		par->tiles_in_X= (info->var.xres + 63 ) / 64;
+		par->tiles_in_X = (info->var.xres + 63 ) / 64;
 	}
 
-	f_dprintk("sst_set_par(%dx%d)\n", info->var.xres, info->var.yres);
-	f_ddprintk("var->hsync_len hSyncOff var->vsync_len vSyncOff\n");
+	f_ddprintk("hsync_len hSyncOff vsync_len vSyncOff\n");
 	f_ddprintk("%-7d %-8d %-7d %-8d\n",
 	           info->var.hsync_len, par->hSyncOff,
 	           par->vSyncOn, par->vSyncOff);
-	f_ddprintk("var->left_margin var->upper_margin var->xres var->yres Freq\n");
-	f_ddprintk("%-10d %-10d %-4d %-4d %-8d\n",
-	           info->var.left_margin, var->upper_margin,
-	           info->var.xres, info->var.yres, par->freq);
+	f_ddprintk("left_margin upper_margin xres yres Freq\n");
+	f_ddprintk("%-10d %-10d %-4d %-4d %-8ld\n",
+	           info->var.left_margin, info->var.upper_margin,
+	           info->var.xres, info->var.yres, PICOS2KHZ(info->var.pixclock));
 
 	sst_write(NOPCMD, 0);
 	sst_wait_idle();
@@ -678,8 +607,8 @@
 	sst_write(HSYNC, (par->hSyncOff - 1) << 16 | (info->var.hsync_len - 1));
 	sst_write(VSYNC,       par->vSyncOff << 16 | par->vSyncOn);
 
-	fbiinit2=sst_read(FBIINIT2);
-	fbiinit3=sst_read(FBIINIT3);
+	fbiinit2 = sst_read(FBIINIT2);
+	fbiinit3 = sst_read(FBIINIT3);
 
 	/* everything is reset. we enable fbiinit2/3 remap : dac acces ok */
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
@@ -703,10 +632,10 @@
 	            | EN_BLANK_OE
 	            | EN_HVSYNC_OE
 	            | EN_DCLK_OE
-/*	            | (15 << TILES_IN_X_SHIFT)*/
+		 /* | (15 << TILES_IN_X_SHIFT) */
 	            | SEL_INPUT_VCLK_2X
-/*	            | (2 << VCLK_2X_SEL_DEL_SHIFT)
-	            | (2 << VCLK_DEL_SHIFT)*/;
+		 /* | (2 << VCLK_2X_SEL_DEL_SHIFT)
+	            | (2 << VCLK_DEL_SHIFT) */;
 /* try with vclk_in_delay =0 (bits 29:30) , vclk_out_delay =0 (bits(27:28)
  in (near) future set them accordingly to revision + resolution (cf glide)
  first understand what it stands for :)
@@ -718,7 +647,7 @@
 	ntiles = par->tiles_in_X;
 	if (IS_VOODOO2(par)) {
 		fbiinit1 |= ((ntiles & 0x20) >> 5) << TILES_IN_X_MSB_SHIFT
-		            | ((ntiles & 0x1e) >> 1) << TILES_IN_X_SHIFT ;
+		            | ((ntiles & 0x1e) >> 1) << TILES_IN_X_SHIFT;
 /* as the only value of importance for us in fbiinit6 is tiles in X (lsb),
    and as reading fbinit 6 will return crap (see FBIINIT6_DEFAULT) we just
    write our value. BTW due to the dac unable to read odd number of tiles, this
@@ -735,15 +664,12 @@
 #ifdef EN_24_32_BPP
 	case 24:
 	case 32:
-/*	orig	sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP); */
+		/* sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP);*/
 		fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP;
 		break;
 #endif
 	default:
-		dprintk("bug line %d: bad depth '%u'\n", __LINE__,
-			info->var.bits_per_pixel );
-		return 0;
-		break;
+		return -EINVAL;
 	}
 	sst_write(FBIINIT1, fbiinit1);
 	if (IS_VOODOO2(par)) {
@@ -751,7 +677,7 @@
 		fbiinit5=sst_read(FBIINIT5) & FBIINIT5_MASK ;
 		if (info->var.vmode & FB_VMODE_INTERLACED)
 			fbiinit5 |= INTERLACE;
-		if (info->var.vmode & FB_VMODE_DOUBLE )
+		if (info->var.vmode & FB_VMODE_DOUBLE)
 			fbiinit5 |= VDOUBLESCAN;
 		if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
 			fbiinit5 |= HSYNC_HIGH;
@@ -763,7 +689,7 @@
 	sst_unset_bits(FBIINIT1, VIDEO_RESET);
 	sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
 	sst_set_bits(FBIINIT2, EN_DRAM_REFRESH);
-/* disables fbiinit writes */
+	/* disables fbiinit writes */
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR);
 
 	/* set lfbmode : set mode + front buffer for reads/writes
@@ -781,10 +707,7 @@
 		break;
 #endif
 	default:
-		dprintk("bug line %d: bad depth '%u'\n", __LINE__,
-			info->var.bits_per_pixel );
-		return 0;
-		break;
+		return -EINVAL;
 	}
 
 #if defined(__BIG_ENDIAN)
@@ -792,7 +715,7 @@
 	 * With this enabled, all our read- and write-accesses to
 	 * the voodoo framebuffer can be done in native format, and
 	 * the hardware will automatically convert it to little-endian.
-	 * (tested on HP-PARISC, deller@gmx.de) */
+	 * - tested on HP-PARISC, Helge Deller <deller@gmx.de> */
 	lfbmode |= ( LFB_WORD_SWIZZLE_WR | LFB_BYTE_SWIZZLE_WR |
 		     LFB_WORD_SWIZZLE_RD | LFB_BYTE_SWIZZLE_RD );
 #endif
@@ -807,20 +730,28 @@
 	/* btw, it requires enabling pixel pipeline in LFBMODE .
 	   off screen read/writes will just wrap and read/print pixels
 	   on screen. Ugly but not that dangerous */
-
 		f_ddprintk("setting clipping dimensions 0..%d, 0..%d\n",
 		            info->var.xres - 1, par->yDim - 1);
 
-		sst_write(CLIP_LEFT_RIGHT, info->var.xres );
-		sst_write(CLIP_LOWY_HIGHY, par->yDim );
+		sst_write(CLIP_LEFT_RIGHT, info->var.xres);
+		sst_write(CLIP_LOWY_HIGHY, par->yDim);
 		sst_set_bits(FBZMODE, EN_CLIPPING | EN_RGB_WRITE);
 	} else {
 		/* no clipping : direct access, no pipeline */
-		sst_write(LFBMODE, lfbmode );
+		sst_write(LFBMODE, lfbmode);
 	}
-	return 1;
+	return 0;
 }
 
+/**
+ *      sstfb_setcolreg - Optional function. Sets a color register.
+ *      @regno: hardware colormap register
+ *      @red: frame buffer colormap structure
+ *      @green: The green value which can be up to 16 bits wide
+ *      @blue:  The blue value which can be up to 16 bits wide.
+ *      @transp: If supported the alpha value which can be up to 16 bits wide.
+ *      @info: frame buffer info structure
+ */
 static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                            u_int transp, struct fb_info *info)
 {
@@ -829,7 +760,8 @@
 	f_dddprintk("sstfb_setcolreg\n");
 	f_dddprintk("%-2d rgbt: %#x, %#x, %#x, %#x\n",
 	            regno, red, green, blue, transp);
-	if (regno >= 16) return 1;
+	if (regno >= 16)
+		return -EINVAL;
 
 	red    >>= (16 - info->var.red.length);
 	green  >>= (16 - info->var.green.length);
@@ -839,6 +771,9 @@
 	    | (green << info->var.green.offset)
 	    | (blue  << info->var.blue.offset)
 	    | (transp << info->var.transp.offset);
+	
+	((u32 *)info->pseudo_palette)[regno] = col;
+
 	return 0;
 }
 
@@ -850,103 +785,140 @@
 	u32 fbiinit0, tmp, val;
 	u_long p;
 
-	f_dprintk("sstfb_ioctl(%x)\n", cmd);
 	switch (cmd) {
-	
+		
+	/* dump current FBIINIT values to system log */
+	case _IO('F', 0xdb):            /* 0x46db */
+		return sstfb_dump_regs(info);
+		
 	/* fills lfb with #arg pixels */
 	case _IOW('F', 0xdc, u32):	/* 0x46dc */
-		if (copy_from_user(&val, (void *) arg, sizeof(val)))
+		if (copy_from_user(&val, (void *)arg, sizeof(val)))
 			return -EFAULT;
 		if (val > info->fix.smem_len)
 			val = info->fix.smem_len;
-		f_dprintk("filling %#x \n", val);
-		for (p = 0 ; p < val; p+=2)
-			writew( p >> 6 , info->screen_base + p);
+		printk("filling %#x \n", val);
+		for (p=0 ; p<val; p+=2)
+			writew(p >> 6, info->screen_base + p);
 		return 0;
 		
 	/* change VGA pass_through mode */
 	case _IOW('F', 0xdd, u32):	/* 0x46dd */
-		if (copy_from_user(&val, (void *) arg, sizeof(val)))
+		if (copy_from_user(&val, (void *)arg, sizeof(val)))
 			return -EFAULT;
-		f_dprintk("switch VGA pass-through\n");
 		pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
 		pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
 				       tmp | PCI_EN_INIT_WR );
 		fbiinit0 = sst_read (FBIINIT0);
 		if (val) {
 			sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
-			iprintk( "Disabling VGA pass-through\n");
+			iprintk("Disabling VGA pass-through\n");
 		} else {
 			sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
-			iprintk( "Enabling VGA pass-through\n");
+			iprintk("Enabling VGA pass-through\n");
 		}
 		pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
 		return 0;
 		
 	/* draw test image  */
 	case _IO('F', 0xde):		/* 0x46de */
-		f_dprintk("test color display\n");
-		f_ddprintk("bpp %d\n", 
-			  sst_info->par.bpp);
-		memset_io(info->screen_base, 0, info->fix.smem_len);
-		switch (info->var.bits_per_pixel) {
-		  case 16:
-			sstfb_test16(info);
-			break;
-#ifdef EN_24_32_BPP
-		  case 24:
-		  case 32:
-			sstfb_test32(info);
-			break;
-#endif
-		  default:
-			BUG();
-		  }
+		f_dprintk("test color display at %d bpp\n",
+					info->var.bits_per_pixel);
+		sstfb_drawdebugimage(info);
 		return 0;
 	}
 	return -EINVAL;
 }
 
+
 /*
- * Low level routines
+ * Screen-to-Screen BitBlt 2D command (for the bmove fb op.) - Voodoo2 only
  */
+#if 0
+static void sstfb_copyarea(struct fb_info *info, struct fb_copyarea *area)  
+{
+	struct sstfb_par *par = (struct sstfb_par *) info->par;
+	u32 stride = info->fix.line_length;
+   
+	if (!IS_VOODOO2(par))
+		return;
+
+	sst_write(BLTSRCBASEADDR, 0);
+	sst_write(BLTDSTBASEADDR, 0);
+	sst_write(BLTROP, BLTROP_COPY);
+	sst_write(BLTXYSTRIDES, stride | (stride << 16));
+	sst_write(BLTSRCXY, area->sx | (area->sy << 16));
+	sst_write(BLTDSTXY, area->dx | (area->dy << 16));
+	sst_write(BLTSIZE, area->width | (area->height << 16));
+	sst_write(BLTCOMMAND, BLT_SCR2SCR_BITBLT | LAUNCH_BITBLT |
+		(BLT_16BPP_FMT << 3) /* | BIT(14) */ | BIT(15) );
+	sst_wait_idle();
+}
+#endif
+
+
+/*
+ * FillRect 2D command (solidfill or invert (via ROP_XOR)) - Voodoo2 only
+ */
+static void sstfb_fillrect(struct fb_info *info, struct fb_fillrect *rect) 
+{
+	struct sstfb_par *par = (struct sstfb_par *) info->par;
+	u32 stride = info->fix.line_length;
+
+	if (!IS_VOODOO2(par))
+		return;
+   	
+	sst_write(BLTCLIPX, info->var.xres);
+	sst_write(BLTCLIPY, info->var.yres);
+	
+	sst_write(BLTDSTBASEADDR, 0);
+	sst_write(BLTCOLOR, rect->color);
+	sst_write(BLTROP, rect->rop == ROP_COPY ? BLTROP_COPY : BLTROP_XOR);
+	sst_write(BLTXYSTRIDES, stride | (stride << 16));
+	sst_write(BLTDSTXY, rect->dx | (rect->dy << 16));
+	sst_write(BLTSIZE, rect->width | (rect->height << 16));
+	sst_write(BLTCOMMAND, BLT_RECFILL_BITBLT | LAUNCH_BITBLT
+		 | (BLT_16BPP_FMT << 3) /* | BIT(14) */ | BIT(15) | BIT(16) );
+	sst_wait_idle();
+}
+
 
-/* get lfb size */
 
-static int __devinit sst_get_memsize(struct fb_info *info, u_long *memsize)
+/* 
+ * get lfb size 
+ */
+static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize)
 {
-	u_long fbbase_virt = (ulong) info->screen_base;
-	f_dprintk("sst_get_memsize\n");
+	u_long fbbase_virt = (u_long) info->screen_base;
 
 	/* force memsize */
 	if ((mem >= 1 ) &&  (mem <= 4)) {
 		*memsize = (mem * 0x100000);
-		iprintk("supplied memsize: %#lx\n", *memsize);
+		iprintk("supplied memsize: %#x\n", *memsize);
 		return 1;
 	}
 
-	writel (0xdeadbeef, fbbase_virt);
-	writel (0xdeadbeef, fbbase_virt+0x100000);
-	writel (0xdeadbeef, fbbase_virt+0x200000);
-	f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#x\n",
+	writel(0xdeadbeef, fbbase_virt);
+	writel(0xdeadbeef, fbbase_virt+0x100000);
+	writel(0xdeadbeef, fbbase_virt+0x200000);
+	f_ddprintk("0MB: %#x, 1MB: %#x, 2MB: %#x\n",
 	           readl(fbbase_virt), readl(fbbase_virt + 0x100000),
 	           readl(fbbase_virt + 0x200000));
 
-	writel (0xabcdef01, fbbase_virt);
+	writel(0xabcdef01, fbbase_virt);
 
-	f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#x\n",
+	f_ddprintk("0MB: %#x, 1MB: %#x, 2MB: %#x\n",
 	           readl(fbbase_virt), readl(fbbase_virt + 0x100000),
 	           readl(fbbase_virt + 0x200000));
 
-	/* checks for 4mb lfb , then 2, then defaults to 1*/
-	if (readl(fbbase_virt + 0x200000) == 0xdeadbeef) {
+	/* checks for 4mb lfb, then 2, then defaults to 1 */
+	if (readl(fbbase_virt + 0x200000) == 0xdeadbeef)
 		*memsize = 0x400000;
-	} else if (readl(fbbase_virt + 0x100000) == 0xdeadbeef) {
+	else if (readl(fbbase_virt + 0x100000) == 0xdeadbeef)
 		*memsize = 0x200000;
-	} else {
+	else
 		*memsize = 0x100000;
-	}
-	f_ddprintk("detected memsize: %#lx\n", *memsize);
+	f_ddprintk("detected memsize: %dMB\n", *memsize >> 20);
 	return 1;
 }
 
@@ -963,7 +935,6 @@
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
 	int i, mir, dir;
 
-	f_dprintk("sst_detect_att\n");
 	for (i=0; i<3; i++) {
 		sst_dac_write(DACREG_WMA, 0); 	/* backdoor */
 		sst_dac_read(DACREG_RMR);	/* read 4 times RMR */
@@ -989,7 +960,6 @@
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
 	int i, mir, dir;
 
-	f_dprintk("sst_detect_ti\n");
 	for (i = 0; i<3; i++) {
 		sst_dac_write(DACREG_WMA, 0); 	/* backdoor */
 		sst_dac_read(DACREG_RMR);	/* read 4 times RMR */
@@ -1028,7 +998,6 @@
 	int n_clk0_1, n_clk0_7, n_clk1_b;
 	int i;
 
-	f_dprintk("sst_detect_ics\n");
 	for (i = 0; i<5; i++ ) {
 		sst_dac_write(DACREG_ICS_PLLRMA, 0x1);	/* f1 */
 		m_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA);
@@ -1064,9 +1033,7 @@
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
 	u8 cr0, cc;
 
-	f_dprintk("sst_set_pll_att_ti\n");
 	/* enable indexed mode */
-
 	sst_dac_write(DACREG_WMA, 0); 	/* backdoor */
 	sst_dac_read(DACREG_RMR);	/* 1 time:  RMR */
 	sst_dac_read(DACREG_RMR);	/* 2 RMR */
@@ -1102,8 +1069,8 @@
 		            (cc & 0xf0) | DACREG_CC_CLKB | DACREG_CC_CLKB_D);
 		break;
 	default:
-		dprintk("bug line %d: wrong clock code '%d'\n",
-		        __LINE__,clock);
+		dprintk("%s: wrong clock code '%d'\n",
+		        __FUNCTION__, clock);
 		return 0;
 		}
 	udelay(300);
@@ -1120,8 +1087,6 @@
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
 	u8 pll_ctrl;
 
-	f_dprintk("sst_set_pll_ics\n");
-
 	sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL);
 	pll_ctrl = sst_dac_read(DACREG_ICS_PLLDATA);
 	switch(clock) {
@@ -1146,8 +1111,8 @@
 		              (pll_ctrl & 0xef) | DACREG_ICS_CLK1_A);
 		break;
 	default:
-		dprintk("bug line %d: wrong clock code '%d'\n",
-		        __LINE__, clock);
+		dprintk("%s: wrong clock code '%d'\n",
+		        __FUNCTION__, clock);
 		return 0;
 		}
 	udelay(300);
@@ -1159,8 +1124,6 @@
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
 	u8 cr0;
 
-	f_dprintk("sst_set_vidmod_att_ti(bpp: %d)\n", bpp);
-
 	sst_dac_write(DACREG_WMA, 0); 	/* backdoor */
 	sst_dac_read(DACREG_RMR);	/* read 4 times RMR */
 	sst_dac_read(DACREG_RMR);
@@ -1186,7 +1149,7 @@
 		break;
 #endif
 	default:
-		dprintk("bug line %d: bad depth '%u'\n", __LINE__, bpp);
+		dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
 		break;
 	}
 }
@@ -1195,7 +1158,6 @@
 {
 	struct sstfb_par *par = (struct sstfb_par *) info->par;
 
-	f_dprintk("sst_set_vidmod_ics(bpp: %d)\n", bpp);
 	switch(bpp) {
 	case 16:
 		sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP);
@@ -1207,7 +1169,7 @@
 		break;
 #endif
 	default:
-		dprintk("bug line %d: bad depth '%u'\n", __LINE__, bpp);
+		dprintk("%s: bad depth '%u'\n", __FUNCTION__, bpp);
 		break;
 	}
 }
@@ -1238,16 +1200,15 @@
 
 static int __devinit sst_detect_dactype(struct fb_info *info, struct sstfb_par *par)
 {
-	int ret = 0,i;
+	int i, ret = 0;
 	
-	f_dprintk("sst_detect_dactype\n");
 	for (i=0; i<sizeof(dacs)/sizeof(dacs[0]); i++) {
 		ret = dacs[i].detect(info);
 		if (ret) break;
 	}
 	if (!ret)
 		return 0;
-	f_dprintk("found %s\n", dacs[i].name);
+	f_dprintk("%s found %s\n", __FUNCTION__, dacs[i].name);
 	par->dac_sw = dacs[i];
 	return 1;
 }
@@ -1260,20 +1221,19 @@
 	u32 fbiinit0, fbiinit1, fbiinit4;
 	struct pci_dev *dev = par->dev;
 	struct pll_timing gfx_timings;
-	struct sst_spec * spec;
+	struct sst_spec *spec;
 	int Fout;
 
 	spec = &voodoo_spec[par->type];
-	f_dprintk("sst_init\n");
 	f_ddprintk(" fbiinit0   fbiinit1   fbiinit2   fbiinit3   fbiinit4  "
 	           " fbiinit6\n");
 	f_ddprintk("%0#10x %0#10x %0#10x %0#10x %0#10x %0#10x\n",
 	            sst_read(FBIINIT0), sst_read(FBIINIT1), sst_read(FBIINIT2),
 	            sst_read(FBIINIT3), sst_read(FBIINIT4), sst_read(FBIINIT6));
 	/* disable video clock */
-	pci_write_config_dword(dev, PCI_VCLK_DISABLE,0);
+	pci_write_config_dword(dev, PCI_VCLK_DISABLE, 0);
 
-	/* enable writing to init registers ,disable pci fifo*/
+	/* enable writing to init registers, disable pci fifo */
 	pci_write_config_dword(dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
 	/* reset video */
 	sst_set_bits(FBIINIT1, VIDEO_RESET);
@@ -1294,11 +1254,11 @@
 	sst_wait_idle();
 	/* remap fbinit2/3 to dac */
 	pci_write_config_dword(dev, PCI_INIT_ENABLE,
-	                               PCI_EN_INIT_WR | PCI_REMAP_DAC );
+				PCI_EN_INIT_WR | PCI_REMAP_DAC );
 	/* detect dac type */
 	if (!sst_detect_dactype(info, par)) {
 		eprintk("Unknown dac type\n");
-		//FIXME watch it : we are not in a safe state, bad bad bad .
+		//FIXME watch it: we are not in a safe state, bad bad bad.
 		return 0;
 	}
 
@@ -1308,7 +1268,7 @@
 		iprintk("Using supplied graphic freq : %dMHz\n", gfxclk);
 		 par->gfx_clock = gfxclk *1000;
 	} else if (gfxclk) {
-		wprintk ("You fool, %dMhz is way out of spec! Using default\n", gfxclk);
+		wprintk ("%dMhz is way out of spec! Using default\n", gfxclk);
 	}
 
 	sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings);
@@ -1348,7 +1308,7 @@
 		sst_wait_idle();
 	}
 
-	pci_write_config_dword(dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR );
+	pci_write_config_dword(dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR);
 	pci_write_config_dword(dev, PCI_VCLK_ENABLE, 0);
 	return 1;
 }
@@ -1360,7 +1320,6 @@
 	struct pll_timing gfx_timings;
 	int Fout;
 
-	f_dprintk("sst_shutdown\n");
 	/* reset video, gfx, fifo, disable dram + remap fbiinit2/3 */
 	pci_write_config_dword(dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
 	sst_set_bits(FBIINIT1, VIDEO_RESET | EN_BLANKING);
@@ -1368,8 +1327,8 @@
 	sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
 	sst_wait_idle();
 	pci_write_config_dword(dev, PCI_INIT_ENABLE,
-	                       PCI_EN_INIT_WR | PCI_REMAP_DAC );
-	/*set 20Mhz gfx clock */
+	                       PCI_EN_INIT_WR | PCI_REMAP_DAC);
+	/* set 20Mhz gfx clock */
 	sst_calc_pll(20000, &Fout, &gfx_timings);
 	par->dac_sw.set_pll(info, &gfx_timings, GFX_CLOCK);
 	/* TODO maybe shutdown the dac, vrefresh and so on... */
@@ -1377,7 +1336,8 @@
 	                       PCI_EN_INIT_WR);
 	sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | EN_VGA_PASSTHROUGH);
 	pci_write_config_dword(dev, PCI_VCLK_DISABLE,0);
-/* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct at the beginining ? */
+	/* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct
+	 * from start ? */
 	pci_write_config_dword(dev, PCI_INIT_ENABLE, 0);
 
 }
@@ -1390,8 +1350,6 @@
 {
 	char *this_opt;
 
-	f_dprintk("sstfb_setup\n");
-
 	if (!options || !*options)
 		return 0;
 
@@ -1400,11 +1358,7 @@
 
 		f_ddprintk("option %s\n", this_opt);
 
-		if (!strcmp(this_opt, "inverse")) {
-			inverse = 1;
-			fb_invert_cmaps();
-		}
-		else if (!strcmp(this_opt, "vganopass"))
+		if (!strcmp(this_opt, "vganopass"))
 			vgapass = 0;
 		else if (!strcmp(this_opt, "vgapass"))
 			vgapass = 1;
@@ -1417,11 +1371,9 @@
 		else if (!strcmp(this_opt, "slowpci"))
 		        slowpci = 1;
 		else if (!strncmp(this_opt, "mem:",4))
-			mem=simple_strtoul (this_opt+4, NULL, 0);
+			mem = simple_strtoul (this_opt+4, NULL, 0);
 		else if (!strncmp(this_opt, "gfxclk:",7))
-			gfxclk=simple_strtoul (this_opt+7, NULL, 0);
-		else if (!strncmp(this_opt, "dev:",4))
-			dev=simple_strtoul (this_opt+4, NULL, 0);
+			gfxclk = simple_strtoul (this_opt+7, NULL, 0);
 		else
 			mode_option = this_opt;
 	}
@@ -1433,53 +1385,57 @@
 	.fb_check_var	= sstfb_check_var,
 	.fb_set_par	= sstfb_set_par,
 	.fb_setcolreg	= sstfb_setcolreg,
-	.fb_fillrect	= cfb_fillrect,
-	.fb_copyarea	= cfb_copyarea,
+	.fb_fillrect	= cfb_fillrect, /* sstfb_fillrect */
+	.fb_copyarea	= cfb_copyarea, /* sstfb_copyarea */
 	.fb_imageblit	= cfb_imageblit,
 	.fb_cursor	= soft_cursor,
 	.fb_ioctl	= sstfb_ioctl,
 };
 
-static int __devinit sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int __devinit sstfb_probe(struct pci_dev *pdev,
+			const struct pci_device_id *id)
 {
-	struct sstfb_par *default_par;
+	struct fb_info *info;
 	struct fb_fix_screeninfo *fix;
+	struct sstfb_par *par;
 	struct sst_spec *spec;
-	struct fb_info *info;
 	int err;
-	f_dprintk("sstfb_probe\n");
-
-	/* dev >  0  the device is not the one asked for.   skip */
-	/* dev == 0  this is the device the user asked.     init */
-	/* dev == -1 we already inited the asked device.    skip */
-	/* dev < -1  init all devices. including this one.  init */
-	if ((dev == -1 ) || (dev-- > 0))
-		return -ENODEV;
 
+	struct all_info {
+		struct fb_info info;
+		struct sstfb_par par;
+		u32 pseudo_palette[16];
+	} *all;
+	
+	/* Enable device in PCI config. */
 	if ((err=pci_enable_device(pdev))) {
 		eprintk("cannot enable device\n");
 		return err;
 	}
 
-	info = kmalloc(sizeof(struct fb_info) + sizeof(struct sstfb_par), GFP_KERNEL);
-	if (!info)
+	/* Allocate the fb and par structures.  */
+	all = kmalloc(sizeof(*all), GFP_KERNEL);
+	if (!all)
 		return -ENOMEM;
-	default_par = (struct sstfb_par *) (info + 1);
+	memset(all, 0, sizeof(*all));
+	pci_set_drvdata(pdev, all);
+	
+	info = &all->info;
+	par  = info->par = &all->par;
 	fix  = &info->fix;
-	info->par	= default_par;
 	
-	pci_set_drvdata(pdev, info);
-	default_par->type = id->driver_data;
-	spec = &voodoo_spec[default_par->type];
+	par->type = id->driver_data;
+	spec = &voodoo_spec[par->type];
 	f_ddprintk("found device : %s\n", spec->name);
 
-	default_par->dev = pdev;
-	pci_read_config_byte(pdev, PCI_REVISION_ID, &default_par->revision);
+	par->dev = pdev;
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &par->revision);
 
 	fix->mmio_start = pci_resource_start(pdev,0);
+	fix->mmio_len	= 0x400000;
 	fix->smem_start = fix->mmio_start + 0x400000;
 
-	if (!request_mem_region(fix->mmio_start, 0x400000,"sstfb MMIO")) {
+	if (!request_mem_region(fix->mmio_start, fix->mmio_len, "sstfb MMIO")) {
 		eprintk("cannot reserve mmio memory\n");
 		goto fail_mmio_mem;
 	}
@@ -1489,8 +1445,9 @@
 		goto fail_fb_mem;
 	}
 
-	default_par->mmio_vbase = (u_long) ioremap_nocache(fix->mmio_start, 0x400000);
-	if (!default_par->mmio_vbase) {
+	par->mmio_vbase = (u_long) ioremap_nocache(fix->mmio_start,
+					fix->mmio_len);
+	if (!par->mmio_vbase) {
 		eprintk("cannot remap register area %#lx\n",
 		        fix->mmio_start);
 		goto fail_mmio_remap;
@@ -1502,37 +1459,37 @@
 		goto fail_fb_remap;
 	}
 
-	if(!sst_init(info, default_par)) {
+	if (!sst_init(info, par)) {
 		eprintk("Init failed\n");
 		goto fail;
 	}
-	sst_get_memsize(info, (unsigned long *) &fix->smem_len);
+	sst_get_memsize(info, &fix->smem_len);
 	strncpy(fix->id, spec->name, sizeof(fix->id));
 
-	iprintk("%s with %s dac\n", fix->id, default_par->dac_sw.name);
-	iprintk("framebuffer at %#lx, mapped to %#lx,"
-	        " size %dMb\n",
-	        fix->smem_start, (unsigned long) info->screen_base,
+	iprintk("%s (revision %d) with %s dac\n",
+		fix->id, par->revision, par->dac_sw.name);
+	iprintk("framebuffer at %#lx, mapped to 0x%p, size %dMB\n",
+	        fix->smem_start, info->screen_base,
 	        fix->smem_len >> 20);
 
-	f_ddprintk("revision: %d\n", default_par->revision);
-	f_ddprintk("regbase_virt: %#lx\n", default_par->mmio_vbase);
+	f_ddprintk("regbase_virt: %#lx\n", par->mmio_vbase);
 	f_ddprintk("membase_phys: %#lx\n", fix->smem_start);
-	f_ddprintk("fbbase_virt: %#lx\n", info->screen_base);
+	f_ddprintk("fbbase_virt: %p\n", info->screen_base);
 
 	info->node	= NODEV;
 	info->flags	= FBINFO_FLAG_DEFAULT;
 	info->fbops	= &sstfb_ops;
+	info->currcon	= -1;
+	info->pseudo_palette = &all->pseudo_palette;
 
-	fix->mmio_len	= 0x400000;
 	fix->type	= FB_TYPE_PACKED_PIXELS;
 	fix->visual	= FB_VISUAL_TRUECOLOR;
 	fix->accel	= FB_ACCEL_NONE;  /* FIXME */
 	/*
-	 *   According to the specs, the linelength must be of 1024 *pixels*.
+	 * According to the specs, the linelength must be of 1024 *pixels*
 	 * and the 24bpp mode is in fact a 32 bpp mode.
 	 */
-	fix->line_length= 2048;	/* default value, for 24 or 32bit: 4096*/
+	fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */
 	
 	if ( mode_option &&
 	     fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) {
@@ -1542,30 +1499,41 @@
 		info->var = sstfb_default;
 
 	if (sstfb_check_var(&info->var, info)) {
+		eprintk("invalid default video mode.\n");
+		goto fail;
+	}
+
+	if (sstfb_set_par(info)) {
 		eprintk("can't set default video mode.\n");
 		goto fail;
 	}
 	
-	fb_alloc_cmap(&info->cmap, 16, 0);
+	fb_alloc_cmap(&info->cmap, 256, 0);
 
 	/* register fb */
 	if (register_framebuffer(info) < 0) {
 		eprintk("can't register framebuffer.\n");
 		goto fail;
 	}
-	printk(KERN_INFO "fb%d: %s frame buffer device\n",
-	       minor(info->node), fix->id);
+
+	if (1) /* set to 0 to see an initial bitmap instead */
+		sstfb_clear_screen(info);
+	else
+		sstfb_drawdebugimage(info);
+
+	printk(KERN_INFO "fb%d: %s frame buffer device at 0x%p\n",
+	       minor(info->node), fix->id, info->screen_base);
 
 	return 0;
 
 fail:
 	iounmap(info->screen_base);
 fail_fb_remap:
-	iounmap((void *)default_par->mmio_vbase);
+	iounmap((void *)par->mmio_vbase);
 fail_mmio_remap:
 	release_mem_region(fix->smem_start, 0x400000);
 fail_fb_mem:
-	release_mem_region(fix->mmio_start, 0x400000);
+	release_mem_region(fix->mmio_start, info->fix.mmio_len);
 fail_mmio_mem:
 	kfree(info);
 	return -ENXIO; 	/* no voodoo detected */
@@ -1576,7 +1544,6 @@
 	struct sstfb_par *par;
 	struct fb_info *info;
 
-	f_dprintk("sstfb_remove\n");
 	info = pci_get_drvdata(pdev);
 	par = (struct sstfb_par *) info->par;
 	
@@ -1584,7 +1551,7 @@
 	unregister_framebuffer(info);
 	iounmap(info->screen_base);
 	iounmap((void*)par->mmio_vbase);
-	release_mem_region(info->fix.smem_start, info->fix.smem_len);
+	release_mem_region(info->fix.smem_start, 0x400000);
 	release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
 	kfree(info);
 }
@@ -1608,109 +1575,127 @@
 
 int __devinit sstfb_init(void)
 {
-	f_dprintk("sstfb_init\n");
-	dprintk("Compile date: "__DATE__" "__TIME__"\n");
 	return pci_module_init(&sstfb_driver);
 }
 
 void __devexit sstfb_exit(void)
 {
-	f_dprintk("sstfb_exit\n");
 	pci_unregister_driver(&sstfb_driver);
 }
 
 
 /*
- * console driver
+ * testing and debugging functions
  */
 
-#if 1
-/* print some squares on the fb (presuming 16bpp)  */
-static void sstfb_test16(struct fb_info *info)
+static int sstfb_dump_regs(struct fb_info *info)
 {
-	u_long fbbase_virt = (u_long) info->screen_base;
-	u_long p;
-	int i,j;
+#ifdef SST_DEBUG
+	static struct { u32 reg ; const char *reg_name;}  pci_regs[] = {
+		{ PCI_INIT_ENABLE, "initenable"},
+		{ PCI_VCLK_ENABLE, "enable vclk"},
+		{ PCI_VCLK_DISABLE, "disable vclk"},
+	};
+
+	static struct { u32 reg ; const char *reg_name;}  sst_regs[] = {
+		{FBIINIT0,"fbiinit0"},
+		{FBIINIT1,"fbiinit1"},
+		{FBIINIT2,"fbiinit2"},
+		{FBIINIT3,"fbiinit3"},
+		{FBIINIT4,"fbiinit4"},
+		{FBIINIT5,"fbiinit5"},
+		{FBIINIT6,"fbiinit6"},
+		{FBIINIT7,"fbiinit7"},
+		{LFBMODE,"lfbmode"},
+		{FBZMODE,"fbzmode"},
+	};
 
-	f_dprintk("sstfb_test16\n");
-	/* draw white rect 20x100+200+0 */
-	for (i=0 ; i<100; i++) {
-	  p = fbbase_virt + 2048*i+400;
-	  for (j=0 ; j<10 ; j++) {
-	    writel(0xffffffff, p);
-	    p += 4;
-	  }
-	}
-	/* draw blue rect 180x200+0+0 */
-	for (i=0 ; i<200; i++) {
-	  p = fbbase_virt + 2048*i;
-	  for (j=0 ; j<90 ; j++) {
-	    writel(0x001f001f, p);
-	    p += 4;
-	  }
-	}
-	/* draw green rect 40x40+100+0 */
-	for (i=0 ; i<40 ; i++) {
-	  p = fbbase_virt + 2048*i + 200;
-	  for (j=0; j <20;j++) {
-	    writel(0x07e007e0, p);
-	    p += 4;
-	  }
-	}
-	/* draw red rect 40x40+100+40 */
-	for (i=0; i<40; i++) {
-	  p = fbbase_virt + 2048 * (i+40) + 200;
-	  for (j=0; j<20;j++) {
-	    writel(0xf800f800, p);
-	    p += 4;
-	  }
+	const int pci_s = sizeof(pci_regs)/sizeof(pci_regs[0]);
+	const int sst_s = sizeof(sst_regs)/sizeof(sst_regs[0]);
+	struct sstfb_par *par = (struct sstfb_par *) info->par;
+	struct pci_dev *dev = par->dev;
+	u32 pci_res[pci_s];
+	u32 sst_res[sst_s];
+	int i;
+
+	for (i=0; i<pci_s; i++) {
+		pci_read_config_dword(dev, pci_regs[i].reg, &pci_res[i]);
 	}
-}
+	for (i=0; i<sst_s; i++) {
+		sst_res[i] = sst_read(sst_regs[i].reg);
+	}
+
+	dprintk("hardware register dump:\n");
+	for (i=0; i<pci_s; i++) {
+		dprintk("%s %0#10x\n", pci_regs[i].reg_name, pci_res[i]);
+	}
+	for (i=0; i<sst_s; i++) {
+		dprintk("%s %0#10x\n", sst_regs[i].reg_name, sst_res[i]);
+	}
+	return 0;
+#else
+	return -EINVAL;
 #endif
+}
 
-#ifdef EN_24_32_BPP
-/* print some squares on the fb (24/32bpp)  */
-static void sstfb_test32(struct fb_info *info)
+static void sstfb_fillrect_softw( struct fb_info *info, struct fb_fillrect *rect)
 {
-	int i,j;
-	u_long p;
-	u_long fbbase_virt = info->screen_base;
-
-	f_dprintk("sstfb_test32\n");
-	/* draw white rect 20x100+200+0 */
-	for (i=0 ; i<100; i++) {
-	  p = fbbase_virt + 4096*i + 800;
-	  for (j=0 ; j<20; j++) {
-	    writel(0x00ffffff, p);
-	    p += 4;
-	  }
-	}
-	/* draw blue rect 180x200+0+0 */
-	for (i=0 ; i<200; i++) {
-	  p = fbbase_virt + 4096*i;
-	  for (j=0 ; j<180; j++) {
-	    writel(0x000000ff,p);
-	    p += 4;
-	  }
-	}
-	/* draw green rect 40x40+100+0 */
-	for (i=0 ; i<40 ; i++) {
-	  p = fbbase_virt + 4096*i + 400;
-	  for (j=0; j<40; j++) {
-	    writel(0x0000ff00, p);
-	    p += 4;
-	  }
-	}
-	/* draw red rect 40x40+100+10 */
-	for (i=0; i<40; i++) {
-	  p = fbbase_virt + 4096 * (i+40) + 400;
-	  for (j=0; j<40; j++) {
-	    writel(0x00ff0000, p);
-	    p += 4;
-	  }
+	unsigned long fbbase_virt = (unsigned long) info->screen_base;
+	unsigned long p;
+	int x, y, w = info->var.bits_per_pixel == 16 ? 2 : 4;
+	u32 color = rect->color;
+	
+	if (w==2) color |= color<<16;
+	for (y=rect->dy; rect->height; y++, rect->height--) {
+		p = fbbase_virt + y*info->fix.line_length + rect->dx*w;
+		x = rect->width;
+		if (w==2) x>>=1;
+		while (x) {
+			writel(color, p);
+			p += 4;
+			x--;
+		}
 	}
 }
-#endif
+
+static void sstfb_drawrect_XY( struct fb_info *info, int x, int y,
+		int w, int h, int color, int hwfunc)
+{
+	struct fb_fillrect rect;
+	rect.dx = x;
+	rect.dy = y;
+	rect.height = h;
+	rect.width = w;
+	rect.color = color;
+	rect.rop = ROP_COPY;
+	if (hwfunc)
+		sstfb_fillrect(info, &rect);
+	else
+		sstfb_fillrect_softw(info, &rect);
+}
+
+/* print some squares on the fb */
+static void sstfb_drawdebugimage(struct fb_info *info)
+{
+	static int idx;
+
+	/* clear screen */
+	sstfb_clear_screen(info);
+	
+   	idx = (idx+1) & 1;
+
+	/* white rect */
+	sstfb_drawrect_XY(info, 0, 0, 50, 50, 0xffff, idx);
+	
+	/* blue rect */
+	sstfb_drawrect_XY(info, 50, 50, 50, 50, 0x001f, idx);
+
+	/* green rect */
+	sstfb_drawrect_XY(info, 100, 100, 80, 80, 0x07e0, idx);
+	
+	/* red rect */
+	sstfb_drawrect_XY(info, 250, 250, 120, 100, 0xf800, idx);
+}
 
 
 #ifdef MODULE
@@ -1723,17 +1708,13 @@
 MODULE_LICENSE("GPL");
 
 MODULE_PARM(mem, "i");
-MODULE_PARM_DESC(mem, "Size of frame buffer memory in MiB (1, 2, 4 Mb, default=autodetect)");
+MODULE_PARM_DESC(mem, "Size of frame buffer memory in MB (1, 2, 4 MB, default=autodetect)");
 MODULE_PARM(vgapass, "i");
-MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough cable (0 or 1) (default=0)");
-MODULE_PARM(inverse, "i");
-MODULE_PARM_DESC(inverse, "Inverse colormap (0 or 1) (default=0)");
+MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough mode (0 or 1) (default=0)");
 MODULE_PARM(clipping , "i");
 MODULE_PARM_DESC(clipping, "Enable clipping (slower, safer) (0 or 1) (default=1)");
 MODULE_PARM(gfxclk , "i");
-MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in Mhz. DANGEROUS. (default=auto)");
+MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
 MODULE_PARM(slowpci, "i");
 MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
-MODULE_PARM(dev,"i");
-MODULE_PARM_DESC(dev , "Attach to device ID (0..n) (default=1st device)");
 
diff -Nru a/drivers/video/sstfb.h b/drivers/video/sstfb.h
--- a/drivers/video/sstfb.h	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/sstfb.h	Thu Jan 16 18:23:05 2003
@@ -17,7 +17,7 @@
  */
 
 #ifdef SST_DEBUG
-#  define dprintk(X...)	printk(KERN_DEBUG "sstfb: " X)
+#  define dprintk(X...)		printk("sstfb: " X)
 #else
 #  define dprintk(X...)
 #  undef SST_DEBUG_REG
@@ -76,8 +76,6 @@
 # define ABS(x)		(((x)<0)?-(x):(x))
 #endif
 
-//void Dump_regs(void);
-
 /*
  *
  *  Const
@@ -180,6 +178,29 @@
 #  define TILES_IN_X_LSB_SHIFT	  30		/* v2 */
 #define FBIINIT7		0x024c		/* v2 specific */
 
+#define BLTSRCBASEADDR		0x02c0	/* BitBLT Source base address */
+#define BLTDSTBASEADDR		0x02c4	/* BitBLT Destination base address */
+#define BLTXYSTRIDES		0x02c8	/* BitBLT Source and Destination strides */
+#define BLTSRCCHROMARANGE	0x02cc	/* BitBLT Source Chroma key range */
+#define BLTDSTCHROMARANGE	0x02d0	/* BitBLT Destination Chroma key range */
+#define BLTCLIPX		0x02d4	/* BitBLT Min/Max X clip values */
+#define BLTCLIPY		0x02d8	/* BitBLT Min/Max Y clip values */
+#define BLTSRCXY		0x02e0	/* BitBLT Source starting XY coordinates */
+#define BLTDSTXY		0x02e4	/* BitBLT Destination starting XY coordinates */
+#define BLTSIZE			0x02e8	/* BitBLT width and height */
+#define BLTROP			0x02ec	/* BitBLT Raster operations */
+#  define BLTROP_COPY		  0x0cccc
+#  define BLTROP_INVERT		  0x05555
+#  define BLTROP_XOR		  0x06666
+#define BLTCOLOR		0x02f0	/* BitBLT and foreground background colors */
+#define BLTCOMMAND		0x02f8	/* BitBLT command mode (v2 specific) */
+# define BLT_SCR2SCR_BITBLT	  0	  /* Screen-to-Screen BitBLT */
+# define BLT_CPU2SCR_BITBLT	  1	  /* CPU-to-screen BitBLT */
+# define BLT_RECFILL_BITBLT	  2	  /* BitBLT Rectangle Fill */
+# define BLT_16BPP_FMT		  2	  /* 16 BPP (5-6-5 RGB) */
+#define BLTDATA			0x02fc	/* BitBLT data for CPU-to-Screen BitBLTs */
+#  define LAUNCH_BITBLT		  BIT(31) /* Launch BitBLT in BltCommand, bltDstXY or bltSize */
+
 /* Dac Registers */
 #define DACREG_WMA		0x0	/* pixel write mode address */
 #define DACREG_LUT		0x01	/* color value */
@@ -211,7 +232,7 @@
 #define DACREG_DIR_TI		0x09
 #define DACREG_MIR_ATT		0x84
 #define DACREG_DIR_ATT		0x09
-/* ics dac specific registers*/
+/* ics dac specific registers */
 #define DACREG_ICS_PLLWMA	0x04	/* PLL write mode address */
 #define DACREG_ICS_PLLDATA	0x05	/* PLL data /parameter */
 #define DACREG_ICS_CMD		0x06	/* command */
@@ -299,8 +320,6 @@
 	unsigned int n;
 	unsigned int p;
 };
-
-struct sstfb_info;
 
 struct dac_switch {
 	char * name;
diff -Nru a/drivers/video/sticore.h b/drivers/video/sticore.h
--- a/drivers/video/sticore.h	Thu Jan 16 18:23:07 2003
+++ b/drivers/video/sticore.h	Thu Jan 16 18:23:07 2003
@@ -72,27 +72,6 @@
 #define sti_font_x(sti) (PTR_STI(sti->font)->width)
 #define sti_font_y(sti) (PTR_STI(sti->font)->height)
 
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
-#endif
-
-extern struct sti_struct *sti_init_roms(void);
-
-/* XXX: this probably should not be here, but we rely on STI being
-   initialized early and independently of stifb at the moment, so
-   there's no other way for stifb to find it. */
-extern struct sti_struct *default_sti;
-
-int  sti_init_graph(struct sti_struct *sti);
-void sti_inq_conf(struct sti_struct *sti);
-void sti_putc(struct sti_struct *sti, int c, int y, int x);
-void sti_set(struct sti_struct *sti, int src_y, int src_x,
-	     int height, int width, u8 color);
-void sti_clear(struct sti_struct *sti, int src_y, int src_x,
-	       int height, int width, int c);
-void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
-	       int dst_y, int dst_x, int height, int width);
-
 
 /* STI function configuration structs */
 
@@ -170,7 +149,7 @@
 
 struct sti_init_inptr {
 	s32 text_planes;	/* number of planes to use for text */
-	u32 ext_ptr;		 /* pointer to extended init_graph inptr data structure*/
+	u32 ext_ptr;		/* pointer to extended init_graph inptr data structure*/
 };
 
 
@@ -382,27 +361,20 @@
 };
 
 
+/* sticore interface functions */
 
-/* helper functions */
-struct sti_struct *sti_init_roms(void);
-struct sti_struct *sti_get_rom(int);
-void sti_rom_copy(unsigned long base, unsigned long count, void *dest);
-struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom,
-	    int (*search_font_fnc) (struct sti_cooked_rom *,int,int) );
-
-int sti_read_rom(int wordmode, struct sti_struct *sti,
-	    unsigned long address);
-
-
-/* FIXME: Do we have another solution for this ? */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <asm/cacheflush.h>
-static inline void sti_flush(unsigned long from, unsigned long len)
-{
-	flush_data_cache();
-	flush_kernel_dcache_range(from, len);
-	flush_icache_range(from, from+len);
-}
+struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */
+
+/* functions to call the STI ROM directly */
+
+int  sti_init_graph(struct sti_struct *sti);
+void sti_inq_conf(struct sti_struct *sti);
+void sti_putc(struct sti_struct *sti, int c, int y, int x);
+void sti_set(struct sti_struct *sti, int src_y, int src_x,
+	     int height, int width, u8 color);
+void sti_clear(struct sti_struct *sti, int src_y, int src_x,
+	       int height, int width, int c);
+void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
+	       int dst_y, int dst_x, int height, int width);
 
 #endif	/* STICORE_H */
diff -Nru a/drivers/video/stifb.c b/drivers/video/stifb.c
--- a/drivers/video/stifb.c	Thu Jan 16 18:23:07 2003
+++ b/drivers/video/stifb.c	Thu Jan 16 18:23:07 2003
@@ -111,7 +111,7 @@
 	int deviceSpecificConfig;
 };
 
-static int stifb_force_bpp[MAX_STI_ROMS] = {0, };
+static int __initdata stifb_force_bpp[MAX_STI_ROMS];
 
 /* ------------------- chipset specific functions -------------------------- */
 
@@ -487,8 +487,7 @@
 	SETUP_HW(fb);
 	WRITE_BYTE(1, fb, REG_16b1);
 
-	/* XXX: replace by fb_setmem(), smem_start or screen_base ? */
-	memset_io(fb->info.fix.smem_start, 0xff,
+	fb_memset(fb->info.fix.smem_start, 0xff,
 		fb->info.var.yres*fb->info.fix.line_length);
     
 	CRX24_SET_OVLY_MASK(fb);
@@ -882,6 +881,82 @@
 
 /* ------------------- driver specific functions --------------------------- */
 
+#define TMPBUFLEN 2048
+
+static ssize_t
+stifb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+	unsigned long p = *ppos;
+	struct inode *inode = file->f_dentry->d_inode;
+	int fbidx = minor(inode->i_rdev);
+	struct fb_info *info = registered_fb[fbidx];
+	char tmpbuf[TMPBUFLEN];
+
+	if (!info || ! info->screen_base)
+		return -ENODEV;
+
+	if (p >= info->fix.smem_len)
+	    return 0;
+	if (count >= info->fix.smem_len)
+	    count = info->fix.smem_len;
+	if (count + p > info->fix.smem_len)
+		count = info->fix.smem_len - p;
+	if (count > sizeof(tmpbuf))
+		count = sizeof(tmpbuf);
+	if (count) {
+	    char *base_addr;
+
+	    base_addr = info->screen_base;
+	    memcpy_fromio(&tmpbuf, base_addr+p, count);
+	    count -= copy_to_user(buf, &tmpbuf, count);
+	    if (!count)
+		return -EFAULT;
+	    *ppos += count;
+	}
+	return count;
+}
+
+static ssize_t
+stifb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	int fbidx = minor(inode->i_rdev);
+	struct fb_info *info = registered_fb[fbidx];
+	unsigned long p = *ppos;
+	size_t c;
+	int err;
+	char tmpbuf[TMPBUFLEN];
+
+	if (!info || !info->screen_base)
+		return -ENODEV;
+
+	if (p > info->fix.smem_len)
+	    return -ENOSPC;
+	if (count >= info->fix.smem_len)
+	    count = info->fix.smem_len;
+	err = 0;
+	if (count + p > info->fix.smem_len) {
+	    count = info->fix.smem_len - p;
+	    err = -ENOSPC;
+	}
+
+	p += (unsigned long)info->screen_base;
+	c = count;
+	while (c) {
+	    int len = c > sizeof(tmpbuf) ? sizeof(tmpbuf) : c;
+	    err = -EFAULT;
+	    if (copy_from_user(&tmpbuf, buf, len))
+		    break;
+	    memcpy_toio(p, &tmpbuf, len);
+	    c -= len;
+	    p += len;
+	    buf += len;
+	    *ppos += len;
+	}
+	if (count-c)
+		return (count-c);
+	return err;
+}
 
 static int
 stifb_setcolreg(u_int regno, u_int red, u_int green,
@@ -1018,11 +1093,12 @@
 	SETUP_FB(fb);
 }
 
-
 /* ------------ Interfaces to hardware functions ------------ */
 
 static struct fb_ops stifb_ops = {
 	.owner		= THIS_MODULE,
+	.fb_read	= stifb_read,
+	.fb_write	= stifb_write,
 	.fb_setcolreg	= stifb_setcolreg,
 	.fb_blank	= stifb_blank,
 	.fb_fillrect	= cfb_fillrect,
@@ -1166,6 +1242,11 @@
 	fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8;
 	if (!fix->line_length)
 		fix->line_length = 2048; /* default */
+	
+	/* limit fbsize to max visible screen size */
+	if (fix->smem_len > yres*fix->line_length)
+		fix->smem_len = yres*fix->line_length;
+	
 	fix->accel = FB_ACCEL_NONE;
 
 	switch (bpp) {
@@ -1206,7 +1287,7 @@
 	fb_alloc_cmap(&info->cmap, 256, 0);
 	stifb_init_display(fb);
 
-	if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb")) {
+	if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) {
 		printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n",
 				fix->smem_start, fix->smem_start+fix->smem_len);
 		goto out_err1;
@@ -1252,15 +1333,11 @@
 	struct sti_struct *sti;
 	int i;
 	
-	if (sti_init_roms() == NULL)
-		return -ENXIO; /* no STI cards available */
-
-	for (i = 0; i < MAX_STI_ROMS; i++) {
+	for (i = 1; i < MAX_STI_ROMS; i++) {
 		sti = sti_get_rom(i);
-		if (sti)
-			stifb_init_fb(sti, stifb_force_bpp[i]);
-		else
+		if (!sti)
 			break;
+		stifb_init_fb(sti, stifb_force_bpp[i]);
 	}
 	return 0;
 }
@@ -1275,7 +1352,7 @@
 	struct sti_struct *sti;
 	int i;
 	
-	for (i = 0; i < MAX_STI_ROMS; i++) {
+	for (i = 1; i < MAX_STI_ROMS; i++) {
 		sti = sti_get_rom(i);
 		if (!sti)
 			break;
diff -Nru a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
--- a/drivers/video/tdfxfb.c	Thu Jan 16 18:23:05 2003
+++ b/drivers/video/tdfxfb.c	Thu Jan 16 18:23:05 2003
@@ -177,7 +177,7 @@
 	.fb_pan_display	= tdfxfb_pan_display,
 	.fb_fillrect	= tdfxfb_fillrect,
 	.fb_copyarea	= tdfxfb_copyarea,
-	.fb_imageblit	= tdfxfb_imageblit,
+	.fb_imageblit	= cfb_imageblit,
 	.fb_sync	= banshee_wait_idle,
 	.fb_cursor	= soft_cursor,
 };
@@ -939,14 +939,16 @@
 	u8 *chardata = (u8 *) pixmap->data;
 	u32 srcfmt;
 
-	if (pixmap->depth == 1) {
+	if (pixmap->depth != 1) {
+		//banshee_make_room(par, 6 + ((size + 3) >> 2));
+		//srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
+		cfb_imageblit(info, pixmap);
+		return;
+	} else {
 		banshee_make_room(par, 8 + ((size + 3) >> 2));
 		tdfx_outl(par, COLORFORE, pixmap->fg_color);
 		tdfx_outl(par, COLORBACK, pixmap->bg_color);
 		srcfmt = 0x400000;
-	} else {
-		//banshee_make_room(par, 6 + ((size + 3) >> 2));
-		//srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000;
 	}	
 
 	tdfx_outl(par,	SRCXY,     0);
diff -Nru a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
--- a/drivers/video/tridentfb.c	Thu Jan 16 18:23:06 2003
+++ b/drivers/video/tridentfb.c	Thu Jan 16 18:23:06 2003
@@ -1,24 +1,18 @@
 /*
  * Frame buffer driver for Trident Blade and Image series
  *
- * Copyright 2001,2002 - Jani Monoses   <jani@astechnix.ro>
+ * Copyright 2001,2002 - Jani Monoses   <jani@iv.ro>
  *
- * $Id: tridentfb.c,v 1.3 2002/02/25 20:09:41 marcelo Exp $
  *
  * CREDITS:(in order of appearance)
  * 	skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
  * 	Special thanks ;) to Mattia Crivellini <tia@mclink.it>
- * 	much inspired by the XFree86 4.1.0 Trident driver sources by Alan Hourihane
+ * 	much inspired by the XFree86 4.x Trident driver sources by Alan Hourihane
  * 	the FreeVGA project
  *	Francesco Salvestrini <salvestrini@users.sf.net> XP support,code,suggestions
- * NOTES:
- * 	Tested on Compaq Presario 12XL300 with CyberBladei1
- * 	Tested on Toshiba 1800-514 with CyberBladeXPAi1
- * 	No monitors were harmed during the writing of this driver
  * TODO:
  * 	timing value tweaking so it looks good on every monitor in every mode
- * 	test text acceleration for the Image series
- *	test DPMS stuff
+ *	TGUI acceleration	
  */
 
 #include <linux/config.h>
@@ -27,69 +21,41 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
+#include <linux/delay.h>
+#include <video/trident.h>
 
-#include "tridentfb.h"
-
-#define VERSION		"0.6.9"
+#define VERSION		"0.7.8-NEWAPI"
 
 struct tridentfb_par {
-	struct fb_var_screeninfo var;
-	int bpp;
-	int hres;
-	int vres;
-	int linelength;
 	int vclk;		//in MHz
-
-	int vtotal;
-	int vdispend;
-	int vsyncstart;
-	int vsyncend;
-	int vblankstart;
-	int vblankend;
-
-	int htotal;
-	int hdispend;
-	int hsyncstart;
-	int hsyncend;
-	int hblankstart;
-	int hblankend;
-};
-
-struct tridentfb_info {
-	struct fb_info_gen gen;
-	unsigned int fbmem_virt;	//framebuffer virtual memory address
-	unsigned int fbmem;		//framebuffer physical memory address
-	unsigned int memsize;		//size of fbmem
-	unsigned int io;		//io space address
-	unsigned int io_virt;		//iospace virtual memory address
-	unsigned int nativex;		//flat panel xres
-	struct tridentfb_par currentmode;
+	unsigned int io_virt;	//iospace virtual memory address
 };
 
+unsigned char eng_oper;		//engine operation...
 static struct fb_ops tridentfb_ops;
 
-static struct tridentfb_info fb_info;
-static struct display disp;
+static struct tridentfb_par default_par;
+
+/* FIXME:kmalloc these 3 instead */
+static struct fb_info fb_info;
+static int pseudo_pal[16];
 
-static struct { unsigned char red,green,blue,transp; } palette[256];
 
 static struct fb_var_screeninfo default_var;
 
-static char * tridentfb_name = "Trident";
+static struct fb_fix_screeninfo tridentfb_fix = {
+	.id = "Trident",	
+	.type = FB_TYPE_PACKED_PIXELS,
+	.ypanstep = 1,
+	.visual = FB_VISUAL_PSEUDOCOLOR,
+	.accel = FB_ACCEL_NONE,
+};
 
-static int family;
-static int pci_id;
+static int chip_id;
 
 static int defaultaccel;
 static int displaytype;
 
-static int pseudo_pal[16];
-
 
 /* defaults which are normally overriden by user values */
 
@@ -98,7 +64,6 @@
 static int bpp = 8;
 
 static int noaccel;
-static int accel;
 
 static int center;
 static int stretch;
@@ -116,7 +81,6 @@
 MODULE_PARM(center,"i");
 MODULE_PARM(stretch,"i");
 MODULE_PARM(noaccel,"i");
-MODULE_PARM(accel,"i");
 MODULE_PARM(memsize,"i");
 MODULE_PARM(memdiff,"i");
 MODULE_PARM(nativex,"i");
@@ -124,6 +88,54 @@
 MODULE_PARM(crt,"i");
 
 
+static int chip3D;
+static int chipcyber;
+
+int is3Dchip(int id)
+{
+	return 	((id == BLADE3D) || (id == CYBERBLADEE4) ||
+		 (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) ||
+		 (id == CYBER9397) || (id == CYBER9397DVD) ||
+		 (id == CYBER9520) || (id == CYBER9525DVD) ||
+		 (id == IMAGE975) || (id == IMAGE985) ||
+		 (id == CYBERBLADEi1) || (id == CYBERBLADEi1D) ||
+		 (id ==	CYBERBLADEAi1) || (id == CYBERBLADEAi1D) ||
+		 (id ==	CYBERBLADEXPm8) || (id == CYBERBLADEXPm16) ||
+		 (id ==	CYBERBLADEXPAi1));
+}
+
+int iscyber(int id)
+{
+	switch (id) {
+		case CYBER9388:		
+		case CYBER9382:
+		case CYBER9385:
+		case CYBER9397:
+		case CYBER9397DVD:
+		case CYBER9520:
+		case CYBER9525DVD:
+		case CYBERBLADEE4:
+		case CYBERBLADEi7D:
+		case CYBERBLADEi1:
+		case CYBERBLADEi1D: 
+		case CYBERBLADEAi1: 
+		case CYBERBLADEAi1D:
+		case CYBERBLADEXPAi1:
+			return 1;
+		
+		case CYBER9320:
+		case TGUI9660:     
+		case IMAGE975:
+		case IMAGE985:
+		case BLADE3D:
+		case CYBERBLADEi7: /* VIA MPV4 integrated version */
+
+		default:
+			/* case CYBERBLDAEXPm8:	 Strange */
+			/* case CYBERBLDAEXPm16: Strange */
+			return 0;
+	}
+}
 
 #define CRT 0x3D0		//CRTC registers offset for color display
 
@@ -132,8 +144,8 @@
 #endif
 
 #if TRIDENT_MMIO
-	#define t_outb(val,reg)	writeb(val,fb_info.io_virt + reg)
-	#define t_inb(reg)	readb(fb_info.io_virt + reg)
+	#define t_outb(val,reg)	writeb(val,((struct tridentfb_par *)(fb_info.par))->io_virt + reg)
+	#define t_inb(reg)	readb(((struct tridentfb_par*)(fb_info.par))->io_virt + reg)
 #else
 	#define t_outb(val,reg) outb(val,reg)
 	#define t_inb(reg) inb(reg)
@@ -143,16 +155,17 @@
 static struct accel_switch {
 	void (*init_accel)(int,int);
 	void (*wait_engine)(void);
-	void (*fill_rect)(int,int,int,int,int);
-	void (*copy_rect)(int,int,int,int,int,int);
+	void (*fill_rect)(__u32,__u32,__u32,__u32,__u32,__u32);
+	void (*copy_rect)(__u32,__u32,__u32,__u32,__u32,__u32);
 } *acc;
 
-#define writemmr(r,v)	writel(v, fb_info.io_virt + r)
-#define readmmr(r)	readl(fb_info.io_virt + r)
+#define writemmr(r,v)	writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r)
+#define readmmr(r)	readl(((struct tridentfb_par *)fb_info.par)->io_virt + r)
+
+
 
 /*
- * Blade specific acceleration.Not XP's though those are
- * unaccelerated.
+ * Blade specific acceleration.
  */
 
 #define point(x,y) ((y)<<16|(x))
@@ -165,7 +178,6 @@
 #define DR1	0x2108
 #define DR2	0x210C
 
-#define REPL(x)	x = x | x<<16
 #define ROP_S	0xCC
 
 static void blade_init_accel(int pitch,int bpp)
@@ -196,26 +208,26 @@
 	while(readmmr(STA) & 0xFA800000);
 }
 
-static void blade_fill_rect(int x,int y,int w,int h,int c)
+static void blade_fill_rect(__u32 x,__u32 y,__u32 w,__u32 h,__u32 c,__u32 rop)
 {
 	writemmr(CLR,c);
-	writemmr(ROP,ROP_S);
+	writemmr(ROP,rop ? 0x66:ROP_S);
 	writemmr(CMD,0x20000000|1<<19|1<<4|2<<2);
 
 	writemmr(DR1,point(x,y));
 	writemmr(DR2,point(x+w-1,y+h-1));
 }
 
-static void blade_copy_rect(int x1,int y1,int x2,int y2,int w,int h)
+static void blade_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h)
 {
-	int s1,s2,d1,d2;
+	__u32 s1,s2,d1,d2;
 	int direction = 2;
 	s1 = point(x1,y1);
 	s2 = point(x1+w-1,y1+h-1);
 	d1 = point(x2,y2);
 	d2 = point(x2+w-1,y2+h-1);
 
-	if ((y1 > y2) || ((y1 == y2) && (x1 >x2)))
+	if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
 			direction = 0;
 
 
@@ -235,6 +247,130 @@
 	blade_copy_rect,
 };
 
+
+/*
+ * BladeXP specific acceleration functions
+ */
+
+#define ROP_P 0xF0
+#define masked_point(x,y) ((y & 0xffff)<<16|(x & 0xffff))
+
+static void xp_init_accel(int pitch,int bpp)
+{
+	int tmp = 0,v1;
+	unsigned char x = 0;
+
+	switch (bpp) {
+		case 8:  x = 0; break;
+		case 16: x = 1; break;
+		case 24: x = 3; break;
+		case 32: x = 2; break;
+	}
+
+	switch (pitch << (bpp >> 3)) {
+		case 8192:
+		case 512:  x |= 0x00; break;
+		case 1024: x |= 0x04; break;
+		case 2048: x |= 0x08; break;
+		case 4096: x |= 0x0C; break;
+	}
+
+	t_outb(x,0x2125);
+
+	eng_oper = x | 0x40;
+
+	switch (bpp) {
+		case 8:  tmp = 18; break;
+		case 15:
+		case 16: tmp = 19; break;
+		case 24:
+		case 32: tmp = 20; break;
+	}
+
+	v1 = pitch << tmp;
+
+	writemmr(0x2154,v1);
+	writemmr(0x2150,v1);
+	t_outb(3,0x2126);
+}
+
+static void xp_wait_engine(void)
+{
+	int busy;
+	int count, timeout;
+
+	count = 0;
+	timeout = 0;
+	for (;;) {
+		busy = t_inb(STA) & 0x80;
+		if (busy != 0x80)
+			return;
+		count++;
+		if (count == 10000000) {
+			/* Timeout */
+			count = 9990000;
+			timeout++;
+			if (timeout == 8) {
+				/* Reset engine */
+				t_outb(0x00, 0x2120);
+				return;
+			}
+		}
+	}
+}
+
+static void xp_fill_rect(__u32 x,__u32 y,__u32 w,__u32 h,__u32 c,__u32 rop)
+{
+	writemmr(0x2127,ROP_P);
+	writemmr(0x2158,c);
+	writemmr(0x2128,0x4000);
+	writemmr(0x2140,masked_point(h,w));
+	writemmr(0x2138,masked_point(y,x));
+	t_outb(0x01,0x2124);
+        t_outb(eng_oper,0x2125);
+}
+
+static void xp_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h)
+{
+	int direction;
+	__u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp;
+
+	direction = 0x0004;
+	
+	if ((x1 < x2) && (y1 == y2)) {
+		direction |= 0x0200;
+		x1_tmp = x1 + w - 1;
+		x2_tmp = x2 + w - 1;
+	} else {
+		x1_tmp = x1;
+		x2_tmp = x2;
+	}
+  
+	if (y1 < y2) {
+		direction |= 0x0100;
+		y1_tmp = y1 + h - 1;
+		y2_tmp = y2 + h - 1;
+  	} else {
+		y1_tmp = y1;
+		y2_tmp = y2;
+	}
+
+	writemmr(0x2128,direction);	
+	t_outb(ROP_S,0x2127);
+	writemmr(0x213C,masked_point(y1_tmp,x1_tmp));
+	writemmr(0x2138,masked_point(y2_tmp,x2_tmp));
+	writemmr(0x2140,masked_point(h,w));
+	t_outb(0x01,0x2124);
+}
+
+static struct accel_switch accel_xp = {
+  	xp_init_accel,
+	xp_wait_engine,
+	xp_fill_rect,
+	xp_copy_rect,
+};
+
+
 /*
  * Image specific acceleration functions
  */
@@ -255,7 +391,7 @@
 	writemmr(0x2148, 0x00000000);
 	writemmr(0x2150, 0x00000000);
 	writemmr(0x2154, 0x00000000);
-	writemmr(0x2120, 0x60000000 |(pitch<<16) |pitch);
+	writemmr(0x2120, 0x60000000|(pitch<<16) |pitch);
 	writemmr(0x216C, 0x00000000);
 	writemmr(0x2170, 0x00000000);
 	writemmr(0x217C, 0x00000000);
@@ -268,7 +404,7 @@
 	while(readmmr(0x2164) & 0xF0000000);
 }
 
-static void image_fill_rect(int x,int y,int w,int h,int c)
+static void image_fill_rect(__u32 x, __u32 y, __u32 w, __u32 h, __u32 c, __u32 rop)
 {
 	writemmr(0x2120,0x80000000);
 	writemmr(0x2120,0x90000000|ROP_S);
@@ -281,9 +417,9 @@
 	writemmr(0x2124,0x80000000|3<<22|1<<10|1<<9);
 }
 
-static void image_copy_rect(int x1,int y1,int x2,int y2,int w,int h)
+static void image_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h)
 {
-	int s1,s2,d1,d2;
+	__u32 s1,s2,d1,d2;
 	int direction = 2;
 	s1 = point(x1,y1);
 	s2 = point(x1+w-1,y1+h-1);
@@ -315,108 +451,45 @@
  * Accel functions called by the upper layers
  */
 
-static void trident_bmove (struct display *p, int sy, int sx,
-				int dy, int dx, int height, int width)
+static void tridentfb_fillrect(struct fb_info * info, struct fb_fillrect *fr)
 {
-	sx *= fontwidth(p);
-	dx *= fontwidth(p);
-	width *= fontwidth(p);
-	sy *= fontheight(p);
-	dy *= fontheight(p);
-	height *= fontheight(p);
-	acc->copy_rect(sx,sy,dx,dy,width,height);
+	int bpp = info->var.bits_per_pixel;
+	int dx,dy,w,h,col;
+	
+	switch (bpp) {
+		case 8: col = fr->color;
+			break;
+		case 16: col = ((u16 *)(info->pseudo_palette))[fr->color];
+			 break;
+		case 32: col = ((u32 *)(info->pseudo_palette))[fr->color];
+			 break;
+	}		 
+			
+	acc->fill_rect(fr->dx, fr->dy, fr->width, fr->height, col, fr->rop);
 	acc->wait_engine();
 }
-static void trident_clear_helper (int c, struct display *p,
-				int sy, int sx, int height, int width)
+static void tridentfb_copyarea(struct fb_info *info, struct fb_copyarea *ca)
 {
-	sx *= fontwidth(p);
-	sy *= fontheight(p);
-	width *= fontwidth(p);
-	height *= fontheight(p);
-	acc->fill_rect(sx,sy,width,height,c);
+	acc->copy_rect(ca->sx,ca->sy,ca->dx,ca->dy,ca->width,ca->height);
 	acc->wait_engine();
 }
 
-
-#ifdef FBCON_HAS_CFB8
-static void trident_8bpp_clear (struct vc_data *conp, struct display *p,
-				int sy, int sx, int height, int width)
-{
-	int c;
-	c = attr_bgcol_ec(p,conp) & 0xFF;
-	c |= c<<8;
-	c |= c<<16;
-	trident_clear_helper(c,p,sy,sx,height,width);
-}
-
-static struct display_switch trident_8bpp = {
-	.setup =	fbcon_cfb8_setup,
-	.bmove =	trident_bmove,
-	.clear =	trident_8bpp_clear,
-	.putc =		fbcon_cfb8_putc,
-	.putcs =	fbcon_cfb8_putcs,
-	.revc =		fbcon_cfb8_revc,
-	.clear_margins =fbcon_cfb8_clear_margins,
-	.fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
-};
-#endif
-#ifdef FBCON_HAS_CFB16
-static void trident_16bpp_clear (struct vc_data *conp, struct display *p,
-				int sy, int sx, int height, int width)
-{
-	int c;
-	c = ((u16*)p->dispsw_data)[attr_bgcol_ec(p,conp)];
-	c = c | c<<16;
-	trident_clear_helper(c,p,sy,sx,height,width);
-}
-
-static struct display_switch trident_16bpp = {
-	.setup =	fbcon_cfb16_setup,
-	.bmove =	trident_bmove,
-	.clear =	trident_16bpp_clear,
-	.putc =		fbcon_cfb16_putc,
-	.putcs =	fbcon_cfb16_putcs,
-	.revc =		fbcon_cfb16_revc,
-	.clear_margins =fbcon_cfb16_clear_margins,
-	.fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
-};
-#endif
-#ifdef FBCON_HAS_CFB32
-static void trident_32bpp_clear (struct vc_data *conp, struct display *p,
-				int sy, int sx, int height, int width)
-{
-	int c;
-	c = ((u32*)p->dispsw_data)[attr_bgcol_ec(p,conp)];
-	trident_clear_helper(c,p,sy,sx,height,width);
-}
-
-static struct display_switch trident_32bpp = {
-	.setup =	fbcon_cfb32_setup,
-	.bmove =	trident_bmove,
-	.clear =	trident_32bpp_clear,
-	.putc =		fbcon_cfb32_putc,
-	.putcs =	fbcon_cfb32_putcs,
-	.revc =		fbcon_cfb32_revc,
-	.clear_margins =fbcon_cfb32_clear_margins,
-	.fontwidthmask =FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
-};
-#endif
-
 /*
  * Hardware access functions
  */
 
 static inline unsigned char read3X4(int reg)
 {
-	writeb(reg, fb_info.io_virt + CRT + 4);
-	return readb(fb_info.io_virt + CRT + 5);
+	struct tridentfb_par * par = (struct tridentfb_par *)fb_info.par;
+	writeb(reg, par->io_virt + CRT + 4);
+	return readb( par->io_virt + CRT + 5);
 }
 
 static inline void write3X4(int reg, unsigned char val)
 {
-	writeb(reg, fb_info.io_virt + CRT + 4);
-	writeb(val, fb_info.io_virt + CRT + 5);
+	struct tridentfb_par * par = (struct tridentfb_par *)fb_info.par;
+	writeb(reg, par->io_virt + CRT + 4);
+	writeb(val, par->io_virt + CRT + 5);
 }
 
 static inline unsigned char read3C4(int reg)
@@ -439,14 +512,14 @@
 
 static inline void writeAttr(int reg, unsigned char val)
 {
-	readb(fb_info.io_virt + CRT + 0x0A);	//flip-flop to index
+	readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A);	//flip-flop to index
 	t_outb(reg, 0x3C0);
 	t_outb(val, 0x3C0);
 }
 
 static inline unsigned char readAttr(int reg)
 {
-	readb(fb_info.io_virt + CRT + 0x0A);	//flip-flop to index
+	readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A);	//flip-flop to index
 	t_outb(reg, 0x3C0);
 	return t_inb(0x3C1);
 }
@@ -457,11 +530,22 @@
 	t_outb(val, 0x3CF);
 }
 
-#define unprotect_all()	write3C4(Protection, 0x92);unprotect()
-#define unprotect()	write3C4(NewMode1,0xC2)
-#define bios_reg(reg) 	write3CE(BiosReg, reg)
-#define enable_mmio()	outb(PCIReg, 0x3D4); \
-			outb(inb(0x3D5) | 0x01, 0x3D5)
+static inline void enable_mmio(void)
+{
+	/* Goto New Mode */
+	outb(0x0B, 0x3C4);
+	inb(0x3C5);
+
+	/* Unprotect registers */
+	outb(NewMode1, 0x3C4);
+	outb(0x80, 0x3C5);
+  
+	/* Enable MMIO */
+	outb(PCIReg, 0x3D4); 
+	outb(inb(0x3D5) | 0x01, 0x3D5);
+}
+
+
 #define crtc_unlock()	write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
 
 /*  Return flat panel's maximum x resolution */
@@ -474,15 +558,13 @@
 
        	tmp = (read3CE(VertStretch) >> 4) & 3;
 
-	/* detection broken on XPAi ??? misdetects 1024 for 800 */
-	if (pci_id == CYBERBLADEXPAi1 && tmp == 3)
-		tmp = 2;
-
 	switch (tmp) {
-		case 0:x = 1280;y = 1024;break;
-		case 1:x = 640;y = 480;break;
-		case 2:x = 1024;y = 768;break;
-		default:x = 800;y = 600;break;
+		case 0: x = 1280; y = 1024; break;
+		case 2: x = 1024; y = 768;  break;
+		case 3: x = 800;  y = 600;  break; 
+		case 4: x = 1400; y = 1050; break;
+		case 1: 
+		default:x = 640;  y = 480;  break;
 	}
 
 	output("%dx%d flat panel found\n", x, y);
@@ -499,6 +581,10 @@
 /* For resolutions smaller than FP resolution stretch */
 static void screen_stretch(void)
 {
+  	if (chip_id != CYBERBLADEXPAi1)
+  		write3CE(BiosReg,0);
+  	else
+  		write3CE(BiosReg,8);
 	write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 1);
 	write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 1);
 }
@@ -506,7 +592,6 @@
 /* For resolutions smaller than FP resolution center */
 static void screen_center(void)
 {
-	bios_reg(0);		// no stretch
 	write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 0x80);
 	write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 0x80);
 }
@@ -515,13 +600,13 @@
 static void set_screen_start(int base)
 {
 	write3X4(StartAddrLow, base & 0xFF);
-	write3X4(StartAddrHigh, (base & 0xFF00) >>8);
-	write3X4(CRTCModuleTest, (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >>11));
-	write3X4(CRTHiOrd, (read3X4(CRTHiOrd) & 0xF8) | (base & 0xE0000) >> 17);
+	write3X4(StartAddrHigh, (base & 0xFF00) >> 8);
+	write3X4(CRTCModuleTest, (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11));
+	write3X4(CRTHiOrd, (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));
 }
 
 /* Use 20.12 fixed-point for NTSC value and frequency calculation */
-#define calc_freq(n,m,k)  ( (unsigned long)0xE517 * (n+8) / (m+2)*(1<<k) )
+#define calc_freq(n,m,k)  ( ((unsigned long)0xE517 * (n+8) / ((m+2)*(1<<k))) >> 12 )
 
 /* Set dotclock frequency */
 static void set_vclk(int freq)
@@ -542,8 +627,13 @@
 			hi = (k<<6) | m;
 		}
 	}
-	write3C4(ClockHigh,hi);
-	write3C4(ClockLow,lo);
+	if (chip3D) {
+		write3C4(ClockHigh,hi);
+		write3C4(ClockLow,lo);
+	} else {
+		outb(lo,0x43C8);
+		outb(hi,0x43C9);
+	}
 	debug("VCLK = %X %X\n",hi,lo);
 }
 
@@ -551,7 +641,9 @@
 static void set_number_of_lines(int lines)
 {
 	int tmp = read3CE(CyberEnhance) & 0x8F;
-	if (lines > 768)
+	if (lines > 1024)
+		tmp |= 0x50;
+	else if (lines > 768)
 		tmp |= 0x30;
 	else if (lines > 600)
 		tmp |= 0x20;
@@ -568,7 +660,7 @@
 {
 	if (fp)
 		return DISPLAY_FP;
-	if (crt)
+	if (crt || !chipcyber)
 		return DISPLAY_CRT;
 	return (read3CE(FPConfig) & 0x10)?DISPLAY_FP:DISPLAY_CRT;
 }
@@ -576,26 +668,42 @@
 /* Try detecting the video memory size */
 static unsigned int __init get_memsize(void)
 {
-	unsigned char tmp;
+	unsigned char tmp, tmp2;
 	unsigned int k;
 
 	/* If memory size provided by user */
 	if (memsize)
 		k = memsize * Kb;
 	else
-	switch (pci_id) {
-		case CYBER9525DVD:k = 2560 * Kb;break;
-		case CYBERBLADEXPAi1:k = 16 * Mb;break;
-		case CYBERBLADEXPm16:k = 16 * Mb;break;
-		case CYBERBLADEXPm8:k = 8 * Mb;break;
+	switch (chip_id) {
+		case CYBER9525DVD:    k = 2560 * Kb; break;
 		default:
 			tmp = read3X4(SPR) & 0x0F;
 			switch (tmp) {
-				case 3:k = 1 * Mb;break;
-				case 7:k = 2 * Mb;break;
-				case 15:k = 4 * Mb;break;
-				case 4:k = 8 * Mb;break;
-				default:k = 1 * Mb;
+
+				case 0x01: k = 512;     break;
+				case 0x02: k = 6 * Mb;  break; /* XP */
+				case 0x03: k = 1 * Mb;  break;
+				case 0x04: k = 8 * Mb;  break;
+				case 0x06: k = 10 * Mb; break; /* XP */
+				case 0x07: k = 2 * Mb;  break;
+				case 0x08: k = 12 * Mb; break; /* XP */
+				case 0x0A: k = 14 * Mb; break; /* XP */
+				case 0x0C: k = 16 * Mb; break; /* XP */
+				case 0x0E:                     /* XP */
+  
+					tmp2 = read3C4(0xC1);
+					switch (tmp2) {
+						case 0x00: k = 20 * Mb; break;
+						case 0x01: k = 24 * Mb; break;
+						case 0x10: k = 28 * Mb; break;
+						case 0x11: k = 32 * Mb; break;
+						default:   k = 1 * Mb;  break;
+					}
+				break;
+	
+				case 0x0F: k = 4 * Mb; break;
+				default:   k = 1 * Mb;
 			}
 	}
 
@@ -604,209 +712,112 @@
 	return k;
 }
 
-
-/* Fill in fix */
-static int trident_encode_fix(struct fb_fix_screeninfo *fix,
-				  const void *par,
-				  struct fb_info_gen *info)
+/* See if we can handle the video mode described in var */
+static int tridentfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	struct tridentfb_info * i = (struct tridentfb_info *)info;
-	struct tridentfb_par * p = (struct tridentfb_par *)par;
-
+	int bpp = var->bits_per_pixel;
 	debug("enter\n");
 
-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-	strcpy(fix->id,tridentfb_name);
-
-	fix->smem_start = i->fbmem;
-	fix->smem_len = i->memsize;
-
-	fix->type = FB_TYPE_PACKED_PIXELS;
-	fix->type_aux = 0;
-
-	fix->visual = p->bpp==8 ? FB_VISUAL_PSEUDOCOLOR:FB_VISUAL_TRUECOLOR;
-
-	fix->xpanstep = fix->ywrapstep = 0;
-	fix->ypanstep = 1;
-	fix->line_length = p->linelength;
-	fix->mmio_start = 0;
-	fix->mmio_len = 0;
-
-	fix->accel = FB_ACCEL_NONE;
-
-	debug("exit\n");
-	return 0;
-}
-
-/* Fill in par from var */
-static int trident_decode_var(const struct fb_var_screeninfo *var,
-				  void *par,
-				  struct fb_info_gen *info)
-{
-	struct tridentfb_par * p = (struct tridentfb_par *)par;
-	struct tridentfb_info * i = (struct tridentfb_info *)info;
-	int vres,vfront,vback,vsync;
-	debug("enter\n");
-	p->var = *var;
-	p->bpp = var->bits_per_pixel;
-
-	if (p->bpp == 24 )
-		p->bpp = 32;
-
-	p->linelength = var->xres_virtual * p->bpp/8;
+	/* check color depth */
+	if (bpp == 24 )
+		bpp = var->bits_per_pixel = 32;
+	/* check whether resolution fits on panel and in memory*/
+	if (var->xres > nativex)
+		return -EINVAL;
+	if (var->xres * var->yres_virtual * bpp/8 > info->fix.smem_len)
+		return -EINVAL;
 
-	switch (p->bpp) {
+	switch (bpp) {
 		case 8:
-			p->var.red.offset = 0;
-			p->var.green.offset = 0;
-			p->var.blue.offset = 0;
-			p->var.red.length = 6;
-			p->var.green.length = 6;
-			p->var.blue.length = 6;
+			var->red.offset = 0;
+			var->green.offset = 0;
+			var->blue.offset = 0;
+			var->red.length = 6;
+			var->green.length = 6;
+			var->blue.length = 6;
 			break;
 		case 16:
-			p->var.red.offset = 11;
-			p->var.green.offset = 5;
-			p->var.blue.offset = 0;
-			p->var.red.length = 5;
-			p->var.green.length = 6;
-			p->var.blue.length = 5;
+			var->red.offset = 11;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length = 5;
+			var->green.length = 6;
+			var->blue.length = 5;
 			break;
 		case 32:
-			p->var.red.offset = 16;
-			p->var.green.offset = 8;
-			p->var.blue.offset = 0;
-			p->var.red.length = 8;
-			p->var.green.length = 8;
-			p->var.blue.length = 8;
+			var->red.offset = 16;
+			var->green.offset = 8;
+			var->blue.offset = 0;
+			var->red.length = 8;
+			var->green.length = 8;
+			var->blue.length = 8;
 			break;
 		default:
-			return -EINVAL;
+			return -EINVAL;	
 	}
-
-	/* convert from picoseconds to MHz */
-	p->vclk = 1000000/var->pixclock;
-
-	if (p->bpp == 32)
-		p->vclk *=2;
-
-	p->hres = var->xres;
-	vres = p->vres = var->yres;
-
-	/* See if requested resolution is larger than flat panel */
-	if (p->hres > i->nativex && flatpanel) {
-		return -EINVAL;
-	}
-
-	/* See if requested resolution fits in available memory */
-	if (p->hres * p->vres * p->bpp/8 > i->memsize) {
-		return -EINVAL;
-	}
-
-	vfront = var->upper_margin;
-	vback =	var->lower_margin;
-	vsync =	var->vsync_len;
-
-	/* Compute horizontal and vertical VGA CRTC timing values */
-	if (var->vmode & FB_VMODE_INTERLACED) {
-		vres /= 2;
-		vfront /=2;
-		vback /=2;
-		vsync /=2;
-	}
-
-	if (var->vmode & FB_VMODE_DOUBLE) {
-		vres *= 2;
-		vfront *=2;
-		vback *=2;
-		vsync *=2;
-	}
-
-	p->htotal = (p->hres + var->left_margin + var->right_margin + var->hsync_len)/8 - 10;
-	p->hdispend = p->hres/8 - 1;
-	p->hsyncstart = (p->hres + var->right_margin)/8;
-	p->hsyncend = var->hsync_len/8;
-	p->hblankstart = p->hdispend + 1;
-	p->hblankend = p->htotal + 5;
-
-	p->vtotal = vres + vfront + vback + vsync - 2;
-	p->vdispend = vres - 1;
-	p->vsyncstart = vres + vback;
-	p->vsyncend = vsync;
-	p->vblankstart = vres;
-	p->vblankend = p->vtotal + 2;
-
 	debug("exit\n");
 
 	return 0;
-}
 
-
-/* Fill in var from info */
-static int trident_encode_var(struct fb_var_screeninfo *var,
-				  const void *par,
-				  struct fb_info_gen *info)
-{
-	struct tridentfb_par * p = (struct tridentfb_par *)par;
-	debug("enter\n");
-	*var = p->var;
-	var->bits_per_pixel = p->bpp;
-	debug("exit\n");
-	return 0;
 }
-
-/* Fill in par from hardware */
-static void trident_get_par(void *par, struct fb_info_gen *info)
-{
-	struct tridentfb_par * p = (struct tridentfb_par *)par;
-	struct tridentfb_info * i = (struct tridentfb_info *)info;
-
-	debug("enter\n");
-	*p = i->currentmode;
-	debug("exit\n");
-}
-
 /* Pan the display */
-static int trident_pan_display(const struct fb_var_screeninfo *var,
-				   struct fb_info_gen *info)
+static int tridentfb_pan_display(struct fb_var_screeninfo *var,
+				   struct fb_info *info)
 {
 	unsigned int offset;
-	struct tridentfb_info * i = (struct tridentfb_info *)info;
 
 	debug("enter\n");
-
 	offset = (var->xoffset + (var->yoffset * var->xres))
 			* var->bits_per_pixel/32;
-	i->currentmode.var.xoffset = var->xoffset;
-	i->currentmode.var.yoffset = var->yoffset;
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
 	set_screen_start(offset);
 	debug("exit\n");
 	return 0;
 }
 
-/* Set the hardware from par */
-static void trident_set_par(const void *par, struct fb_info_gen *info)
+#define shadowmode_on()  write3CE(CyberControl,read3CE(CyberControl) | 0x81)
+#define shadowmode_off() write3CE(CyberControl,read3CE(CyberControl) & 0x7E)
+
+/* Set the hardware to the requested video mode */
+static int tridentfb_set_par(struct fb_info *info)
 {
-	struct tridentfb_par * p = (struct tridentfb_par *)par;
-	struct tridentfb_info * i = (struct tridentfb_info *)info;
+	struct tridentfb_par * par = (struct tridentfb_par *)(info->par);
+	u32	htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend,
+		vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend;
+	struct fb_var_screeninfo *var = &info->var;	
+	int bpp = var->bits_per_pixel;
 	unsigned char tmp;
 	debug("enter\n");
+	htotal = (var->xres + var->left_margin + var->right_margin + var->hsync_len)/8 - 10;
+	hdispend = var->xres/8 - 1;
+	hsyncstart = (var->xres + var->right_margin)/8;
+	hsyncend = var->hsync_len/8;
+	hblankstart = hdispend + 1;
+	hblankend = htotal + 5;
+
+	vtotal = var->yres + var->upper_margin + var->lower_margin + var->vsync_len - 2;
+	vdispend = var->yres - 1;
+	vsyncstart = var->yres + var->lower_margin;
+	vsyncend = var->vsync_len;
+	vblankstart = var->yres;
+	vblankend = vtotal + 2;
 
-	i->currentmode = *p;
-	unprotect_all();
-	crtc_unlock();
 	enable_mmio();
-
+	crtc_unlock();
 	write3CE(CyberControl,8);
-	if (flatpanel && p->hres < i->nativex) {
+
+	if (flatpanel && var->xres < nativex) {
 		/*
 		 * on flat panels with native size larger
 		 * than requested resolution decide whether
 		 * we stretch or center
 		 */
 		t_outb(0xEB,0x3C2);
-		write3CE(CyberControl,0x81);
-		if (center) //|| (p->bpp==32 && pci_id == CYBERBLADEi1D))
+
+		shadowmode_on();
+
+		if (center) 
 			screen_center();
 		else if (stretch)
 			screen_stretch();
@@ -817,76 +828,87 @@
 	}
 
 	/* vertical timing values */
-	write3X4(CRTVTotal, p->vtotal & 0xFF);
-	write3X4(CRTVDispEnd, p->vdispend & 0xFF);
-	write3X4(CRTVSyncStart, p->vsyncstart & 0xFF);
-	write3X4(CRTVSyncEnd, (p->vsyncend & 0x0F));
-	write3X4(CRTVBlankStart, p->vblankstart & 0xFF);
+	write3X4(CRTVTotal, vtotal & 0xFF);
+	write3X4(CRTVDispEnd, vdispend & 0xFF);
+	write3X4(CRTVSyncStart, vsyncstart & 0xFF);
+	write3X4(CRTVSyncEnd, (vsyncend & 0x0F));
+	write3X4(CRTVBlankStart, vblankstart & 0xFF);
 	write3X4(CRTVBlankEnd, 0/*p->vblankend & 0xFF*/);
 
 	/* horizontal timing values */
-	write3X4(CRTHTotal, p->htotal & 0xFF);
-	write3X4(CRTHDispEnd, p->hdispend & 0xFF);
-	write3X4(CRTHSyncStart, p->hsyncstart & 0xFF);
-	write3X4(CRTHSyncEnd, (p->hsyncend & 0x1F) | ((p->hblankend & 0x20)<<2));
-	write3X4(CRTHBlankStart, p->hblankstart & 0xFF);
+	write3X4(CRTHTotal, htotal & 0xFF);
+	write3X4(CRTHDispEnd, hdispend & 0xFF);
+	write3X4(CRTHSyncStart, hsyncstart & 0xFF);
+	write3X4(CRTHSyncEnd, (hsyncend & 0x1F) | ((hblankend & 0x20)<<2));
+	write3X4(CRTHBlankStart, hblankstart & 0xFF);
 	write3X4(CRTHBlankEnd, 0/*(p->hblankend & 0x1F)*/);
 
 	/* higher bits of vertical timing values */
 	tmp = 0x10;
-	if (p->vtotal & 0x100) tmp |= 0x01;
-	if (p->vdispend & 0x100) tmp |= 0x02;
-	if (p->vsyncstart & 0x100) tmp |= 0x04;
-	if (p->vblankstart & 0x100) tmp |= 0x08;
-
-	if (p->vtotal & 0x200) tmp |= 0x20;
-	if (p->vdispend & 0x200) tmp |= 0x40;
-	if (p->vsyncstart & 0x200) tmp |= 0x80;
-
+	if (vtotal & 0x100) tmp |= 0x01;
+	if (vdispend & 0x100) tmp |= 0x02;
+	if (vsyncstart & 0x100) tmp |= 0x04;
+	if (vblankstart & 0x100) tmp |= 0x08;
+
+	if (vtotal & 0x200) tmp |= 0x20;
+	if (vdispend & 0x200) tmp |= 0x40;
+	if (vsyncstart & 0x200) tmp |= 0x80;
 	write3X4(CRTOverflow, tmp);
 
-
 	tmp = read3X4(CRTHiOrd) | 0x08;	//line compare bit 10
-
-	if (p->vtotal & 0x400) tmp |= 0x80;
-	if (p->vblankstart & 0x400) tmp |= 0x40;
-	if (p->vsyncstart & 0x400) tmp |= 0x20;
-	if (p->vdispend & 0x400) tmp |= 0x10;
+	if (vtotal & 0x400) tmp |= 0x80;
+	if (vblankstart & 0x400) tmp |= 0x40;
+	if (vsyncstart & 0x400) tmp |= 0x20;
+	if (vdispend & 0x400) tmp |= 0x10;
 	write3X4(CRTHiOrd, tmp);
 
-	write3X4(HorizOverflow, 0);
-
+	tmp = 0;
+	if (htotal & 0x800) tmp |= 0x800 >> 11;
+	if (hblankstart & 0x800) tmp |= 0x800 >> 7;
+	write3X4(HorizOverflow, tmp);
+	
 	tmp = 0x40;
-	if (p->vblankstart & 0x200) tmp |= 0x20;
-	if (p->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80;  //double scan for 200 line modes
+	if (vblankstart & 0x200) tmp |= 0x20;
+//FIXME	if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80;  //double scan for 200 line modes
 	write3X4(CRTMaxScanLine, tmp);
+
 	write3X4(CRTLineCompare,0xFF);
 	write3X4(CRTPRowScan,0);
 	write3X4(CRTModeControl,0xC3);
+
 	write3X4(LinearAddReg,0x20);	//enable linear addressing
-	tmp = (p->var.vmode & FB_VMODE_INTERLACED) ? 0x84:0x80;
+
+	tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84:0x80;
 	write3X4(CRTCModuleTest,tmp);	//enable access extended memory
-	write3X4(GraphEngReg, 0x80);	//enable GE for text acceleration
 
-	if (p->var.accel_flags & FB_ACCELF_TEXT)
-		acc->init_accel(p->hres,p->bpp);
+	write3X4(GraphEngReg, 0x80);	//enable GE for text acceleration
 
-	switch (p->bpp) {
-		case 8:tmp=0;break;
-		case 16:tmp=5;break;
-		case 24:
-			/* tmp=0x29;break; */
-			/* seems like 24bpp is same as 32bpp when using vesafb */
-		case 32:tmp=9;break;
+//	if (info->var.accel_flags & FB_ACCELF_TEXT)
+//FIXME		acc->init_accel(info->var.xres,bpp);
+	
+	switch (bpp) {
+		case 8:  tmp = 0x00; break;
+		case 16: tmp = 0x05; break;
+		case 24: tmp = 0x29; break;
+		case 32: tmp = 0x09; 
 	}
+
 	write3X4(PixelBusReg, tmp);
 
-	write3X4(InterfaceSel, 0x5B);	//32bit internal data path
-	write3X4(DRAMControl, 0x30);	//both IO,linear enable
-	write3X4(Performance, 0xBF);
+	tmp = 0x10;
+	if (chipcyber)
+	    tmp |= 0x20;
+	write3X4(DRAMControl, tmp);	//both IO,linear enable
+
+	write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40);
+	write3X4(Performance,0x20);
 	write3X4(PCIReg,0x07);		//MMIO & PCI read and write burst enable
 
-	set_vclk(p->vclk);
+	/* convert from picoseconds to MHz */
+	par->vclk = 1000000/info->var.pixclock;
+	if (bpp == 32)
+		par->vclk *=2;
+	set_vclk(par->vclk);
 
 	write3C4(0,3);
 	write3C4(1,1);		//set char clock 8 dots wide
@@ -894,12 +916,17 @@
 	write3C4(3,0);
 	write3C4(4,0x0E);	//memory mode enable bitmaps ??
 
-	write3CE(MiscExtFunc,(p->bpp==32)?0x1A:0x12);	//divide clock by 2 if 32bpp
+	write3CE(MiscExtFunc,(bpp==32)?0x1A:0x12);	//divide clock by 2 if 32bpp
 							//chain4 mode display and CPU path
 	write3CE(0x5,0x40);	//no CGA compat,allow 256 col
 	write3CE(0x6,0x05);	//graphics mode
 	write3CE(0x7,0x0F);	//planes?
 
+	if (chip_id == CYBERBLADEXPAi1) {
+		/* This fixes snow-effect in 32 bpp */
+		write3X4(CRTHSyncStart,0x84);
+	}
+
 	writeAttr(0x10,0x41);	//graphics mode and support 256 color modes
 	writeAttr(0x12,0x0F);	//planes
 	writeAttr(0x13,0);	//horizontal pel panning
@@ -907,10 +934,10 @@
 	//colors
 	for(tmp = 0;tmp < 0x10;tmp++)
 		writeAttr(tmp,tmp);
-	readb(fb_info.io_virt + CRT + 0x0A);	//flip-flop to index
+	readb(par->io_virt + CRT + 0x0A);	//flip-flop to index
 	t_outb(0x20, 0x3C0);			//enable attr
 
-	switch (p->bpp) {
+	switch (bpp) {
 		case 8:	tmp = 0;break;		//256 colors
 		case 15: tmp = 0x10;break;
 		case 16: tmp = 0x30;break;	//hicolor
@@ -927,31 +954,11 @@
 	t_inb(0x3C8);
 
 	if (flatpanel)
-		set_number_of_lines(p->vres);
-	set_lwidth(p->hres*p->bpp/(4*16));
-
-	trident_pan_display(&p->var,info);
-	debug("exit\n");
-}
-
-/* Get value of one color register */
-static int trident_getcolreg(unsigned regno, unsigned *red,
-				 unsigned *green, unsigned *blue,
-				 unsigned *transp, struct fb_info *info)
-{
-	struct tridentfb_info * i = (struct tridentfb_info *)info;
-	int m = i->currentmode.bpp==8?256:16;
-
-	debug("enter %d\n",regno);
-
-	if (regno >= m)
-		return 1;
-
-	*red = palette[regno].red;
-	*green = palette[regno].green;
-	*blue = palette[regno].blue;
-	*transp = palette[regno].transp;
-
+		set_number_of_lines(info->var.yres);
+	set_lwidth(info->var.xres * bpp/(4*16));
+	info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+	info->fix.line_length = info->var.xres * (bpp >> 3);  
+	info->cmap.len = (bpp == 8) ? 256: 16;
 	debug("exit\n");
 	return 0;
 }
@@ -961,19 +968,11 @@
 				 unsigned blue, unsigned transp,
 				 struct fb_info *info)
 {
-	struct tridentfb_info * i = (struct tridentfb_info *)info;
-	int bpp = i->currentmode.bpp;
-	int m = bpp==8?256:16;
+	int bpp = info->var.bits_per_pixel;
 
-	debug("enter %d\n",regno);
-
-	if (regno >= m)
+	if (regno >= info->cmap.len)
 		return 1;
 
-	palette[regno].red = red;
-	palette[regno].green = green;
-	palette[regno].blue = blue;
-	palette[regno].transp = transp;
 
 	if (bpp==8) {
 		t_outb(0xFF,0x3C6);
@@ -995,12 +994,12 @@
 			((green & 0xFF00))		|
 			((blue & 0xFF00)>>8);
 
-	debug("exit\n");
+//	debug("exit\n");
 	return 0;
 }
 
 /* Try blanking the screen.For flat panels it does nothing */
-static int trident_blank(int blank_mode, struct fb_info_gen *info)
+static int tridentfb_blank(int blank_mode, struct fb_info *info)
 {
 	unsigned char PMCont,DPMSCont;
 
@@ -1035,218 +1034,194 @@
     	}
 
 	write3CE(PowerStatus,DPMSCont);
-    	t_outb(4,0x83C8);
-    	t_outb(PMCont,0x83C6);
+	t_outb(4,0x83C8);
+	t_outb(PMCont,0x83C6);
 
 	debug("exit\n");
 	return 0;
 }
 
-/* Set display switch used by console */
-static void trident_set_disp(const void *par, struct display *disp,
-				 struct fb_info_gen *info)
-{
-	struct tridentfb_info * i = (struct tridentfb_info *)info;
-	struct fb_info * ii = (struct fb_info *)info;
-	struct tridentfb_par * p = (struct tridentfb_par *)par;
-	int isaccel = p->var.accel_flags & FB_ACCELF_TEXT;
-
-	info->info.screen_base = (char *)i->fbmem_virt;
-	debug("enter\n");
-#ifdef FBCON_HAS_CFB8
-	if (p->bpp == 8 ) {
-		if (isaccel)
-			disp->dispsw = &trident_8bpp;
-		else
-			disp->dispsw = &fbcon_cfb8;
-	} else
-#endif
-#ifdef FBCON_HAS_CFB16
-	if (p->bpp == 16) {
-		if (isaccel)
-			disp->dispsw = &trident_16bpp;
-		else
-			disp->dispsw = &fbcon_cfb16;
-		disp->dispsw_data =ii->pseudo_palette;	/* console palette */
-	} else
-#endif
-#ifdef FBCON_HAS_CFB32
-	if (p->bpp == 32) {
-		if (isaccel)
-			disp->dispsw = &trident_32bpp;
-		else
-			disp->dispsw = &fbcon_cfb32;
-		disp->dispsw_data =ii->pseudo_palette;	/* console palette */
-	} else
-#endif
-	disp->dispsw = &fbcon_dummy;
-	debug("exit\n");
-}
-
-static struct fbgen_hwswitch trident_hwswitch = {
-	NULL, /* detect not needed */
-	trident_encode_fix,
-	trident_decode_var,
-	trident_encode_var,
-	trident_get_par,
-	trident_set_par,
-	trident_getcolreg,
-	trident_pan_display,
-	trident_blank,
-	trident_set_disp
-};
+static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_device_id * id)
+{
+	int err;
+	unsigned char revision;
 
-/* List of boards that we are trying to support */
-static struct almost_supported_board {
-	int pci_id;
-	int family;
-	struct accel_switch * acc;
-	char* board_name;
-	int accel;
-} asb[] __initdata = {
-	{ BLADE3D,		BLADE,	&accel_blade, "Blade3D",	ACCEL	},
-	{ CYBERBLADEi7,	BLADE,	&accel_blade, "CyberBladei7",	ACCEL	},
-	{ CYBERBLADEi7D,	BLADE,	&accel_blade, "CyberBladei7D",	ACCEL	},
-	{ CYBERBLADEi1,	BLADE,	&accel_blade, "CyberBladei1",	ACCEL	},
-	{ CYBERBLADEi1D,	BLADE,	&accel_blade, "CyberBladei1D",	ACCEL	},
-	{ CYBERBLADEAi1,	BLADE,	&accel_blade, "CyberBladeAi1",	ACCEL	},
-	{ CYBERBLADEAi1D,	BLADE,	&accel_blade, "CyberBladeAi1D",	ACCEL	},
-	{ CYBERBLADEE4,	BLADE,	&accel_blade, "CyberBladeE4",	ACCEL	},
-
-	{ IMAGE975,	IMAGE,	&accel_image,	"IMAGE975",	NOACCEL	},
-	{ IMAGE985,	IMAGE,	&accel_image,	"IMAGE985",	NOACCEL	},
-	{ CYBER9320,	IMAGE,	&accel_image,	"Cyber9320",	NOACCEL	},
-	{ CYBER9388,	IMAGE,	&accel_image,	"Cyber9388",	NOACCEL	},
-	{ CYBER9520,	IMAGE,	&accel_image,	"Cyber9520",	NOACCEL	},
-	{ CYBER9525DVD,	IMAGE,	&accel_image,	"Cyber9525DVD",	NOACCEL	},
-	{ CYBER9397,	IMAGE,	&accel_image,	"Cyber9397",	NOACCEL	},
-	{ CYBER9397DVD,	IMAGE,	&accel_image,	"Cyber9397DVD",	NOACCEL	},
-
-	{ CYBERBLADEXPAi1,	XP,	&accel_blade,	"CyberBladeXPAi1",	NOACCEL },
-	{ CYBERBLADEXPm8,	XP,	&accel_blade,	"CyberBladeXPm8",	NOACCEL },
-	{ CYBERBLADEXPm16,	XP,	&accel_blade,	"CyberBladeXPm16",	NOACCEL },
-};
+	err = pci_enable_device(dev);
+	if (err)
+		return err;
+
+	chip_id = id->device;
+
+	/* If PCI id is 0x9660 then further detect chip type */
+	
+	if (chip_id == TGUI9660) {
+		outb(RevisionID,0x3C4);
+		revision = inb(0x3C5);	
+	
+		switch (revision) {
+			case 0x22:
+			case 0x23: chip_id = CYBER9397;break;
+			case 0x2A: chip_id = CYBER9397DVD;break;
+			case 0x30:
+			case 0x33:
+			case 0x34:
+			case 0x35:
+			case 0x38:
+			case 0x3A:
+			case 0xB3: chip_id = CYBER9385;break;
+			case 0x40 ... 0x43: chip_id = CYBER9382;break;
+			case 0x4A: chip_id = CYBER9388;break;
+			default:break;	
+		}
+	}
 
-static __init int trident_find_board(void)
-{
-	int i;
-	struct pci_dev * board;
+	chip3D = is3Dchip(chip_id);
+	chipcyber = iscyber(chip_id);
 
-	for (i = 0;i < ARRAY_SIZE(asb);i++) {
-      		if ((board = pci_find_device(PCI_VENDOR_ID_TRIDENT,
-				   asb[i].pci_id,
-				   NULL))) {
-	 		family = asb[i].family;
-	 		acc = asb[i].acc;
-	 		pci_id = asb[i].pci_id;
-	 		defaultaccel = asb[i].accel;
-
-			fb_info.io = pci_resource_start(board,1);
-			fb_info.fbmem = pci_resource_start(board,0);
-	 		output("%s board found\n", asb[i].board_name);
-	 		return 1;
-      		}
-   	}
-	output("No Trident board found\n");
-	return 0;
-}
+	if (is_xp(chip_id)) {
+		acc = &accel_xp;
+	} else 
+	if (is_blade(chip_id)) {
+		acc = &accel_blade;
+	} else {
+		acc = &accel_image;
+	}
 
-int __init tridentfb_init(void)
-{
+	/* acceleration is on by default for 3D chips */
+	defaultaccel = chip3D && !noaccel;
 
-	output("Trident framebuffer  %s initializing\n", VERSION);
+	fb_info.par = &default_par;
 
-	if (!trident_find_board())
-     		return -1;
+	/* setup MMIO region */
+	tridentfb_fix.mmio_start = pci_resource_start(dev,1);
+	tridentfb_fix.mmio_len = chip3D ? 0x20000:0x10000;
 
-	if (!request_mem_region(fb_info.io, TRIDENT_IOSIZE, "tridentfb")) {
+	if (!request_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len, "tridentfb")) {
 		debug("request_region failed!\n");
 		return -1;
-	};
+	}
 
-	fb_info.io_virt = (unsigned int)ioremap_nocache(fb_info.io, TRIDENT_IOSIZE);
+	default_par.io_virt = (unsigned int)ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
 
-	if (!fb_info.io_virt) {
-		release_region(fb_info.io, TRIDENT_IOSIZE);
+	if (!default_par.io_virt) {
+		release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
 		debug("ioremap failed\n");
 		return -1;
 	}
 
-	fb_info.memsize = get_memsize();
-	if (!request_mem_region(fb_info.fbmem, fb_info.memsize, "tridentfb")) {
+	enable_mmio();
+	
+	/* setup framebuffer memory */
+	tridentfb_fix.smem_start = pci_resource_start(dev,0);
+	tridentfb_fix.smem_len = get_memsize();
+	
+	if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {
 		debug("request_mem_region failed!\n");
 		return -1;
 	}
 
-	fb_info.fbmem_virt = (unsigned int)ioremap_nocache(fb_info.fbmem, fb_info.memsize);
+	fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,
+		       			tridentfb_fix.smem_len);
 
-	if (!fb_info.fbmem_virt) {
-		release_mem_region(fb_info.fbmem, fb_info.memsize);
+	if (!fb_info.screen_base) {
+		release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
 		debug("ioremap failed\n");
 		return -1;
 	}
 
-	debug("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n",
-		fb_info.fbmem, fb_info.io, fb_info.fbmem_virt, fb_info.io_virt);
-
-	fb_info.gen.parsize = sizeof (struct tridentfb_par);
-	fb_info.gen.fbhw = &trident_hwswitch;
-
-	strcpy(fb_info.gen.info.modename, tridentfb_name);
+	output("%s board found\n", dev->dev.name);
+#if 0	
+	output("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n",
+		tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt);
+#endif
 	displaytype = get_displaytype();
+
 	if(flatpanel)
-		fb_info.nativex = get_nativex();
-	fb_info.gen.info.changevar = NULL;
-	fb_info.gen.info.node = NODEV;
-	fb_info.gen.info.fbops = &tridentfb_ops;
-	fb_info.gen.info.disp = &disp;
-
-	fb_info.gen.info.switch_con = &fbgen_switch;
-	fb_info.gen.info.updatevar = &fbgen_update_var;
-
-	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
-	fb_info.gen.info.fontname[0] = '\0';
-	fb_info.gen.info.pseudo_palette = pseudo_pal;
-
-	/* This should give a reasonable default video mode */
-	fb_find_mode(&default_var,&fb_info.gen.info,mode,NULL,0,NULL,bpp);
-	/*
-	 * Unless user explicitly requires accel/noaccel use
-	 * per chip defaults.Accel has priority over noaccel.
-	 */
-	if (accel)
-		defaultaccel = ACCEL;
-	else if (noaccel)
-		defaultaccel = NOACCEL;
+		nativex = get_nativex();
+
+	fb_info.fix = tridentfb_fix;
+	fb_info.node = NODEV;
+	fb_info.fbops = &tridentfb_ops;
 
-	if (defaultaccel == ACCEL)
+
+	fb_info.flags = FBINFO_FLAG_DEFAULT;
+	fb_info.pseudo_palette = pseudo_pal;
+
+	if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp))
+		return -EINVAL;
+	fb_alloc_cmap(&fb_info.cmap,256,0);
+	if (defaultaccel && acc)
 		default_var.accel_flags |= FB_ACCELF_TEXT;
 	else
 		default_var.accel_flags &= ~FB_ACCELF_TEXT;
-
-	trident_decode_var(&default_var, &fb_info.currentmode, &fb_info.gen);
-	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
 	default_var.activate |= FB_ACTIVATE_NOW;
-	fbgen_set_disp(-1, &fb_info.gen);
-
-	if (register_framebuffer(&fb_info.gen.info) < 0) {
-		printk("Could not register Trident framebuffer\n");
+	fb_info.var = default_var;
+	if (register_framebuffer(&fb_info) < 0) {
+		output("Could not register Trident framebuffer\n");
 		return -EINVAL;
 	}
-
 	output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
-	   minor(fb_info.gen.info.node), fb_info.gen.info.modename,default_var.xres,
+	   minor(fb_info.node), fb_info.fix.id,default_var.xres,
 	   default_var.yres,default_var.bits_per_pixel);
 	return 0;
 }
 
+static void __devexit trident_pci_remove(struct pci_dev * dev)
+{
+	struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par;
+	unregister_framebuffer(&fb_info);
+	iounmap((void *)par->io_virt);
+	iounmap((void*)fb_info.screen_base);
+	release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
+	release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
+}
+
+/* List of boards that we are trying to support */
+static struct pci_device_id trident_devices[] __devinitdata = {
+	{PCI_VENDOR_ID_TRIDENT,	BLADE3D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi7, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi7D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEAi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEE4, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	TGUI9660, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	IMAGE975, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	IMAGE985, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9320, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9388, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9520, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9525DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9397, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBER9397DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEXPAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEXPm8, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEXPm16, PCI_ANY_ID,PCI_ANY_ID,0,0,0},
+	{0,}
+};	
+	
+MODULE_DEVICE_TABLE(pci,trident_devices); 
+
+static struct pci_driver tridentfb_pci_driver = {
+	name:"tridentfb",
+	id_table:trident_devices,
+	probe:trident_pci_probe,
+	remove:__devexit_p(trident_pci_remove)
+};
+
+int __init tridentfb_init(void)
+{
+	output("Trident framebuffer %s initializing\n", VERSION);
+	return pci_module_init(&tridentfb_pci_driver);
+}
+
 void __exit tridentfb_exit(void)
 {
-	unregister_framebuffer(&fb_info.gen.info);
-	iounmap((void *)fb_info.io_virt);
-	iounmap((void *)fb_info.fbmem_virt);
+	pci_unregister_driver(&tridentfb_pci_driver);
 }
 
+
 /*
  * Parse user specified options (`video=trident:')
  * example:
@@ -1257,12 +1232,10 @@
 	char * opt;
 	if (!options || !*options)
 		return 0;
-	while((opt=strsep(&options,",")) != NULL) {
+	while((opt = strsep(&options,",")) != NULL ) {
 		if (!*opt) continue;
 		if (!strncmp(opt,"noaccel",7))
 			noaccel = 1;
-		else if (!strncmp(opt,"accel",5))
-			accel = 1;
 		else if (!strncmp(opt,"fp",2))
 			displaytype = DISPLAY_FP;
 		else if (!strncmp(opt,"crt",3))
@@ -1286,13 +1259,18 @@
 }
 
 static struct fb_ops tridentfb_ops = {
-	.fb_get_fix =	fbgen_get_fix,
-	.fb_get_var =	fbgen_get_var,
-	.fb_set_var =	fbgen_set_var,
-	.fb_get_cmap =	fbgen_get_cmap,
-	.fb_set_cmap =	fbgen_set_cmap,
-	.fb_setcolreg =	tridentfb_setcolreg,
-	.fb_pan_display =fbgen_pan_display,
+	.owner	= THIS_MODULE,
+	.fb_setcolreg = tridentfb_setcolreg,
+	.fb_pan_display = tridentfb_pan_display,
+	.fb_blank = tridentfb_blank,
+	.fb_check_var = tridentfb_check_var,
+	.fb_set_par = tridentfb_set_par,
+//	.fb_fillrect = tridentfb_fillrect,
+//	.fb_copyarea= tridentfb_copyarea,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea= cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_cursor = soft_cursor,
 };
 
 #ifdef MODULE
@@ -1300,6 +1278,7 @@
 #endif
 module_exit(tridentfb_exit);
 
-MODULE_AUTHOR("Jani Monoses <jani@astechnix.ro>");
+MODULE_AUTHOR("Jani Monoses <jani@iv.ro>");
 MODULE_DESCRIPTION("Framebuffer driver for Trident cards");
 MODULE_LICENSE("GPL");
+
diff -Nru a/drivers/video/tridentfb.h b/drivers/video/tridentfb.h
--- a/drivers/video/tridentfb.h	Thu Jan 16 18:23:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,169 +0,0 @@
-
-#ifndef TRIDENTFB_DEBUG
-#define TRIDENTFB_DEBUG 0
-#endif
-
-#if TRIDENTFB_DEBUG
-#define debug(f,a...)	printk("%s:" f,  __FUNCTION__ , ## a)
-#else
-#define debug(f,a...)
-#endif
-
-#define output(f, a...) printk("tridentfb: " f, ## a)
-
-#define Kb	(1024)
-#define Mb	(Kb*Kb)
-
-/* PCI IDS of supported cards temporarily here */
-
-#define CYBER9320	0x9320
-#define CYBER9388	0x9388
-#define CYBER9397	0x9397
-#define CYBER9397DVD	0x939A
-#define CYBER9520	0x9520
-#define CYBER9525DVD	0x9525
-#define IMAGE975	0x9750
-#define IMAGE985	0x9850
-#define BLADE3D		0x9880
-#define CYBERBLADEE4	0x9540
-#define CYBERBLADEi7	0x8400
-#define CYBERBLADEi7D	0x8420
-#define CYBERBLADEi1	0x8500
-#define CYBERBLADEi1D	0x8520
-#define CYBERBLADEAi1	0x8600
-#define CYBERBLADEAi1D	0x8620
-#define CYBERBLADEXPAi1 0x8820
-#define CYBERBLADEXPm8  0x9910
-#define CYBERBLADEXPm16 0x9930
-
-/* acceleration families */
-#define IMAGE	0
-#define BLADE	1
-#define XP	2
-
-#define is_image()	(family == IMAGE)
-#define is_blade()	(family == BLADE)
-#define is_xp()		(family == XP)
-
-/* these defines are for 'lcd' variable */
-#define LCD_STRETCH	0
-#define LCD_CENTER	1
-#define LCD_BIOS	2
-
-/* display types */
-#define DISPLAY_CRT	0
-#define DISPLAY_FP	1
-
-#define flatpanel (displaytype == DISPLAY_FP)
-/* these are for defaultaccel variable */
-#define ACCEL	1
-#define NOACCEL	0
-
-#define TRIDENT_IOSIZE	0x20000
-#define NTSC 14.31818
-#define PAL  17.73448
-
-/* General Registers */
-#define SPR	0x1F		/* Software Programming Register (videoram) */
-
-/* 3C4 */
-#define RevisionID 0x09
-#define OldOrNew 0x0B
-#define ConfPort1 0x0C
-#define ConfPort2 0x0C
-#define NewMode2 0x0D
-#define NewMode1 0x0E
-#define Protection 0x11
-#define MCLKLow 0x16
-#define MCLKHigh 0x17
-#define ClockLow 0x18
-#define ClockHigh 0x19
-#define SSetup 0x20
-#define SKey 0x37
-#define SPKey 0x57
-
-/* 0x3x4 */
-#define CRTHTotal	0x00
-#define CRTHDispEnd	0x01
-#define CRTHBlankStart	0x02
-#define CRTHBlankEnd	0x03
-#define CRTHSyncStart	0x04
-#define CRTHSyncEnd	0x05
-
-#define CRTVTotal	0x06
-#define CRTVDispEnd	0x12
-#define CRTVBlankStart	0x15
-#define CRTVBlankEnd	0x16
-#define CRTVSyncStart	0x10
-#define CRTVSyncEnd	0x11
-
-#define CRTOverflow	0x07
-#define CRTPRowScan	0x08
-#define CRTMaxScanLine	0x09
-#define CRTModeControl	0x17
-#define CRTLineCompare	0x18
-
-/* 3x4 */
-#define StartAddrHigh 0x0C
-#define StartAddrLow 0x0D
-#define Offset 0x13
-#define Underline 0x14
-#define CRTCMode 0x17
-#define CRTCModuleTest 0x1E
-#define FIFOControl 0x20
-#define LinearAddReg 0x21
-#define DRAMTiming 0x23
-#define New32 0x23
-#define RAMDACTiming 0x25
-#define CRTHiOrd 0x27
-#define AddColReg 0x29
-#define InterfaceSel 0x2A
-#define HorizOverflow 0x2B
-#define GETest 0x2D
-#define Performance 0x2F
-#define GraphEngReg 0x36
-#define I2C 0x37
-#define PixelBusReg 0x38
-#define PCIReg 0x39
-#define DRAMControl 0x3A
-#define MiscContReg 0x3C
-#define CursorXLow 0x40
-#define CursorXHigh 0x41
-#define CursorYLow 0x42
-#define CursorYHigh 0x43
-#define CursorLocLow 0x44
-#define CursorLocHigh 0x45
-#define CursorXOffset 0x46
-#define CursorYOffset 0x47
-#define CursorFG1 0x48
-#define CursorFG2 0x49
-#define CursorFG3 0x4A
-#define CursorFG4 0x4B
-#define CursorBG1 0x4C
-#define CursorBG2 0x4D
-#define CursorBG3 0x4E
-#define CursorBG4 0x4F
-#define CursorControl 0x50
-#define PCIRetry 0x55
-#define PreEndControl 0x56
-#define PreEndFetch 0x57
-#define PCIMaster 0x60
-#define Enhancement0 0x62
-#define NewEDO 0x64
-#define TVinterface 0xC0
-#define TVMode 0xC1
-#define ClockControl 0xCF
-
-
-/* 3CE */
-#define MiscExtFunc 0x0F
-#define PowerStatus 0x23
-#define MiscIntContReg 0x2F
-#define CyberControl 0x30
-#define CyberEnhance 0x31
-#define FPConfig     0x33
-#define VertStretch  0x52
-#define HorStretch   0x53
-#define BiosMode     0x5c
-#define BiosReg      0x5d
-
diff -Nru a/fs/block_dev.c b/fs/block_dev.c
--- a/fs/block_dev.c	Thu Jan 16 18:23:07 2003
+++ b/fs/block_dev.c	Thu Jan 16 18:23:07 2003
@@ -799,24 +799,20 @@
 }
 
 /**
- * open_bdev_excl  -  open a block device by name and set it up for use
+ * lookup_bdev  - lookup a struct block_device by name
  *
  * @path:	special file representing the block device
- * @flags:	%MS_RDONLY for opening read-only
- * @kind:	usage (same as the 4th paramter to blkdev_get)
- * @holder:	owner for exclusion
  *
- * Open the blockdevice described by the special file at @path, claim it
- * for the @holder and properly set it up for @kind usage.
+ * Get a reference to the blockdevice at @path in the current
+ * namespace if possible and return it.  Return ERR_PTR(error)
+ * otherwise.
  */
-struct block_device *open_bdev_excl(const char *path, int flags,
-				    int kind, void *holder)
+struct block_device *lookup_bdev(const char *path)
 {
-	struct inode *inode;
 	struct block_device *bdev;
+	struct inode *inode;
 	struct nameidata nd;
-	mode_t mode = FMODE_READ;
-	int error = 0;
+	int error;
 
 	if (!path || !*path)
 		return ERR_PTR(-EINVAL);
@@ -828,17 +824,44 @@
 	inode = nd.dentry->d_inode;
 	error = -ENOTBLK;
 	if (!S_ISBLK(inode->i_mode))
-		goto path_release;
+		goto fail;
 	error = -EACCES;
 	if (nd.mnt->mnt_flags & MNT_NODEV)
-		goto path_release;
+		goto fail;
 	error = bd_acquire(inode);
 	if (error)
-		goto path_release;
+		goto fail;
 	bdev = inode->i_bdev;
 
-	/* Done with lookups */
+out:
 	path_release(&nd);
+	return bdev;
+fail:
+	bdev = ERR_PTR(error);
+	goto out;
+}
+
+/**
+ * open_bdev_excl  -  open a block device by name and set it up for use
+ *
+ * @path:	special file representing the block device
+ * @flags:	%MS_RDONLY for opening read-only
+ * @kind:	usage (same as the 4th paramter to blkdev_get)
+ * @holder:	owner for exclusion
+ *
+ * Open the blockdevice described by the special file at @path, claim it
+ * for the @holder and properly set it up for @kind usage.
+ */
+struct block_device *open_bdev_excl(const char *path, int flags,
+				    int kind, void *holder)
+{
+	struct block_device *bdev;
+	mode_t mode = FMODE_READ;
+	int error = 0;
+
+	bdev = lookup_bdev(path);
+	if (IS_ERR(bdev))
+		return bdev;
 
 	if (!(flags & MS_RDONLY))
 		mode |= FMODE_WRITE;
@@ -856,10 +879,6 @@
 	
 blkdev_put:
 	blkdev_put(bdev, BDEV_FS);
-	return ERR_PTR(error);
-
-path_release:
-	path_release(&nd);
 	return ERR_PTR(error);
 }
 
diff -Nru a/fs/devfs/Makefile b/fs/devfs/Makefile
--- a/fs/devfs/Makefile	Thu Jan 16 18:23:05 2003
+++ b/fs/devfs/Makefile	Thu Jan 16 18:23:05 2003
@@ -8,27 +8,3 @@
 
 devfs-objs := base.o util.o
 
-# Special case to support building documentation
-ifndef TOPDIR
-TOPDIR = ../..
-endif
-
-# Rule to build documentation
-doc:	base.c util.c
-	@echo '$$PACKAGE devfs' > devfs.doc
-	@echo '$$NAME Linux Kernel' >> devfs.doc
-	@echo '$$SUMMARY devfs (Device FileSystem) functions' >> devfs.doc
-	@echo '$$SYNOPSIS "#include <linux/devfs_fs.h>"' >> devfs.doc
-	@echo '$$END' >> devfs.doc
-	c2doc base.c util.c >> devfs.doc
-	karma_doc2man -section 9 devfs.doc .
-	rm devfs.doc
-	gzip --best *.9
-	mv *.9.gz /usr/man/man9
-
-
-# Rule for test compiling
-test:
-	gcc -o /tmp/base.o -D__KERNEL__ -I../../include -Wall \
-	-Wstrict-prototypes -O2 -fomit-frame-pointer -pipe \
-	-fno-strength-reduce   -DEXPORT_SYMTAB -c base.c
diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c
--- a/fs/devfs/base.c	Thu Jan 16 18:23:05 2003
+++ b/fs/devfs/base.c	Thu Jan 16 18:23:05 2003
@@ -685,6 +685,8 @@
 #include <asm/bitops.h>
 #include <asm/atomic.h>
 
+#include "internal.h"
+
 #define DEVFS_VERSION            "1.22 (20021013)"
 
 #define DEVFS_NAME "devfs"
@@ -935,9 +937,9 @@
 	     de->parent ? de->parent->name : "no parent");
     if ( S_ISLNK (de->mode) ) kfree (de->u.symlink.linkname);
     if ( S_ISCHR (de->mode) && de->u.cdev.autogen )
-	devfs_dealloc_devnum (DEVFS_SPECIAL_CHR, de->u.cdev.dev);
+	devfs_dealloc_devnum (de->mode, de->u.cdev.dev);
     if ( S_ISBLK (de->mode) && de->u.bdev.autogen )
-	devfs_dealloc_devnum(DEVFS_SPECIAL_BLK, de->u.bdev.dev);
+	devfs_dealloc_devnum (de->mode, de->u.bdev.dev);
     WRITE_ENTRY_MAGIC (de, 0);
 #ifdef CONFIG_DEVFS_DEBUG
     spin_lock (&stat_lock);
@@ -1102,13 +1104,13 @@
     /*  And create the entry for ".devfsd"  */
     if ( ( new = _devfs_alloc_entry (".devfsd", 0, S_IFCHR |S_IRUSR |S_IWUSR) )
 	 == NULL ) return NULL;
-    new->u.cdev.dev = devfs_alloc_devnum (DEVFS_SPECIAL_CHR);
+    new->u.cdev.dev = devfs_alloc_devnum (S_IFCHR |S_IRUSR |S_IWUSR);
     new->u.cdev.ops = &devfsd_fops;
     _devfs_append_entry (root_entry, new, FALSE, NULL);
 #ifdef CONFIG_DEVFS_DEBUG
     if ( ( new = _devfs_alloc_entry (".stat", 0, S_IFCHR | S_IRUGO | S_IWUGO) )
 	 == NULL ) return NULL;
-    new->u.cdev.dev = devfs_alloc_devnum (DEVFS_SPECIAL_CHR);
+    new->u.cdev.dev = devfs_alloc_devnum (S_IFCHR | S_IRUGO | S_IWUGO);
     new->u.cdev.ops = &stat_fops;
     _devfs_append_entry (root_entry, new, FALSE, NULL);
 #endif
@@ -1469,7 +1471,6 @@
 			       unsigned int major, unsigned int minor,
 			       umode_t mode, void *ops, void *info)
 {
-    char devtype = S_ISCHR (mode) ? DEVFS_SPECIAL_CHR : DEVFS_SPECIAL_BLK;
     int err;
     dev_t devnum = 0, dev = MKDEV(major, minor);
     struct devfs_entry *de;
@@ -1497,7 +1498,7 @@
     if ( ( S_ISCHR (mode) || S_ISBLK (mode) ) &&
 	 (flags & DEVFS_FL_AUTO_DEVNUM) )
     {
-	devnum = devfs_alloc_devnum (devtype);
+	devnum = devfs_alloc_devnum (mode);
 	if (!devnum) {
 	    PRINTK ("(%s): exhausted %s device numbers\n",
 		    name, S_ISCHR (mode) ? "char" : "block");
@@ -1508,7 +1509,7 @@
     if ( ( de = _devfs_prepare_leaf (&dir, name, mode) ) == NULL )
     {
 	PRINTK ("(%s): could not prepare leaf\n", name);
-	if (devnum) devfs_dealloc_devnum (devtype, devnum);
+	if (devnum) devfs_dealloc_devnum (mode, devnum);
 	return NULL;
     }
     if (S_ISCHR (mode)) {
@@ -1544,7 +1545,7 @@
     {
 	PRINTK ("(%s): could not append to parent, err: %d\n", name, err);
 	devfs_put (dir);
-	if (devnum) devfs_dealloc_devnum (devtype, devnum);
+	if (devnum) devfs_dealloc_devnum (mode, devnum);
 	return NULL;
     }
     DPRINTK (DEBUG_REGISTER, "(%s): de: %p dir: %p \"%s\"  pp: %p\n",
@@ -1953,7 +1954,6 @@
 EXPORT_SYMBOL(devfs_mk_dir);
 EXPORT_SYMBOL(devfs_remove);
 EXPORT_SYMBOL(devfs_generate_path);
-EXPORT_SYMBOL(devfs_only);
 
 
 /**
diff -Nru a/fs/devfs/internal.h b/fs/devfs/internal.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/devfs/internal.h	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,3 @@
+
+extern dev_t devfs_alloc_devnum(umode_t mode);
+extern void devfs_dealloc_devnum(umode_t mode, dev_t devnum);
diff -Nru a/fs/devfs/util.c b/fs/devfs/util.c
--- a/fs/devfs/util.c	Thu Jan 16 18:23:06 2003
+++ b/fs/devfs/util.c	Thu Jan 16 18:23:06 2003
@@ -60,14 +60,18 @@
                Copied and used macro for error messages from fs/devfs/base.c 
     20021013   Richard Gooch <rgooch@atnf.csiro.au>
                Documentation fix.
+    20030101   Adam J. Richter <adam@yggdrasil.com>
+               Eliminate DEVFS_SPECIAL_{CHR,BLK}.  Use mode_t instead.
+    20030106   Christoph Hellwig <hch@infradead.org>
+               Rewrite devfs_{,de}alloc_devnum to look like C code.
 */
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-
 #include <asm/bitops.h>
+#include "internal.h"
 
 #define PRINTK(format, args...) \
    {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);}
@@ -145,49 +149,11 @@
 
 /**
  *	devfs_alloc_major - Allocate a major number.
- *	@type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)
-
+ *	@mode: The file mode (must be block device or character device).
  *	Returns the allocated major, else -1 if none are available.
  *	This routine is thread safe and does not block.
  */
 
-int devfs_alloc_major (char type)
-{
-    int major;
-    struct major_list *list;
-
-    list = (type == DEVFS_SPECIAL_CHR) ? &char_major_list : &block_major_list;
-    spin_lock (&list->lock);
-    major = find_first_zero_bit (list->bits, 256);
-    if (major < 256) __set_bit (major, list->bits);
-    else major = -1;
-    spin_unlock (&list->lock);
-    return major;
-}   /*  End Function devfs_alloc_major  */
-EXPORT_SYMBOL(devfs_alloc_major);
-
-
-/**
- *	devfs_dealloc_major - Deallocate a major number.
- *	@type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)
- *	@major: The major number.
- *	This routine is thread safe and does not block.
- */
-
-void devfs_dealloc_major (char type, int major)
-{
-    int was_set;
-    struct major_list *list;
-
-    if (major < 0) return;
-    list = (type == DEVFS_SPECIAL_CHR) ? &char_major_list : &block_major_list;
-    spin_lock (&list->lock);
-    was_set = __test_and_clear_bit (major, list->bits);
-    spin_unlock (&list->lock);
-    if (!was_set) PRINTK ("(): major %d was already free\n", major);
-}   /*  End Function devfs_dealloc_major  */
-EXPORT_SYMBOL(devfs_dealloc_major);
-
 
 struct minor_list
 {
@@ -196,130 +162,110 @@
     struct minor_list *next;
 };
 
-struct device_list
-{
-    struct minor_list *first, *last;
-    int none_free;
-};
-
-static DECLARE_MUTEX (block_semaphore);
-static struct device_list block_list;
+static struct device_list {
+	struct minor_list	*first;
+	struct minor_list	*last;
+	int			none_free;
+} block_list, char_list;
 
-static DECLARE_MUTEX (char_semaphore);
-static struct device_list char_list;
+static DECLARE_MUTEX(device_list_mutex);
 
 
 /**
  *	devfs_alloc_devnum - Allocate a device number.
- *	@type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
+ *	@mode: The file mode (must be block device or character device).
  *
  *	Returns the allocated device number, else NODEV if none are available.
  *	This routine is thread safe and may block.
  */
 
-dev_t devfs_alloc_devnum (char type)
+dev_t devfs_alloc_devnum(umode_t mode)
 {
-    int minor;
-    struct semaphore *semaphore;
-    struct device_list *list;
-    struct minor_list *entry;
-
-    if (type == DEVFS_SPECIAL_CHR)
-    {
-	semaphore = &char_semaphore;
-	list = &char_list;
-    }
-    else
-    {
-	semaphore = &block_semaphore;
-	list = &block_list;
-    }
-    if (list->none_free) return 0;  /*  Fast test  */
-    down (semaphore);
-    if (list->none_free)
-    {
-	up (semaphore);
-	return 0;
-    }
-    for (entry = list->first; entry != NULL; entry = entry->next)
-    {
-	minor = find_first_zero_bit (entry->bits, 256);
-	if (minor >= 256) continue;
-	__set_bit (minor, entry->bits);
-	up (semaphore);
+	struct device_list *list;
+	struct major_list *major_list;
+	struct minor_list *entry;
+	int minor;
+
+	if (S_ISCHR(mode)) {
+		major_list = &char_major_list;
+		list = &char_list;
+	} else {
+		major_list = &block_major_list;
+		list = &block_list;
+	}
+
+	down(&device_list_mutex);
+	if (list->none_free)
+		goto out_unlock;
+
+	for (entry = list->first; entry; entry = entry->next) {
+		minor = find_first_zero_bit (entry->bits, 256);
+		if (minor >= 256)
+			continue;
+		goto out_done;
+	}
+	
+	/*  Need to allocate a new major  */
+	entry = kmalloc (sizeof *entry, GFP_KERNEL);
+	if (!entry)
+		goto out_full;
+	memset(entry, 0, sizeof *entry);
+
+	spin_lock(&major_list->lock);
+	entry->major = find_first_zero_bit(major_list->bits, 256);
+	if (entry->major >= 256) {
+		spin_unlock(&major_list->lock);
+		kfree(entry);
+		goto out_full;
+	}
+	__set_bit(entry->major, major_list->bits);
+	spin_unlock(&major_list->lock);
+
+	if (!list->first)
+		list->first = entry;
+	else
+		list->last->next = entry;
+	list->last = entry;
+
+	minor = 0;
+ out_done:
+	__set_bit(minor, entry->bits);
+	up(&device_list_mutex);
 	return MKDEV(entry->major, minor);
-    }
-    /*  Need to allocate a new major  */
-    if ( ( entry = kmalloc (sizeof *entry, GFP_KERNEL) ) == NULL )
-    {
-	list->none_free = 1;
-	up (semaphore);
-	return 0;
-    }
-    memset (entry, 0, sizeof *entry);
-    if ( ( entry->major = devfs_alloc_major (type) ) < 0 )
-    {
+ out_full:
 	list->none_free = 1;
-	up (semaphore);
-	kfree (entry);
+ out_unlock:
+	up(&device_list_mutex);
 	return 0;
-    }
-    __set_bit (0, entry->bits);
-    if (list->first == NULL) list->first = entry;
-    else list->last->next = entry;
-    list->last = entry;
-    up (semaphore);
-    return MKDEV(entry->major, 0);
-}   /*  End Function devfs_alloc_devnum  */
-EXPORT_SYMBOL(devfs_alloc_devnum);
+}
 
 
 /**
  *	devfs_dealloc_devnum - Dellocate a device number.
- *	@type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
+ *	@mode: The file mode (must be block device or character device).
  *	@devnum: The device number.
  *
  *	This routine is thread safe and may block.
  */
 
-void devfs_dealloc_devnum (char type, dev_t devnum)
+void devfs_dealloc_devnum(umode_t mode, dev_t devnum)
 {
-    int major, minor;
-    struct semaphore *semaphore;
-    struct device_list *list;
-    struct minor_list *entry;
-
-    if (!devnum) return;
-    if (type == DEVFS_SPECIAL_CHR)
-    {
-	semaphore = &char_semaphore;
-	list = &char_list;
-    }
-    else
-    {
-	semaphore = &block_semaphore;
-	list = &block_list;
-    }
-    major = MAJOR (devnum);
-    minor = MINOR (devnum);
-    down (semaphore);
-    for (entry = list->first; entry != NULL; entry = entry->next)
-    {
-	int was_set;
-
-	if (entry->major != major) continue;
-	was_set = __test_and_clear_bit (minor, entry->bits);
-	if (was_set) list->none_free = 0;
-	up (semaphore);
-	if (!was_set)
-	    PRINTK ( "(): device %s was already free\n", kdevname (to_kdev_t(devnum)) );
-	return;
-    }
-    up (semaphore);
-    PRINTK ( "(): major for %s not previously allocated\n",
-	     kdevname (to_kdev_t(devnum)) );
-}   /*  End Function devfs_dealloc_devnum  */
-EXPORT_SYMBOL(devfs_dealloc_devnum);
+	struct device_list *list = S_ISCHR(mode) ? &char_list : &block_list;
+	struct minor_list *entry;
+
+	if (!devnum)
+		return;
+
+	down(&device_list_mutex);
+	for (entry = list->first; entry; entry = entry->next) {
+		if (entry->major == MAJOR(devnum)) {
+			if (__test_and_clear_bit(MINOR(devnum), entry->bits))
+				list->none_free = 0;
+			break;
+		}
+	}
+	up(&device_list_mutex);
+}
 
 
 /**
diff -Nru a/fs/devpts/inode.c b/fs/devpts/inode.c
--- a/fs/devpts/inode.c	Thu Jan 16 18:23:05 2003
+++ b/fs/devpts/inode.c	Thu Jan 16 18:23:05 2003
@@ -180,7 +180,7 @@
 static void __exit exit_devpts_fs(void)
 {
 	unregister_filesystem(&devpts_fs_type);
-	kern_umount(devpts_mnt);
+	mntput(devpts_mnt);
 }
 
 module_init(init_devpts_fs)
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	Thu Jan 16 18:23:05 2003
+++ b/fs/exec.c	Thu Jan 16 18:23:05 2003
@@ -1031,6 +1031,8 @@
 	int retval;
 	int i;
 
+	sched_balance_exec();
+
 	file = open_exec(filename);
 
 	retval = PTR_ERR(file);
diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
--- a/fs/ext3/ialloc.c	Thu Jan 16 18:23:06 2003
+++ b/fs/ext3/ialloc.c	Thu Jan 16 18:23:06 2003
@@ -417,7 +417,7 @@
 	struct buffer_head *bitmap_bh = NULL;
 	struct buffer_head *bh2;
 	int group;
-	ino_t ino;
+	unsigned long ino;
 	struct inode * inode;
 	struct ext3_group_desc * gdp;
 	struct ext3_super_block * es;
@@ -463,7 +463,7 @@
 		BUFFER_TRACE(bitmap_bh, "get_write_access");
 		err = ext3_journal_get_write_access(handle, bitmap_bh);
 		if (err) goto fail;
-		
+
 		if (ext3_set_bit(ino, bitmap_bh->b_data)) {
 			ext3_error (sb, "ext3_new_inode",
 				      "bit already set for inode %lu", ino);
@@ -619,19 +619,18 @@
 }
 
 /* Verify that we are loading a valid orphan from disk */
-struct inode *ext3_orphan_get (struct super_block * sb, ino_t ino)
+struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
 {
-	ino_t max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
+	unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
 	unsigned long block_group;
 	int bit;
 	struct buffer_head *bitmap_bh = NULL;
 	struct inode *inode = NULL;
-	
+
 	/* Error cases - e2fsck has already cleaned up for us */
 	if (ino > max_ino) {
 		ext3_warning(sb, __FUNCTION__,
-			     "bad orphan ino %lu!  e2fsck was run?\n",
-			     (unsigned long) ino);
+			     "bad orphan ino %lu!  e2fsck was run?\n", ino);
 		goto out;
 	}
 
@@ -640,8 +639,7 @@
 	bitmap_bh = read_inode_bitmap(sb, block_group);
 	if (!bitmap_bh) {
 		ext3_warning(sb, __FUNCTION__,
-			     "inode bitmap error for orphan %lu\n",
-			     (unsigned long) ino);
+			     "inode bitmap error for orphan %lu\n", ino);
 		goto out;
 	}
 
@@ -653,19 +651,17 @@
 			!(inode = iget(sb, ino)) || is_bad_inode(inode) ||
 			NEXT_ORPHAN(inode) > max_ino) {
 		ext3_warning(sb, __FUNCTION__,
-			     "bad orphan inode %lu!  e2fsck was run?\n", (unsigned long)ino);
+			     "bad orphan inode %lu!  e2fsck was run?\n", ino);
 		printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
-		       bit, 
-			(unsigned long long)bitmap_bh->b_blocknr, 
-			ext3_test_bit(bit, bitmap_bh->b_data));
+		       bit, (unsigned long long)bitmap_bh->b_blocknr,
+		       ext3_test_bit(bit, bitmap_bh->b_data));
 		printk(KERN_NOTICE "inode=%p\n", inode);
 		if (inode) {
 			printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
 			       is_bad_inode(inode));
-			printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%d\n",
+			printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n",
 			       NEXT_ORPHAN(inode));
-			printk(KERN_NOTICE "max_ino=%lu\n",
-			       (unsigned long) max_ino);
+			printk(KERN_NOTICE "max_ino=%lu\n", max_ino);
 		}
 		/* Avoid freeing blocks if we got a bad deleted inode */
 		if (inode && inode->i_nlink == 0)
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	Thu Jan 16 18:23:06 2003
+++ b/fs/ext3/inode.c	Thu Jan 16 18:23:06 2003
@@ -1098,20 +1098,14 @@
 	return ret;
 }
 
-static int journal_dirty_sync_data(handle_t *handle, struct buffer_head *bh)
-{
-	return ext3_journal_dirty_data(handle, bh, 0);
-}
-
-/*
- * For ext3_writepage().  We also brelse() the buffer to account for
- * the bget() which ext3_writepage() performs.
- */
-static int journal_dirty_async_data(handle_t *handle, struct buffer_head *bh)
+static int
+ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
 {
-	int ret = ext3_journal_dirty_data(handle, bh, 1);
-	__brelse(bh);
-	return ret;
+	int err = journal_dirty_data(handle, bh);
+	if (err)
+		ext3_journal_abort_handle(__FUNCTION__, __FUNCTION__,
+						bh, handle,err);
+	return err;
 }
 
 /* For commit_write() in data=journal mode */
@@ -1154,7 +1148,7 @@
 	} else {
 		if (ext3_should_order_data(inode)) {
 			ret = walk_page_buffers(handle, page_buffers(page),
-				from, to, NULL, journal_dirty_sync_data);
+				from, to, NULL, ext3_journal_dirty_data);
 		}
 		/* Be careful here if generic_commit_write becomes a
 		 * required invocation after block_prepare_write. */
@@ -1228,7 +1222,13 @@
 
 static int bget_one(handle_t *handle, struct buffer_head *bh)
 {
-	atomic_inc(&bh->b_count);
+	get_bh(bh);
+	return 0;
+}
+
+static int bput_one(handle_t *handle, struct buffer_head *bh)
+{
+	put_bh(bh);
 	return 0;
 }
 
@@ -1348,7 +1348,9 @@
 	/* And attach them to the current transaction */
 	if (order_data) {
 		err = walk_page_buffers(handle, page_bufs,
-			0, PAGE_CACHE_SIZE, NULL, journal_dirty_async_data);
+			0, PAGE_CACHE_SIZE, NULL, ext3_journal_dirty_data);
+		walk_page_buffers(handle, page_bufs, 0,
+				PAGE_CACHE_SIZE, NULL, bput_one);
 		if (!ret)
 			ret = err;
 	}
@@ -1587,7 +1589,7 @@
 		err = ext3_journal_dirty_metadata(handle, bh);
 	} else {
 		if (ext3_should_order_data(inode))
-			err = ext3_journal_dirty_data(handle, bh, 0);
+			err = ext3_journal_dirty_data(handle, bh);
 		mark_buffer_dirty(bh);
 	}
 
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
--- a/fs/ext3/namei.c	Thu Jan 16 18:23:06 2003
+++ b/fs/ext3/namei.c	Thu Jan 16 18:23:06 2003
@@ -1871,10 +1871,10 @@
 	struct list_head *prev;
 	struct ext3_inode_info *ei = EXT3_I(inode);
 	struct ext3_sb_info *sbi;
-	ino_t ino_next; 
+	unsigned long ino_next;
 	struct ext3_iloc iloc;
 	int err = 0;
-	
+
 	lock_super(inode->i_sb);
 	if (list_empty(&ei->i_orphan)) {
 		unlock_super(inode->i_sb);
@@ -1885,7 +1885,7 @@
 	prev = ei->i_orphan.prev;
 	sbi = EXT3_SB(inode->i_sb);
 
-	jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino);
+	jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino);
 
 	list_del_init(&ei->i_orphan);
 
@@ -1895,13 +1895,13 @@
 	 * list in memory. */
 	if (!handle)
 		goto out;
-	
+
 	err = ext3_reserve_inode_write(handle, inode, &iloc);
 	if (err)
 		goto out_err;
 
 	if (prev == &sbi->s_orphan) {
-		jbd_debug(4, "superblock will point to %ld\n", ino_next);
+		jbd_debug(4, "superblock will point to %lu\n", ino_next);
 		BUFFER_TRACE(sbi->s_sbh, "get_write_access");
 		err = ext3_journal_get_write_access(handle, sbi->s_sbh);
 		if (err)
@@ -1912,8 +1912,8 @@
 		struct ext3_iloc iloc2;
 		struct inode *i_prev =
 			&list_entry(prev, struct ext3_inode_info, i_orphan)->vfs_inode;
-		
-		jbd_debug(4, "orphan inode %ld will point to %ld\n",
+
+		jbd_debug(4, "orphan inode %lu will point to %lu\n",
 			  i_prev->i_ino, ino_next);
 		err = ext3_reserve_inode_write(handle, i_prev, &iloc2);
 		if (err)
@@ -1928,7 +1928,7 @@
 	if (err)
 		goto out_brelse;
 
-out_err: 	
+out_err:
 	ext3_std_error(inode->i_sb, err);
 out:
 	unlock_super(inode->i_sb);
diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
--- a/fs/hugetlbfs/inode.c	Thu Jan 16 18:23:06 2003
+++ b/fs/hugetlbfs/inode.c	Thu Jan 16 18:23:06 2003
@@ -457,11 +457,8 @@
 };
 
 struct file_operations hugetlbfs_file_operations = {
-	.read		= generic_file_read,
-	.write		= generic_file_write,
 	.mmap		= hugetlbfs_file_mmap,
 	.fsync		= simple_sync_file,
-	.sendfile	= generic_file_sendfile,
 };
 
 static struct inode_operations hugetlbfs_dir_inode_operations = {
diff -Nru a/fs/intermezzo/vfs.c b/fs/intermezzo/vfs.c
--- a/fs/intermezzo/vfs.c	Thu Jan 16 18:23:05 2003
+++ b/fs/intermezzo/vfs.c	Thu Jan 16 18:23:05 2003
@@ -182,12 +182,13 @@
 {
         int minor = presto_f2m(fset);
         int errorval = izo_channels[minor].uc_errorval;
-        kdev_t dev = to_kdev_t(fset->fset_dentry->d_inode->i_sb->s_dev);
+	struct block_device *bdev = fset->fset_dentry->d_inode->i_sb->s_bdev;
 
-        if (errorval && errorval == (long)value && !is_read_only(dev)) {
-                CDEBUG(D_SUPER, "setting device %s read only\n", kdevname(dev));
-                BLKDEV_FAIL(kdev_val(dev), 1);
-                izo_channels[minor].uc_errorval = -kdev_val(dev);
+        if (errorval && errorval == (long)value && !bdev_read_only(bdev)) {
+                CDEBUG(D_SUPER, "setting device %s read only\n",
+				bdevname(bdev));
+                BLKDEV_FAIL(bdev, 1);
+                izo_channels[minor].uc_errorval = -bdev->bd_dev;
         }
 }
 #else
diff -Nru a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
--- a/fs/jbd/checkpoint.c	Thu Jan 16 18:23:05 2003
+++ b/fs/jbd/checkpoint.c	Thu Jan 16 18:23:05 2003
@@ -585,7 +585,6 @@
 	J_ASSERT (transaction->t_ilist == NULL);
 	J_ASSERT (transaction->t_buffers == NULL);
 	J_ASSERT (transaction->t_sync_datalist == NULL);
-	J_ASSERT (transaction->t_async_datalist == NULL);
 	J_ASSERT (transaction->t_forget == NULL);
 	J_ASSERT (transaction->t_iobuf_list == NULL);
 	J_ASSERT (transaction->t_shadow_list == NULL);
diff -Nru a/fs/jbd/commit.c b/fs/jbd/commit.c
--- a/fs/jbd/commit.c	Thu Jan 16 18:23:06 2003
+++ b/fs/jbd/commit.c	Thu Jan 16 18:23:06 2003
@@ -264,37 +264,6 @@
 	goto write_out_data_locked;
 
 sync_datalist_empty:
-	/*
-	 * Wait for all the async writepage data.  As they become unlocked
-	 * in end_buffer_async_write(), the only place where they can be
-	 * reaped is in try_to_free_buffers(), and we're locked against
-	 * that.
-	 */
-	while ((jh = commit_transaction->t_async_datalist)) {
-		struct buffer_head *bh = jh2bh(jh);
-		if (buffer_locked(bh)) {
-			spin_unlock(&journal_datalist_lock);
-			unlock_journal(journal);
-			wait_on_buffer(bh);
-			lock_journal(journal);
-			spin_lock(&journal_datalist_lock);
-			continue;	/* List may have changed */
-		}
-		if (jh->b_next_transaction) {
-			/*
-			 * For writepage() buffers in journalled data mode: a
-			 * later transaction may want the buffer for "metadata"
-			 */
-			__journal_refile_buffer(jh);
-		} else {
-			BUFFER_TRACE(bh, "finished async writeout: unfile");
-			__journal_unfile_buffer(jh);
-			jh->b_transaction = NULL;
-			__journal_remove_journal_head(bh);
-			BUFFER_TRACE(bh, "finished async writeout: refile");
-			__brelse(bh);
-		}
-	}
 	spin_unlock(&journal_datalist_lock);
 
 	/*
@@ -304,7 +273,6 @@
 	 * clean by now, so check that it is in fact empty.
 	 */
 	J_ASSERT (commit_transaction->t_sync_datalist == NULL);
-	J_ASSERT (commit_transaction->t_async_datalist == NULL);
 
 	jbd_debug (3, "JBD: commit phase 3\n");
 
@@ -629,7 +597,6 @@
 	jbd_debug(3, "JBD: commit phase 7\n");
 
 	J_ASSERT(commit_transaction->t_sync_datalist == NULL);
-	J_ASSERT(commit_transaction->t_async_datalist == NULL);
 	J_ASSERT(commit_transaction->t_buffers == NULL);
 	J_ASSERT(commit_transaction->t_checkpoint_list == NULL);
 	J_ASSERT(commit_transaction->t_iobuf_list == NULL);
diff -Nru a/fs/jbd/transaction.c b/fs/jbd/transaction.c
--- a/fs/jbd/transaction.c	Thu Jan 16 18:23:05 2003
+++ b/fs/jbd/transaction.c	Thu Jan 16 18:23:05 2003
@@ -578,9 +578,6 @@
  * part of the transaction, that is).
  *
  * Returns an error code or 0 on success.
- *
- * In full data journalling mode the buffer may be of type BJ_AsyncData,
- * because we're write()ing a buffer which is also part of a shared mapping.
  */
 
 static int
@@ -949,26 +946,16 @@
  * The buffer is placed on the transaction's data list and is marked as
  * belonging to the transaction.
  *
- * If `async' is set then the writebabk will be initiated by the caller
- * using submit_bh -> end_buffer_async_write.  We put the buffer onto
- * t_async_datalist.
- * 
  * Returns error number or 0 on success.  
  *
  * journal_dirty_data() can be called via page_launder->ext3_writepage
  * by kswapd.  So it cannot block.  Happily, there's nothing here
  * which needs lock_journal if `async' is set.
- *
- * When the buffer is on the current transaction we freely move it
- * between BJ_AsyncData and BJ_SyncData according to who tried to
- * change its state last.
  */
-
-int journal_dirty_data (handle_t *handle, struct buffer_head *bh, int async)
+int journal_dirty_data (handle_t *handle, struct buffer_head *bh)
 {
 	journal_t *journal = handle->h_transaction->t_journal;
 	int need_brelse = 0;
-	int wanted_jlist = async ? BJ_AsyncData : BJ_SyncData;
 	struct journal_head *jh;
 
 	if (is_handle_aborted(handle))
@@ -1046,8 +1033,7 @@
 			 * the write() data.
 			 */
 			if (jh->b_jlist != BJ_None &&
-					jh->b_jlist != BJ_SyncData &&
-					jh->b_jlist != BJ_AsyncData) {
+					jh->b_jlist != BJ_SyncData) {
 				JBUFFER_TRACE(jh, "Not stealing");
 				goto no_journal;
 			}
@@ -1058,7 +1044,7 @@
 			 * again because that can cause the write-out loop in
 			 * commit to never terminate.
 			 */
-			if (!async && buffer_dirty(bh)) {
+			if (buffer_dirty(bh)) {
 				atomic_inc(&bh->b_count);
 				spin_unlock(&journal_datalist_lock);
 				need_brelse = 1;
@@ -1084,18 +1070,18 @@
 		 * committing transaction, so might still be left on that
 		 * transaction's metadata lists.
 		 */
-		if (jh->b_jlist != wanted_jlist) {
+		if (jh->b_jlist != BJ_SyncData) {
 			JBUFFER_TRACE(jh, "not on correct data list: unfile");
 			J_ASSERT_JH(jh, jh->b_jlist != BJ_Shadow);
 			__journal_unfile_buffer(jh);
 			jh->b_transaction = NULL;
 			JBUFFER_TRACE(jh, "file as data");
 			__journal_file_buffer(jh, handle->h_transaction,
-						wanted_jlist);
+						BJ_SyncData);
 		}
 	} else {
 		JBUFFER_TRACE(jh, "not on a transaction");
-		__journal_file_buffer(jh, handle->h_transaction, wanted_jlist);
+		__journal_file_buffer(jh, handle->h_transaction, BJ_SyncData);
 	}
 no_journal:
 	spin_unlock(&journal_datalist_lock);
@@ -1559,12 +1545,12 @@
  * Remove a buffer from the appropriate transaction list.
  *
  * Note that this function can *change* the value of
- * bh->b_transaction->t_sync_datalist, t_async_datalist, t_buffers, t_forget,
+ * bh->b_transaction->t_sync_datalist, t_buffers, t_forget,
  * t_iobuf_list, t_shadow_list, t_log_list or t_reserved_list.  If the caller
  * is holding onto a copy of one of thee pointers, it could go bad.
  * Generally the caller needs to re-read the pointer from the transaction_t.
  *
- * If bh->b_jlist is BJ_SyncData or BJ_AsyncData then we may have been called
+ * If bh->b_jlist is BJ_SyncData then we may have been called
  * via journal_try_to_free_buffer() or journal_clean_data_list().  In that
  * case, journal_datalist_lock will be held, and the journal may not be locked.
  */
@@ -1590,9 +1576,6 @@
 	case BJ_SyncData:
 		list = &transaction->t_sync_datalist;
 		break;
-	case BJ_AsyncData:
-		list = &transaction->t_async_datalist;
-		break;
 	case BJ_Metadata:
 		transaction->t_nr_buffers--;
 		J_ASSERT_JH(jh, transaction->t_nr_buffers >= 0);
@@ -1658,7 +1641,7 @@
 		goto out;
 
 	if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) {
-		if (jh->b_jlist == BJ_SyncData || jh->b_jlist==BJ_AsyncData) {
+		if (jh->b_jlist == BJ_SyncData) {
 			/* A written-back ordered data buffer */
 			JBUFFER_TRACE(jh, "release data");
 			__journal_unfile_buffer(jh);
@@ -1993,9 +1976,6 @@
 		return;
 	case BJ_SyncData:
 		list = &transaction->t_sync_datalist;
-		break;
-	case BJ_AsyncData:
-		list = &transaction->t_async_datalist;
 		break;
 	case BJ_Metadata:
 		transaction->t_nr_buffers++;
diff -Nru a/fs/partitions/sgi.c b/fs/partitions/sgi.c
--- a/fs/partitions/sgi.c	Thu Jan 16 18:23:05 2003
+++ b/fs/partitions/sgi.c	Thu Jan 16 18:23:05 2003
@@ -7,31 +7,33 @@
 #include "check.h"
 #include "sgi.h"
 
+struct sgi_disklabel {
+	s32 magic_mushroom;		/* Big fat spliff... */
+	s16 root_part_num;		/* Root partition number */
+	s16 swap_part_num;		/* Swap partition number */
+	s8 boot_file[16];		/* Name of boot file for ARCS */
+	u8 _unused0[48];		/* Device parameter useless crapola.. */
+	struct sgi_volume {
+		s8 name[8];		/* Name of volume */
+		s32 block_num;		/* Logical block number */
+		s32 num_bytes;		/* How big, in bytes */
+	} volume[15];
+	struct sgi_partition {
+		u32 num_blocks;		/* Size in logical blocks */
+		u32 first_block;	/* First logical block */
+		s32 type;		/* Type of this partition */
+	} partitions[16];
+	s32 csum;			/* Disk label checksum */
+	s32 _unused1;			/* Padding */
+};
+
 int sgi_partition(struct parsed_partitions *state, struct block_device *bdev)
 {
 	int i, csum, magic;
 	int slot = 1;
 	unsigned int *ui, start, blocks, cs;
 	Sector sect;
-	struct sgi_disklabel {
-		int magic_mushroom;         /* Big fat spliff... */
-		short root_part_num;        /* Root partition number */
-		short swap_part_num;        /* Swap partition number */
-		char boot_file[16];         /* Name of boot file for ARCS */
-		unsigned char _unused0[48]; /* Device parameter useless crapola.. */
-		struct sgi_volume {
-			char name[8];       /* Name of volume */
-			int  block_num;     /* Logical block number */
-			int  num_bytes;     /* How big, in bytes */
-		} volume[15];
-		struct sgi_partition {
-			int num_blocks;     /* Size in logical blocks */
-			int first_block;    /* First logical block */
-			int type;           /* Type of this partition */
-		} partitions[16];
-		int csum;                   /* Disk label checksum */
-		int _unused1;               /* Padding */
-	} *label;
+	struct sgi_disklabel *label;
 	struct sgi_partition *p;
 
 	label = (struct sgi_disklabel *) read_dev_sector(bdev, 0, &sect);
diff -Nru a/fs/proc/Makefile b/fs/proc/Makefile
--- a/fs/proc/Makefile	Thu Jan 16 18:23:05 2003
+++ b/fs/proc/Makefile	Thu Jan 16 18:23:05 2003
@@ -9,6 +9,12 @@
 proc-objs    := inode.o root.o base.o generic.o array.o \
 		kmsg.o proc_tty.o proc_misc.o kcore.o
 
+ifeq ($(CONFIG_MMU),y)
+proc-objs    += task_mmu.o
+else
+proc-objs    += task_nommu.o
+endif
+
 ifeq ($(CONFIG_PROC_DEVICETREE),y)
 proc-objs    += proc_devtree.o
 endif
diff -Nru a/fs/proc/array.c b/fs/proc/array.c
--- a/fs/proc/array.c	Thu Jan 16 18:23:06 2003
+++ b/fs/proc/array.c	Thu Jan 16 18:23:06 2003
@@ -180,47 +180,6 @@
 	return buffer;
 }
 
-static inline char * task_mem(struct mm_struct *mm, char *buffer)
-{
-	struct vm_area_struct * vma;
-	unsigned long data = 0, stack = 0;
-	unsigned long exec = 0, lib = 0;
-
-	down_read(&mm->mmap_sem);
-	for (vma = mm->mmap; vma; vma = vma->vm_next) {
-		unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
-		if (!vma->vm_file) {
-			data += len;
-			if (vma->vm_flags & VM_GROWSDOWN)
-				stack += len;
-			continue;
-		}
-		if (vma->vm_flags & VM_WRITE)
-			continue;
-		if (vma->vm_flags & VM_EXEC) {
-			exec += len;
-			if (vma->vm_flags & VM_EXECUTABLE)
-				continue;
-			lib += len;
-		}
-	}
-	buffer += sprintf(buffer,
-		"VmSize:\t%8lu kB\n"
-		"VmLck:\t%8lu kB\n"
-		"VmRSS:\t%8lu kB\n"
-		"VmData:\t%8lu kB\n"
-		"VmStk:\t%8lu kB\n"
-		"VmExe:\t%8lu kB\n"
-		"VmLib:\t%8lu kB\n",
-		mm->total_vm << (PAGE_SHIFT-10),
-		mm->locked_vm << (PAGE_SHIFT-10),
-		mm->rss << (PAGE_SHIFT-10),
-		data - stack, stack,
-		exec - lib, lib);
-	up_read(&mm->mmap_sem);
-	return buffer;
-}
-
 static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
 				    sigset_t *catch)
 {
@@ -277,7 +236,7 @@
 			    cap_t(p->cap_effective));
 }
 
-
+extern char *task_mem(struct mm_struct *, char *);
 int proc_pid_status(struct task_struct *task, char * buffer)
 {
 	char * orig = buffer;
@@ -298,6 +257,7 @@
 	return buffer - orig;
 }
 
+extern unsigned long task_vsize(struct mm_struct *);
 int proc_pid_stat(struct task_struct *task, char * buffer)
 {
 	unsigned long vsize, eip, esp, wchan;
@@ -321,13 +281,8 @@
 	}
 	task_unlock(task);
 	if (mm) {
-		struct vm_area_struct *vma;
 		down_read(&mm->mmap_sem);
-		vma = mm->mmap;
-		while (vma) {
-			vsize += vma->vm_end - vma->vm_start;
-			vma = vma->vm_next;
-		}
+		vsize = task_vsize(mm);
 		eip = KSTK_EIP(task);
 		esp = KSTK_ESP(task);
 		up_read(&mm->mmap_sem);
@@ -397,206 +352,21 @@
 		mmput(mm);
 	return res;
 }
-		
-int proc_pid_statm(task_t *task, char *buffer)
-{
-	int size, resident, shared, text, lib, data, dirty;
-	struct mm_struct *mm = get_task_mm(task);
-	struct vm_area_struct * vma;
-
-	size = resident = shared = text = lib = data = dirty = 0;
-
-	if (!mm)
-		goto out;
 
-	down_read(&mm->mmap_sem);
-	resident = mm->rss;
-	for (vma = mm->mmap; vma; vma = vma->vm_next) {
-		int pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
-
-		size += pages;
-		if (is_vm_hugetlb_page(vma)) {
-			if (!(vma->vm_flags & VM_DONTCOPY))
-				shared += pages;
-			continue;
-		}
-		if (vma->vm_flags & VM_SHARED || !list_empty(&vma->shared))
-			shared += pages;
-		if (vma->vm_flags & VM_EXECUTABLE)
-			text += pages;
-		else
-			data += pages;
-	}
-	up_read(&mm->mmap_sem);
-	mmput(mm);
-out:
-	return sprintf(buffer,"%d %d %d %d %d %d %d\n",
-		       size, resident, shared, text, lib, data, dirty);
-}
-
-/*
- * The way we support synthetic files > 4K
- * - without storing their contents in some buffer and
- * - without walking through the entire synthetic file until we reach the
- *   position of the requested data
- * is to cleverly encode the current position in the file's f_pos field.
- * There is no requirement that a read() call which returns `count' bytes
- * of data increases f_pos by exactly `count'.
- *
- * This idea is Linus' one. Bruno implemented it.
- */
-
-/*
- * For the /proc/<pid>/maps file, we use fixed length records, each containing
- * a single line.
- *
- * f_pos = (number of the vma in the task->mm->mmap list) * PAGE_SIZE
- *         + (index into the line)
- */
-/* for systems with sizeof(void*) == 4: */
-#define MAPS_LINE_FORMAT4	  "%08lx-%08lx %s %08lx %02x:%02x %lu"
-#define MAPS_LINE_MAX4	49 /* sum of 8  1  8  1 4 1 8 1 5 1 10 1 */
-
-/* for systems with sizeof(void*) == 8: */
-#define MAPS_LINE_FORMAT8	  "%016lx-%016lx %s %016lx %02x:%02x %lu"
-#define MAPS_LINE_MAX8	73 /* sum of 16  1  16  1 4 1 16 1 5 1 10 1 */
-
-#define MAPS_LINE_FORMAT	(sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8)
-#define MAPS_LINE_MAX	(sizeof(void*) == 4 ?  MAPS_LINE_MAX4 :  MAPS_LINE_MAX8)
-
-static int proc_pid_maps_get_line (char *buf, struct vm_area_struct *map)
-{
-	/* produce the next line */
-	char *line;
-	char str[5];
-	int flags;
-	dev_t dev;
-	unsigned long ino;
-	int len;
-
-	flags = map->vm_flags;
-
-	str[0] = flags & VM_READ ? 'r' : '-';
-	str[1] = flags & VM_WRITE ? 'w' : '-';
-	str[2] = flags & VM_EXEC ? 'x' : '-';
-	str[3] = flags & VM_MAYSHARE ? 's' : 'p';
-	str[4] = 0;
-
-	dev = 0;
-	ino = 0;
-	if (map->vm_file != NULL) {
-		struct inode *inode = map->vm_file->f_dentry->d_inode;
-		dev = inode->i_sb->s_dev;
-		ino = inode->i_ino;
-		line = d_path(map->vm_file->f_dentry,
-			      map->vm_file->f_vfsmnt,
-			      buf, PAGE_SIZE);
-		buf[PAGE_SIZE-1] = '\n';
-		line -= MAPS_LINE_MAX;
-		if(line < buf)
-			line = buf;
-	} else
-		line = buf;
-
-	len = sprintf(line,
-		      MAPS_LINE_FORMAT,
-		      map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
-		      MAJOR(dev), MINOR(dev), ino);
-
-	if(map->vm_file) {
-		int i;
-		for(i = len; i < MAPS_LINE_MAX; i++)
-			line[i] = ' ';
-		len = buf + PAGE_SIZE - line;
-		memmove(buf, line, len);
-	} else
-		line[len++] = '\n';
-	return len;
-}
-
-#ifdef CONFIG_MMU
-ssize_t proc_pid_read_maps(struct task_struct *task, struct file *file,
-			   char *buf, size_t count, loff_t *ppos)
+extern int task_statm(struct mm_struct *, int *, int *, int *, int *);
+int proc_pid_statm(struct task_struct *task, char *buffer)
 {
-	struct mm_struct *mm;
-	struct vm_area_struct * map;
-	char *tmp, *kbuf;
-	long retval;
-	int off, lineno, loff;
-
-	/* reject calls with out of range parameters immediately */
-	retval = 0;
-	if (*ppos > LONG_MAX)
-		goto out;
-	if (count == 0)
-		goto out;
-	off = (long)*ppos;
-	/*
-	 * We might sleep getting the page, so get it first.
-	 */
-	retval = -ENOMEM;
-	kbuf = (char*)__get_free_page(GFP_KERNEL);
-	if (!kbuf)
-		goto out;
-
-	tmp = (char*)__get_free_page(GFP_KERNEL);
-	if (!tmp)
-		goto out_free1;
+	int size = 0, resident = 0, shared = 0, text = 0, lib = 0, data = 0;
+	struct mm_struct *mm = get_task_mm(task);
+	
+	if (mm) {
+		down_read(&mm->mmap_sem);
+		size = task_statm(mm, &shared, &text, &data, &resident);
+		up_read(&mm->mmap_sem);
 
-	mm = get_task_mm(task);
- 
-	retval = 0;
-	if (!mm)
-		goto out_free2;
-
-	down_read(&mm->mmap_sem);
-	map = mm->mmap;
-	lineno = 0;
-	loff = 0;
-	if (count > PAGE_SIZE)
-		count = PAGE_SIZE;
-	while (map) {
-		int len;
-		if (off > PAGE_SIZE) {
-			off -= PAGE_SIZE;
-			goto next;
-		}
-		len = proc_pid_maps_get_line(tmp, map);
-		len -= off;
-		if (len > 0) {
-			if (retval+len > count) {
-				/* only partial line transfer possible */
-				len = count - retval;
-				/* save the offset where the next read
-				 * must start */
-				loff = len+off;
-			}
-			memcpy(kbuf+retval, tmp+off, len);
-			retval += len;
-		}
-		off = 0;
-next:
-		if (!loff)
-			lineno++;
-		if (retval >= count)
-			break;
-		if (loff) BUG();
-		map = map->vm_next;
+		mmput(mm);
 	}
-	up_read(&mm->mmap_sem);
-	mmput(mm);
 
-	if (retval > count) BUG();
-	if (copy_to_user(buf, kbuf, retval))
-		retval = -EFAULT;
-	else
-		*ppos = (lineno << PAGE_SHIFT) + loff;
-
-out_free2:
-	free_page((unsigned long)tmp);
-out_free1:
-	free_page((unsigned long)kbuf);
-out:
-	return retval;
+	return sprintf(buffer,"%d %d %d %d %d %d %d\n",
+		       size, resident, shared, text, lib, data, 0);
 }
-#endif /* CONFIG_MMU */
diff -Nru a/fs/proc/base.c b/fs/proc/base.c
--- a/fs/proc/base.c	Thu Jan 16 18:23:06 2003
+++ b/fs/proc/base.c	Thu Jan 16 18:23:06 2003
@@ -75,9 +75,7 @@
   E(PROC_PID_CMDLINE,	"cmdline",	S_IFREG|S_IRUGO),
   E(PROC_PID_STAT,	"stat",		S_IFREG|S_IRUGO),
   E(PROC_PID_STATM,	"statm",	S_IFREG|S_IRUGO),
-#ifdef CONFIG_MMU
   E(PROC_PID_MAPS,	"maps",		S_IFREG|S_IRUGO),
-#endif
   E(PROC_PID_MEM,	"mem",		S_IFREG|S_IRUSR|S_IWUSR),
   E(PROC_PID_CWD,	"cwd",		S_IFLNK|S_IRWXUGO),
   E(PROC_PID_ROOT,	"root",		S_IFLNK|S_IRWXUGO),
@@ -323,7 +321,6 @@
 	return proc_check_root(inode);
 }
 
-#ifdef CONFIG_MMU
 extern ssize_t proc_pid_read_maps(struct task_struct *, struct file *,
 				  char *, size_t, loff_t *);
 static ssize_t pid_maps_read(struct file * file, char * buf,
@@ -340,7 +337,6 @@
 static struct file_operations proc_maps_operations = {
 	.read		= pid_maps_read,
 };
-#endif /* CONFIG_MMU */
 
 extern struct seq_operations mounts_op;
 static int mounts_open(struct inode *inode, struct file *file)
@@ -1029,11 +1025,9 @@
 			inode->i_fop = &proc_info_file_operations;
 			ei->op.proc_read = proc_pid_statm;
 			break;
-#ifdef CONFIG_MMU
 		case PROC_PID_MAPS:
 			inode->i_fop = &proc_maps_operations;
 			break;
-#endif
 		case PROC_PID_MEM:
 			inode->i_op = &proc_mem_inode_operations;
 			inode->i_fop = &proc_mem_operations;
diff -Nru a/fs/proc/inode.c b/fs/proc/inode.c
--- a/fs/proc/inode.c	Thu Jan 16 18:23:06 2003
+++ b/fs/proc/inode.c	Thu Jan 16 18:23:06 2003
@@ -221,7 +221,6 @@
 int proc_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct inode * root_inode;
-	struct task_struct *p;
 
 	s->s_blocksize = 1024;
 	s->s_blocksize_bits = 10;
@@ -234,11 +233,7 @@
 	/*
 	 * Fixup the root inode's nlink value
 	 */
-	read_lock(&tasklist_lock);
-	for_each_process(p)
-		if (p->pid)
-			root_inode->i_nlink++;
-	read_unlock(&tasklist_lock);
+	root_inode->i_nlink += nr_processes();
 	s->s_root = d_alloc_root(root_inode);
 	if (!s->s_root)
 		goto out_no_root;
diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
--- a/fs/proc/proc_misc.c	Thu Jan 16 18:23:05 2003
+++ b/fs/proc/proc_misc.c	Thu Jan 16 18:23:05 2003
@@ -140,9 +140,10 @@
 	struct page_state ps;
 	unsigned long inactive;
 	unsigned long active;
+	unsigned long free;
 
 	get_page_state(&ps);
-	get_zone_counts(&active, &inactive);
+	get_zone_counts(&active, &inactive, &free);
 
 /*
  * display in kilobytes.
diff -Nru a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/proc/task_mmu.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,247 @@
+
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <asm/uaccess.h>
+
+char *task_mem(struct mm_struct *mm, char *buffer)
+{
+	unsigned long data = 0, stack = 0, exec = 0, lib = 0;
+	struct vm_area_struct *vma;
+
+	down_read(&mm->mmap_sem);
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
+		if (!vma->vm_file) {
+			data += len;
+			if (vma->vm_flags & VM_GROWSDOWN)
+				stack += len;
+			continue;
+		}
+		if (vma->vm_flags & VM_WRITE)
+			continue;
+		if (vma->vm_flags & VM_EXEC) {
+			exec += len;
+			if (vma->vm_flags & VM_EXECUTABLE)
+				continue;
+			lib += len;
+		}
+	}
+	buffer += sprintf(buffer,
+		"VmSize:\t%8lu kB\n"
+		"VmLck:\t%8lu kB\n"
+		"VmRSS:\t%8lu kB\n"
+		"VmData:\t%8lu kB\n"
+		"VmStk:\t%8lu kB\n"
+		"VmExe:\t%8lu kB\n"
+		"VmLib:\t%8lu kB\n",
+		mm->total_vm << (PAGE_SHIFT-10),
+		mm->locked_vm << (PAGE_SHIFT-10),
+		mm->rss << (PAGE_SHIFT-10),
+		data - stack, stack,
+		exec - lib, lib);
+	up_read(&mm->mmap_sem);
+	return buffer;
+}
+
+unsigned long task_vsize(struct mm_struct *mm)
+{
+	struct vm_area_struct *vma;
+	unsigned long vsize = 0;
+
+	for (vma = mm->mmap; vma; vma = vma->vm_next)
+		vsize += vma->vm_end - vma->vm_start;
+
+	return vsize;
+}
+
+int task_statm(struct mm_struct *mm, int *shared, int *text,
+	       int *data, int *resident)
+{
+	struct vm_area_struct *vma;
+	int size = 0;
+
+	*resident = mm->rss;
+	for (vma = mm->mmap; vma; vma = vma->vm_next) {
+		int pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+
+		size += pages;
+		if (is_vm_hugetlb_page(vma)) {
+			if (!(vma->vm_flags & VM_DONTCOPY))
+				*shared += pages;
+			continue;
+		}
+		if (vma->vm_flags & VM_SHARED || !list_empty(&vma->shared))
+			*shared += pages;
+		if (vma->vm_flags & VM_EXECUTABLE)
+			*text += pages;
+		else
+			*data += pages;
+	}
+
+	return size;
+}
+
+/*
+ * The way we support synthetic files > 4K
+ * - without storing their contents in some buffer and
+ * - without walking through the entire synthetic file until we reach the
+ *   position of the requested data
+ * is to cleverly encode the current position in the file's f_pos field.
+ * There is no requirement that a read() call which returns `count' bytes
+ * of data increases f_pos by exactly `count'.
+ *
+ * This idea is Linus' one. Bruno implemented it.
+ */
+
+/*
+ * For the /proc/<pid>/maps file, we use fixed length records, each containing
+ * a single line.
+ *
+ * f_pos = (number of the vma in the task->mm->mmap list) * PAGE_SIZE
+ *         + (index into the line)
+ */
+/* for systems with sizeof(void*) == 4: */
+#define MAPS_LINE_FORMAT4	  "%08lx-%08lx %s %08lx %02x:%02x %lu"
+#define MAPS_LINE_MAX4	49 /* sum of 8  1  8  1 4 1 8 1 5 1 10 1 */
+
+/* for systems with sizeof(void*) == 8: */
+#define MAPS_LINE_FORMAT8	  "%016lx-%016lx %s %016lx %02x:%02x %lu"
+#define MAPS_LINE_MAX8	73 /* sum of 16  1  16  1 4 1 16 1 5 1 10 1 */
+
+#define MAPS_LINE_FORMAT	(sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8)
+#define MAPS_LINE_MAX	(sizeof(void*) == 4 ?  MAPS_LINE_MAX4 :  MAPS_LINE_MAX8)
+
+static int proc_pid_maps_get_line (char *buf, struct vm_area_struct *map)
+{
+	/* produce the next line */
+	char *line;
+	char str[5];
+	int flags;
+	dev_t dev;
+	unsigned long ino;
+	int len;
+
+	flags = map->vm_flags;
+
+	str[0] = flags & VM_READ ? 'r' : '-';
+	str[1] = flags & VM_WRITE ? 'w' : '-';
+	str[2] = flags & VM_EXEC ? 'x' : '-';
+	str[3] = flags & VM_MAYSHARE ? 's' : 'p';
+	str[4] = 0;
+
+	dev = 0;
+	ino = 0;
+	if (map->vm_file != NULL) {
+		struct inode *inode = map->vm_file->f_dentry->d_inode;
+		dev = inode->i_sb->s_dev;
+		ino = inode->i_ino;
+		line = d_path(map->vm_file->f_dentry,
+			      map->vm_file->f_vfsmnt,
+			      buf, PAGE_SIZE);
+		buf[PAGE_SIZE-1] = '\n';
+		line -= MAPS_LINE_MAX;
+		if(line < buf)
+			line = buf;
+	} else
+		line = buf;
+
+	len = sprintf(line,
+		      MAPS_LINE_FORMAT,
+		      map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
+		      MAJOR(dev), MINOR(dev), ino);
+
+	if(map->vm_file) {
+		int i;
+		for(i = len; i < MAPS_LINE_MAX; i++)
+			line[i] = ' ';
+		len = buf + PAGE_SIZE - line;
+		memmove(buf, line, len);
+	} else
+		line[len++] = '\n';
+	return len;
+}
+
+ssize_t proc_pid_read_maps(struct task_struct *task, struct file *file,
+			   char *buf, size_t count, loff_t *ppos)
+{
+	struct mm_struct *mm;
+	struct vm_area_struct * map;
+	char *tmp, *kbuf;
+	long retval;
+	int off, lineno, loff;
+
+	/* reject calls with out of range parameters immediately */
+	retval = 0;
+	if (*ppos > LONG_MAX)
+		goto out;
+	if (count == 0)
+		goto out;
+	off = (long)*ppos;
+	/*
+	 * We might sleep getting the page, so get it first.
+	 */
+	retval = -ENOMEM;
+	kbuf = (char*)__get_free_page(GFP_KERNEL);
+	if (!kbuf)
+		goto out;
+
+	tmp = (char*)__get_free_page(GFP_KERNEL);
+	if (!tmp)
+		goto out_free1;
+
+	mm = get_task_mm(task);
+ 
+	retval = 0;
+	if (!mm)
+		goto out_free2;
+
+	down_read(&mm->mmap_sem);
+	map = mm->mmap;
+	lineno = 0;
+	loff = 0;
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
+	while (map) {
+		int len;
+		if (off > PAGE_SIZE) {
+			off -= PAGE_SIZE;
+			goto next;
+		}
+		len = proc_pid_maps_get_line(tmp, map);
+		len -= off;
+		if (len > 0) {
+			if (retval+len > count) {
+				/* only partial line transfer possible */
+				len = count - retval;
+				/* save the offset where the next read
+				 * must start */
+				loff = len+off;
+			}
+			memcpy(kbuf+retval, tmp+off, len);
+			retval += len;
+		}
+		off = 0;
+next:
+		if (!loff)
+			lineno++;
+		if (retval >= count)
+			break;
+		if (loff) BUG();
+		map = map->vm_next;
+	}
+	up_read(&mm->mmap_sem);
+	mmput(mm);
+
+	if (retval > count) BUG();
+	if (copy_to_user(buf, kbuf, retval))
+		retval = -EFAULT;
+	else
+		*ppos = (lineno << PAGE_SHIFT) + loff;
+
+out_free2:
+	free_page((unsigned long)tmp);
+out_free1:
+	free_page((unsigned long)kbuf);
+out:
+	return retval;
+}
diff -Nru a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/proc/task_nommu.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,107 @@
+
+#include <linux/mm.h>
+
+/*
+ * Logic: we've got two memory sums for each process, "shared", and
+ * "non-shared". Shared memory may get counted more then once, for
+ * each process that owns it. Non-shared memory is counted
+ * accurately.
+ */
+char *task_mem(struct mm_struct *mm, char *buffer)
+{
+	unsigned long bytes = 0, sbytes = 0, slack = 0;
+	struct mm_tblock_struct *tblock;
+        
+	down_read(&mm->mmap_sem);
+	for (tblock = &mm->context.tblock; tblock; tblock = tblock->next) {
+		if (!tblock->rblock)
+			continue;
+		bytes += kobjsize(tblock);
+		if (atomic_read(&mm->mm_count) > 1 ||
+		    tblock->rblock->refcount > 1) {
+			sbytes += kobjsize(tblock->rblock->kblock);
+			sbytes += kobjsize(tblock->rblock);
+		} else {
+			bytes += kobjsize(tblock->rblock->kblock);
+			bytes += kobjsize(tblock->rblock);
+			slack += kobjsize(tblock->rblock->kblock) -
+					tblock->rblock->size;
+		}
+	}
+
+	if (atomic_read(&mm->mm_count) > 1)
+		sbytes += kobjsize(mm);
+	else
+		bytes += kobjsize(mm);
+	
+	if (current->fs && atomic_read(&current->fs->count) > 1)
+		sbytes += kobjsize(current->fs);
+	else
+		bytes += kobjsize(current->fs);
+
+	if (current->files && atomic_read(&current->files->count) > 1)
+		sbytes += kobjsize(current->files);
+	else
+		bytes += kobjsize(current->files);
+
+	if (current->sig && atomic_read(&current->sig->count) > 1)
+		sbytes += kobjsize(current->sig);
+	else
+		bytes += kobjsize(current->sig);
+
+	bytes += kobjsize(current); /* includes kernel stack */
+
+	buffer += sprintf(buffer,
+		"Mem:\t%8lu bytes\n"
+		"Slack:\t%8lu bytes\n"
+		"Shared:\t%8lu bytes\n",
+		bytes, slack, sbytes);
+
+	up_read(&mm->mmap_sem);
+	return buffer;
+}
+
+unsigned long task_vsize(struct mm_struct *mm)
+{
+	struct mm_tblock_struct *tbp;
+	unsigned long vsize;
+
+	for (tbp = &mm->context.tblock; tbp; tbp = tbp->next) {
+		if (tbp->rblock)
+			vsize += kobjsize(tbp->rblock->kblock);
+	}
+
+	return vsize;
+}
+
+int task_statm(struct mm_struct *mm, int *shared, int *text,
+	       int *data, int *resident)
+{
+	struct mm_tblock_struct *tbp;
+	int size = kobjsize(mm);
+	
+	for (tbp = &mm->context.tblock; tbp; tbp = tbp->next) {
+		if (tbp->next)
+			size += kobjsize(tbp->next);
+		if (tbp->rblock) {
+			size += kobjsize(tbp->rblock);
+			size += kobjsize(tbp->rblock->kblock);
+		}
+	}
+
+	size += (text = mm->end_code - mm->start_code);
+	size += (data = mm->start_stack - mm->start_data);
+
+	*resident = size;
+	return size;
+}
+
+/*
+ * Albert D. Cahalan suggested to fake entries for the traditional
+ * sections here.  This might be worth investigating.
+ */
+ssize_t proc_pid_read_maps(struct task_struct *task, struct file *file,
+			   char *buf, size_t count, loff_t *ppos)
+{
+	return 0;
+}
diff -Nru a/fs/quota.c b/fs/quota.c
--- a/fs/quota.c	Thu Jan 16 18:23:07 2003
+++ b/fs/quota.c	Thu Jan 16 18:23:07 2003
@@ -102,35 +102,6 @@
 	return security_quotactl (cmd, type, id, sb);
 }
 
-/* Resolve device pathname to superblock */
-static struct super_block *resolve_dev(const char *path)
-{
-	int ret;
-	mode_t mode;
-	struct nameidata nd;
-	struct block_device *bdev;
-	struct super_block *sb;
-
-	ret = user_path_walk(path, &nd);
-	if (ret)
-		goto out;
-
-	bdev = nd.dentry->d_inode->i_bdev;
-	mode = nd.dentry->d_inode->i_mode;
-	path_release(&nd);
-
-	ret = -ENOTBLK;
-	if (!S_ISBLK(mode))
-		goto out;
-	ret = -ENODEV;
-	sb = get_super(bdev);
-	if (!sb)
-		goto out;
-	return sb;
-out:
-	return ERR_PTR(ret);
-}
-
 /* Copy parameters and call proper function */
 static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, caddr_t addr)
 {
@@ -249,21 +220,24 @@
 {
 	uint cmds, type;
 	struct super_block *sb = NULL;
-	int ret = -EINVAL;
+	struct block_device *bdev;
+	int ret = -ENODEV;
 
 	cmds = cmd >> SUBCMDSHIFT;
 	type = cmd & SUBCMDMASK;
 
-	if (IS_ERR(sb = resolve_dev(special))) {
-		ret = PTR_ERR(sb);
-		sb = NULL;
-		goto out;
-	}
-	if ((ret = check_quotactl_valid(sb, type, cmds, id)) < 0)
-		goto out;
-	ret = do_quotactl(sb, type, cmds, id, addr);
-out:
-	if (sb)
+	bdev = lookup_bdev(special);
+	if (IS_ERR(bdev))
+		return PTR_ERR(bdev);
+	sb = get_super(bdev);
+	bdput(bdev);
+
+	if (sb) {
+		ret = check_quotactl_valid(sb, type, cmds, id);
+		if (ret >= 0)
+			ret = do_quotactl(sb, type, cmds, id, addr);
 		drop_super(sb);
+	}
+
 	return ret;
 }
diff -Nru a/fs/xfs/linux/xfs_linux.h b/fs/xfs/linux/xfs_linux.h
--- a/fs/xfs/linux/xfs_linux.h	Thu Jan 16 18:23:05 2003
+++ b/fs/xfs/linux/xfs_linux.h	Thu Jan 16 18:23:05 2003
@@ -42,6 +42,7 @@
 #include <linux/sched.h>
 #include <linux/bitops.h>
 #include <linux/major.h>
+#include <linux/pagemap.h>
 #include <linux/vfs.h>
 
 #include <asm/page.h>
@@ -169,7 +170,6 @@
 #define DEFAULT_PROJID	0
 #define dfltprid	DEFAULT_PROJID
 
-#define MAXNAMELEN	256
 #define MAXPATHLEN	1024
 
 #define FINVIS		0x0100	/* don't update timestamps - XFS */
diff -Nru a/fs/xfs/linux/xfs_lrw.c b/fs/xfs/linux/xfs_lrw.c
--- a/fs/xfs/linux/xfs_lrw.c	Thu Jan 16 18:23:05 2003
+++ b/fs/xfs/linux/xfs_lrw.c	Thu Jan 16 18:23:05 2003
@@ -872,13 +872,12 @@
 	int error;
 
 	mp = XFS_BHVTOM(bdp);
-	xfs_binval(mp->m_ddev_targp);
+	pagebuf_delwri_flush(mp->m_ddev_targp, PBDF_WAIT, &pincount);
+	xfs_finish_reclaim_all(mp);
 
 	do {
-		xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC);
 		VFS_SYNC(XFS_MTOVFS(mp), SYNC_ATTR|SYNC_WAIT, NULL, error);
-		pagebuf_delwri_flush(mp->m_ddev_targp,
-				PBDF_WAIT, &pincount);
+		pagebuf_delwri_flush(mp->m_ddev_targp, PBDF_WAIT, &pincount);
 		if (pincount == 0) {delay(50); count++;}
 	}  while (count < 2);
 
diff -Nru a/fs/xfs/linux/xfs_vnode.h b/fs/xfs/linux/xfs_vnode.h
--- a/fs/xfs/linux/xfs_vnode.h	Thu Jan 16 18:23:07 2003
+++ b/fs/xfs/linux/xfs_vnode.h	Thu Jan 16 18:23:07 2003
@@ -671,13 +671,14 @@
 #define VN_HOLD(vp)		((void)vn_hold(vp))
 #define VN_RELE(vp)		(iput(LINVFS_GET_IP(vp)))
 
-#endif	/* ! (defined(CONFIG_XFS_VNODE_TRACING) */
+#endif	/* ! (defined(CONFIG_XFS_VNODE_TRACING)) */
 
 /*
  * Vname handling macros.
  */
 #define VNAME(dentry)		((char *) (dentry)->d_name.name)
 #define VNAMELEN(dentry)	((dentry)->d_name.len)
+#define VNAME_TO_VNODE(dentry)	(LINVFS_GET_VP((dentry)->d_inode))
 
 /*
  * Vnode spinlock manipulation.
diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c
--- a/fs/xfs/pagebuf/page_buf.c	Thu Jan 16 18:23:05 2003
+++ b/fs/xfs/pagebuf/page_buf.c	Thu Jan 16 18:23:05 2003
@@ -1108,7 +1108,7 @@
  *	pagebuf_iodone
  *
  *	pagebuf_iodone marks a buffer for which I/O is in progress
- *	done with respect to that I/O.	The pb_done routine, if
+ *	done with respect to that I/O.	The pb_iodone routine, if
  *	present, will be called as a side-effect.
  */
 void
@@ -1173,7 +1173,7 @@
  *	pagebuf_iostart initiates I/O on a buffer, based on the flags supplied.
  *	If necessary, it will arrange for any disk space allocation required,
  *	and it will break up the request if the block mappings require it.
- *	An pb_iodone routine in the buffer supplied will only be called
+ *	The pb_iodone routine in the buffer supplied will only be called
  *	when all of the subsidiary I/O requests, if any, have been completed.
  *	pagebuf_iostart calls the pagebuf_ioinitiate routine or
  *	pagebuf_iorequest, if the former routine is not defined, to start
@@ -1317,7 +1317,7 @@
 
 	/* Set the count to 1 initially, this will stop an I/O
 	 * completion callout which happens before we have started
-	 * all the I/O from calling iodone too early
+	 * all the I/O from calling pagebuf_iodone too early.
 	 */
 	atomic_set(&pb->pb_io_remaining, 1);
 
diff -Nru a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
--- a/fs/xfs/support/debug.c	Thu Jan 16 18:23:05 2003
+++ b/fs/xfs/support/debug.c	Thu Jan 16 18:23:05 2003
@@ -41,7 +41,10 @@
 static spinlock_t 	xfs_err_lock = SPIN_LOCK_UNLOCKED;
 
 /* Translate from CE_FOO to KERN_FOO, err_level(CE_FOO) == KERN_FOO */
-static char		*err_level[8] = {KERN_EMERG, KERN_ALERT, KERN_CRIT,
+#define XFS_MAX_ERR_LEVEL	7
+#define XFS_ERR_MASK		((1 << 3) - 1)
+static char		*err_level[XFS_MAX_ERR_LEVEL+1] =
+					{KERN_EMERG, KERN_ALERT, KERN_CRIT,
 					 KERN_ERR, KERN_WARNING, KERN_NOTICE,
 					 KERN_INFO, KERN_DEBUG};
 
@@ -82,15 +85,22 @@
 cmn_err(register int level, char *fmt, ...)
 {
 	char	*fp = fmt;
-	va_list ap;
-
-	spin_lock(&xfs_err_lock);
+	int	len;
+	int	flags;
+	va_list	ap;
+
+	level &= XFS_ERR_MASK;
+	if (level > XFS_MAX_ERR_LEVEL)
+		level = XFS_MAX_ERR_LEVEL;
+	spin_lock_irqsave(&xfs_err_lock,flags);
 	va_start(ap, fmt);
 	if (*fmt == '!') fp++;
-	vsprintf(message, fp, ap);
-	printk("%s%s\n", err_level[level], message);
+	len = vsprintf(message, fp, ap);
+	if (message[len-1] != '\n')
+		strcat(message, "\n");
+	printk("%s%s", err_level[level], message);
 	va_end(ap);
-	spin_unlock(&xfs_err_lock);
+	spin_unlock_irqrestore(&xfs_err_lock,flags);
 
 	if (level == CE_PANIC)
 		BUG();
@@ -100,10 +110,18 @@
 void
 icmn_err(register int level, char *fmt, va_list ap)
 {
-	spin_lock(&xfs_err_lock);
-	vsprintf(message, fmt, ap);
-	spin_unlock(&xfs_err_lock);
-	printk("%s%s\n", err_level[level], message);
+	int	len;
+	int	flags;
+
+	level &= XFS_ERR_MASK;
+	if(level > XFS_MAX_ERR_LEVEL)
+		level = XFS_MAX_ERR_LEVEL;
+	spin_lock_irqsave(&xfs_err_lock,flags);
+	len = vsprintf(message, fmt, ap);
+	if (message[len-1] != '\n')
+		strcat(message, "\n");
+	spin_unlock_irqrestore(&xfs_err_lock,flags);
+	printk("%s%s", err_level[level], message);
 	if (level == CE_PANIC)
 		BUG();
 }
diff -Nru a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c
--- a/fs/xfs/xfs_dir.c	Thu Jan 16 18:23:05 2003
+++ b/fs/xfs/xfs_dir.c	Thu Jan 16 18:23:05 2003
@@ -386,9 +386,6 @@
 	int retval;
 
 	ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
-	if (namelen >= MAXNAMELEN) {
-		return(XFS_ERROR(EINVAL));
-	}
 
 	XFS_STATS_INC(xfsstats.xs_dir_lookup);
 	/*
@@ -479,9 +476,6 @@
 	int retval;
 
 	ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
-	if (namelen >= MAXNAMELEN) {
-		return(XFS_ERROR(EINVAL));
-	}
 
 	if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum)))
 		return retval;
diff -Nru a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
--- a/fs/xfs/xfs_dir2.c	Thu Jan 16 18:23:07 2003
+++ b/fs/xfs/xfs_dir2.c	Thu Jan 16 18:23:07 2003
@@ -232,10 +232,8 @@
 	int		v;		/* type-checking value */
 
 	ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
-	if (namelen >= MAXNAMELEN) {
-		return XFS_ERROR(EINVAL);
-	}
 	XFS_STATS_INC(xfsstats.xs_dir_lookup);
+
 	/*
 	 * Fill in the arg structure for this request.
 	 */
@@ -395,9 +393,7 @@
 	int		v;		/* type-checking value */
 
 	ASSERT((dp->i_d.di_mode & IFMT) == IFDIR);
-	if (namelen >= MAXNAMELEN) {
-		return XFS_ERROR(EINVAL);
-	}
+
 	if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) {
 		return rval;
 	}
diff -Nru a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
--- a/fs/xfs/xfs_inode.h	Thu Jan 16 18:23:06 2003
+++ b/fs/xfs/xfs_inode.h	Thu Jan 16 18:23:06 2003
@@ -414,11 +414,9 @@
  * max file offset is 2^(31+PAGE_SHIFT) - 1 (due to linux page cache)
  *
  * NOTE: XFS itself can handle 2^63 - 1 (largest positive value of xfs_fsize_t)
- * but Linux can't go above 2^(31+PAGE_SHIFT)-1: the Linux VM uses a 32 bit
- * signed variable to index cache data, so 2^31 * PAGE_SIZE is as big as
- * you can go.
+ * but this is the Linux limit.
  */
-#define XFS_MAX_FILE_OFFSET	((long long)((1ULL<<(31+PAGE_SHIFT))-1ULL))
+#define XFS_MAX_FILE_OFFSET	MAX_LFS_FILESIZE
 
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_ITOV)
 struct vnode *xfs_itov(xfs_inode_t *ip);
@@ -483,6 +481,7 @@
 void		xfs_ifunlock(xfs_inode_t *);
 void		xfs_ireclaim(xfs_inode_t *);
 int		xfs_finish_reclaim(xfs_inode_t *, int, int);
+int		xfs_finish_reclaim_all(struct xfs_mount *);
 
 /*
  * xfs_inode.c prototypes.
diff -Nru a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
--- a/fs/xfs/xfs_log_recover.c	Thu Jan 16 18:23:06 2003
+++ b/fs/xfs/xfs_log_recover.c	Thu Jan 16 18:23:06 2003
@@ -2952,7 +2952,6 @@
 
 				if (!error) {
 					ASSERT(ip->i_d.di_nlink == 0);
-					ASSERT(ip->i_d.di_mode != 0);
 
 					/* setup for the next pass */
 					agino = INT_GET(dip->di_next_unlinked,
@@ -2970,7 +2969,9 @@
 					ip->i_d.di_dmevmask = 0;
 
 					/*
-					 * Drop our reference to the
+					 * If this is a new inode, handle
+					 * it specially.  Otherwise,
+					 * just drop our reference to the
 					 * inode.  If there are no
 					 * other references, this will
 					 * send the inode to
@@ -2978,7 +2979,10 @@
 					 * truncate the file and free
 					 * the inode.
 					 */
-					VN_RELE(XFS_ITOV(ip));
+					if (ip->i_d.di_mode == 0)
+						xfs_iput_new(ip, 0);
+					else
+						VN_RELE(XFS_ITOV(ip));
 				} else {
 					/*
 					 * We can't read in the inode
diff -Nru a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
--- a/fs/xfs/xfs_rename.c	Thu Jan 16 18:23:05 2003
+++ b/fs/xfs/xfs_rename.c	Thu Jan 16 18:23:05 2003
@@ -72,14 +72,13 @@
  * We are renaming dp1/name1 to dp2/name2.
  *
  * Return ENOENT if dp1 does not exist, other lookup errors, or 0 for success.
- * Return EAGAIN if the caller needs to try again.
  */
 STATIC int
 xfs_lock_for_rename(
 	xfs_inode_t	*dp1,	/* old (source) directory inode */
 	xfs_inode_t	*dp2,	/* new (target) directory inode */
-	vname_t		*dentry1, /* old entry name */
-	vname_t		*dentry2, /* new entry name */
+	vname_t		*vname1,/* old entry name */
+	vname_t		*vname2,/* new entry name */
 	xfs_inode_t	**ipp1, /* inode of old entry */
 	xfs_inode_t	**ipp2, /* inode of new entry, if it
 				   already exists, NULL otherwise. */
@@ -102,7 +101,7 @@
 	 * to see if we still have the right inodes, directories, etc.
 	 */
 	lock_mode = xfs_ilock_map_shared(dp1);
-	error = xfs_get_dir_entry(dentry1, &ip1);
+	error = xfs_get_dir_entry(vname1, &ip1);
 	if (error) {
 		xfs_iunlock_map_shared(dp1, lock_mode);
 		return error;
@@ -123,7 +122,7 @@
 	}
 
 	error = xfs_dir_lookup_int(XFS_ITOBHV(dp2), lock_mode,
-				   dentry2, &inum2, &ip2);
+				   vname2, &inum2, &ip2);
 	if (error == ENOENT) {		/* target does not need to exist. */
 		inum2 = 0;
 	} else if (error) {
@@ -213,20 +212,15 @@
 
 int rename_which_error_return = 0;
 
-#ifdef DEBUG
-int xfs_rename_agains;
-int xfs_renames;
-#endif
-
 /*
  * xfs_rename
  */
 int
 xfs_rename(
 	bhv_desc_t	*src_dir_bdp,
-	vname_t		*src_dentry,
+	vname_t		*src_vname,
 	vnode_t		*target_dir_vp,
-	vname_t		*target_dentry,
+	vname_t		*target_vname,
 	cred_t		*credp)
 {
 	xfs_trans_t	*tp;
@@ -246,15 +240,11 @@
 	int		spaceres;
 	int		target_link_zero = 0;
 	int		num_inodes;
-	char		*src_name = VNAME(src_dentry);
-	char		*target_name = VNAME(target_dentry);
-	int		src_namelen;
-	int		target_namelen;
-#ifdef DEBUG
-	int		retries;
+	char		*src_name = VNAME(src_vname);
+	char		*target_name = VNAME(target_vname);
+	int		src_namelen = VNAMELEN(src_vname);
+	int		target_namelen = VNAMELEN(target_vname);
 
-	xfs_renames++;
-#endif
 	src_dir_vp = BHV_TO_VNODE(src_dir_bdp);
 	vn_trace_entry(src_dir_vp, "xfs_rename", (inst_t *)__return_address);
 	vn_trace_entry(target_dir_vp, "xfs_rename", (inst_t *)__return_address);
@@ -268,14 +258,10 @@
 	if (target_dir_bdp == NULL) {
 		return XFS_ERROR(EXDEV);
 	}
-	src_namelen = VNAMELEN(src_dentry);
-	if (src_namelen >= MAXNAMELEN)
-		return XFS_ERROR(ENAMETOOLONG);
-	target_namelen = VNAMELEN(target_dentry);
-	if (target_namelen >= MAXNAMELEN)
-		return XFS_ERROR(ENAMETOOLONG);
+
 	src_dp = XFS_BHVTOI(src_dir_bdp);
 	target_dp = XFS_BHVTOI(target_dir_bdp);
+
 	if (DM_EVENT_ENABLED(src_dir_vp->v_vfsp, src_dp, DM_EVENT_RENAME) ||
 	    DM_EVENT_ENABLED(target_dir_vp->v_vfsp,
 				target_dp, DM_EVENT_RENAME)) {
@@ -290,9 +276,6 @@
 	}
 	/* Return through std_return after this point. */
 
-#ifdef DEBUG
-	retries = 0;
-#endif
 	/*
 	 * Lock all the participating inodes. Depending upon whether
 	 * the target_name exists in the target directory, and
@@ -302,15 +285,9 @@
 	 * does not exist in the source directory.
 	 */
 	tp = NULL;
-	do {
-		error = xfs_lock_for_rename(src_dp, target_dp, src_dentry,
-				target_dentry, &src_ip, &target_ip, inodes,
-				&num_inodes);
-#ifdef DEBUG
-		if (error == EAGAIN)
-			xfs_rename_agains++;
-#endif
-	} while (error == EAGAIN);
+	error = xfs_lock_for_rename(src_dp, target_dp, src_vname,
+			target_vname, &src_ip, &target_ip, inodes,
+			&num_inodes);
 
 	if (error) {
 		rename_which_error_return = __LINE__;
diff -Nru a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
--- a/fs/xfs/xfs_utils.c	Thu Jan 16 18:23:07 2003
+++ b/fs/xfs/xfs_utils.c	Thu Jan 16 18:23:07 2003
@@ -47,9 +47,7 @@
 	vnode_t		*vp;
 	bhv_desc_t	*bdp;
 
-	ASSERT(dentry->d_inode);
-
-	vp = LINVFS_GET_VP(dentry->d_inode);
+	vp = VNAME_TO_VNODE(dentry);
 	bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(vp), &xfs_vnodeops);
 	if (!bdp) {
 		*ipp = NULL;
diff -Nru a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
--- a/fs/xfs/xfs_vfsops.c	Thu Jan 16 18:23:05 2003
+++ b/fs/xfs/xfs_vfsops.c	Thu Jan 16 18:23:05 2003
@@ -926,7 +926,7 @@
 		IPOINTER_CLR; \
 	}
 
-#define PREEMPT_MASK	0x7f
+#define XFS_PREEMPT_MASK	0x7f
 
 	if (bypassed)
 		*bypassed = 0;
@@ -1395,7 +1395,7 @@
 		 * if we have looped many times without dropping the
 		 * lock.
 		 */
-		if ((++preempt & PREEMPT_MASK) == 0) {
+		if ((++preempt & XFS_PREEMPT_MASK) == 0) {
 			if (mount_locked) {
 				IPOINTER_INSERT(ip, mp);
 			}
diff -Nru a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
--- a/fs/xfs/xfs_vnodeops.c	Thu Jan 16 18:23:07 2003
+++ b/fs/xfs/xfs_vnodeops.c	Thu Jan 16 18:23:07 2003
@@ -82,7 +82,7 @@
 /*
  * xfs_getattr
  */
-int
+STATIC int
 xfs_getattr(
 	bhv_desc_t	*bdp,
 	vattr_t		*vap,
@@ -1935,8 +1935,6 @@
 
 	dm_di_mode = vap->va_mode|VTTOIF(vap->va_type);
 	namelen = VNAMELEN(dentry);
-	if (namelen >= MAXNAMELEN)
-		return XFS_ERROR(ENAMETOOLONG);
 
 	if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) {
 		error = dm_send_namesp_event(DM_EVENT_CREATE,
@@ -2433,8 +2431,7 @@
 		return XFS_ERROR(EIO);
 
 	namelen = VNAMELEN(dentry);
-	if (namelen >= MAXNAMELEN)
-		return XFS_ERROR(ENAMETOOLONG);
+
 	if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
 		error = dm_send_namesp_event(DM_EVENT_REMOVE, dir_bdp, DM_RIGHT_NULL,
 					NULL, DM_RIGHT_NULL,
@@ -2668,8 +2665,6 @@
 	vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address);
 
 	target_namelen = VNAMELEN(dentry);
-	if (target_namelen >= MAXNAMELEN)
-		return XFS_ERROR(ENAMETOOLONG);
 	if (src_vp->v_type == VDIR)
 		return XFS_ERROR(EPERM);
 
@@ -2857,8 +2852,6 @@
 		return XFS_ERROR(EIO);
 
 	dir_namelen = VNAMELEN(dentry);
-	if (dir_namelen >= MAXNAMELEN)
-		return XFS_ERROR(ENAMETOOLONG);
 
 	tp = NULL;
 	dp_joined_to_trans = B_FALSE;
@@ -3100,8 +3093,6 @@
 	if (XFS_FORCED_SHUTDOWN(XFS_BHVTOI(dir_bdp)->i_mount))
 		return XFS_ERROR(EIO);
 	namelen = VNAMELEN(dentry);
-	if (namelen >= MAXNAMELEN)
-		return XFS_ERROR(ENAMETOOLONG);
 
 	if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
 		error = dm_send_namesp_event(DM_EVENT_REMOVE,
@@ -3415,8 +3406,7 @@
 		return XFS_ERROR(EIO);
 
 	link_namelen = VNAMELEN(dentry);
-	if (link_namelen >= MAXNAMELEN)
-		return XFS_ERROR(ENAMETOOLONG);
+
 	/*
 	 * Check component lengths of the target path name.
 	 */
@@ -4067,6 +4057,49 @@
 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
 
 	xfs_ireclaim(ip);
+	return 0;
+}
+
+int
+xfs_finish_reclaim_all(xfs_mount_t *mp)
+{
+	int		purged;
+	xfs_inode_t	*ip;
+	vnode_t		*vp;
+	int		done = 0;
+
+	while (!done) {
+		purged = 0;
+		XFS_MOUNT_ILOCK(mp);
+		ip = mp->m_inodes;
+		if (ip == NULL) {
+			break;
+		}
+		do {
+			/* Make sure we skip markers inserted by sync */
+			if (ip->i_mount == NULL) {
+				ip = ip->i_mnext;
+				continue;
+			}
+	
+			/*
+			 * It's up to our caller to purge the root
+			 * and quota vnodes later.
+			 */
+			vp = XFS_ITOV_NULL(ip);
+	
+			if (!vp) {
+				XFS_MOUNT_IUNLOCK(mp);	
+				xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
+				purged = 1;
+				break;
+			}
+		} while (ip != mp->m_inodes);
+	
+		done = !purged;
+	}
+
+	XFS_MOUNT_IUNLOCK(mp);
 	return 0;
 }
 
diff -Nru a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h
--- a/include/asm-alpha/agp.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-alpha/agp.h	Thu Jan 16 18:23:05 2003
@@ -1,6 +1,8 @@
 #ifndef AGP_H
 #define AGP_H 1
 
+#include <asm/io.h>
+
 /* dummy for now */
 
 #define map_page_into_agp(page) 
diff -Nru a/include/asm-alpha/agp_backend.h b/include/asm-alpha/agp_backend.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-alpha/agp_backend.h	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,43 @@
+#ifndef _ALPHA_AGP_BACKEND_H
+#define _ALPHA_AGP_BACKEND_H 1
+
+typedef	union _alpha_agp_mode {
+	struct {
+		u32 rate : 3;
+		u32 reserved0 : 1;
+		u32 fw : 1;
+		u32 fourgb : 1;
+		u32 reserved1 : 2;
+		u32 enable : 1;
+		u32 sba : 1;
+		u32 reserved2 : 14;
+		u32 rq : 8;
+	} bits;
+	u32 lw;
+} alpha_agp_mode;
+
+typedef struct _alpha_agp_info {
+	enum chipset_type type;
+	struct pci_controller *hose;
+	struct {
+		dma_addr_t bus_base;
+		unsigned long size;
+		void *sysdata;
+	} aperture;
+	alpha_agp_mode capability;
+	alpha_agp_mode mode;
+	void *private;
+	struct alpha_agp_ops *ops;
+} alpha_agp_info;
+
+struct alpha_agp_ops {
+	int (*setup)(alpha_agp_info *);
+	void (*cleanup)(alpha_agp_info *);
+	int (*configure)(alpha_agp_info *);
+	int (*bind)(alpha_agp_info *, off_t, agp_memory *);
+	int (*unbind)(alpha_agp_info *, off_t, agp_memory *);
+	unsigned long (*translate)(alpha_agp_info *, dma_addr_t);
+};
+
+
+#endif /* _ALPHA_AGP_BACKEND_H */
diff -Nru a/include/asm-alpha/console.h b/include/asm-alpha/console.h
--- a/include/asm-alpha/console.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-alpha/console.h	Thu Jan 16 18:23:05 2003
@@ -10,6 +10,8 @@
 #define CCB_SET_TERM_INT	0x04
 #define CCB_SET_TERM_CTL	0x05
 #define CCB_PROCESS_KEYCODE	0x06
+#define CCB_OPEN_CONSOLE	0x07
+#define CCB_CLOSE_CONSOLE	0x08
 
 #define CCB_OPEN		0x10
 #define CCB_CLOSE		0x11
@@ -47,6 +49,9 @@
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 extern long callback_puts(long unit, const char *s, long length);
+extern long callback_getc(long unit);
+extern long callback_open_console(void);
+extern long callback_close_console(void);
 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);
diff -Nru a/include/asm-alpha/core_marvel.h b/include/asm-alpha/core_marvel.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-alpha/core_marvel.h	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,579 @@
+/*
+ * Marvel systems use the IO7 I/O chip provides PCI/PCIX/AGP access
+ *
+ * This file is based on:
+ *
+ * Marvel / EV7 System Programmer's Manual
+ * Revision 1.00
+ * 14 May 2001
+ */
+
+#ifndef __ALPHA_MARVEL__H__
+#define __ALPHA_MARVEL__H__
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+
+#include <asm/compiler.h>
+
+#define MARVEL_MAX_PIDS		 32 /* as long as we rely on 43-bit superpage */
+#define MARVEL_IRQ_VEC_PE_SHIFT	(10)
+#define MARVEL_IRQ_VEC_IRQ_MASK	((1 << MARVEL_IRQ_VEC_PE_SHIFT) - 1)
+#define MARVEL_NR_IRQS		\
+	(16 + (MARVEL_MAX_PIDS * (1 << MARVEL_IRQ_VEC_PE_SHIFT)))
+
+/*
+ * EV7 RBOX Registers
+ */
+typedef struct {
+	volatile unsigned long csr __attribute__((aligned(16)));
+} ev7_csr;
+
+typedef struct {
+	ev7_csr	RBOX_CFG;		/* 0x0000 */
+	ev7_csr	RBOX_NSVC;
+	ev7_csr	RBOX_EWVC;
+	ev7_csr	RBOX_WHAMI;
+	ev7_csr	RBOX_TCTL;		/* 0x0040 */
+	ev7_csr	RBOX_INT;
+	ev7_csr	RBOX_IMASK;
+	ev7_csr	RBOX_IREQ;
+	ev7_csr	RBOX_INTQ;		/* 0x0080 */
+	ev7_csr	RBOX_INTA;
+	ev7_csr	RBOX_IT;
+	ev7_csr	RBOX_SCRATCH1;
+	ev7_csr	RBOX_SCRATCH2;		/* 0x00c0 */
+	ev7_csr	RBOX_L_ERR;
+} ev7_csrs;
+
+/*
+ * EV7 CSR addressing macros
+ */
+#define EV7_MASK40(addr)        ((addr) & ((1UL << 41) - 1))
+#define EV7_KERN_ADDR(addr)	((void *)(IDENT_ADDR | EV7_MASK40(addr)))
+
+#define EV7_PE_MASK		0x1ffUL /* 9 bits ( 256 + mem/io ) */
+#define EV7_IPE(pe)		((~((long)(pe)) & EV7_PE_MASK) << 35)
+
+#define EV7_CSR_PHYS(pe, off)	(EV7_IPE(pe) | (0x7FFCUL << 20) | (off))
+#define EV7_CSRS_PHYS(pe)	(EV7_CSR_PHYS(pe, 0UL))
+
+#define EV7_CSR_KERN(pe, off)	(EV7_KERN_ADDR(EV7_CSR_PHYS(pe, off)))
+#define EV7_CSRS_KERN(pe)	(EV7_KERN_ADDR(EV7_CSRS_PHYS(pe)))
+
+#define EV7_CSR_OFFSET(name)	((unsigned long)&((ev7_csrs *)NULL)->name.csr)
+
+/*
+ * IO7 registers
+ */
+typedef struct {
+	volatile unsigned long csr __attribute__((aligned(64)));
+} io7_csr;
+
+typedef struct {
+	/* I/O Port Control Registers */
+	io7_csr	POx_CTRL;	       	/* 0x0000 */
+	io7_csr	POx_CACHE_CTL;
+	io7_csr POx_TIMER;
+	io7_csr POx_IO_ADR_EXT;
+	io7_csr	POx_MEM_ADR_EXT;	/* 0x0100 */
+	io7_csr POx_XCAL_CTRL;
+	io7_csr rsvd1[2];	/* ?? spec doesn't show 0x180 */
+	io7_csr POx_DM_SOURCE;		/* ox0200 */
+	io7_csr POx_DM_DEST;
+	io7_csr POx_DM_SIZE;
+	io7_csr POx_DM_STATE;
+	io7_csr rsvd2[4];		/* 0x0300 */
+
+	/* AGP Control Registers -- port 3 only */
+	io7_csr AGP_CAP_ID;		/* 0x0400 */
+	io7_csr AGP_STAT;
+	io7_csr	AGP_CMD;
+	io7_csr	rsvd3;
+
+	/* I/O Port Monitor Registers */
+	io7_csr	POx_MONCTL;		/* 0x0500 */
+	io7_csr POx_CTRA;
+	io7_csr POx_CTRB;
+	io7_csr POx_CTR56;
+	io7_csr POx_SCRATCH;		/* 0x0600 */
+	io7_csr POx_XTRA_A;
+	io7_csr POx_XTRA_TS;
+	io7_csr POx_XTRA_Z;
+	io7_csr rsvd4;			/* 0x0700 */
+	io7_csr POx_THRESHA;
+	io7_csr POx_THRESHB;
+	io7_csr rsvd5[33];
+
+	/* System Address Space Window Control Registers */
+
+	io7_csr POx_WBASE[4];		/* 0x1000 */
+	io7_csr POx_WMASK[4];
+	io7_csr POx_TBASE[4];
+	io7_csr POx_SG_TBIA;
+	io7_csr POx_MSI_WBASE;
+	io7_csr rsvd6[50];
+
+	/* I/O Port Error Registers */
+	io7_csr POx_ERR_SUM;
+	io7_csr POx_FIRST_ERR;
+	io7_csr POx_MSK_HEI;
+	io7_csr POx_TLB_ERR;
+	io7_csr POx_SPL_COMPLT;
+	io7_csr POx_TRANS_SUM;
+	io7_csr POx_FRC_PCI_ERR;
+	io7_csr POx_MULT_ERR;
+	io7_csr rsvd7[8];
+
+	/* I/O Port End of Interrupt Registers */
+	io7_csr EOI_DAT;
+	io7_csr rsvd8[7];
+	io7_csr POx_IACK_SPECIAL;
+	io7_csr rsvd9[103];
+} io7_ioport_csrs;
+
+typedef struct {
+	io7_csr IO_ASIC_REV;		/* 0x30.0000 */
+	io7_csr IO_SYS_REV;
+	io7_csr SER_CHAIN3;
+	io7_csr PO7_RST1;
+	io7_csr PO7_RST2;		/* 0x30.0100 */
+	io7_csr POx_RST[4];
+	io7_csr IO7_DWNH;
+	io7_csr IO7_MAF;
+	io7_csr IO7_MAF_TO;
+	io7_csr IO7_ACC_CLUMP;		/* 0x30.0300 */
+	io7_csr IO7_PMASK;
+	io7_csr IO7_IOMASK;
+	io7_csr IO7_UPH;
+	io7_csr IO7_UPH_TO;		/* 0x30.0400 */
+	io7_csr RBX_IREQ_OFF;
+	io7_csr RBX_INTA_OFF;
+	io7_csr INT_RTY;
+	io7_csr PO7_MONCTL;		/* 0x30.0500 */
+	io7_csr PO7_CTRA;
+	io7_csr PO7_CTRB;
+	io7_csr PO7_CTR56;
+	io7_csr PO7_SCRATCH;		/* 0x30.0600 */
+	io7_csr PO7_XTRA_A;
+	io7_csr PO7_XTRA_TS;
+	io7_csr PO7_XTRA_Z;
+	io7_csr PO7_PMASK;		/* 0x30.0700 */
+	io7_csr PO7_THRESHA;
+	io7_csr PO7_THRESHB;
+	io7_csr rsvd1[97];
+	io7_csr PO7_ERROR_SUM;		/* 0x30.2000 */
+	io7_csr PO7_BHOLE_MASK;
+	io7_csr PO7_HEI_MSK;
+	io7_csr PO7_CRD_MSK;
+	io7_csr PO7_UNCRR_SYM;		/* 0x30.2100 */
+	io7_csr PO7_CRRCT_SYM;
+	io7_csr PO7_ERR_PKT[2];
+	io7_csr PO7_UGBGE_SYM;		/* 0x30.2200 */
+	io7_csr rsbv2[887];
+	io7_csr PO7_LSI_CTL[128];	/* 0x31.0000 */
+	io7_csr rsvd3[123];
+	io7_csr HLT_CTL;		/* 0x31.3ec0 */
+	io7_csr HPI_CTL;		/* 0x31.3f00 */
+	io7_csr CRD_CTL;
+	io7_csr STV_CTL;
+	io7_csr HEI_CTL;
+	io7_csr PO7_MSI_CTL[16];	/* 0x31.4000 */
+	io7_csr rsvd4[240];
+
+	/*
+	 * Interrupt Diagnostic / Test
+	 */
+	struct {
+		io7_csr INT_PND;
+		io7_csr INT_CLR;
+		io7_csr INT_EOI;
+		io7_csr rsvd[29];
+	} INT_DIAG[4];
+	io7_csr rsvd5[125];	    	/* 0x31.a000 */
+	io7_csr MISC_PND;		/* 0x31.b800 */
+	io7_csr rsvd6[31];
+	io7_csr MSI_PND[16];		/* 0x31.c000 */
+	io7_csr rsvd7[16];
+	io7_csr MSI_CLR[16];		/* 0x31.c800 */
+} io7_port7_csrs;
+
+/* 
+ * IO7 DMA Window Base register (POx_WBASEx)
+ */
+#define wbase_m_ena  0x1
+#define wbase_m_sg   0x2
+#define wbase_m_dac  0x4
+#define wbase_m_addr 0xFFF00000
+union IO7_POx_WBASE {
+	struct {
+		unsigned ena : 1;	/* <0>			*/
+		unsigned sg : 1;	/* <1>			*/
+		unsigned dac : 1;	/* <2> -- window 3 only */
+		unsigned rsvd1 : 17; 
+		unsigned addr : 12;	/* <31:20>		*/
+		unsigned rsvd2 : 32;
+	} bits;
+	unsigned as_long[2];
+	unsigned as_quad;
+};
+
+/*
+ * IO7 IID (Interrupt IDentifier) format
+ *
+ * For level-sensative interupts, int_num is encoded as:
+ *
+ *	bus/port	slot/device	INTx
+ *	<7:5>		<4:2>		<1:0>
+ */
+union IO7_IID {
+	struct {
+		unsigned int_num : 9;		/* <8:0>    	*/
+		unsigned tpu_mask : 4;		/* <12:9> rsvd	*/
+		unsigned msi : 1;		/* 13		*/
+		unsigned ipe : 10;		/* <23:14>	*/
+		unsigned long rsvd : 40;		
+	} bits;
+	unsigned int as_long[2];
+	unsigned long as_quad;
+};
+
+/*
+ * IO7 addressing macros
+ */
+#define IO7_KERN_ADDR(addr)	(EV7_KERN_ADDR(addr))
+
+#define IO7_PORT_MASK	   	0x07UL	/* 3 bits of port 	   */
+
+#define IO7_IPE(pe)		(EV7_IPE(pe))
+#define IO7_IPORT(port)		((~((long)(port)) & IO7_PORT_MASK) << 32)
+
+#define IO7_HOSE(pe, port)	(IO7_IPE(pe) | IO7_IPORT(port))
+
+#define IO7_MEM_PHYS(pe, port)	(IO7_HOSE(pe, port) | 0x00000000UL)
+#define IO7_CONF_PHYS(pe, port)	(IO7_HOSE(pe, port) | 0xFE000000UL)
+#define IO7_IO_PHYS(pe, port)	(IO7_HOSE(pe, port) | 0xFF000000UL)
+#define IO7_CSR_PHYS(pe, port, off) \
+                                (IO7_HOSE(pe, port) | 0xFF800000UL | (off))
+#define IO7_CSRS_PHYS(pe, port)	(IO7_CSR_PHYS(pe, port, 0UL))
+#define IO7_PORT7_CSRS_PHYS(pe) (IO7_CSR_PHYS(pe, 7, 0x300000UL))
+
+#define IO7_MEM_KERN(pe, port)      (IO7_KERN_ADDR(IO7_MEM_PHYS(pe, port)))
+#define IO7_CONF_KERN(pe, port)     (IO7_KERN_ADDR(IO7_CONF_PHYS(pe, port)))
+#define IO7_IO_KERN(pe, port)       (IO7_KERN_ADDR(IO7_IO_PHYS(pe, port)))
+#define IO7_CSR_KERN(pe, port, off) (IO7_KERN_ADDR(IO7_CSR_PHYS(pe,port,off)))
+#define IO7_CSRS_KERN(pe, port)     (IO7_KERN_ADDR(IO7_CSRS_PHYS(pe, port)))
+#define IO7_PORT7_CSRS_KERN(pe)	    (IO7_KERN_ADDR(IO7_PORT7_CSRS_PHYS(pe)))
+
+#define IO7_PLL_RNGA(pll)	(((pll) >> 3) & 0x7)
+#define IO7_PLL_RNGB(pll)	(((pll) >> 6) & 0x7)
+
+#define IO7_MEM_SPACE		(2UL * 1024 * 1024 * 1024)	/* 2GB MEM */
+#define IO7_IO_SPACE		(8UL * 1024 * 1024)		/* 8MB I/O */
+
+ 
+/* 
+ * Offset between ram physical addresses and pci64 DAC addresses
+ */
+#define IO7_DAC_OFFSET		(1UL << 49)
+
+/*
+ * This is needed to satisify the IO() macro used in initializing the machvec
+ */
+#define MARVEL_IACK_SC 							\
+        ((unsigned long)						\
+	 (&(((io7_ioport_csrs *)IO7_CSRS_KERN(0, 0))->POx_IACK_SPECIAL)))
+
+#ifdef __KERNEL__
+
+/*
+ * IO7 structs
+ */
+#define IO7_NUM_PORTS 4
+#define IO7_AGP_PORT  3
+
+struct io7_port {
+	struct io7 *io7;
+	struct pci_controller *hose;
+
+	int enabled;
+	unsigned int port;
+	io7_ioport_csrs *csrs;
+
+	unsigned long saved_wbase[4];
+	unsigned long saved_wmask[4];
+	unsigned long saved_tbase[4];
+};
+
+struct io7 {
+	struct io7 *next;
+
+	unsigned int pe;
+	io7_port7_csrs *csrs;
+	struct io7_port ports[IO7_NUM_PORTS];
+
+	spinlock_t irq_lock;
+};
+
+#ifndef __EXTERN_INLINE
+# define __EXTERN_INLINE extern inline
+# define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * I/O functions. All access through linear space.
+ */
+
+#define vucp	volatile unsigned char *
+#define vusp	volatile unsigned short *
+#define vuip	volatile unsigned int *
+#define vulp	volatile unsigned long *
+
+#ifdef CONFIG_VGA_HOSE
+extern struct pci_controller *pci_vga_hose;
+
+# define __marvel_is_port_vga(a)	\
+        (((a) >= 0x3b0) && ((a) < 0x3e0) && ((a) != 0x3b3) && ((a) != 0x3d3))
+# define __marvel_is_mem_vga(a)	(((a) >= 0xa0000) && ((a) <= 0xc0000))
+# define FIXUP_IOADDR_VGA(a) do {			\
+	if (pci_vga_hose && __marvel_is_port_vga(a))	\
+		a += pci_vga_hose->io_space->start;	\
+    } while(0)
+#else
+# define FIXUP_IOADDR_VGA(a)
+#endif 
+
+#define __marvel_is_port_kbd(a)	(((a) == 0x60) || ((a) == 0x64))
+#define __marvel_is_port_rtc(a)	(((a) == 0x70) || ((a) == 0x71))
+
+#define FIXUP_IOADDR_LEGACY(a)
+
+#define FIXUP_IOADDR(a) do {				\
+	FIXUP_IOADDR_VGA(a);				\
+        FIXUP_IOADDR_LEGACY(a);				\
+    } while(0)
+
+#if 0
+# define IOBUG(x) printk x
+# define IOBUG_FILTER_IOADDR(a, x)	\
+    if (!__marvel_is_port_kbd(a) && !__marvel_is_port_rtc(a)) IOBUG(x)
+#else
+# define IOBUG(x)
+# define IOBUG_FILTER_IOADDR(a, x)
+#endif
+
+extern u8 __marvel_rtc_io(int write, u8 b, unsigned long addr);
+#define __marvel_rtc_inb(a)	__marvel_rtc_io(0, 0, (a))
+#define __marvel_rtc_outb(b, a)	__marvel_rtc_io(1, (b), (a))
+
+__EXTERN_INLINE int marvel_is_ioaddr(unsigned long addr)
+{
+	return (addr & (1UL << 40)) != 0; /*FIXME - hardwire*/
+}
+
+__EXTERN_INLINE u8 marvel_inb(unsigned long addr)
+{
+	FIXUP_IOADDR(addr);
+	if (!marvel_is_ioaddr(addr)) {
+		if (__marvel_is_port_kbd(addr))
+			return (u8)0;
+		if (__marvel_is_port_rtc(addr))
+			return __marvel_rtc_inb(addr);
+		IOBUG_FILTER_IOADDR(addr, 
+				    ("Bad IO addr %lx - reading -1\n", addr));
+		return (u8)-1;
+	}
+	return __kernel_ldbu(*(vucp)addr);
+}
+
+__EXTERN_INLINE void marvel_outb(u8 b, unsigned long addr)
+{
+	FIXUP_IOADDR(addr);
+	if (!marvel_is_ioaddr(addr)) {
+		if (__marvel_is_port_rtc(addr)) 
+			return (void)__marvel_rtc_outb(b, addr);
+		IOBUG_FILTER_IOADDR(addr, 
+				    ("Bad IO addr %lx - reading -1\n", addr));
+		return;
+	}
+	__kernel_stb(b, *(vucp)addr);
+	mb();
+}
+
+__EXTERN_INLINE u16 marvel_inw(unsigned long addr)
+{
+	FIXUP_IOADDR(addr);
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG_FILTER_IOADDR(addr, 
+				    ("Bad IO addr %lx - reading -1\n", addr));
+		return (u16)-1;
+	}
+	return __kernel_ldwu(*(vusp)addr);
+}
+
+__EXTERN_INLINE void marvel_outw(u16 w, unsigned long addr)
+{
+	FIXUP_IOADDR(addr);
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG_FILTER_IOADDR(addr, 
+				    ("Bad IO addr %lx - reading -1\n", addr));
+		return;
+	}
+	__kernel_stw(w, *(vusp)addr);
+	mb();
+}
+
+__EXTERN_INLINE u32 marvel_inl(unsigned long addr)
+{
+	FIXUP_IOADDR(addr);
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG_FILTER_IOADDR(addr, 
+				    ("Bad IO addr %lx - reading -1\n", addr));
+		return (u32)-1;
+	}
+	return *(vuip)addr;
+}
+
+__EXTERN_INLINE void marvel_outl(u32 l, unsigned long addr)
+{
+	FIXUP_IOADDR(addr);
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG_FILTER_IOADDR(addr, 
+				    ("Bad IO addr %lx - reading -1\n", addr));
+		return;
+	}
+	*(vuip)addr = l;
+	mb();
+}
+
+/*
+ * Memory functions.  All accesses through linear space.
+ */
+
+extern unsigned long marvel_ioremap(unsigned long addr, unsigned long size);
+extern void marvel_iounmap(unsigned long addr);
+
+__EXTERN_INLINE u8 marvel_readb(unsigned long addr)
+{
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG(("Bad MEM addr %lx - reading -1\n", addr));
+		return (u8)-1;
+	}
+	return __kernel_ldbu(*(vucp)addr);
+}
+
+__EXTERN_INLINE u16 marvel_readw(unsigned long addr)
+{
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG(("Bad MEM addr %lx - reading -1\n", addr));
+		return (u16)-1;
+	}
+	return __kernel_ldwu(*(vusp)addr);
+}
+
+__EXTERN_INLINE u32 marvel_readl(unsigned long addr)
+{
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG(("Bad MEM addr %lx - reading -1\n", addr));
+		return (u32)-1;
+	}
+	return *(vuip)addr;
+}
+
+__EXTERN_INLINE u64 marvel_readq(unsigned long addr)
+{
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG(("Bad MEM addr %lx - reading -1\n", addr));
+		return (u64)-1;
+	}
+	return *(vulp)addr;
+}
+
+__EXTERN_INLINE void marvel_writeb(u8 b, unsigned long addr)
+{
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG(("Bad MEM addr %lx - dropping store\n", addr));
+		return;
+	}
+	__kernel_stb(b, *(vucp)addr);
+}
+
+__EXTERN_INLINE void marvel_writew(u16 w, unsigned long addr)
+{
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG(("Bad MEM addr %lx - dropping store\n", addr));
+		return;
+	}
+	__kernel_stw(w, *(vusp)addr);
+}
+
+__EXTERN_INLINE void marvel_writel(u32 l, unsigned long addr)
+{
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG(("Bad MEM addr %lx - dropping store\n", addr));
+		return;
+	}
+	*(vuip)addr = l;
+}
+
+__EXTERN_INLINE void marvel_writeq(u64 q, unsigned long addr)
+{
+	if (!marvel_is_ioaddr(addr)) {
+		IOBUG(("Bad MEM addr %lx - dropping store\n", addr));
+		return;
+	}
+	*(vulp)addr = q;
+}
+
+#undef FIXUP_IOADDR
+#undef FIXUP_IOADDR_LEGACY
+#undef FIXUP_IOADDR_VGA
+
+#undef vucp
+#undef vusp
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#define __inb(p)		marvel_inb((unsigned long)(p))
+#define __inw(p)		marvel_inw((unsigned long)(p))
+#define __inl(p)		marvel_inl((unsigned long)(p))
+#define __outb(x,p)		marvel_outb((x),(unsigned long)(p))
+#define __outw(x,p)		marvel_outw((x),(unsigned long)(p))
+#define __outl(x,p)		marvel_outl((x),(unsigned long)(p))
+#define __readb(a)		marvel_readb((unsigned long)(a))
+#define __readw(a)		marvel_readw((unsigned long)(a))
+#define __readl(a)		marvel_readl((unsigned long)(a))
+#define __readq(a)		marvel_readq((unsigned long)(a))
+#define __writeb(x,a)		marvel_writeb((x),(unsigned long)(a))
+#define __writew(x,a)		marvel_writew((x),(unsigned long)(a))
+#define __writel(x,a)		marvel_writel((x),(unsigned long)(a))
+#define __writeq(x,a)		marvel_writeq((x),(unsigned long)(a))
+#define __ioremap(a,s)		marvel_ioremap((unsigned long)(a),(s))
+#define __iounmap(a)		marvel_iounmap((unsigned long)(a))
+#define __is_ioaddr(a)		marvel_is_ioaddr((unsigned long)(a))
+
+/* Disable direct inlining of these calls with the debug checks present.  */
+#if 0
+#define __raw_readb(a)		__readb(a)
+#define __raw_readw(a)		__readw(a)
+#define __raw_readl(a)		__readl(a)
+#define __raw_readq(a)		__readq(a)
+#define __raw_writeb(v,a)	__writeb(v,a)
+#define __raw_writew(v,a)	__writew(v,a)
+#define __raw_writel(v,a)	__writel(v,a)
+#define __raw_writeq(v,a)	__writeq(v,a)
+#endif
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+# undef __EXTERN_INLINE
+# undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_MARVEL__H__ */
diff -Nru a/include/asm-alpha/core_titan.h b/include/asm-alpha/core_titan.h
--- a/include/asm-alpha/core_titan.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-alpha/core_titan.h	Thu Jan 16 18:23:06 2003
@@ -2,6 +2,7 @@
 #define __ALPHA_TITAN__H__
 
 #include <linux/types.h>
+#include <linux/pci.h>
 #include <asm/compiler.h>
 
 /*
@@ -293,13 +294,15 @@
  * 		2 - pachip 0 / A Port
  *      	3 - pachip 1 / A Port
  */
-#define TITAN_HOSE(h)		(((unsigned long)(h)) << 33)
+#define TITAN_HOSE_SHIFT       (33) 
+#define TITAN_HOSE(h)		(((unsigned long)(h)) << TITAN_HOSE_SHIFT)
 #define TITAN_BASE		(IDENT_ADDR + TI_BIAS)
 #define TITAN_MEM(h)	     	(TITAN_BASE+TITAN_HOSE(h)+0x000000000UL)
 #define _TITAN_IACK_SC(h)    	(TITAN_BASE+TITAN_HOSE(h)+0x1F8000000UL)
 #define TITAN_IO(h)	     	(TITAN_BASE+TITAN_HOSE(h)+0x1FC000000UL)
 #define TITAN_CONF(h)	     	(TITAN_BASE+TITAN_HOSE(h)+0x1FE000000UL)
 
+#define TITAN_HOSE_MASK		TITAN_HOSE(3)
 #define TITAN_IACK_SC	     	_TITAN_IACK_SC(0) /* hack! */
 
 /* 
@@ -427,17 +430,8 @@
  * Memory functions.  all accesses are done through linear space.
  */
 
-__EXTERN_INLINE unsigned long titan_ioremap(unsigned long addr, 
-					    unsigned long size
-					    __attribute__((unused)))
-{
-	return addr + TITAN_MEM_BIAS;
-}
-
-__EXTERN_INLINE void titan_iounmap(unsigned long addr)
-{
-	return;
-}
+extern unsigned long titan_ioremap(unsigned long addr, unsigned long size);
+extern void titan_iounmap(unsigned long addr);
 
 __EXTERN_INLINE int titan_is_ioaddr(unsigned long addr)
 {
diff -Nru a/include/asm-alpha/gct.h b/include/asm-alpha/gct.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-alpha/gct.h	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,58 @@
+#ifndef __ALPHA_GCT_H
+#define __ALPHA_GCT_H
+
+typedef u64 gct_id;
+typedef u64 gct6_handle;
+
+typedef struct __gct6_node {
+	u8 type;	
+	u8 subtype;
+	u16 size;
+	u32 hd_extension;
+	gct6_handle owner;
+	gct6_handle active_user;
+	gct_id id;
+	u64 flags;
+	u16 rev;
+	u16 change_counter;
+	u16 max_child;
+	u16 reserved1;
+	gct6_handle saved_owner;
+	gct6_handle affinity;
+	gct6_handle parent;
+	gct6_handle next;
+	gct6_handle prev;
+	gct6_handle child;
+	u64 fw_flags;
+	u64 os_usage;
+	u64 fru_id;
+	u32 checksum;
+	u32 magic;	/* 'GLXY' */
+} gct6_node;
+
+typedef struct {
+	u8 type;	
+	u8 subtype;
+	void (*callout)(gct6_node *);
+} gct6_search_struct;
+
+#define GCT_NODE_MAGIC	  0x59584c47	/* 'GLXY' */
+
+/* 
+ * node types 
+ */
+#define GCT_TYPE_HOSE			0x0E
+
+/*
+ * node subtypes
+ */
+#define GCT_SUBTYPE_IO_PORT_MODULE	0x2C
+
+#define GCT_NODE_PTR(off) ((gct6_node *)((char *)hwrpb + 		\
+					 hwrpb->frut_offset + 		\
+					 (gct6_handle)(off)))		\
+
+int gct6_find_nodes(gct6_node *, gct6_search_struct *);
+
+#endif /* __ALPHA_GCT_H */
+
diff -Nru a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h
--- a/include/asm-alpha/hardirq.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-alpha/hardirq.h	Thu Jan 16 18:23:06 2003
@@ -55,10 +55,12 @@
 
 /*
  * The hardirq mask has to be large enough to have
- * space for potentially all IRQ sources in the system
- * nesting on a single CPU:
+ * space for potentially nestable IRQ sources in the system
+ * to nest on a single CPU. On Alpha, interrupts are masked at the CPU
+ * by IPL as well as at the system level. We only have 8 IPLs (UNIX PALcode)
+ * so we really only have 8 nestable IRQs, but allow some overhead
  */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
+#if (1 << HARDIRQ_BITS) < 16
 #error HARDIRQ_BITS is too low!
 #endif
 
diff -Nru a/include/asm-alpha/hwrpb.h b/include/asm-alpha/hwrpb.h
--- a/include/asm-alpha/hwrpb.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-alpha/hwrpb.h	Thu Jan 16 18:23:05 2003
@@ -64,6 +64,7 @@
 #define ST_DEC_CUSCO		 36	/* CUSCO systype	*/
 #define ST_DEC_EIGER		 37	/* Eiger systype	*/
 #define ST_DEC_TITAN		 38	/* Titan systype	*/
+#define ST_DEC_MARVEL		 39	/* Marvel systype	*/
 
 /* UNOFFICIAL!!! */
 #define ST_UNOFFICIAL_BIAS	100
diff -Nru a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h
--- a/include/asm-alpha/ide.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-alpha/ide.h	Thu Jan 16 18:23:06 2003
@@ -16,7 +16,7 @@
 #include <linux/config.h>
 
 #ifndef MAX_HWIFS
-#define MAX_HWIFS	4
+#define MAX_HWIFS	CONFIG_IDE_MAX_HWIFS
 #endif
 
 static __inline__ int ide_default_irq(ide_ioreg_t base)
diff -Nru a/include/asm-alpha/io.h b/include/asm-alpha/io.h
--- a/include/asm-alpha/io.h	Thu Jan 16 18:23:07 2003
+++ b/include/asm-alpha/io.h	Thu Jan 16 18:23:07 2003
@@ -20,6 +20,7 @@
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/machvec.h>
+#include <asm/hwrpb.h>
 
 /*
  * We try to avoid hae updates (thus the cache), but when we
@@ -51,6 +52,7 @@
 /*
  * Change virtual addresses to physical addresses and vv.
  */
+#ifdef USE_48_BIT_KSEG
 static inline unsigned long virt_to_phys(void *address)
 {
 	return (unsigned long)address - IDENT_ADDR;
@@ -60,8 +62,28 @@
 {
 	return (void *) (address + IDENT_ADDR);
 }
+#else
+static inline unsigned long virt_to_phys(void *address)
+{
+        unsigned long phys = (unsigned long)address;
+
+	/* Sign-extend from bit 41.  */
+	phys <<= (64 - 41);
+	phys = (long)phys >> (64 - 41);
+
+	/* Crop to the physical address width of the processor.  */
+        phys &= (1ul << hwrpb->pa_bits) - 1;
+
+        return phys;
+}
+
+static inline void * phys_to_virt(unsigned long address)
+{
+        return (void *)(IDENT_ADDR + (address & ((1ul << 41) - 1)));
+}
+#endif
 
-#define page_to_phys(page)	PAGE_TO_PA(page)
+#define page_to_phys(page)	page_to_pa(page)
 
 /* This depends on working iommu.  */
 #define BIO_VMERGE_BOUNDARY	(alpha_mv.mv_pci_tbi ? PAGE_SIZE : 0)
@@ -168,6 +190,8 @@
 # include <asm/jensen.h>
 #elif defined(CONFIG_ALPHA_LCA)
 # include <asm/core_lca.h>
+#elif defined(CONFIG_ALPHA_MARVEL)
+# include <asm/core_marvel.h>
 #elif defined(CONFIG_ALPHA_MCPCIA)
 # include <asm/core_mcpcia.h>
 #elif defined(CONFIG_ALPHA_POLARIS)
diff -Nru a/include/asm-alpha/irq.h b/include/asm-alpha/irq.h
--- a/include/asm-alpha/irq.h	Thu Jan 16 18:23:07 2003
+++ b/include/asm-alpha/irq.h	Thu Jan 16 18:23:07 2003
@@ -16,7 +16,7 @@
    many places throughout the kernel to size static arrays.  That's ok,
    we'll use alpha_mv.nr_irqs when we want the real thing.  */
 
-# define NR_IRQS	2048 /* enuff for WILDFIRE with 8 QBBs */
+# define NR_IRQS	(32768 + 16) 	/* marvel - 32 pids*/
 
 #elif defined(CONFIG_ALPHA_CABRIOLET) || \
       defined(CONFIG_ALPHA_EB66P)     || \
@@ -55,6 +55,9 @@
 
 #elif defined(CONFIG_ALPHA_WILDFIRE)
 # define NR_IRQS	2048 /* enuff for 8 QBBs */
+
+#elif defined(CONFIG_ALPHA_MARVEL)
+# define NR_IRQS	(32768 + 16) 	/* marvel - 32 pids*/
 
 #else /* everyone else */
 # define NR_IRQS	16
diff -Nru a/include/asm-alpha/machvec.h b/include/asm-alpha/machvec.h
--- a/include/asm-alpha/machvec.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-alpha/machvec.h	Thu Jan 16 18:23:05 2003
@@ -22,6 +22,7 @@
 struct pci_dev;
 struct pci_ops;
 struct pci_controller;
+struct _alpha_agp_info;
 
 struct alpha_machine_vector
 {
@@ -80,6 +81,7 @@
 	void (*device_interrupt)(unsigned long vector, struct pt_regs *regs);
 	void (*machine_check)(u64 vector, u64 la, struct pt_regs *regs);
 
+	void (*smp_callin)(void);
 	void (*init_arch)(void);
 	void (*init_irq)(void);
 	void (*init_rtc)(void);
@@ -90,7 +92,15 @@
 	int (*pci_map_irq)(struct pci_dev *, u8, u8);
 	struct pci_ops *pci_ops;
 
+	struct _alpha_agp_info *(*agp_info)(void);
+
 	const char *vector_name;
+
+	/* NUMA information */
+	int (*pa_to_nid)(unsigned long);
+	int (*cpuid_to_nid)(int);
+	unsigned long (*node_mem_start)(int);
+	unsigned long (*node_mem_size)(int);
 
 	/* System specific parameters.  */
 	union {
diff -Nru a/include/asm-alpha/mmzone.h b/include/asm-alpha/mmzone.h
--- a/include/asm-alpha/mmzone.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-alpha/mmzone.h	Thu Jan 16 18:23:06 2003
@@ -6,25 +6,7 @@
 #define _ASM_MMZONE_H_
 
 #include <linux/config.h>
-#ifdef CONFIG_NUMA_SCHED
-#include <linux/numa_sched.h>
-#endif
-#ifdef NOTYET
-#include <asm/sn/types.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/klkernvars.h>
-#endif /* NOTYET */
-
-typedef struct plat_pglist_data {
-	pg_data_t	gendata;
-#ifdef NOTYET
-	kern_vars_t	kern_vars;
-#endif
-#if defined(CONFIG_NUMA) && defined(CONFIG_NUMA_SCHED)
-	struct numa_schedule_data schedule_data;
-#endif
-} plat_pg_data_t;
+#include <asm/smp.h>
 
 struct bootmem_data_t; /* stupid forward decl. */
 
@@ -32,19 +14,26 @@
  * Following are macros that are specific to this numa platform.
  */
 
-extern plat_pg_data_t *plat_node_data[];
+extern pg_data_t node_data[];
 
-#ifdef CONFIG_ALPHA_WILDFIRE
-# define ALPHA_PA_TO_NID(pa)	((pa) >> 36)	/* 16 nodes max due 43bit kseg */
-# define NODE_MAX_MEM_SIZE	(64L * 1024L * 1024L * 1024L) /* 64 GB */
-#else
-# define ALPHA_PA_TO_NID(pa)	(0)
-# define NODE_MAX_MEM_SIZE	(~0UL)
-#endif
+#define alpha_pa_to_nid(pa)		\
+        (alpha_mv.pa_to_nid 		\
+	 ? alpha_mv.pa_to_nid(pa)	\
+	 : (0))
+#define node_mem_start(nid)		\
+        (alpha_mv.node_mem_start 	\
+	 ? alpha_mv.node_mem_start(nid) \
+	 : (0UL))
+#define node_mem_size(nid)		\
+        (alpha_mv.node_mem_size 	\
+	 ? alpha_mv.node_mem_size(nid) 	\
+	 : ((nid) ? (0UL) : (~0UL)))
+
+#define pa_to_nid(pa)		alpha_pa_to_nid(pa)
+#define NODE_DATA(nid)		(&node_data[(nid)])
+#define node_size(nid)		(NODE_DATA(nid)->node_size)
 
-#define PHYSADDR_TO_NID(pa)		ALPHA_PA_TO_NID(pa)
-#define PLAT_NODE_DATA(n)		(plat_node_data[(n)])
-#define PLAT_NODE_DATA_SIZE(n)		(PLAT_NODE_DATA(n)->gendata.node_size)
+#define node_localnr(pfn, nid)	((pfn) - NODE_DATA(nid)->node_start_pfn)
 
 #if 1
 #define PLAT_NODE_DATA_LOCALNR(p, n)	\
@@ -68,46 +57,76 @@
 /*
  * Given a kernel address, find the home node of the underlying memory.
  */
-#define KVADDR_TO_NID(kaddr)	PHYSADDR_TO_NID(__pa(kaddr))
+#define kvaddr_to_nid(kaddr)	pa_to_nid(__pa(kaddr))
+#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
+#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 
-/*
- * Return a pointer to the node data for node n.
- */
-#define NODE_DATA(n)	(&((PLAT_NODE_DATA(n))->gendata))
-
-/*
- * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
- */
-#define NODE_MEM_MAP(nid)	(NODE_DATA(nid)->node_mem_map)
-
-/*
- * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
- * and returns the mem_map of that node.
- */
-#define ADDR_TO_MAPBASE(kaddr) \
-			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
+#define local_mapnr(kvaddr) \
+      ((__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)))
 
 /*
  * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
  * and returns the kaddr corresponding to first physical page in the
  * node's mem_map.
  */
-#define LOCAL_BASE_ADDR(kaddr)	((unsigned long)__va(NODE_DATA(KVADDR_TO_NID(kaddr))->node_start_pfn << PAGE_SHIFT))
+#define LOCAL_BASE_ADDR(kaddr)						  \
+    ((unsigned long)__va(NODE_DATA(kvaddr_to_nid(kaddr))->node_start_pfn  \
+			 << PAGE_SHIFT))
+
+#define kern_addr_valid(kaddr)						  \
+    test_bit(local_mapnr(kaddr), 					  \
+	     NODE_DATA(kvaddr_to_nid(kaddr))->valid_addr_bitmap)
 
-#define LOCAL_MAP_NR(kvaddr) \
-	(((unsigned long)(kvaddr)-LOCAL_BASE_ADDR(kvaddr)) >> PAGE_SHIFT)
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 
-#define kern_addr_valid(kaddr)	test_bit(LOCAL_MAP_NR(kaddr), \
-					 NODE_DATA(KVADDR_TO_NID(kaddr))->valid_addr_bitmap)
-
-#define virt_to_page(kaddr)	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
 #define VALID_PAGE(page)	(((page) - mem_map) < max_mapnr)
 
-#ifdef CONFIG_NUMA
-#ifdef CONFIG_NUMA_SCHED
-#define NODE_SCHEDULE_DATA(nid)	(&((PLAT_NODE_DATA(nid))->schedule_data))
-#endif
-#endif /* CONFIG_NUMA */
+#define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> 32))
+#define pte_pfn(pte)		(pte_val(pte) >> 32)
+
+#define mk_pte(page, pgprot)						     \
+({								 	     \
+	pte_t pte;                                                           \
+	unsigned long pfn;                                                   \
+									     \
+	pfn = ((unsigned long)((page)-page_zone(page)->zone_mem_map)) << 32; \
+	pfn += page_zone(page)->zone_start_pfn << 32;			     \
+	pte_val(pte) = pfn | pgprot_val(pgprot);			     \
+									     \
+	pte;								     \
+})
+
+#define pte_page(x)							\
+({									\
+       	unsigned long kvirt;						\
+	struct page * __xx;						\
+									\
+	kvirt = (unsigned long)__va(pte_val(x) >> (32-PAGE_SHIFT));	\
+	__xx = virt_to_page(kvirt);					\
+									\
+	__xx;                                                           \
+})
+
+#define pfn_to_page(pfn)						\
+({									\
+ 	unsigned long kaddr = (unsigned long)__va(pfn << PAGE_SHIFT);	\
+	(node_mem_map(kvaddr_to_nid(kaddr)) + local_mapnr(kaddr));	\
+})
+
+#define page_to_pfn(page)						\
+	((page) - page_zone(page)->zone_mem_map +			\
+	 (page_zone(page)->zone_start_pfn))
+
+#define page_to_pa(page)						\
+	((( (page) - page_zone(page)->zone_mem_map )			\
+	+ page_zone(page)->zone_start_pfn) << PAGE_SHIFT)
+
+#define pfn_to_nid(pfn)		pa_to_nid(((u64)pfn << PAGE_SHIFT))
+#define pfn_valid(pfn)							\
+	(((pfn) - node_start_pfn(pfn_to_nid(pfn))) <			\
+	 node_size(pfn_to_nid(pfn)))					\
+
+#define virt_addr_valid(kaddr)	pfn_valid((__pa(kaddr) >> PAGE_SHIFT))
 
 #endif /* CONFIG_DISCONTIGMEM */
 
diff -Nru a/include/asm-alpha/numnodes.h b/include/asm-alpha/numnodes.h
--- a/include/asm-alpha/numnodes.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-alpha/numnodes.h	Thu Jan 16 18:23:05 2003
@@ -1,12 +1,6 @@
 #ifndef _ASM_MAX_NUMNODES_H
 #define _ASM_MAX_NUMNODES_H
 
-/*
- * Currently the Wildfire is the only discontigmem/NUMA capable Alpha core.
- */
-#if defined(CONFIG_ALPHA_WILDFIRE) || defined(CONFIG_ALPHA_GENERIC)
-# include <asm/core_wildfire.h>
-# define MAX_NUMNODES		WILDFIRE_MAX_QBB
-#endif
+#define MAX_NUMNODES		128 /* Marvel */
 
 #endif /* _ASM_MAX_NUMNODES_H */
diff -Nru a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
--- a/include/asm-alpha/pci.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-alpha/pci.h	Thu Jan 16 18:23:05 2003
@@ -42,6 +42,8 @@
 
 	struct pci_iommu_arena *sg_pci;
 	struct pci_iommu_arena *sg_isa;
+
+	void *sysdata;
 };
 
 /* Override the logic in pci_scan_bus for skipping already-configured
diff -Nru a/include/asm-alpha/pgalloc.h b/include/asm-alpha/pgalloc.h
--- a/include/asm-alpha/pgalloc.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-alpha/pgalloc.h	Thu Jan 16 18:23:05 2003
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <linux/mm.h>
+#include <linux/mmzone.h>
 
 /*      
  * Allocate and free page tables. The xxx_kernel() versions are
@@ -13,7 +14,7 @@
 static inline void
 pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
 {
-	pmd_set(pmd, (pte_t *)(((pte - mem_map) << PAGE_SHIFT) + PAGE_OFFSET));
+	pmd_set(pmd, (pte_t *)(page_to_pa(pte) + PAGE_OFFSET));
 }
 
 static inline void
diff -Nru a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
--- a/include/asm-alpha/pgtable.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-alpha/pgtable.h	Thu Jan 16 18:23:05 2003
@@ -192,14 +192,8 @@
  * and a page entry and page directory to the page they refer to.
  */
 #ifndef CONFIG_DISCONTIGMEM
-#define PAGE_TO_PA(page)	((page - mem_map) << PAGE_SHIFT)
-#else
-#define PAGE_TO_PA(page) \
-		((( (page) - (page)->zone->zone_mem_map ) \
-		+ (page)->zone->zone_start_pfn) << PAGE_SHIFT)
-#endif
+#define page_to_pa(page)	((page - mem_map) << PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
 #define pte_pfn(pte)	(pte_val(pte) >> 32)
 #define pte_page(pte)	pfn_to_page(pte_pfn(pte))
 #define mk_pte(page, pgprot)						\
@@ -209,28 +203,6 @@
 	pte_val(pte) = (page_to_pfn(page) << 32) | pgprot_val(pgprot);	\
 	pte;								\
 })
-#else
-#define mk_pte(page, pgprot)							\
-({										\
-	pte_t pte;								\
-	unsigned long pfn;							\
-										\
-	pfn = ((unsigned long)((page)-(page)->zone->zone_mem_map)) << 32;	\
-	pfn += (page)->zone->zone_start_pfn << 32);				\
-	pte_val(pte) = pfn | pgprot_val(pgprot);				\
-										\
-	pte;									\
-})
-#define pte_page(x)							\
-({									\
-	unsigned long kvirt;						\
-	struct page * __xx;						\
-									\
-	kvirt = (unsigned long)__va(pte_val(x) >> (32-PAGE_SHIFT));	\
-	__xx = virt_to_page(kvirt);					\
-									\
-	__xx;								\
-})
 #endif
 
 extern inline pte_t pfn_pte(unsigned long physpfn, pgprot_t pgprot)
@@ -252,7 +224,9 @@
 	return ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT)) + PAGE_OFFSET;
 }
 
+#ifndef CONFIG_DISCONTIGMEM
 #define pmd_page(pmd)	(mem_map + ((pmd_val(pmd) & _PFN_MASK) >> 32))
+#endif
 
 extern inline unsigned long pgd_page(pgd_t pgd)
 { return PAGE_OFFSET + ((pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
diff -Nru a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h
--- a/include/asm-alpha/smp.h	Thu Jan 16 18:23:07 2003
+++ b/include/asm-alpha/smp.h	Thu Jan 16 18:23:07 2003
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <linux/threads.h>
+#include <linux/bitops.h>
 #include <asm/pal.h>
 
 /* HACK: Cabrio WHAMI return value is bogus if more than 8 bits used.. :-( */
@@ -21,7 +22,6 @@
 
 #ifdef CONFIG_SMP
 
-#include <linux/threads.h>
 #include <asm/irq.h>
 
 struct cpuinfo_alpha {
@@ -45,12 +45,17 @@
 #define smp_processor_id()	(current_thread_info()->cpu)
 
 extern unsigned long cpu_present_mask;
+extern volatile unsigned long cpu_online_map;
 extern int smp_num_cpus;
 
-#define cpu_online_map		cpu_present_mask
-#define num_online_cpus()	(smp_num_cpus)
-#define cpu_online(cpu)		(cpu_present_mask & (1<<(cpu)))
-#define cpu_possible(cpu)	cpu_online(cpu)
+#define cpu_possible(cpu)	(cpu_present_mask & (1UL << (cpu)))
+#define cpu_online(cpu)		(cpu_online_map & (1UL << (cpu)))
+
+static inline int
+num_online_cpus(void)
+{
+	return hweight64(cpu_online_map);
+}
 
 extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu);
 
diff -Nru a/include/asm-alpha/system.h b/include/asm-alpha/system.h
--- a/include/asm-alpha/system.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-alpha/system.h	Thu Jan 16 18:23:06 2003
@@ -23,7 +23,7 @@
 #ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
 #define KERNEL_START_PHYS	0x300000 /* Old bootloaders hardcoded this.  */
 #else
-#define KERNEL_START_PHYS	0x800000 /* Wildfire has a huge console */
+#define KERNEL_START_PHYS	0x1000000 /* required: Wildfire/Titan/Marvel */
 #endif
 
 #define KERNEL_START	(PAGE_OFFSET+KERNEL_START_PHYS)
diff -Nru a/include/asm-alpha/topology.h b/include/asm-alpha/topology.h
--- a/include/asm-alpha/topology.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-alpha/topology.h	Thu Jan 16 18:23:05 2003
@@ -1,15 +1,50 @@
 #ifndef _ASM_ALPHA_TOPOLOGY_H
 #define _ASM_ALPHA_TOPOLOGY_H
 
-#if defined(CONFIG_NUMA) && defined(CONFIG_ALPHA_WILDFIRE)
+#include <linux/smp.h>
+#include <linux/threads.h>
+#include <asm/machvec.h>
 
-/* With wildfire assume 4 CPUs per node */
-#define __cpu_to_node(cpu)		((cpu) >> 2)
+#ifdef CONFIG_NUMA
+static inline int __cpu_to_node(int cpu)
+{
+	int node;
+	
+	if (!alpha_mv.cpuid_to_nid)
+		return 0;
 
-#else /* !CONFIG_NUMA || !CONFIG_ALPHA_WILDFIRE */
+	node = alpha_mv.cpuid_to_nid(cpu);
 
-#include <asm-generic/topology.h>
+#ifdef DEBUG_NUMA
+	if (node < 0)
+		BUG();
+#endif
 
-#endif /* CONFIG_NUMA && CONFIG_ALPHA_WILDFIRE */
+	return node;
+}
+
+static inline int __node_to_cpu_mask(int node)
+{
+	unsigned long node_cpu_mask = 0;
+	int cpu;
+
+	for(cpu = 0; cpu < NR_CPUS; cpu++) {
+		if (cpu_online(cpu) && (__cpu_to_node(cpu) == node))
+			node_cpu_mask |= 1UL << cpu;
+	}
+
+#if DEBUG_NUMA
+	printk("node %d: cpu_mask: %016lx\n", node, node_cpu_mask);
+#endif
+
+	return node_cpu_mask;
+}
+
+# define __node_to_memblk(node)		(node)
+# define __memblk_to_node(memblk)	(memblk)
+
+#else /* CONFIG_NUMA */
+# include <asm-generic/topology.h>
+#endif /* !CONFIG_NUMA */
 
 #endif /* _ASM_ALPHA_TOPOLOGY_H */
diff -Nru a/include/asm-arm/arch-integrator/memory.h b/include/asm-arm/arch-integrator/memory.h
--- a/include/asm-arm/arch-integrator/memory.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-arm/arch-integrator/memory.h	Thu Jan 16 18:23:05 2003
@@ -46,6 +46,8 @@
 #define __phys_to_virt__is_a_macro
 #define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
 
+#define BUS_OFFSET	(0x80000000UL)
+
 /*
  * Virtual view <-> DMA view memory address translations
  * virt_to_bus: Used to translate the virtual address to an
@@ -54,8 +56,8 @@
  *              to an address that the kernel can use.
  */
 #define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)	(x - PAGE_OFFSET + INTEGRATOR_HDR0_SDRAM_BASE)
+#define __virt_to_bus(x)	(x - PAGE_OFFSET + BUS_OFFSET)
 #define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)	(x - INTEGRATOR_HDR0_SDRAM_BASE + PAGE_OFFSET)
+#define __bus_to_virt(x)	(x - BUS_OFFSET + PAGE_OFFSET)
 
 #endif
diff -Nru a/include/asm-arm/ide.h b/include/asm-arm/ide.h
--- a/include/asm-arm/ide.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-arm/ide.h	Thu Jan 16 18:23:05 2003
@@ -36,8 +36,6 @@
  * The following are not needed for the non-m68k ports
  */
 #define ide_ack_intr(hwif)		(1)
-#define ide_release_lock(lock)		do {} while (0)
-#define ide_get_lock(lock, hdlr, data)	do {} while (0)
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
--- a/include/asm-arm/unistd.h	Thu Jan 16 18:23:07 2003
+++ b/include/asm-arm/unistd.h	Thu Jan 16 18:23:07 2003
@@ -1,7 +1,7 @@
 /*
  *  linux/include/asm-arm/unistd.h
  *
- *  Copyright (C) 2001 Russell King
+ *  Copyright (C) 2001-2003 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -32,7 +32,7 @@
 #define __NR_write			(__NR_SYSCALL_BASE+  4)
 #define __NR_open			(__NR_SYSCALL_BASE+  5)
 #define __NR_close			(__NR_SYSCALL_BASE+  6)
-#define __NR_waitpid			(__NR_SYSCALL_BASE+  7)
+#define __NR_waitpid			(__NR_SYSCALL_BASE+  7)	/* removed */
 #define __NR_creat			(__NR_SYSCALL_BASE+  8)
 #define __NR_link			(__NR_SYSCALL_BASE+  9)
 #define __NR_unlink			(__NR_SYSCALL_BASE+ 10)
@@ -42,8 +42,8 @@
 #define __NR_mknod			(__NR_SYSCALL_BASE+ 14)
 #define __NR_chmod			(__NR_SYSCALL_BASE+ 15)
 #define __NR_lchown			(__NR_SYSCALL_BASE+ 16)
-#define __NR_break			(__NR_SYSCALL_BASE+ 17)
-
+#define __NR_break			(__NR_SYSCALL_BASE+ 17)	/* removed */
+					/* 18 was sys_stat */
 #define __NR_lseek			(__NR_SYSCALL_BASE+ 19)
 #define __NR_getpid			(__NR_SYSCALL_BASE+ 20)
 #define __NR_mount			(__NR_SYSCALL_BASE+ 21)
@@ -56,11 +56,11 @@
 
 #define __NR_pause			(__NR_SYSCALL_BASE+ 29)
 #define __NR_utime			(__NR_SYSCALL_BASE+ 30)
-#define __NR_stty			(__NR_SYSCALL_BASE+ 31)
-#define __NR_gtty			(__NR_SYSCALL_BASE+ 32)
+#define __NR_stty			(__NR_SYSCALL_BASE+ 31)	/* removed */
+#define __NR_gtty			(__NR_SYSCALL_BASE+ 32)	/* removed */
 #define __NR_access			(__NR_SYSCALL_BASE+ 33)
 #define __NR_nice			(__NR_SYSCALL_BASE+ 34)
-#define __NR_ftime			(__NR_SYSCALL_BASE+ 35)
+#define __NR_ftime			(__NR_SYSCALL_BASE+ 35)	/* removed */
 #define __NR_sync			(__NR_SYSCALL_BASE+ 36)
 #define __NR_kill			(__NR_SYSCALL_BASE+ 37)
 #define __NR_rename			(__NR_SYSCALL_BASE+ 38)
@@ -69,22 +69,22 @@
 #define __NR_dup			(__NR_SYSCALL_BASE+ 41)
 #define __NR_pipe			(__NR_SYSCALL_BASE+ 42)
 #define __NR_times			(__NR_SYSCALL_BASE+ 43)
-#define __NR_prof			(__NR_SYSCALL_BASE+ 44)
+#define __NR_prof			(__NR_SYSCALL_BASE+ 44)	/* removed */
 #define __NR_brk			(__NR_SYSCALL_BASE+ 45)
 #define __NR_setgid			(__NR_SYSCALL_BASE+ 46)
 #define __NR_getgid			(__NR_SYSCALL_BASE+ 47)
-#define __NR_signal			(__NR_SYSCALL_BASE+ 48)
+#define __NR_signal			(__NR_SYSCALL_BASE+ 48)	/* removed */
 #define __NR_geteuid			(__NR_SYSCALL_BASE+ 49)
 #define __NR_getegid			(__NR_SYSCALL_BASE+ 50)
 #define __NR_acct			(__NR_SYSCALL_BASE+ 51)
 #define __NR_umount2			(__NR_SYSCALL_BASE+ 52)
-#define __NR_lock			(__NR_SYSCALL_BASE+ 53)
+#define __NR_lock			(__NR_SYSCALL_BASE+ 53)	/* removed */
 #define __NR_ioctl			(__NR_SYSCALL_BASE+ 54)
 #define __NR_fcntl			(__NR_SYSCALL_BASE+ 55)
-#define __NR_mpx			(__NR_SYSCALL_BASE+ 56)
+#define __NR_mpx			(__NR_SYSCALL_BASE+ 56)	/* removed */
 #define __NR_setpgid			(__NR_SYSCALL_BASE+ 57)
-#define __NR_ulimit			(__NR_SYSCALL_BASE+ 58)
-
+#define __NR_ulimit			(__NR_SYSCALL_BASE+ 58)	/* removed */
+					/* 59 was sys_olduname */
 #define __NR_umask			(__NR_SYSCALL_BASE+ 60)
 #define __NR_chroot			(__NR_SYSCALL_BASE+ 61)
 #define __NR_ustat			(__NR_SYSCALL_BASE+ 62)
@@ -93,8 +93,8 @@
 #define __NR_getpgrp			(__NR_SYSCALL_BASE+ 65)
 #define __NR_setsid			(__NR_SYSCALL_BASE+ 66)
 #define __NR_sigaction			(__NR_SYSCALL_BASE+ 67)
-#define __NR_sgetmask			(__NR_SYSCALL_BASE+ 68)
-#define __NR_ssetmask			(__NR_SYSCALL_BASE+ 69)
+#define __NR_sgetmask			(__NR_SYSCALL_BASE+ 68)	/* removed */
+#define __NR_ssetmask			(__NR_SYSCALL_BASE+ 69)	/* removed */
 #define __NR_setreuid			(__NR_SYSCALL_BASE+ 70)
 #define __NR_setregid			(__NR_SYSCALL_BASE+ 71)
 #define __NR_sigsuspend			(__NR_SYSCALL_BASE+ 72)
@@ -109,7 +109,7 @@
 #define __NR_setgroups			(__NR_SYSCALL_BASE+ 81)
 #define __NR_select			(__NR_SYSCALL_BASE+ 82)
 #define __NR_symlink			(__NR_SYSCALL_BASE+ 83)
-
+					/* 84 was sys_lstat */
 #define __NR_readlink			(__NR_SYSCALL_BASE+ 85)
 #define __NR_uselib			(__NR_SYSCALL_BASE+ 86)
 #define __NR_swapon			(__NR_SYSCALL_BASE+ 87)
@@ -123,7 +123,7 @@
 #define __NR_fchown			(__NR_SYSCALL_BASE+ 95)
 #define __NR_getpriority		(__NR_SYSCALL_BASE+ 96)
 #define __NR_setpriority		(__NR_SYSCALL_BASE+ 97)
-#define __NR_profil			(__NR_SYSCALL_BASE+ 98)
+#define __NR_profil			(__NR_SYSCALL_BASE+ 98)	/* removed */
 #define __NR_statfs			(__NR_SYSCALL_BASE+ 99)
 #define __NR_fstatfs			(__NR_SYSCALL_BASE+100)
 #define __NR_ioperm			(__NR_SYSCALL_BASE+101)
@@ -134,8 +134,8 @@
 #define __NR_stat			(__NR_SYSCALL_BASE+106)
 #define __NR_lstat			(__NR_SYSCALL_BASE+107)
 #define __NR_fstat			(__NR_SYSCALL_BASE+108)
-
-
+					/* 109 was sys_uname */
+					/* 110 was sys_iopl */
 #define __NR_vhangup			(__NR_SYSCALL_BASE+111)
 #define __NR_idle			(__NR_SYSCALL_BASE+112)
 #define __NR_syscall			(__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
@@ -152,10 +152,10 @@
 #define __NR_adjtimex			(__NR_SYSCALL_BASE+124)
 #define __NR_mprotect			(__NR_SYSCALL_BASE+125)
 #define __NR_sigprocmask		(__NR_SYSCALL_BASE+126)
-#define __NR_create_module		(__NR_SYSCALL_BASE+127)
+#define __NR_create_module		(__NR_SYSCALL_BASE+127)	/* removed */
 #define __NR_init_module		(__NR_SYSCALL_BASE+128)
 #define __NR_delete_module		(__NR_SYSCALL_BASE+129)
-#define __NR_get_kernel_syms		(__NR_SYSCALL_BASE+130)
+#define __NR_get_kernel_syms		(__NR_SYSCALL_BASE+130)	/* removed */
 #define __NR_quotactl			(__NR_SYSCALL_BASE+131)
 #define __NR_getpgid			(__NR_SYSCALL_BASE+132)
 #define __NR_fchdir			(__NR_SYSCALL_BASE+133)
@@ -191,8 +191,8 @@
 #define __NR_mremap			(__NR_SYSCALL_BASE+163)
 #define __NR_setresuid			(__NR_SYSCALL_BASE+164)
 #define __NR_getresuid			(__NR_SYSCALL_BASE+165)
-#define __NR_vm86			(__NR_SYSCALL_BASE+166)
-#define __NR_query_module		(__NR_SYSCALL_BASE+167)
+#define __NR_vm86			(__NR_SYSCALL_BASE+166)	/* removed */
+#define __NR_query_module		(__NR_SYSCALL_BASE+167)	/* removed */
 #define __NR_poll			(__NR_SYSCALL_BASE+168)
 #define __NR_nfsservctl			(__NR_SYSCALL_BASE+169)
 #define __NR_setresgid			(__NR_SYSCALL_BASE+170)
@@ -264,6 +264,24 @@
 #define __NR_lremovexattr		(__NR_SYSCALL_BASE+236)
 #define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
 #define __NR_tkill			(__NR_SYSCALL_BASE+238)
+#define __NR_sendfile64			(__NR_SYSCALL_BASE+239)
+#define __NR_futex			(__NR_SYSCALL_BASE+240)
+#define __NR_sched_setaffinity		(__NR_SYSCALL_BASE+241)
+#define __NR_sched_getaffinity		(__NR_SYSCALL_BASE+242)
+#define __NR_io_setup			(__NR_SYSCALL_BASE+243)
+#define __NR_io_destroy			(__NR_SYSCALL_BASE+244)
+#define __NR_io_getevents		(__NR_SYSCALL_BASE+245)
+#define __NR_io_submit			(__NR_SYSCALL_BASE+246)
+#define __NR_io_cancel			(__NR_SYSCALL_BASE+247)
+#define __NR_exit_group			(__NR_SYSCALL_BASE+248)
+#define __NR_lookup_dcookie		(__NR_SYSCALL_BASE+249)
+#define __NR_epoll_create		(__NR_SYSCALL_BASE+250)
+#define __NR_epoll_ctl			(__NR_SYSCALL_BASE+251)
+#define __NR_epoll_wait			(__NR_SYSCALL_BASE+252)
+#define __NR_remap_file_pages		(__NR_SYSCALL_BASE+253)
+					/* 254 for set_thread_area */
+					/* 255 for get_thread_area */
+					/* 256 for set_tid_address */
 
 /*
  * The following SWIs are ARM private.
diff -Nru a/include/asm-generic/topology.h b/include/asm-generic/topology.h
--- a/include/asm-generic/topology.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-generic/topology.h	Thu Jan 16 18:23:05 2003
@@ -48,4 +48,9 @@
 #define __node_to_memblk(node)		(0)
 #endif
 
+/* Cross-node load balancing interval. */
+#ifndef NODE_BALANCE_RATE
+#define NODE_BALANCE_RATE 10
+#endif
+
 #endif /* _ASM_GENERIC_TOPOLOGY_H */
diff -Nru a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-generic/vmlinux.lds.h	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,33 @@
+#ifndef LOAD_OFFSET
+#define LOAD_OFFSET 0
+#endif
+
+#define RODATA								\
+	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\
+		*(.rodata) *(.rodata.*)					\
+		*(__vermagic)		/* Kernel version magic */	\
+	}								\
+									\
+	.rodata1          : AT(ADDR(.rodata1) - LOAD_OFFSET) {		\
+		*(.rodata1)						\
+	}								\
+									\
+	/* Kernel symbol table: Normal symbols */			\
+	__start___ksymtab = .;						\
+	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
+		*(__ksymtab)						\
+	}								\
+	__stop___ksymtab = .;						\
+									\
+	/* Kernel symbol table: GPL-only symbols */			\
+	__start___gpl_ksymtab = .;					\
+	__gpl_ksymtab     : AT(ADDR(__gpl_ksymtab) - LOAD_OFFSET) {	\
+		*(__gpl_ksymtab)					\
+	}								\
+	__stop___gpl_ksymtab = .;					\
+									\
+	/* Kernel symbol table: strings */				\
+        __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
+		*(__ksymtab_strings)					\
+	}
+
diff -Nru a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
--- a/include/asm-i386/apicdef.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-i386/apicdef.h	Thu Jan 16 18:23:06 2003
@@ -11,8 +11,13 @@
 #define		APIC_DEFAULT_PHYS_BASE	0xfee00000
  
 #define		APIC_ID		0x20
-#define			APIC_ID_MASK		(0x0F<<24)
-#define			GET_APIC_ID(x)		(((x)>>24)&0x0F)
+#ifdef CONFIG_X86_SUMMIT
+ #define		APIC_ID_MASK		(0xFF<<24)
+ #define		GET_APIC_ID(x)		(((x)>>24)&0xFF)
+#else
+ #define		APIC_ID_MASK		(0x0F<<24)
+ #define		GET_APIC_ID(x)		(((x)>>24)&0x0F)
+#endif
 #define		APIC_LVR	0x30
 #define			APIC_LVR_MASK		0xFF00FF
 #define			GET_APIC_VERSION(x)	((x)&0xFF)
diff -Nru a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h
--- a/include/asm-i386/mach-bigsmp/mach_apic.h	Thu Jan 16 18:23:07 2003
+++ b/include/asm-i386/mach-bigsmp/mach_apic.h	Thu Jan 16 18:23:07 2003
@@ -21,8 +21,12 @@
 #define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
 #define TARGET_CPUS	((cpu_online_map < 0xf)?cpu_online_map:0xf)
 
+#define INT_DELIVERY_MODE dest_LowestPrio
+#define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
+
 #define APIC_BROADCAST_ID     (0x0f)
 #define check_apicid_used(bitmap, apicid) (0)
+#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit))
 
 static inline unsigned long calculate_ldr(unsigned long old)
 {
@@ -64,17 +68,24 @@
 	return 0;
 }
 
-extern u8 raw_phys_apicid[];
+extern u8 bios_cpu_apicid[];
 
 static inline int cpu_present_to_apicid(int mps_cpu)
 {
-	return (int) raw_phys_apicid[mps_cpu];
+	return (int) bios_cpu_apicid[mps_cpu];
 }
 
 static inline unsigned long apicid_to_cpu_present(int phys_apicid)
 {
 	return (1ul << phys_apicid);
 }
+
+extern volatile u8 cpu_2_logical_apicid[];
+/* Mapping from cpu number to logical apicid */
+static inline int cpu_to_logical_apicid(int cpu)
+{
+       return (int)cpu_2_logical_apicid[cpu];
+ }
 
 static inline int mpc_apic_id(struct mpc_config_processor *m, int quad)
 {
diff -Nru a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h
--- a/include/asm-i386/mach-default/mach_apic.h	Thu Jan 16 18:23:07 2003
+++ b/include/asm-i386/mach-default/mach_apic.h	Thu Jan 16 18:23:07 2003
@@ -12,8 +12,12 @@
 #define no_balance_irq (0)
 #define esr_disable (0)
 
+#define INT_DELIVERY_MODE dest_LowestPrio
+#define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
+
 #define APIC_BROADCAST_ID      0x0F
 #define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid))
+#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit))
 
 static inline int apic_id_registered(void)
 {
@@ -57,6 +61,12 @@
 static inline int apicid_to_node(int logical_apicid)
 {
 	return 0;
+}
+
+/* Mapping from cpu number to logical apicid */
+static inline int cpu_to_logical_apicid(int cpu)
+{
+	return 1 << cpu;
 }
 
 static inline int cpu_present_to_apicid(int mps_cpu)
diff -Nru a/include/asm-i386/mach-default/mach_mpparse.h b/include/asm-i386/mach-default/mach_mpparse.h
--- a/include/asm-i386/mach-default/mach_mpparse.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-i386/mach-default/mach_mpparse.h	Thu Jan 16 18:23:06 2003
@@ -17,4 +17,10 @@
 {
 }
 
+/* Hook from generic ACPI tables.c */
+static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+}
+
+
 #endif /* __ASM_MACH_MPPARSE_H */
diff -Nru a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h
--- a/include/asm-i386/mach-numaq/mach_apic.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-i386/mach-numaq/mach_apic.h	Thu Jan 16 18:23:05 2003
@@ -8,8 +8,12 @@
 #define no_balance_irq (1)
 #define esr_disable (1)
 
+#define INT_DELIVERY_MODE dest_LowestPrio
+#define INT_DEST_MODE 0     /* physical delivery on LOCAL quad */
+ 
 #define APIC_BROADCAST_ID      0x0F
 #define check_apicid_used(bitmap, apicid) ((bitmap) & (1 << (apicid)))
+#define check_apicid_present(bit) (phys_cpu_present_map & (1 << bit))
 
 static inline int apic_id_registered(void)
 {
@@ -40,6 +44,13 @@
 {
 	/* We don't have a good way to do this yet - hack */
 	return 0xf;
+}
+
+/* Mapping from cpu number to logical apicid */
+extern volatile u8 cpu_2_logical_apicid[];
+static inline int cpu_to_logical_apicid(int cpu)
+{
+	return (int)cpu_2_logical_apicid[cpu];
 }
 
 static inline int cpu_present_to_apicid(int mps_cpu)
diff -Nru a/include/asm-i386/mach-numaq/mach_mpparse.h b/include/asm-i386/mach-numaq/mach_mpparse.h
--- a/include/asm-i386/mach-numaq/mach_mpparse.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-i386/mach-numaq/mach_mpparse.h	Thu Jan 16 18:23:05 2003
@@ -34,4 +34,9 @@
 				mpc->mpc_oemsize);
 }
 
+/* Hook from generic ACPI tables.c */
+static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+}
+
 #endif /* __ASM_MACH_MPPARSE_H */
diff -Nru a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
--- a/include/asm-i386/mach-summit/mach_apic.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-i386/mach-summit/mach_apic.h	Thu Jan 16 18:23:06 2003
@@ -4,6 +4,7 @@
 extern int x86_summit;
 
 #define esr_disable (1)
+#define no_balance_irq (0)
 
 #define XAPIC_DEST_CPUS_MASK    0x0Fu
 #define XAPIC_DEST_CLUSTER_MASK 0xF0u
@@ -11,22 +12,43 @@
 #define xapic_phys_to_log_apicid(phys_apic) ( (1ul << ((phys_apic) & 0x3)) |\
 		((phys_apic) & XAPIC_DEST_CLUSTER_MASK) )
 
-static inline unsigned long calculate_ldr(unsigned long old)
+#define APIC_DFR_VALUE	(x86_summit ? APIC_DFR_CLUSTER : APIC_DFR_FLAT)
+#define TARGET_CPUS	(x86_summit ? XAPIC_DEST_CPUS_MASK : cpu_online_map)
+
+#define INT_DELIVERY_MODE dest_Fixed
+#define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
+
+#define APIC_BROADCAST_ID     (x86_summit ? 0xFF : 0x0F)
+#define check_apicid_used(bitmap, apicid) (0)
+
+/* we don't use the phys_cpu_present_map to indicate apicid presence */
+#define check_apicid_present(bit) (1) 
+
+extern u8 bios_cpu_apicid[];
+
+static inline void init_apic_ldr(void)
 {
-	unsigned long id;
+	unsigned long val, id;
 
 	if (x86_summit)
 		id = xapic_phys_to_log_apicid(hard_smp_processor_id());
 	else
 		id = 1UL << smp_processor_id();
-	return ((old & ~APIC_LDR_MASK) | SET_APIC_LOGICAL_ID(id));
+	apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+	val |= SET_APIC_LOGICAL_ID(id);
+	apic_write_around(APIC_LDR, val);
 }
 
-#define APIC_DFR_VALUE	(x86_summit ? APIC_DFR_CLUSTER : APIC_DFR_FLAT)
-#define TARGET_CPUS	(x86_summit ? XAPIC_DEST_CPUS_MASK : cpu_online_map)
+static inline int multi_timer_check(int apic, int irq)
+{
+	return 0;
+}
 
-#define APIC_BROADCAST_ID     (x86_summit ? 0xFF : 0x0F)
-#define check_apicid_used(bitmap, apicid) (0)
+static inline int apic_id_registered(void)
+{
+	return 1;
+}
 
 static inline void clustered_apic_check(void)
 {
@@ -39,10 +61,17 @@
 	return (logical_apicid >> 5);          /* 2 clusterids per CEC */
 }
 
+/* Mapping from cpu number to logical apicid */
+extern volatile u8 cpu_2_logical_apicid[];
+static inline int cpu_to_logical_apicid(int cpu)
+{
+	return (int)cpu_2_logical_apicid[cpu];
+}
+
 static inline int cpu_present_to_apicid(int mps_cpu)
 {
 	if (x86_summit)
-		return (int) raw_phys_apicid[mps_cpu];
+		return (int) bios_cpu_apicid[mps_cpu];
 	else
 		return mps_cpu;
 }
@@ -53,12 +82,22 @@
 	return (x86_summit ? 0x0F : phys_map);
 }
 
-static inline unsigned long apicid_to_phys_cpu_present(int apicid)
+static inline unsigned long apicid_to_cpu_present(int apicid)
 {
 	if (x86_summit)
-		return (1ul << (((apicid >> 4) << 2) | (apicid & 0x3)));
+		return 1;
 	else
 		return (1ul << apicid);
+}
+
+static inline int mpc_apic_id(struct mpc_config_processor *m, int quad)
+{
+	printk("Processor #%d %ld:%ld APIC version %d\n",
+			m->mpc_apicid,
+			(m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
+			(m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
+			m->mpc_apicver);
+	return (m->mpc_apicid);
 }
 
 static inline void setup_portio_remap(void)
diff -Nru a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h
--- a/include/asm-i386/mach-summit/mach_mpparse.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-i386/mach-summit/mach_mpparse.h	Thu Jan 16 18:23:05 2003
@@ -15,8 +15,16 @@
 static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, 
 		char *productid)
 {
-	if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(str, "VIGIL SMP", 9))
+	if (!strncmp(oem, "IBM ENSW", 8) && 
+			(!strncmp(productid, "VIGIL SMP", 9) 
+			 || !strncmp(productid, "RUTHLESS SMP", 12)))
 		x86_summit = 1;
 }
 
+/* Hook from generic ACPI tables.c */
+static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+	if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "SERVIGIL", 8))
+		x86_summit = 1;
+}
 #endif /* __ASM_MACH_MPPARSE_H */
diff -Nru a/include/asm-i386/module.h b/include/asm-i386/module.h
--- a/include/asm-i386/module.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-i386/module.h	Thu Jan 16 18:23:05 2003
@@ -1,5 +1,6 @@
 #ifndef _ASM_I386_MODULE_H
 #define _ASM_I386_MODULE_H
+
 /* x86 is simple */
 struct mod_arch_specific
 {
@@ -8,4 +9,47 @@
 #define Elf_Shdr Elf32_Shdr
 #define Elf_Sym Elf32_Sym
 #define Elf_Ehdr Elf32_Ehdr
+
+#ifdef CONFIG_M386
+#define MODULE_PROC_FAMILY "386 "
+#elif CONFIG_M486
+#define MODULE_PROC_FAMILY "486 "
+#elif CONFIG_M586
+#define MODULE_PROC_FAMILY "586 "
+#elif CONFIG_M586TSC
+#define MODULE_PROC_FAMILY "586TSC "
+#elif CONFIG_M586MMX
+#define MODULE_PROC_FAMILY "586MMX "
+#elif CONFIG_M686
+#define MODULE_PROC_FAMILY "686 "
+#elif CONFIG_MPENTIUMII
+#define MODULE_PROC_FAMILY "PENTIUMII "
+#elif CONFIG_MPENTIUMIII
+#define MODULE_PROC_FAMILY "PENTIUMIII "
+#elif CONFIG_MPENTIUM4
+#define MODULE_PROC_FAMILY "PENTIUM4 "
+#elif CONFIG_MK6
+#define MODULE_PROC_FAMILY "K6 "
+#elif CONFIG_MK7
+#define MODULE_PROC_FAMILY "K7 "
+#elif CONFIG_MK8
+#define MODULE_PROC_FAMILY "K8 "
+#elif CONFIG_MELAN
+#define MODULE_PROC_FAMILY "ELAN "
+#elif CONFIG_MCRUSOE
+#define MODULE_PROC_FAMILY "CRUSOE "
+#elif CONFIG_MWINCHIPC6
+#define MODULE_PROC_FAMILY "WINCHIPC6 "
+#elif CONFIG_MWINCHIP2
+#define MODULE_PROC_FAMILY "WINCHIP2 "
+#elif CONFIG_MWINCHIP3D
+#define MODULE_PROC_FAMILY "WINCHIP3D "
+#elif CONFIG_MCYRIXIII
+#define MODULE_PROC_FAMILY "CYRIXIII "
+#else
+#error unknown processor family
+#endif
+
+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
+
 #endif /* _ASM_I386_MODULE_H */
diff -Nru a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h
--- a/include/asm-i386/mpspec.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-i386/mpspec.h	Thu Jan 16 18:23:05 2003
@@ -16,11 +16,11 @@
 /*
  * a maximum of 16 APICs with the current APIC ID architecture.
  */
-#ifdef CONFIG_X86_NUMA
+#if defined(CONFIG_X86_NUMAQ) || defined (CONFIG_X86_SUMMIT)
 #define MAX_APICS 256
-#else /* !CONFIG_X86_NUMA */
+#else
 #define MAX_APICS 16
-#endif /* CONFIG_X86_NUMA */
+#endif
 
 #define MAX_MPC_ENTRY 1024
 
diff -Nru a/include/asm-i386/smp.h b/include/asm-i386/smp.h
--- a/include/asm-i386/smp.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-i386/smp.h	Thu Jan 16 18:23:06 2003
@@ -22,12 +22,6 @@
 #endif
 #endif
 
-#ifdef CONFIG_X86_NUMAQ
- #define INT_DELIVERY_MODE 0     /* physical delivery on LOCAL quad */
-#else
- #define INT_DELIVERY_MODE 1     /* logical delivery broadcast to all procs */
-#endif
-
 #define BAD_APICID 0xFFu
 #ifdef CONFIG_SMP
 #ifndef __ASSEMBLY__
@@ -82,12 +76,6 @@
 	return hweight32(cpu_callout_map);
 }
 
-/* Mapping from cpu number to logical apicid */
-extern volatile u8 cpu_2_logical_apicid[];
-static inline int cpu_to_logical_apicid(int cpu)
-{
-	return (int)cpu_2_logical_apicid[cpu];
-}
 extern void map_cpu_to_logical_apicid(void);
 extern void unmap_cpu_to_logical_apicid(int cpu);
 
diff -Nru a/include/asm-i386/topology.h b/include/asm-i386/topology.h
--- a/include/asm-i386/topology.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-i386/topology.h	Thu Jan 16 18:23:05 2003
@@ -61,6 +61,9 @@
 /* Returns the number of the first MemBlk on Node 'node' */
 #define __node_to_memblk(node) (node)
 
+/* Cross-node load balancing interval. */
+#define NODE_BALANCE_RATE 100
+
 #else /* !CONFIG_NUMA */
 /*
  * Other i386 platforms should define their own version of the 
diff -Nru a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
--- a/include/asm-ia64/topology.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ia64/topology.h	Thu Jan 16 18:23:05 2003
@@ -60,4 +60,7 @@
  */
 #define __node_to_memblk(node) (node)
 
+/* Cross-node load balancing interval. */
+#define NODE_BALANCE_RATE 10
+
 #endif /* _ASM_IA64_TOPOLOGY_H */
diff -Nru a/include/asm-m68k/machdep.h b/include/asm-m68k/machdep.h
--- a/include/asm-m68k/machdep.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-m68k/machdep.h	Thu Jan 16 18:23:05 2003
@@ -23,6 +23,7 @@
 /* machine dependent timer functions */
 extern unsigned long (*mach_gettimeoffset)(void);
 extern int (*mach_hwclk)(int, struct rtc_time*);
+extern unsigned int (*mach_get_ss)(void);
 extern int (*mach_get_rtc_pll)(struct rtc_pll_info *);
 extern int (*mach_set_rtc_pll)(struct rtc_pll_info *);
 extern int (*mach_set_clock_mmss)(unsigned long);
diff -Nru a/include/asm-m68k/mmu_context.h b/include/asm-m68k/mmu_context.h
--- a/include/asm-m68k/mmu_context.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-m68k/mmu_context.h	Thu Jan 16 18:23:06 2003
@@ -142,6 +142,8 @@
 	activate_context(tsk->mm);
 }
 
+#define deactivate_mm(tsk,mm)	do { } while (0)
+
 extern inline void activate_mm(struct mm_struct *prev_mm,
 			       struct mm_struct *next_mm)
 {
diff -Nru a/include/asm-m68k/q40ints.h b/include/asm-m68k/q40ints.h
--- a/include/asm-m68k/q40ints.h	Thu Jan 16 18:23:07 2003
+++ b/include/asm-m68k/q40ints.h	Thu Jan 16 18:23:07 2003
@@ -11,19 +11,19 @@
 
 /* masks for interrupt regiosters*/
 /* internal, IIRQ_REG */
-#define IRQ_KEYB_MASK    (2)
-#define IRQ_SER_MASK     (1<<2)
-#define IRQ_FRAME_MASK   (1<<3)
-#define IRQ_EXT_MASK     (1<<4)    /* is a EIRQ */
+#define Q40_IRQ_KEYB_MASK    (2)
+#define Q40_IRQ_SER_MASK     (1<<2)
+#define Q40_IRQ_FRAME_MASK   (1<<3)
+#define Q40_IRQ_EXT_MASK     (1<<4)    /* is a EIRQ */
 /* eirq, EIRQ_REG */
-#define IRQ3_MASK        (1)
-#define IRQ4_MASK        (1<<1)
-#define IRQ5_MASK        (1<<2)
-#define IRQ6_MASK        (1<<3)
-#define IRQ7_MASK        (1<<4)
-#define IRQ10_MASK       (1<<5)
-#define IRQ14_MASK       (1<<6)
-#define IRQ15_MASK       (1<<7)
+#define Q40_IRQ3_MASK        (1)
+#define Q40_IRQ4_MASK        (1<<1)
+#define Q40_IRQ5_MASK        (1<<2)
+#define Q40_IRQ6_MASK        (1<<3)
+#define Q40_IRQ7_MASK        (1<<4)
+#define Q40_IRQ10_MASK       (1<<5)
+#define Q40_IRQ14_MASK       (1<<6)
+#define Q40_IRQ15_MASK       (1<<7)
 
 extern unsigned long q40_probe_irq_on (void);
 extern int q40_probe_irq_off (unsigned long irqs);
diff -Nru a/include/asm-m68k/rtc.h b/include/asm-m68k/rtc.h
--- a/include/asm-m68k/rtc.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-m68k/rtc.h	Thu Jan 16 18:23:05 2003
@@ -13,14 +13,11 @@
 
 #ifdef __KERNEL__
 
+#include <linux/rtc.h>
 #include <asm/machdep.h>
 
 /* a few implementation details for the emulation : */
 
-extern unsigned gen_rtc_irq_flags; /* which sort(s) of interrupts caused int */
-extern unsigned gen_rtc_irq_ctrl;  /*                             are enabled */
-extern short q40rtc_oldsecs;
-
 #define RTC_PIE 0x40		/* periodic interrupt enable */
 #define RTC_AIE 0x20		/* alarm interrupt enable */
 #define RTC_UIE 0x10		/* update-finished interrupt enable */
@@ -47,6 +44,18 @@
 static inline int set_rtc_time(struct rtc_time *time)
 {
 	return mach_hwclk(1, time);
+}
+
+static inline unsigned int get_rtc_ss(void)
+{
+	if (mach_get_ss)
+		return mach_get_ss();
+	else{
+		struct rtc_time h;
+
+		get_rtc_time(&h);
+		return h.tm_sec;
+	}
 }
 
 static inline int get_rtc_pll(struct rtc_pll_info *pll)
diff -Nru a/include/asm-m68k/uaccess.h b/include/asm-m68k/uaccess.h
--- a/include/asm-m68k/uaccess.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-m68k/uaccess.h	Thu Jan 16 18:23:05 2003
@@ -37,9 +37,6 @@
 	unsigned long insn, fixup;
 };
 
-/* Returns 0 if exception not found and fixup otherwise.  */
-extern unsigned long search_exception_table(unsigned long);
-
 
 /*
  * These are the main single-value transfer routines.  They automatically
diff -Nru a/include/asm-m68knommu/bug.h b/include/asm-m68knommu/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68knommu/bug.h	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,12 @@
+#ifndef _M68KNOMMU_BUG_H
+#define _M68KNOMMU_BUG_H
+
+#define BUG() do { \
+  printk("%s(%d): kernel BUG!\n", __FILE__, __LINE__); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+         BUG(); \
+} while (0)
+
+#endif
diff -Nru a/include/asm-m68knommu/entry.h b/include/asm-m68knommu/entry.h
--- a/include/asm-m68knommu/entry.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-m68knommu/entry.h	Thu Jan 16 18:23:06 2003
@@ -1,15 +1,14 @@
-#ifndef __M68K_ENTRY_H
-#define __M68K_ENTRY_H
+#ifndef __M68KNOMMU_ENTRY_H
+#define __M68KNOMMU_ENTRY_H
 
 #include <linux/config.h>
-#ifndef CONFIG_COLDFIRE
 #include <asm/setup.h>
 #include <asm/page.h>
 
 /*
  * Stack layout in 'ret_from_exception':
  *
- *	This allows access to the syscall arguments in registers d1-d5
+ * This allows access to the syscall arguments in registers d1-d5
  *
  *	 0(sp) - d1
  *	 4(sp) - d2
@@ -22,34 +21,17 @@
  *	20(sp) - d0
  *	24(sp) - orig_d0
  *	28(sp) - stack adjustment
- *	2C(sp) - sr
- *	2E(sp) - pc
- *	32(sp) - format & vector
+ *	2C(sp) - [ sr              ] [ format & vector ]
+ *	2E(sp) - [ pc              ] [ sr              ]
+ *	30(sp) - [ format & vector ] [ pc              ]
+ *		  ^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^
+ *			M68K		  COLDFIRE
  */
 
-/*
- * 97/05/14 Andreas: Register %a2 is now set to the current task throughout
- *		     the whole kernel.
- */
-
-/* the following macro is used when enabling interrupts */
-#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
-	/* block out HSYNC on the atari */
-#define ALLOWINT 0xfbff
-#define	MAX_NOINT_IPL	3
-#else
-	/* portable version */
 #define ALLOWINT 0xf8ff
-#define	MAX_NOINT_IPL	0
-#endif /* machine compilation types */ 
 
 #ifdef __ASSEMBLY__
 
-#define curptr a2
-
-LFLUSH_I_AND_D = 0x00000808
-LSIGTRAP = 5
-
 /* process bits for task_struct.flags */
 PF_TRACESYS_OFF = 3
 PF_TRACESYS_BIT = 5
@@ -58,72 +40,149 @@
 PF_DTRACE_OFF = 1
 PF_DTRACE_BIT = 5
 
-#define SAVE_ALL_INT save_all_int
-#define SAVE_ALL_SYS save_all_sys
-#define RESTORE_ALL restore_all
+LENOSYS = 38
+
+LD0		= 0x20
+LORIG_D0	= 0x24
+LFORMATVEC	= 0x2c
+LSR		= 0x2e
+LPC		= 0x30
+
+#define SWITCH_STACK_SIZE (6*4+4)	/* Includes return address */
+
 /*
  * This defines the normal kernel pt-regs layout.
  *
- * regs a3-a6 and d6-d7 are preserved by C code
+ * regs are a2-a6 and d6-d7 preserved by C code
  * the kernel doesn't mess with usp unless it needs to
  */
 
+#ifdef CONFIG_COLDFIRE
 /*
- * a -1 in the orig_d0 field signifies
- * that the stack frame is NOT for syscall
+ * This is made a little more tricky on the ColdFire. There is no
+ * separate kernel and user stack pointers. Need to artificially
+ * construct a usp in software... When doing this we need to disable
+ * interrupts, otherwise bad things could happen.
  */
-.macro	save_all_int VEC=0
-	oriw	#0x0700,%sr	/* disable interrupts */
-	clrl	%sp@-		/* stk_adj */
-	pea	-1:w		/* orig d0 */
-	movel	%d0,%sp@-	/* d0 */
-	moveml	%d1-%d5/%a0-%a1/%curptr,%sp@-
-.endm
-
-.macro	save_all_sys VEC=0
-	clrl	%sp@-		/* stk_adj */
-	movel	%d0,%sp@-	/* orig d0 */
-	movel	%d0,%sp@-	/* d0 */
-	moveml	%d1-%d5/%a0-%a1/%curptr,%sp@-
+.macro SAVE_ALL
+	move	#0x2700,%sr		/* disable intrs */
+	btst	#5,%sp@(2)		/* from user? */
+	bnes	6f			/* no, skip */
+	movel	%sp,sw_usp		/* save user sp */
+	addql	#8,sw_usp		/* remove exception */
+	movel	sw_ksp,%sp		/* kernel sp */
+	subql	#8,%sp			/* room for exception */
+	clrl	%sp@-			/* stk_adj */
+	movel	%d0,%sp@-		/* orig d0 */
+	movel	%d0,%sp@-		/* d0 */
+	subl	#32,%sp			/* space for 8 regs */
+	moveml	%d1-%d5/%a0-%a2,%sp@
+	movel	sw_usp,%a0		/* get usp */
+	moveml	%a0@(-8),%d1-%d2	/* get exception */
+	moveml	%d1-%d2,%sp@(LFORMATVEC) /* copy exception */
+	bra	7f
+	6:
+	clrl	%sp@-			/* stk_adj */
+	movel	%d0,%sp@-		/* orig d0 */
+	movel	%d0,%sp@-		/* d0 */
+	subl	#32,%sp			/* space for 7 regs */
+	moveml	%d1-%d5/%a0-%a2,%sp@
+	7:
 .endm
 
-.macro	restore_all
-	moveml	%sp@+,%a0-%a1/%curptr/%d1-%d5
+.macro RESTORE_ALL
+	btst	#5,%sp@(LSR)		/* going user? */
+	bnes	8f			/* no, skip */
+	move	#0x2700,%sr		/* disable intrs */
+	movel	sw_usp,%a0		/* get usp */
+	moveml	%sp@(LFORMATVEC),%d1-%d2 /* copy exception */
+	moveml	%d1-%d2,%a0@(-8)
+	moveml	%sp@,%d1-%d5/%a0-%a2
+	addl	#32,%sp			/* space for 8 regs */
 	movel	%sp@+,%d0
-	addql	#4,%sp		/* orig d0 */
-	addl	%sp@+,%sp	/* stk adj */
+	addql	#4,%sp			/* orig d0 */
+	addl	%sp@+,%sp		/* stk adj */
+	addql	#8,%sp			/* remove exception */
+	movel	%sp,sw_ksp		/* save ksp */
+	subql	#8,sw_usp		/* set exception */
+	movel	sw_usp,%sp		/* restore usp */
+	rte
+	8:
+	moveml	%sp@,%d1-%d5/%a0-%a2
+	addl	#32,%sp			/* space for 8 regs */
+	movel	%sp@+,%d0
+	addql	#4,%sp			/* orig d0 */
+	addl	%sp@+,%sp		/* stk adj */
 	rte
 .endm
 
-#define SWITCH_STACK_SIZE (6*4+4)	/* includes return address */
+/*
+ * Quick exception save, use current stack only.
+ */
+.macro SAVE_LOCAL
+	move	#0x2700,%sr		/* disable intrs */
+	clrl	%sp@-			/* stk_adj */
+	movel	%d0,%sp@-		/* orig d0 */
+	movel	%d0,%sp@-		/* d0 */
+	subl	#32,%sp			/* space for 8 regs */
+	moveml	%d1-%d5/%a0-%a2,%sp@
+.endm
 
-#define SAVE_SWITCH_STACK save_switch_stack
-#define RESTORE_SWITCH_STACK restore_switch_stack
-#define GET_CURRENT(tmp)
+.macro RESTORE_LOCAL
+	moveml	%sp@,%d1-%d5/%a0-%a2
+	addl	#32,%sp			/* space for 8 regs */
+	movel	%sp@+,%d0
+	addql	#4,%sp			/* orig d0 */
+	addl	%sp@+,%sp		/* stk adj */
+	rte
+.endm
 
-.macro	save_switch_stack
-	moveml	%a3-%a6/%d6-%d7,%sp@-
+.macro SAVE_SWITCH_STACK
+	subl    #24,%sp			/* 6 regs */
+	moveml	%a3-%a6/%d6-%d7,%sp@
 .endm
 
-.macro	restore_switch_stack
-	moveml	%sp@+,%a3-%a6/%d6-%d7
+.macro RESTORE_SWITCH_STACK
+	moveml	%sp@,%a3-%a6/%d6-%d7
+	addl	#24,%sp			/* 6 regs */
 .endm
 
-#else /* C source */
+/*
+ * Software copy of the user and kernel stack pointers... Ugh...
+ * Need these to get around ColdFire not having separate kernel
+ * and user stack pointers.
+ */
+.globl sw_usp
+.globl sw_ksp
+
+#else /* !CONFIG_COLDFIRE */
+
+/*
+ * Standard 68k interrupt entry and exit macros.
+ */
+.macro SAVE_ALL
+	clrl	%sp@-			/* stk_adj */
+	movel	%d0,%sp@-		/* orig d0 */
+	movel	%d0,%sp@-		/* d0 */
+	moveml	%d1-%d5/%a0-%a2,%sp@-
+.endm
 
-#define STR(X) STR1(X)
-#define STR1(X) #X
+.macro RESTORE_ALL
+	moveml	%sp@+,%a0-%a2/%d1-%d5
+	movel	%sp@+,%d0
+	addql	#4,%sp			/* orig d0 */
+	addl	%sp@+,%sp		/* stk adj */
+	rte
+.endm
 
-#define PT_OFF_ORIG_D0	 0x24
-#define PT_OFF_FORMATVEC 0x32
-#define PT_OFF_SR	 0x2C
-#define SAVE_ALL_INT				\
-	"clrl	%%sp@-;"    /* stk_adj */	\
-	"pea	-1:w;"	    /* orig d0 = -1 */	\
-	"movel	%%d0,%%sp@-;" /* d0 */		\
-	"moveml	%%d1-%%d5/%%a0-%%a2,%%sp@-"
+.macro SAVE_SWITCH_STACK
+	moveml	%a3-%a6/%d6-%d7,%sp@-
+.endm
 
-#endif
+.macro RESTORE_SWITCH_STACK
+	moveml	%sp@+,%a3-%a6/%d6-%d7
+.endm
 
-#endif /* CONFIG_COLDFIRE */
-#endif /* __M68K_ENTRY_H */
+#endif /* !CONFIG_COLDFIRE */
+#endif /* __ASSEMBLY__ */
+#endif /* __M68KNOMMU_ENTRY_H */
diff -Nru a/include/asm-m68knommu/page.h b/include/asm-m68knommu/page.h
--- a/include/asm-m68knommu/page.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-m68knommu/page.h	Thu Jan 16 18:23:05 2003
@@ -94,28 +94,6 @@
 #define	virt_addr_valid(kaddr)	(((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
 				((void *)(kaddr) < (void *)memory_end))
 
-
-#ifdef CONFIG_NO_KERNEL_MSG
-#define	BUG_PRINT()
-#else
-#define	BUG_PRINT() printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__)
-#endif
-
-
-// #define BUG_PANIC()	asm volatile ("halt") /* drop to debugger */
-// #define BUG_PANIC()	while(1)
-#define BUG_PANIC()	panic("BUG!")
-
-
-#define BUG() do { \
-	BUG_PRINT(); \
-	BUG_PANIC(); \
-} while (0)
-
-#define PAGE_BUG(page) do { \
-	BUG(); \
-} while (0)
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-ppc/gt64260.h b/include/asm-ppc/gt64260.h
--- a/include/asm-ppc/gt64260.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ppc/gt64260.h	Thu Jan 16 18:23:05 2003
@@ -5,12 +5,10 @@
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #ifndef __ASMPPC_GT64260_H
 #define __ASMPPC_GT64260_H
diff -Nru a/include/asm-ppc/gt64260_defs.h b/include/asm-ppc/gt64260_defs.h
--- a/include/asm-ppc/gt64260_defs.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-ppc/gt64260_defs.h	Thu Jan 16 18:23:06 2003
@@ -5,12 +5,10 @@
  *
  * Author: Mark A. Greer <mgreer@mvista.com>
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #ifndef __ASMPPC_GT64260_DEFS_H
 #define __ASMPPC_GT64260_DEFS_H
diff -Nru a/include/asm-ppc/harrier.h b/include/asm-ppc/harrier.h
--- a/include/asm-ppc/harrier.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ppc/harrier.h	Thu Jan 16 18:23:05 2003
@@ -1,17 +1,15 @@
 /*
- * arch/ppc/kernel/harrier.h
+ * include/asm-ppc/harrier.h
  *
  * Definitions for Motorola MCG Harrier North Bridge & Memory controller
  *
  * Author: Dale Farnsworth
  *         dale.farnsworth@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __ASMPPC_HARRIER_H
diff -Nru a/include/asm-ppc/ibm403.h b/include/asm-ppc/ibm403.h
--- a/include/asm-ppc/ibm403.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ppc/ibm403.h	Thu Jan 16 18:23:05 2003
@@ -1,35 +1,10 @@
 /*
- * ibm403.h
+ * Authors: Armin Kuster <akuster@mvista.com> and Tom Rini <trini@mvista.com>
  *
- *	This was derived from the ibm4xx.h and all 403 specific definitions
- *	were moved here.
- *	
- *      Armin Kuster <akuster@mvista.com>
- *      Tom Rini <trini@mvista.com>
- *      Oct, 2001
- *
- *
- * Copyright 2001 MontaVista Softare Inc.
- *
- * 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. 
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 
diff -Nru a/include/asm-ppc/ibm405.h b/include/asm-ppc/ibm405.h
--- a/include/asm-ppc/ibm405.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ppc/ibm405.h	Thu Jan 16 18:23:05 2003
@@ -1,34 +1,10 @@
 /*
- * ibm405.h
+ * Author: Armin Kuster <akuster@mvista.com>
  *
- *	This was derived from the ppc4xx.h and contains
- *	common 405 offsets
- *
- *      Armin Kuster akuster@pacbell.net
- *      Jan, 2002
- *
- *
- * Copyright 2002 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-ppc/ibm_ocp_pci.h b/include/asm-ppc/ibm_ocp_pci.h
--- a/include/asm-ppc/ibm_ocp_pci.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-ppc/ibm_ocp_pci.h	Thu Jan 16 18:23:06 2003
@@ -1,34 +1,10 @@
 /*
- * ibm_ocp_pci.h
+ * Author: Armin Kuster <akuster@mvista.com>
  *
- *	This was derived from the ibm_ocp.h 
- *
- * 	Current Maintainer
- *      Armin Kuster akuster@mvista.com
- *      AUg, 2002 
- *
- *
- * Copyright 2001-2002 MontaVista Softare Inc.
- *
- * 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.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001-2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h
--- a/include/asm-ppc/mpc10x.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-ppc/mpc10x.h	Thu Jan 16 18:23:06 2003
@@ -7,12 +7,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #ifndef __PPC_KERNEL_MPC10X_H
 #define __PPC_KERNEL_MPC10X_H
diff -Nru a/include/asm-ppc/ppc405_dma.h b/include/asm-ppc/ppc405_dma.h
--- a/include/asm-ppc/ppc405_dma.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ppc/ppc405_dma.h	Thu Jan 16 18:23:05 2003
@@ -1,17 +1,13 @@
 /*
+ * Author: Pete Popov <ppopov@mvista.com>
  *
- *    Copyright 2000 MontaVista Software Inc.
- *	PPC405 modifications
- * 	Author: MontaVista Software, Inc.
- *         	ppopov@mvista.com or source@mvista.com
- *
- *
- *    Module name: ppc405_dma.h
- *
- *    Description:
- *      Data structures specific to the IBM PowerPC 405 on-chip DMA controller
- *      and API.
+ * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  *
+ * Data structures specific to the IBM PowerPC 405 on-chip DMA controller
+ * and API.
  */
 
 #ifdef __KERNEL__
diff -Nru a/include/asm-ppc/pplus.h b/include/asm-ppc/pplus.h
--- a/include/asm-ppc/pplus.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-ppc/pplus.h	Thu Jan 16 18:23:06 2003
@@ -1,17 +1,15 @@
 /*
- * arch/ppc/kernel/pplus.h
+ * include/asm-ppc/pplus.h
  * 
  * Definitions for Motorola MCG Falcon/Raven & HAWK North Bridge & Memory ctlr.
  *
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #ifndef __ASMPPC_PPLUS_H
diff -Nru a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
--- a/include/asm-ppc/processor.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ppc/processor.h	Thu Jan 16 18:23:05 2003
@@ -50,7 +50,11 @@
 #else
 #define MSR_		(MSR_ME|MSR_RI)
 #endif
+#ifdef CONFIG_4xx
+#define MSR_KERNEL	(MSR_|MSR_IR|MSR_DR|MSR_CE|MSR_DE)
+#else
 #define MSR_KERNEL      (MSR_|MSR_IR|MSR_DR)
+#endif
 #define MSR_USER	(MSR_KERNEL|MSR_PR|MSR_EE)
 
 /* Floating Point Status and Control Register (FPSCR) Fields */
@@ -159,6 +163,7 @@
 #define	SPRN_DBCR1	0x3BD	/* Debug Control Register 1 */		  
 #define	SPRN_DBSR	0x3F0	/* Debug Status Register */		  
 #define   DBSR_IC	    0x80000000	/* Instruction Completion          */
+#define   DBSR_BT	    0x40000000	/* Branch taken */
 #define   DBSR_TIE	    0x10000000	/* Trap Instruction debug Event    */
 #define	SPRN_DCCR	0x3FA	/* Data Cache Cacheability Register */
 #define	  DCCR_NOCACHE		0	/* Noncacheable */
@@ -642,6 +647,10 @@
 	void		*pgdir;		/* root of page-table tree */
 	int		fpexc_mode;	/* floating-point exception mode */
 	signed long     last_syscall;
+#ifdef CONFIG_4xx
+	unsigned long	dbcr0;		/* debug control register values */
+	unsigned long	dbcr1;
+#endif
 	double		fpr[32];	/* Complete floating point set */
 	unsigned long	fpscr_pad;	/* fpr ... fpscr must be contiguous */
 	unsigned long	fpscr;		/* Floating point status */
diff -Nru a/include/asm-ppc/rtc.h b/include/asm-ppc/rtc.h
--- a/include/asm-ppc/rtc.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ppc/rtc.h	Thu Jan 16 18:23:05 2003
@@ -1,9 +1,13 @@
 /* 
  * inclue/asm-ppc/rtc.h
  *
- * Copyright 2002 MontaVista Software Inc.
  * Author: Tom Rini <trini@mvista.com>
  *
+ * 2002 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
  * Based on:
  * include/asm-m68k/rtc.h
  *
@@ -15,10 +19,6 @@
  * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
  *
  * With additional work by Paul Mackerras and Franz Sirl.
- */
-/* permission is hereby granted to copy, modify and redistribute this code
- * in terms of the GNU Library General Public License, Version 2 or later,
- * at your option.
  */
 
 #ifndef __ASM_RTC_H__
diff -Nru a/include/asm-ppc/todc.h b/include/asm-ppc/todc.h
--- a/include/asm-ppc/todc.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-ppc/todc.h	Thu Jan 16 18:23:06 2003
@@ -7,12 +7,10 @@
  * Author: Mark A. Greer
  *         mgreer@mvista.com
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * 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.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.1.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 /*
diff -Nru a/include/asm-ppc64/bug.h b/include/asm-ppc64/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc64/bug.h	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,33 @@
+#ifndef _PPC64_BUG_H
+#define _PPC64_BUG_H
+
+#include <linux/config.h>
+
+/*
+ * Define an illegal instr to trap on the bug.
+ * We don't use 0 because that marks the end of a function
+ * in the ELF ABI.  That's "Boo Boo" in case you wonder...
+ */
+#define BUG_OPCODE .long 0x00b00b00  /* For asm */
+#define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_XMON
+struct pt_regs;
+extern void xmon(struct pt_regs *excp);
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	xmon(0); \
+} while (0)
+#else
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	__asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
+} while (0)
+#endif
+
+#define PAGE_BUG(page) do { BUG(); } while (0)
+
+#endif
+#endif
diff -Nru a/include/asm-ppc64/module.h b/include/asm-ppc64/module.h
--- a/include/asm-ppc64/module.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ppc64/module.h	Thu Jan 16 18:23:05 2003
@@ -1,18 +1,22 @@
 #ifndef _ASM_PPC64_MODULE_H
 #define _ASM_PPC64_MODULE_H
-/*
- * This file contains the PPC architecture specific module code.
- *
- * Copyright (C) 2001 PPC 64 Team, IBM Corp
- *
- * 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 module_map(x)		vmalloc(x)
-#define module_unmap(x)		vfree(x)
-#define arch_init_modules(x)	do { } while (0)
-#define module_arch_init(x)  (0)
+struct mod_arch_specific
+{
+	/* Index of stubs section within module. */
+	unsigned int stubs_section;
+
+	/* What section is the TOC? */
+	unsigned int toc_section;
+};
+
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Ehdr Elf64_Ehdr
+
+/* Make empty section for module_frob_arch_sections to expand. */
+#ifdef MODULE
+asm(".section .stubs,\"ax\",@nobits; .align 3; .previous");
+#endif
+
 #endif /* _ASM_PPC64_MODULE_H */
diff -Nru a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
--- a/include/asm-ppc64/page.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-ppc64/page.h	Thu Jan 16 18:23:05 2003
@@ -22,13 +22,6 @@
 #define SID_MASK        0xfffffffff
 #define GET_ESID(x)     (((x) >> SID_SHIFT) & SID_MASK)
 
-/* Define an illegal instr to trap on the bug.
- * We don't use 0 because that marks the end of a function
- * in the ELF ABI.  That's "Boo Boo" in case you wonder...
- */
-#define BUG_OPCODE .long 0x00b00b00  /* For asm */
-#define BUG_ILLEGAL_INSTR "0x00b00b00" /* For BUG macro */
-
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 #include <asm/naca.h>
@@ -102,22 +95,6 @@
 #define __pgprot(x)	(x)
 
 #endif
-
-#ifdef CONFIG_XMON
-#include <asm/ptrace.h>
-extern void xmon(struct pt_regs *excp);
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	xmon(0); \
-} while (0)
-#else
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	__asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
-} while (0)
-#endif
-
-#define PAGE_BUG(page) do { BUG(); } while (0)
 
 /* Pure 2^n version of get_order */
 static inline int get_order(unsigned long size)
diff -Nru a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h
--- a/include/asm-ppc64/topology.h	Thu Jan 16 18:23:07 2003
+++ b/include/asm-ppc64/topology.h	Thu Jan 16 18:23:07 2003
@@ -46,6 +46,9 @@
 	return mask;
 }
 
+/* Cross-node load balancing interval. */
+#define NODE_BALANCE_RATE 10
+
 #else /* !CONFIG_NUMA */
 
 #define __cpu_to_node(cpu)		(0)
diff -Nru a/include/asm-s390x/compat.h b/include/asm-s390x/compat.h
--- a/include/asm-s390x/compat.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-s390x/compat.h	Thu Jan 16 18:23:05 2003
@@ -76,8 +76,15 @@
 	s32		f_files;
 	s32		f_ffree;
 	compat_fsid_t	f_fsid;
-	s32		f_namelen;  
+	s32		f_namelen;
 	s32		f_spare[6];
 };
+
+typedef u32		compat_old_sigset_t;	/* at least 32 bits */
+
+#define _COMPAT_NSIG		64
+#define _COMPAT_NSIG_BPW	32
+
+typedef u32		compat_sigset_word;
 
 #endif /* _ASM_S390X_COMPAT_H */
diff -Nru a/include/asm-sparc64/bug.h b/include/asm-sparc64/bug.h
--- a/include/asm-sparc64/bug.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-sparc64/bug.h	Thu Jan 16 18:23:06 2003
@@ -13,5 +13,8 @@
 #define BUG()		__builtin_trap()
 #endif
 
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
 
 #endif
diff -Nru a/include/asm-x86_64/bug.h b/include/asm-x86_64/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-x86_64/bug.h	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,24 @@
+#ifndef __ASM_X8664_BUG_H
+#define __ASM_X8664_BUG_H 1
+
+#include <linux/stringify.h>
+
+/*
+ * Tell the user there is some problem.  The exception handler decodes 
+ * this frame.
+ */ 
+struct bug_frame { 
+       unsigned char ud2[2];          
+	/* should use 32bit offset instead, but the assembler doesn't 
+	   like it */ 
+	char *filename;   
+	unsigned short line; 
+} __attribute__((packed)); 
+
+#define BUG() \
+	asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \
+		     "i"(__LINE__), "i" (__stringify(KBUILD_BASENAME)))
+#define PAGE_BUG(page) BUG()
+void out_of_line_bug(void);
+
+#endif
diff -Nru a/include/asm-x86_64/compat.h b/include/asm-x86_64/compat.h
--- a/include/asm-x86_64/compat.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-x86_64/compat.h	Thu Jan 16 18:23:06 2003
@@ -68,4 +68,17 @@
 	compat_pid_t	l_pid;
 };
 
+struct compat_statfs {
+	int		f_type;
+	int		f_bsize;
+	int		f_blocks;
+	int		f_bfree;
+	int		f_bavail;
+	int		f_files;
+	int		f_ffree;
+	compat_fsid_t	f_fsid;
+	int		f_namelen;	/* SunOS ignores this field. */
+	int		f_spare[6];
+};
+
 #endif /* _ASM_X86_64_COMPAT_H */
diff -Nru a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h
--- a/include/asm-x86_64/ia32.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-x86_64/ia32.h	Thu Jan 16 18:23:06 2003
@@ -101,19 +101,6 @@
 } __attribute__((packed));
 
 
-struct statfs32 {
-       int f_type;
-       int f_bsize;
-       int f_blocks;
-       int f_bfree;
-       int f_bavail;
-       int f_files;
-       int f_ffree;
-       compat_fsid_t f_fsid;
-       int f_namelen;  /* SunOS ignores this field. */
-       int f_spare[6];
-};
-
 typedef union sigval32 {
 	int sival_int;
 	unsigned int sival_ptr;
diff -Nru a/include/asm-x86_64/mmu_context.h b/include/asm-x86_64/mmu_context.h
--- a/include/asm-x86_64/mmu_context.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-x86_64/mmu_context.h	Thu Jan 16 18:23:05 2003
@@ -62,7 +62,10 @@
 #endif
 }
 
-#define deactivate_mm(tsk,mm)	do { } while (0)
+#define deactivate_mm(tsk,mm)	do { \
+	load_gs_index(0); \
+	asm volatile("movl %0,%%fs"::"r"(0));  \
+} while(0)
 
 #define activate_mm(prev, next) \
 	switch_mm((prev),(next),NULL,smp_processor_id())
diff -Nru a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
--- a/include/asm-x86_64/page.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-x86_64/page.h	Thu Jan 16 18:23:05 2003
@@ -69,21 +69,7 @@
 
 #ifndef __ASSEMBLY__
 
-#include <linux/stringify.h>
-
-/*
- * Tell the user there is some problem.  The exception handler decodes this frame.
- */ 
-struct bug_frame { 
-       unsigned char ud2[2];          
-	char *filename;    /* should use 32bit offset instead, but the assembler doesn't like it */ 
-	unsigned short line; 
-} __attribute__((packed)); 
-#define BUG() \
-	asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \
-		     "i"(__LINE__), "i" (__stringify(KBUILD_BASENAME)))
-#define PAGE_BUG(page) BUG()
-void out_of_line_bug(void);
+#include <asm/bug.h>
 
 /* Pure 2^n version of get_order */
 extern __inline__ int get_order(unsigned long size)
diff -Nru a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
--- a/include/asm-x86_64/proto.h	Thu Jan 16 18:23:06 2003
+++ b/include/asm-x86_64/proto.h	Thu Jan 16 18:23:06 2003
@@ -43,6 +43,12 @@
 extern int acpi_boot_init(char *);
 
 extern int map_syscall32(struct mm_struct *mm, unsigned long address);
+extern char *syscall32_page;
+
+struct thread_struct;
+
+int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info);
+int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info);
 
 #define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
 #define round_down(x,y) ((x) & ~((y)-1))
diff -Nru a/include/asm-x86_64/ptrace.h b/include/asm-x86_64/ptrace.h
--- a/include/asm-x86_64/ptrace.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-x86_64/ptrace.h	Thu Jan 16 18:23:05 2003
@@ -78,6 +78,10 @@
 #define PTRACE_GETFPXREGS         18
 #define PTRACE_SETFPXREGS         19
 
+#define PTRACE_GET_THREAD_AREA    25
+#define PTRACE_SET_THREAD_AREA    26
+
+
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__) 
 #define user_mode(regs) (!!((regs)->cs & 3))
 #define instruction_pointer(regs) ((regs)->rip)
diff -Nru a/include/asm-x86_64/segment.h b/include/asm-x86_64/segment.h
--- a/include/asm-x86_64/segment.h	Thu Jan 16 18:23:07 2003
+++ b/include/asm-x86_64/segment.h	Thu Jan 16 18:23:07 2003
@@ -10,7 +10,7 @@
 
 /* 
  * we cannot use the same code segment descriptor for user and kernel
- * even not in the long flat model, because of different DPL /kkeil 
+ * -- not even in the long flat mode, because of different DPL /kkeil 
  * The segment offset needs to contain a RPL. Grr. -AK
  * GDT layout to get 64bit syscall right (sysret hardcodes gdt offsets) 
  */
diff -Nru a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
--- a/include/asm-x86_64/uaccess.h	Thu Jan 16 18:23:05 2003
+++ b/include/asm-x86_64/uaccess.h	Thu Jan 16 18:23:05 2003
@@ -299,8 +299,8 @@
 
 long strncpy_from_user(char *dst, const char *src, long count);
 long __strncpy_from_user(char *dst, const char *src, long count);
-#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
 long strnlen_user(const char *str, long n);
+long strlen_user(const char *str);
 unsigned long clear_user(void *mem, unsigned long len);
 unsigned long __clear_user(void *mem, unsigned long len);
 
diff -Nru a/include/linux/compat.h b/include/linux/compat.h
--- a/include/linux/compat.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/compat.h	Thu Jan 16 18:23:05 2003
@@ -33,6 +33,12 @@
 	compat_clock_t		tms_cstime;
 };
 
+#define _COMPAT_NSIG_WORDS	(_COMPAT_NSIG / _COMPAT_NSIG_BPW)
+
+typedef struct {
+	compat_sigset_word	sig[_COMPAT_NSIG_WORDS];
+} compat_sigset_t;
+
 extern int cp_compat_stat(struct kstat *, struct compat_stat *);
 extern int get_compat_flock(struct flock *, struct compat_flock *);
 extern int put_compat_flock(struct flock *, struct compat_flock *);
diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h
--- a/include/linux/cpufreq.h	Thu Jan 16 18:23:06 2003
+++ b/include/linux/cpufreq.h	Thu Jan 16 18:23:06 2003
@@ -130,7 +130,7 @@
 int cpufreq_unregister_driver(struct cpufreq_driver *driver_data);
 /* deprecated */
 #define cpufreq_register(x)   cpufreq_register_driver(x)
-#define cpufreq_unregister(x) cpufreq_unregister_driver(NULL)
+#define cpufreq_unregister() cpufreq_unregister_driver(NULL)
 
 
 void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state);
diff -Nru a/include/linux/devfs_fs_kernel.h b/include/linux/devfs_fs_kernel.h
--- a/include/linux/devfs_fs_kernel.h	Thu Jan 16 18:23:06 2003
+++ b/include/linux/devfs_fs_kernel.h	Thu Jan 16 18:23:06 2003
@@ -21,9 +21,6 @@
 #define DEVFS_FL_DEFAULT        DEVFS_FL_NONE
 
 
-#define DEVFS_SPECIAL_CHR     0
-#define DEVFS_SPECIAL_BLK     1
-
 typedef struct devfs_entry * devfs_handle_t;
 
 #ifdef CONFIG_DEVFS_FS
@@ -58,10 +55,6 @@
 extern int devfs_only (void);
 extern int devfs_register_tape (devfs_handle_t de);
 extern void devfs_unregister_tape(int num);
-extern int devfs_alloc_major (char type);
-extern void devfs_dealloc_major (char type, int major);
-extern dev_t devfs_alloc_devnum (char type);
-extern void devfs_dealloc_devnum (char type, dev_t devnum);
 extern int devfs_alloc_unique_number (struct unique_numspace *space);
 extern void devfs_dealloc_unique_number (struct unique_numspace *space,
 					 int number);
@@ -129,41 +122,18 @@
 static inline void devfs_unregister_tape(int num)
 {
 }
-static inline int devfs_alloc_major (char type)
-{
-    return -1;
-}
-
-static inline void devfs_dealloc_major (char type, int major)
-{
-    return;
-}
-
-static inline dev_t devfs_alloc_devnum (char type)
-{
-    return 0;
-}
-
-static inline void devfs_dealloc_devnum (char type, dev_t devnum)
-{
-    return;
-}
-
 static inline int devfs_alloc_unique_number (struct unique_numspace *space)
 {
     return -1;
 }
-
 static inline void devfs_dealloc_unique_number (struct unique_numspace *space,
 						int number)
 {
     return;
 }
-
 static inline void mount_devfs_fs (void)
 {
     return;
 }
 #endif  /*  CONFIG_DEVFS_FS  */
-
 #endif  /*  _LINUX_DEVFS_FS_KERNEL_H  */
diff -Nru a/include/linux/eisa.h b/include/linux/eisa.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/eisa.h	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,60 @@
+#ifndef _LINUX_EISA_H
+#define _LINUX_EISA_H
+
+#define EISA_SIG_LEN   8
+#define EISA_MAX_SLOTS 8
+
+/* A few EISA constants/offsets... */
+
+#define EISA_DMA1_STATUS            8
+#define EISA_INT1_CTRL           0x20
+#define EISA_INT1_MASK           0x21
+#define EISA_INT2_CTRL           0xA0
+#define EISA_INT2_MASK           0xA1
+#define EISA_DMA2_STATUS         0xD0
+#define EISA_DMA2_WRITE_SINGLE   0xD4
+#define EISA_EXT_NMI_RESET_CTRL 0x461
+#define EISA_INT1_EDGE_LEVEL    0x4D0
+#define EISA_INT2_EDGE_LEVEL    0x4D1
+#define EISA_VENDOR_ID_OFFSET   0xC80
+
+/* The EISA signature, in ASCII form, null terminated */
+struct eisa_device_id {
+	char sig[EISA_SIG_LEN];
+};
+
+/* There is not much we can say about an EISA device, apart from
+ * signature, slot number, and base address */
+struct eisa_device {
+	struct eisa_device_id id;
+	int                   slot;
+	unsigned long         base_addr;
+	struct resource       res;
+	struct device         dev; /* generic device */
+};
+
+#define to_eisa_device(n) container_of(n, struct eisa_device, dev)
+
+struct eisa_driver {
+	const struct eisa_device_id *id_table;
+	struct device_driver         driver;
+};
+
+#define to_eisa_driver(drv) container_of(drv,struct eisa_driver, driver)
+
+extern struct bus_type eisa_bus_type;
+int eisa_driver_register (struct eisa_driver *edrv);
+void eisa_driver_unregister (struct eisa_driver *edrv);
+
+/* Mimics pci.h... */
+static inline void *eisa_get_drvdata (struct eisa_device *edev)
+{
+        return edev->dev.driver_data;
+}
+
+static inline void eisa_set_drvdata (struct eisa_device *edev, void *data)
+{
+        edev->dev.driver_data = data;
+}
+
+#endif
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h	Thu Jan 16 18:23:06 2003
+++ b/include/linux/ext3_fs.h	Thu Jan 16 18:23:06 2003
@@ -707,7 +707,7 @@
 /* ialloc.c */
 extern struct inode * ext3_new_inode (handle_t *, struct inode *, int);
 extern void ext3_free_inode (handle_t *, struct inode *);
-extern struct inode * ext3_orphan_get (struct super_block *, ino_t);
+extern struct inode * ext3_orphan_get (struct super_block *, unsigned long);
 extern unsigned long ext3_count_free_inodes (struct super_block *);
 extern unsigned long ext3_count_dirs (struct super_block *);
 extern void ext3_check_inodes_bitmap (struct super_block *);
diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
--- a/include/linux/ext3_jbd.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/ext3_jbd.h	Thu Jan 16 18:23:05 2003
@@ -132,16 +132,6 @@
 	return err;
 }
 
-static inline int
-__ext3_journal_dirty_data(const char *where,
-			  handle_t *handle, struct buffer_head *bh, int async)
-{
-	int err = journal_dirty_data(handle, bh, async);
-	if (err)
-		ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
-	return err;
-}
-
 static inline void
 ext3_journal_forget(handle_t *handle, struct buffer_head *bh)
 {
@@ -183,8 +173,6 @@
 	__ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh))
 #define ext3_journal_get_write_access(handle, bh) \
 	__ext3_journal_get_write_access(__FUNCTION__, (handle), (bh))
-#define ext3_journal_dirty_data(handle, bh, async) \
-	__ext3_journal_dirty_data(__FUNCTION__, (handle), (bh), (async))
 #define ext3_journal_revoke(handle, blocknr, bh) \
 	__ext3_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh))
 #define ext3_journal_get_create_access(handle, bh) \
diff -Nru a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/fb.h	Thu Jan 16 18:23:05 2003
@@ -240,6 +240,9 @@
 	__u32 hfmax; 			/* hfreq upper limit (Hz) */
 	__u16 vfmin;			/* vfreq lower limit (Hz) */
 	__u16 vfmax;			/* vfreq upper limit (Hz) */
+	__u32 dclkmin;                  /* pixelclock lower limit (Hz) */
+	__u32 dclkmax;                  /* pixelclock upper limit (Hz) */
+	unsigned gtf  : 1;              /* supports GTF */
 	unsigned dpms : 1;		/* supports DPMS */
 };
 
@@ -466,9 +469,19 @@
 extern int num_registered_fb;
 
 /* drivers/video/fbmon.c */
+#define FB_MAXTIMINGS       0
+#define FB_VSYNCTIMINGS     1
+#define FB_HSYNCTIMINGS     2
+#define FB_DCLKTIMINGS      3
+#define FB_IGNOREMON    0x100
+
 extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal,
 			       const struct fb_info *fb_info);
 extern int fbmon_dpms(const struct fb_info *fb_info);
+extern int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
+		       struct fb_info *info);
+extern int fb_validate_mode(struct fb_var_screeninfo *var,
+			    struct fb_info *info);
 
 /* drivers/video/fbcmap.c */
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
diff -Nru a/include/linux/font.h b/include/linux/font.h
--- a/include/linux/font.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/font.h	Thu Jan 16 18:23:05 2003
@@ -8,10 +8,18 @@
  *  for more details.
  */
 
-#ifndef _VIDEO_CONSOLE_FONT_H
-#define _VIDEO_CONSOLE_FONT_H
+#ifndef _VIDEO_FONT_H
+#define _VIDEO_FONT_H
 
-#include <video/font.h>		/* struct font_desc */
+#include <linux/types.h>
+
+struct font_desc {
+    int idx;
+    char *name;
+    int width, height;
+    void *data;
+    int pref;
+};
 
 #define VGA8x8_IDX	0
 #define VGA8x16_IDX	1
@@ -23,13 +31,13 @@
 #define	MINI4x6_IDX	7
 
 extern struct font_desc	font_vga_8x8,
-			font_vga_8x16,
-			font_pearl_8x8,
-			font_vga_6x11,
-			font_sun_8x16,
-			font_sun_12x22,
-			font_acorn_8x8,
-			font_mini_4x6;
+				font_vga_8x16,
+				font_pearl_8x8,
+				font_vga_6x11,
+				font_sun_8x16,
+				font_sun_12x22,
+				font_acorn_8x8,
+				font_mini_4x6;
 
 /* Find a font with a specific name */
 
@@ -42,4 +50,4 @@
 /* Max. length for the name of a predefined font */
 #define MAX_FONT_NAME	32
 
-#endif /* _VIDEO_CONSOLE_FONT_H */
+#endif /* _VIDEO_FONT_H */
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/fs.h	Thu Jan 16 18:23:05 2003
@@ -404,9 +404,6 @@
 	} u;
 };
 
-/* will die */
-#include <linux/coda_fs_i.h>
-
 struct fown_struct {
 	rwlock_t lock;          /* protects pid, uid, euid fields */
 	int pid;		/* pid or -pgrp where SIGIO should be sent */
@@ -992,8 +989,6 @@
 extern int may_umount(struct vfsmount *);
 extern long do_mount(char *, char *, char *, unsigned long, void *);
 
-#define kern_umount mntput
-
 extern int vfs_statfs(struct super_block *, struct statfs *);
 
 /* Return value for VFS lock functions - tells locks.c to lock conventionally
@@ -1103,6 +1098,7 @@
 {
 	return __bdevname(bdev->bd_dev);
 }
+extern struct block_device *lookup_bdev(const char *);
 extern struct block_device *open_bdev_excl(const char *, int, int, void *);
 extern void close_bdev_excl(struct block_device *, int);
 
diff -Nru a/include/linux/i2c.h b/include/linux/i2c.h
--- a/include/linux/i2c.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/i2c.h	Thu Jan 16 18:23:05 2003
@@ -484,14 +484,6 @@
 
 #define I2C_MAJOR	89		/* Device major number		*/
 
-#  ifndef NULL
-#    define NULL ( (void *) 0 )
-#  endif
-
-#  ifndef ENODEV
-#    include <asm/errno.h>
-#  endif
-
 /* These defines are used for probing i2c client addresses */
 /* Default fill of many variables */
 #define I2C_CLIENT_DEFAULTS {I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \
diff -Nru a/include/linux/jbd.h b/include/linux/jbd.h
--- a/include/linux/jbd.h	Thu Jan 16 18:23:06 2003
+++ b/include/linux/jbd.h	Thu Jan 16 18:23:06 2003
@@ -360,13 +360,6 @@
 	 */
 	struct journal_head *	t_sync_datalist;
 	
-	/*
-	 * Doubly-linked circular list of all writepage data buffers
-	 * still to be written before this transaction can be committed.
-	 * Protected by journal_datalist_lock.
-	 */
-	struct journal_head *	t_async_datalist;
-	
 	/* Doubly-linked circular list of all forget buffers (superseded
            buffers which we can un-checkpoint once this transaction
            commits) */
@@ -654,8 +647,7 @@
 extern int	 journal_get_write_access (handle_t *, struct buffer_head *);
 extern int	 journal_get_create_access (handle_t *, struct buffer_head *);
 extern int	 journal_get_undo_access (handle_t *, struct buffer_head *);
-extern int	 journal_dirty_data (handle_t *,
-				struct buffer_head *, int async);
+extern int	 journal_dirty_data (handle_t *, struct buffer_head *);
 extern int	 journal_dirty_metadata (handle_t *, struct buffer_head *);
 extern void	 journal_release_buffer (handle_t *, struct buffer_head *);
 extern void	 journal_forget (handle_t *, struct buffer_head *);
@@ -806,14 +798,13 @@
 /* journaling buffer types */
 #define BJ_None		0	/* Not journaled */
 #define BJ_SyncData	1	/* Normal data: flush before commit */
-#define BJ_AsyncData	2	/* writepage data: wait on it before commit */
-#define BJ_Metadata	3	/* Normal journaled metadata */
-#define BJ_Forget	4	/* Buffer superseded by this transaction */
-#define BJ_IO		5	/* Buffer is for temporary IO use */
-#define BJ_Shadow	6	/* Buffer contents being shadowed to the log */
-#define BJ_LogCtl	7	/* Buffer contains log descriptors */
-#define BJ_Reserved	8	/* Buffer is reserved for access by journal */
-#define BJ_Types	9
+#define BJ_Metadata	2	/* Normal journaled metadata */
+#define BJ_Forget	3	/* Buffer superseded by this transaction */
+#define BJ_IO		4	/* Buffer is for temporary IO use */
+#define BJ_Shadow	5	/* Buffer contents being shadowed to the log */
+#define BJ_LogCtl	6	/* Buffer contains log descriptors */
+#define BJ_Reserved	7	/* Buffer is reserved for access by journal */
+#define BJ_Types	8
  
 extern int jbd_blocks_per_page(struct inode *inode);
 
@@ -860,8 +851,7 @@
 static inline int buffer_jbd_data(struct buffer_head *bh)
 {
 	return SPLICE_LOCK(buffer_jbd(bh),
-			bh2jh(bh)->b_jlist == BJ_SyncData ||
-			bh2jh(bh)->b_jlist == BJ_AsyncData);
+			bh2jh(bh)->b_jlist == BJ_SyncData);
 }
 
 #ifdef CONFIG_SMP
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/kobject.h	Thu Jan 16 18:23:05 2003
@@ -87,7 +87,7 @@
 }
 
 
-extern struct kobject * kset_find_obj(struct kset *, char *);
+extern struct kobject * kset_find_obj(struct kset *, const char *);
 
 
 struct subsystem {
diff -Nru a/include/linux/miscdevice.h b/include/linux/miscdevice.h
--- a/include/linux/miscdevice.h	Thu Jan 16 18:23:06 2003
+++ b/include/linux/miscdevice.h	Thu Jan 16 18:23:06 2003
@@ -18,6 +18,7 @@
 #define RTC_MINOR 135
 #define EFI_RTC_MINOR		136	/* EFI Time services */
 #define SUN_OPENPROM_MINOR 139
+#define DMAPI_MINOR		140	/* DMAPI */
 #define NVRAM_MINOR 144
 #define I2O_MINOR 166
 #define MICROCODE_MINOR		184
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/mm.h	Thu Jan 16 18:23:05 2003
@@ -296,9 +296,10 @@
 	page->flags |= zone_num << ZONE_SHIFT;
 }
 
-#define lowmem_page_address(page)					\
-	__va( ( ((page) - page_zone(page)->zone_mem_map)		\
-			+ page_zone(page)->zone_start_pfn) << PAGE_SHIFT)
+static inline void * lowmem_page_address(struct page *page)
+{
+	return __va( ( (page - page_zone(page)->zone_mem_map)	+ page_zone(page)->zone_start_pfn) << PAGE_SHIFT);
+}
 
 #if defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL)
 #define HASHED_PAGE_VIRTUAL
diff -Nru a/include/linux/mmzone.h b/include/linux/mmzone.h
--- a/include/linux/mmzone.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/mmzone.h	Thu Jan 16 18:23:05 2003
@@ -193,7 +193,8 @@
 extern int numnodes;
 extern struct pglist_data *pgdat_list;
 
-void get_zone_counts(unsigned long *active, unsigned long *inactive);
+void get_zone_counts(unsigned long *active, unsigned long *inactive,
+			unsigned long *free);
 void build_all_zonelists(void);
 void wakeup_kswapd(struct zone *zone);
 
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h	Thu Jan 16 18:23:06 2003
+++ b/include/linux/module.h	Thu Jan 16 18:23:06 2003
@@ -36,7 +36,7 @@
 struct kernel_symbol
 {
 	unsigned long value;
-	char name[MODULE_NAME_LEN];
+	const char *name;
 };
 
 /* These are either module local, or the kernel's dummy ones. */
@@ -140,17 +140,23 @@
 #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
 
 /* For every exported symbol, place a struct in the __ksymtab section */
-#define EXPORT_SYMBOL(sym)				\
-	const struct kernel_symbol __ksymtab_##sym	\
-	__attribute__((section("__ksymtab")))		\
-	= { (unsigned long)&sym, MODULE_SYMBOL_PREFIX #sym }
+#define EXPORT_SYMBOL(sym)					\
+	static const char __kstrtab_##sym[]			\
+	__attribute__((section("__ksymtab_strings")))		\
+	= MODULE_SYMBOL_PREFIX #sym;                    	\
+	static const struct kernel_symbol __ksymtab_##sym	\
+	__attribute__((section("__ksymtab")))			\
+	= { (unsigned long)&sym, __kstrtab_##sym }
 
 #define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
 
-#define EXPORT_SYMBOL_GPL(sym)				\
-	const struct kernel_symbol __ksymtab_##sym	\
-	__attribute__((section("__gpl_ksymtab")))	\
-	= { (unsigned long)&sym, #sym }
+#define EXPORT_SYMBOL_GPL(sym)					\
+	static const char __kstrtab_##sym[]			\
+	__attribute__((section("__ksymtab_strings")))		\
+	= MODULE_SYMBOL_PREFIX #sym;                    	\
+	static const struct kernel_symbol __ksymtab_##sym	\
+	__attribute__((section("__gpl_ksymtab")))		\
+	= { (unsigned long)&sym, __kstrtab_##sym }
 
 struct module_ref
 {
@@ -431,9 +437,6 @@
 #endif
 }
 #define EXPORT_NO_SYMBOLS
-extern int module_dummy_usage;
-#define GET_USE_COUNT(module) (module_dummy_usage)
-#define MOD_IN_USE 0
 #define __MODULE_STRING(x) __stringify(x)
 
 /*
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	Thu Jan 16 18:23:07 2003
+++ b/include/linux/netdevice.h	Thu Jan 16 18:23:07 2003
@@ -480,6 +480,7 @@
 extern int		unregister_netdevice(struct net_device *dev);
 extern int 		register_netdevice_notifier(struct notifier_block *nb);
 extern int		unregister_netdevice_notifier(struct notifier_block *nb);
+extern int		call_netdevice_notifiers(unsigned long val, void *v);
 extern int		dev_new_index(void);
 extern struct net_device	*dev_get_by_index(int ifindex);
 extern struct net_device	*__dev_get_by_index(int ifindex);
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/sched.h	Thu Jan 16 18:23:05 2003
@@ -27,6 +27,7 @@
 #include <linux/compiler.h>
 #include <linux/completion.h>
 #include <linux/pid.h>
+#include <linux/percpu.h>
 
 struct exec_domain;
 
@@ -87,6 +88,8 @@
 
 extern int nr_threads;
 extern int last_pid;
+DECLARE_PER_CPU(unsigned long, process_counts);
+extern int nr_processes(void);
 extern unsigned long nr_running(void);
 extern unsigned long nr_uninterruptible(void);
 extern unsigned long nr_iowait(void);
@@ -442,6 +445,14 @@
 extern void set_cpus_allowed(task_t *p, unsigned long new_mask);
 #else
 # define set_cpus_allowed(p, new_mask) do { } while (0)
+#endif
+
+#ifdef CONFIG_NUMA
+extern void sched_balance_exec(void);
+extern void node_nr_running_init(void);
+#else
+#define sched_balance_exec()   {}
+#define node_nr_running_init() {}
 #endif
 
 extern void set_user_nice(task_t *p, long nice);
diff -Nru a/include/linux/tty_driver.h b/include/linux/tty_driver.h
--- a/include/linux/tty_driver.h	Thu Jan 16 18:23:06 2003
+++ b/include/linux/tty_driver.h	Thu Jan 16 18:23:06 2003
@@ -120,6 +120,7 @@
 
 struct tty_driver {
 	int	magic;		/* magic number for this structure */
+	struct module	*owner;
 	const char	*driver_name;
 	const char	*name;
 	int	name_base;	/* offset of printed name */
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Thu Jan 16 18:23:05 2003
+++ b/include/linux/usb.h	Thu Jan 16 18:23:05 2003
@@ -277,7 +277,9 @@
 const struct usb_device_id *usb_match_id(struct usb_interface *interface,
 					 const struct usb_device_id *id);
 
-struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev);
+extern struct usb_interface *usb_find_interface(struct usb_driver *drv, kdev_t kdev);
+extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum);
+
 
 /**
  * usb_make_path - returns stable device path in the usb tree
diff -Nru a/include/linux/xattr.h b/include/linux/xattr.h
--- a/include/linux/xattr.h	Thu Jan 16 18:23:06 2003
+++ b/include/linux/xattr.h	Thu Jan 16 18:23:06 2003
@@ -4,7 +4,7 @@
   Extended attributes handling.
 
   Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
-  Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
+  Copyright (c) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
 */
 #ifndef _LINUX_XATTR_H
 #define _LINUX_XATTR_H
diff -Nru a/include/video/font.h b/include/video/font.h
--- a/include/video/font.h	Thu Jan 16 18:23:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,24 +0,0 @@
-/*
- *  font.h -- `Soft' font definitions
- *
- *  Created 1995 by Geert Uytterhoeven
- *
- *  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.
- */
-
-#ifndef _VIDEO_FONT_H
-#define _VIDEO_FONT_H
-
-#include <linux/types.h>
-
-struct font_desc {
-    int idx;
-    char *name;
-    int width, height;
-    void *data;
-    int pref;
-};
-
-#endif /* _VIDEO_FONT_H */
diff -Nru a/include/video/trident.h b/include/video/trident.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/video/trident.h	Thu Jan 16 18:23:05 2003
@@ -0,0 +1,175 @@
+
+#ifndef TRIDENTFB_DEBUG
+#define TRIDENTFB_DEBUG 0
+#endif
+
+#if TRIDENTFB_DEBUG
+#define debug(f,a...)	printk("%s:" f,  __FUNCTION__ , ## a);mdelay(1000);
+#else
+#define debug(f,a...)
+#endif
+
+#define output(f, a...) printk("tridentfb: " f, ## a)
+
+#define Kb	(1024)
+#define Mb	(Kb*Kb)
+
+/* PCI IDS of supported cards temporarily here */
+
+#define CYBER9320	0x9320
+#define CYBER9388	0x9388
+#define CYBER9382	0x9382		/* the real PCI id for this is 9660 */
+#define CYBER9385	0x9385		/* ditto */		
+#define CYBER9397	0x9397
+#define CYBER9397DVD	0x939A
+#define CYBER9520	0x9520
+#define CYBER9525DVD	0x9525
+#define TGUI9660	0x9660
+#define IMAGE975	0x9750
+#define IMAGE985	0x9850
+#define BLADE3D		0x9880
+#define CYBERBLADEE4	0x9540
+#define CYBERBLADEi7	0x8400
+#define CYBERBLADEi7D	0x8420
+#define CYBERBLADEi1	0x8500
+#define CYBERBLADEi1D	0x8520
+#define CYBERBLADEAi1	0x8600
+#define CYBERBLADEAi1D	0x8620
+#define CYBERBLADEXPAi1 0x8820
+#define CYBERBLADEXPm8  0x9910
+#define CYBERBLADEXPm16 0x9930
+
+/* acceleration families */
+#define IMAGE	0
+#define BLADE	1
+#define XP	2
+
+#define is_image(id)	
+#define is_xp(id)	((id == CYBERBLADEXPAi1) ||\
+			 (id == CYBERBLADEXPm8) ||\
+			 (id == CYBERBLADEXPm16)) 
+
+#define is_blade(id)	((id == BLADE3D) ||\
+			 (id == CYBERBLADEE4) ||\
+			 (id == CYBERBLADEi7) ||\
+			 (id == CYBERBLADEi7D) ||\
+			 (id == CYBERBLADEi1) ||\
+			 (id == CYBERBLADEi1D) ||\
+			 (id ==	CYBERBLADEAi1) ||\
+			 (id ==	CYBERBLADEAi1D))
+
+/* these defines are for 'lcd' variable */
+#define LCD_STRETCH	0
+#define LCD_CENTER	1
+#define LCD_BIOS	2
+
+/* display types */
+#define DISPLAY_CRT	0
+#define DISPLAY_FP	1
+
+#define flatpanel (displaytype == DISPLAY_FP)
+
+/* General Registers */
+#define SPR	0x1F		/* Software Programming Register (videoram) */
+
+/* 3C4 */
+#define RevisionID 0x09
+#define OldOrNew 0x0B	
+#define ConfPort1 0x0C
+#define ConfPort2 0x0C
+#define NewMode2 0x0D
+#define NewMode1 0x0E
+#define Protection 0x11
+#define MCLKLow 0x16
+#define MCLKHigh 0x17
+#define ClockLow 0x18
+#define ClockHigh 0x19
+#define SSetup 0x20
+#define SKey 0x37
+#define SPKey 0x57
+
+/* 0x3x4 */
+#define CRTHTotal	0x00
+#define CRTHDispEnd	0x01
+#define CRTHBlankStart	0x02
+#define CRTHBlankEnd	0x03
+#define CRTHSyncStart	0x04
+#define CRTHSyncEnd	0x05
+
+#define CRTVTotal	0x06
+#define CRTVDispEnd	0x12
+#define CRTVBlankStart	0x15
+#define CRTVBlankEnd	0x16
+#define CRTVSyncStart	0x10
+#define CRTVSyncEnd	0x11
+
+#define CRTOverflow	0x07
+#define CRTPRowScan	0x08
+#define CRTMaxScanLine	0x09
+#define CRTModeControl	0x17
+#define CRTLineCompare	0x18
+
+/* 3x4 */
+#define StartAddrHigh 0x0C
+#define StartAddrLow 0x0D
+#define Offset 0x13
+#define Underline 0x14
+#define CRTCMode 0x17
+#define CRTCModuleTest 0x1E
+#define FIFOControl 0x20
+#define LinearAddReg 0x21
+#define DRAMTiming 0x23
+#define New32 0x23
+#define RAMDACTiming 0x25
+#define CRTHiOrd 0x27
+#define AddColReg 0x29
+#define InterfaceSel 0x2A
+#define HorizOverflow 0x2B
+#define GETest 0x2D
+#define Performance 0x2F
+#define GraphEngReg 0x36
+#define I2C 0x37
+#define PixelBusReg 0x38
+#define PCIReg 0x39
+#define DRAMControl 0x3A
+#define MiscContReg 0x3C
+#define CursorXLow 0x40
+#define CursorXHigh 0x41
+#define CursorYLow 0x42
+#define CursorYHigh 0x43
+#define CursorLocLow 0x44
+#define CursorLocHigh 0x45
+#define CursorXOffset 0x46
+#define CursorYOffset 0x47
+#define CursorFG1 0x48
+#define CursorFG2 0x49
+#define CursorFG3 0x4A
+#define CursorFG4 0x4B
+#define CursorBG1 0x4C
+#define CursorBG2 0x4D
+#define CursorBG3 0x4E
+#define CursorBG4 0x4F
+#define CursorControl 0x50
+#define PCIRetry 0x55
+#define PreEndControl 0x56
+#define PreEndFetch 0x57
+#define PCIMaster 0x60
+#define Enhancement0 0x62
+#define NewEDO 0x64
+#define TVinterface 0xC0
+#define TVMode 0xC1
+#define ClockControl 0xCF
+
+
+/* 3CE */
+#define MiscExtFunc 0x0F
+#define PowerStatus 0x23
+#define MiscIntContReg 0x2F
+#define CyberControl 0x30
+#define CyberEnhance 0x31
+#define FPConfig     0x33
+#define VertStretch  0x52
+#define HorStretch   0x53
+#define BiosMode     0x5c
+#define BiosReg      0x5d
+
diff -Nru a/init/Kconfig b/init/Kconfig
--- a/init/Kconfig	Thu Jan 16 18:23:06 2003
+++ b/init/Kconfig	Thu Jan 16 18:23:06 2003
@@ -82,50 +82,21 @@
 	  building a kernel for install/rescue disks or your system is very
 	  limited in memory.
 
-choice
-	prompt "Kernel log buffer size"
-	default LOG_BUF_SHIFT_17 if ARCH_S390
-	default LOG_BUF_SHIFT_16 if X86_NUMAQ || IA64
-	default LOG_BUF_SHIFT_15 if SMP
-	default LOG_BUF_SHIFT_14
-	help
-	  Select kernel log buffer size from this list (power of 2).
-	  Defaults:  17 (=> 128 KB for S/390)
-		     16 (=> 64 KB for x86 NUMAQ or IA-64)
-	             15 (=> 32 KB for SMP)
-	             14 (=> 16 KB for uniprocessor)
-
-config LOG_BUF_SHIFT_17
-	bool "128 KB"
-	default y if ARCH_S390
-
-config LOG_BUF_SHIFT_16
-	bool "64 KB"
-	default y if X86_NUMAQ || IA64
-
-config LOG_BUF_SHIFT_15
-	bool "32 KB"
-	default y if SMP
-
-config LOG_BUF_SHIFT_14
-	bool "16 KB"
-
-config LOG_BUF_SHIFT_13
-	bool "8 KB"
-
-config LOG_BUF_SHIFT_12
-	bool "4 KB"
-
-endchoice
-
 config LOG_BUF_SHIFT
-	int
-	default 17 if LOG_BUF_SHIFT_17=y
-	default 16 if LOG_BUF_SHIFT_16=y
-	default 15 if LOG_BUF_SHIFT_15=y
-	default 14 if LOG_BUF_SHIFT_14=y
-	default 13 if LOG_BUF_SHIFT_13=y
-	default 12 if LOG_BUF_SHIFT_12=y
+	int "Kernel log buffer size" if DEBUG_KERNEL
+	default 17 if ARCH_S390
+	default 16 if X86_NUMAQ || IA64
+	default 15 if SMP
+	default 14
+	help
+	  Select kernel log buffer size as a power of 2.
+	  Defaults and Examples:
+	  	     17 => 128 KB for S/390
+		     16 => 64 KB for x86 NUMAQ or IA-64
+	             15 => 32 KB for SMP
+	             14 => 16 KB for uniprocessor
+		     13 =>  8 KB
+		     12 =>  4 KB
 
 endmenu
 
diff -Nru a/init/Makefile b/init/Makefile
--- a/init/Makefile	Thu Jan 16 18:23:05 2003
+++ b/init/Makefile	Thu Jan 16 18:23:05 2003
@@ -2,7 +2,8 @@
 # Makefile for the linux kernel.
 #
 
-obj-y    := main.o version.o do_mounts.o initramfs.o
+obj-y			:= main.o version.o do_mounts.o initramfs.o
+obj-$(CONFIG_MODULES)	+= vermagic.o
 
 # files to be removed upon make clean
 clean-files := ../include/linux/compile.h
diff -Nru a/init/main.c b/init/main.c
--- a/init/main.c	Thu Jan 16 18:23:05 2003
+++ b/init/main.c	Thu Jan 16 18:23:05 2003
@@ -495,6 +495,7 @@
 
 	migration_init();
 #endif
+	node_nr_running_init();
 	spawn_ksoftirqd();
 }
 
diff -Nru a/init/vermagic.c b/init/vermagic.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/init/vermagic.c	Thu Jan 16 18:23:07 2003
@@ -0,0 +1,22 @@
+#include <linux/version.h>
+#include <linux/module.h>
+
+/* Simply sanity version stamp for modules. */
+#ifdef CONFIG_SMP
+#define MODULE_VERMAGIC_SMP "SMP "
+#else
+#define MODULE_VERMAGIC_SMP ""
+#endif
+#ifdef CONFIG_PREEMPT
+#define MODULE_VERMAGIC_PREEMPT "preempt "
+#else
+#define MODULE_VERMAGIC_PREEMPT ""
+#endif
+#ifndef MODULE_ARCH_VERMAGIC
+#define MODULE_ARCH_VERMAGIC ""
+#endif
+
+const char vermagic[] __attribute__((section("__vermagic"))) =
+       UTS_RELEASE " "
+       MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT MODULE_ARCH_VERMAGIC
+       "gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__);
diff -Nru a/kernel/compat.c b/kernel/compat.c
--- a/kernel/compat.c	Thu Jan 16 18:23:06 2003
+++ b/kernel/compat.c	Thu Jan 16 18:23:06 2003
@@ -4,7 +4,7 @@
  *  Kernel compatibililty routines for e.g. 32 bit syscall support
  *  on 64 bit kernels.
  *
- *  Copyright (C) 2002 Stephen Rothwell, IBM Corporation
+ *  Copyright (C) 2002-2003 Stephen Rothwell, IBM Corporation
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
@@ -15,6 +15,7 @@
 #include <linux/compat.h>
 #include <linux/errno.h>
 #include <linux/time.h>
+#include <linux/signal.h>
 
 #include <asm/uaccess.h>
 
@@ -165,4 +166,45 @@
 			return -EFAULT;
 	}
 	return compat_jiffies_to_clock_t(jiffies);
+}
+
+/*
+ * Assumption: old_sigset_t and compat_old_sigset_t are both
+ * types that can be passed to put_user()/get_user().
+ */
+
+extern asmlinkage long sys_sigpending(old_sigset_t *);
+
+asmlinkage long compat_sys_sigpending(compat_old_sigset_t *set)
+{
+	old_sigset_t s;
+	long ret;
+	mm_segment_t old_fs = get_fs();
+
+	set_fs(KERNEL_DS);
+	ret = sys_sigpending(&s);
+	set_fs(old_fs);
+	if (ret == 0)
+		ret = put_user(s, set);
+	return ret;
+}
+
+extern asmlinkage long sys_sigprocmask(int, old_sigset_t *, old_sigset_t *);
+
+asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t *set,
+		compat_old_sigset_t *oset)
+{
+	old_sigset_t s;
+	long ret;
+	mm_segment_t old_fs;
+
+	if (set && get_user(s, set))
+		return -EFAULT;
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
+	set_fs(old_fs);
+	if (ret == 0)
+		ret = put_user(s, oset);
+	return ret;
 }
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	Thu Jan 16 18:23:06 2003
+++ b/kernel/exit.c	Thu Jan 16 18:23:06 2003
@@ -41,6 +41,8 @@
 	if (thread_group_leader(p)) {
 		detach_pid(p, PIDTYPE_PGID);
 		detach_pid(p, PIDTYPE_SID);
+		if (p->pid)
+			per_cpu(process_counts, smp_processor_id())--;
 	}
 
 	REMOVE_LINKS(p);
@@ -191,7 +193,7 @@
 	return will_become_orphaned_pgrp(pgrp, 0);
 }
 
-static inline int __has_stopped_jobs(int pgrp)
+static inline int has_stopped_jobs(int pgrp)
 {
 	int retval = 0;
 	struct task_struct *p;
@@ -207,17 +209,6 @@
 	return retval;
 }
 
-static inline int has_stopped_jobs(int pgrp)
-{
-	int retval;
-
-	read_lock(&tasklist_lock);
-	retval = __has_stopped_jobs(pgrp);
-	read_unlock(&tasklist_lock);
-
-	return retval;
-}
-
 /**
  * reparent_to_init() - Reparent the calling kernel thread to the init task.
  *
@@ -504,7 +495,7 @@
 	    (p->session == father->session)) {
 		int pgrp = p->pgrp;
 
-		if (__will_become_orphaned_pgrp(pgrp, 0) && __has_stopped_jobs(pgrp)) {
+		if (__will_become_orphaned_pgrp(pgrp, 0) && has_stopped_jobs(pgrp)) {
 			__kill_pg_info(SIGHUP, (void *)1, pgrp);
 			__kill_pg_info(SIGCONT, (void *)1, pgrp);
 		}
@@ -589,7 +580,7 @@
 	if ((t->pgrp != current->pgrp) &&
 	    (t->session == current->session) &&
 	    __will_become_orphaned_pgrp(current->pgrp, current) &&
-	    __has_stopped_jobs(current->pgrp)) {
+	    has_stopped_jobs(current->pgrp)) {
 		__kill_pg_info(SIGHUP, (void *)1, current->pgrp);
 		__kill_pg_info(SIGCONT, (void *)1, current->pgrp);
 	}
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Thu Jan 16 18:23:05 2003
+++ b/kernel/fork.c	Thu Jan 16 18:23:05 2003
@@ -48,6 +48,8 @@
 int max_threads;
 unsigned long total_forks;	/* Handle normal Linux uptimes. */
 
+DEFINE_PER_CPU(unsigned long, process_counts) = 0;
+
 rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;  /* outer */
 
 /*
@@ -57,6 +59,18 @@
  */
 static task_t *task_cache[NR_CPUS] __cacheline_aligned;
 
+int nr_processes(void)
+{
+	int cpu;
+	int total = 0;
+
+	for (cpu = 0; cpu < NR_CPUS; cpu++) {
+		if (cpu_online(cpu))
+			total += per_cpu(process_counts, cpu);
+	}
+	return total;
+}
+
 void __put_task_struct(struct task_struct *tsk)
 {
 	if (tsk != current) {
@@ -931,6 +945,8 @@
 		attach_pid(p, PIDTYPE_TGID, p->tgid);
 		attach_pid(p, PIDTYPE_PGID, p->pgrp);
 		attach_pid(p, PIDTYPE_SID, p->session);
+		if (p->pid)
+			per_cpu(process_counts, smp_processor_id())++;
 	} else
 		link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid);
 
diff -Nru a/kernel/kallsyms.c b/kernel/kallsyms.c
--- a/kernel/kallsyms.c	Thu Jan 16 18:23:07 2003
+++ b/kernel/kallsyms.c	Thu Jan 16 18:23:07 2003
@@ -9,12 +9,10 @@
 #include <linux/kallsyms.h>
 #include <linux/module.h>
 
-static char kallsyms_dummy;
-
 /* These will be re-linked against their real values during the second link stage */
-extern unsigned long kallsyms_addresses[1] __attribute__((weak, alias("kallsyms_dummy")));
-extern unsigned long kallsyms_num_syms __attribute__((weak, alias("kallsyms_dummy")));
-extern char kallsyms_names[1] __attribute__((weak, alias("kallsyms_dummy")));
+extern unsigned long kallsyms_addresses[] __attribute__((weak));
+extern unsigned long kallsyms_num_syms __attribute__((weak));
+extern char kallsyms_names[] __attribute__((weak));
 
 /* Defined by the linker script. */
 extern char _stext[], _etext[];
@@ -28,8 +26,7 @@
 	unsigned long i, best = 0;
 
 	/* This kernel should never had been booted. */
-	if ((void *)kallsyms_addresses == &kallsyms_dummy)
-		BUG();
+	BUG_ON(!kallsyms_addresses);
 
 	namebuf[127] = 0;
 	namebuf[0] = 0;
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c	Thu Jan 16 18:23:06 2003
+++ b/kernel/module.c	Thu Jan 16 18:23:06 2003
@@ -963,6 +963,9 @@
 	}
 }
 
+/* From init/vermagic.o */
+extern char vermagic[];
+
 /* Allocate and load the module: note that size of section 0 is always
    zero, and we rely on this for optional sections. */
 static struct module *load_module(void *umod,
@@ -973,7 +976,7 @@
 	Elf_Shdr *sechdrs;
 	char *secstrings, *args;
 	unsigned int i, symindex, exportindex, strindex, setupindex, exindex,
-		modindex, obsparmindex, licenseindex, gplindex;
+		modindex, obsparmindex, licenseindex, gplindex, vmagindex;
 	long arglen;
 	struct module *mod;
 	long err = 0;
@@ -1012,7 +1015,7 @@
 	exportindex = setupindex = obsparmindex = gplindex = licenseindex = 0;
 
 	/* And these should exist, but gcc whinges if we don't init them */
-	symindex = strindex = exindex = modindex = 0;
+	symindex = strindex = exindex = modindex = vmagindex = 0;
 
 	/* Find where important sections are */
 	for (i = 1; i < hdr->e_shnum; i++) {
@@ -1062,6 +1065,11 @@
 			/* EXPORT_SYMBOL_GPL() */
 			DEBUGP("GPL symbols found in section %u\n", i);
 			gplindex = i;
+		} else if (strcmp(secstrings+sechdrs[i].sh_name,
+				  "__vermagic") == 0) {
+			/* Version magic. */
+			DEBUGP("Version magic found in section %u\n", i);
+			vmagindex = i;
 		}
 #ifdef CONFIG_KALLSYMS
 		/* symbol and string tables for decoding later. */
@@ -1082,6 +1090,18 @@
 	}
 	mod = (void *)sechdrs[modindex].sh_addr;
 
+	/* This is allowed: modprobe --force will strip it. */
+	if (!vmagindex) {
+		tainted |= TAINT_FORCED_MODULE;
+		printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
+		       mod->name);
+	} else if (strcmp((char *)sechdrs[vmagindex].sh_addr, vermagic) != 0) {
+		printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
+		       mod->name, (char*)sechdrs[vmagindex].sh_addr, vermagic);
+		err = -ENOEXEC;
+		goto free_hdr;
+	}
+
 	/* Now copy in args */
 	arglen = strlen_user(uargs);
 	if (!arglen) {
@@ -1494,7 +1514,3 @@
 }
 
 __initcall(symbols_init);
-
-/* Obsolete lvalue for broken code which asks about usage */
-int module_dummy_usage = 1;
-EXPORT_SYMBOL(module_dummy_usage);
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Thu Jan 16 18:23:06 2003
+++ b/kernel/sched.c	Thu Jan 16 18:23:06 2003
@@ -67,6 +67,7 @@
 #define INTERACTIVE_DELTA	2
 #define MAX_SLEEP_AVG		(2*HZ)
 #define STARVATION_LIMIT	(2*HZ)
+#define NODE_THRESHOLD          125
 
 /*
  * If a task is 'interactive' then we reinsert it in the active
@@ -153,7 +154,11 @@
 	task_t *curr, *idle;
 	prio_array_t *active, *expired, arrays[2];
 	int prev_nr_running[NR_CPUS];
-
+#ifdef CONFIG_NUMA
+	atomic_t *node_nr_running;
+	unsigned int nr_balanced;
+	int prev_node_load[MAX_NUMNODES];
+#endif
 	task_t *migration_thread;
 	struct list_head migration_queue;
 
@@ -177,6 +182,48 @@
 # define task_running(rq, p)		((rq)->curr == (p))
 #endif
 
+#ifdef CONFIG_NUMA
+
+/*
+ * Keep track of running tasks.
+ */
+
+static atomic_t node_nr_running[MAX_NUMNODES] ____cacheline_maxaligned_in_smp =
+	{[0 ...MAX_NUMNODES-1] = ATOMIC_INIT(0)};
+
+static inline void nr_running_init(struct runqueue *rq)
+{
+	rq->node_nr_running = &node_nr_running[0];
+}
+
+static inline void nr_running_inc(runqueue_t *rq)
+{
+	atomic_inc(rq->node_nr_running);
+	rq->nr_running++;
+}
+
+static inline void nr_running_dec(runqueue_t *rq)
+{
+	atomic_dec(rq->node_nr_running);
+	rq->nr_running--;
+}
+
+__init void node_nr_running_init(void)
+{
+	int i;
+
+	for (i = 0; i < NR_CPUS; i++)
+		cpu_rq(i)->node_nr_running = &node_nr_running[__cpu_to_node(i)];
+}
+
+#else /* !CONFIG_NUMA */
+
+# define nr_running_init(rq)   do { } while (0)
+# define nr_running_inc(rq)    do { (rq)->nr_running++; } while (0)
+# define nr_running_dec(rq)    do { (rq)->nr_running--; } while (0)
+
+#endif /* CONFIG_NUMA */
+
 /*
  * task_rq_lock - lock the runqueue a given task resides on and disable
  * interrupts.  Note the ordering: we can safely lookup the task_rq without
@@ -294,7 +341,7 @@
 		p->prio = effective_prio(p);
 	}
 	enqueue_task(p, array);
-	rq->nr_running++;
+	nr_running_inc(rq);
 }
 
 /*
@@ -302,7 +349,7 @@
  */
 static inline void deactivate_task(struct task_struct *p, runqueue_t *rq)
 {
-	rq->nr_running--;
+	nr_running_dec(rq);
 	if (p->state == TASK_UNINTERRUPTIBLE)
 		rq->nr_uninterruptible++;
 	dequeue_task(p, p->array);
@@ -624,6 +671,125 @@
 		spin_unlock(&rq2->lock);
 }
 
+#if CONFIG_NUMA
+/*
+ * If dest_cpu is allowed for this process, migrate the task to it.
+ * This is accomplished by forcing the cpu_allowed mask to only
+ * allow dest_cpu, which will force the cpu onto dest_cpu.  Then
+ * the cpu_allowed mask is restored.
+ */
+static void sched_migrate_task(task_t *p, int dest_cpu)
+{
+	unsigned long old_mask;
+
+	old_mask = p->cpus_allowed;
+	if (!(old_mask & (1UL << dest_cpu)))
+		return;
+	/* force the process onto the specified CPU */
+	set_cpus_allowed(p, 1UL << dest_cpu);
+
+	/* restore the cpus allowed mask */
+	set_cpus_allowed(p, old_mask);
+}
+
+/*
+ * Find the least loaded CPU.  Slightly favor the current CPU by
+ * setting its runqueue length as the minimum to start.
+ */
+static int sched_best_cpu(struct task_struct *p)
+{
+	int i, minload, load, best_cpu, node = 0;
+	unsigned long cpumask;
+
+	best_cpu = task_cpu(p);
+	if (cpu_rq(best_cpu)->nr_running <= 2)
+		return best_cpu;
+
+	minload = 10000000;
+	for (i = 0; i < numnodes; i++) {
+		load = atomic_read(&node_nr_running[i]);
+		if (load < minload) {
+			minload = load;
+			node = i;
+		}
+	}
+
+	minload = 10000000;
+	cpumask = __node_to_cpu_mask(node);
+	for (i = 0; i < NR_CPUS; ++i) {
+		if (!(cpumask & (1UL << i)))
+			continue;
+		if (cpu_rq(i)->nr_running < minload) {
+			best_cpu = i;
+			minload = cpu_rq(i)->nr_running;
+		}
+	}
+	return best_cpu;
+}
+
+void sched_balance_exec(void)
+{
+	int new_cpu;
+
+	if (numnodes > 1) {
+		new_cpu = sched_best_cpu(current);
+		if (new_cpu != smp_processor_id())
+			sched_migrate_task(current, new_cpu);
+	}
+}
+
+/*
+ * Find the busiest node. All previous node loads contribute with a 
+ * geometrically deccaying weight to the load measure:
+ *      load_{t} = load_{t-1}/2 + nr_node_running_{t}
+ * This way sudden load peaks are flattened out a bit.
+ */
+static int find_busiest_node(int this_node)
+{
+	int i, node = -1, load, this_load, maxload;
+	
+	this_load = maxload = (this_rq()->prev_node_load[this_node] >> 1)
+		+ atomic_read(&node_nr_running[this_node]);
+	this_rq()->prev_node_load[this_node] = this_load;
+	for (i = 0; i < numnodes; i++) {
+		if (i == this_node)
+			continue;
+		load = (this_rq()->prev_node_load[i] >> 1)
+			+ atomic_read(&node_nr_running[i]);
+		this_rq()->prev_node_load[i] = load;
+		if (load > maxload && (100*load > NODE_THRESHOLD*this_load)) {
+			maxload = load;
+			node = i;
+		}
+	}
+	return node;
+}
+
+static inline unsigned long cpus_to_balance(int this_cpu, runqueue_t *this_rq)
+{
+	int this_node = __cpu_to_node(this_cpu);
+	/*
+	 * Avoid rebalancing between nodes too often.
+	 * We rebalance globally once every NODE_BALANCE_RATE load balances.
+	 */
+	if (++(this_rq->nr_balanced) == NODE_BALANCE_RATE) {
+		int node = find_busiest_node(this_node);
+		this_rq->nr_balanced = 0;
+		if (node >= 0)
+			return (__node_to_cpu_mask(node) | (1UL << this_cpu));
+	}
+	return __node_to_cpu_mask(this_node);
+}
+
+#else /* !CONFIG_NUMA */
+
+static inline unsigned long cpus_to_balance(int this_cpu, runqueue_t *this_rq)
+{
+	return cpu_online_map;
+}
+
+#endif /* CONFIG_NUMA */
+
 #if CONFIG_SMP
 
 /*
@@ -652,9 +818,9 @@
 }
 
 /*
- * find_busiest_queue - find the busiest runqueue.
+ * find_busiest_queue - find the busiest runqueue among the cpus in cpumask.
  */
-static inline runqueue_t *find_busiest_queue(runqueue_t *this_rq, int this_cpu, int idle, int *imbalance)
+static inline runqueue_t *find_busiest_queue(runqueue_t *this_rq, int this_cpu, int idle, int *imbalance, unsigned long cpumask)
 {
 	int nr_running, load, max_load, i;
 	runqueue_t *busiest, *rq_src;
@@ -689,7 +855,7 @@
 	busiest = NULL;
 	max_load = 1;
 	for (i = 0; i < NR_CPUS; i++) {
-		if (!cpu_online(i))
+		if (!((1UL << i) & cpumask))
 			continue;
 
 		rq_src = cpu_rq(i);
@@ -736,9 +902,9 @@
 static inline void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p, runqueue_t *this_rq, int this_cpu)
 {
 	dequeue_task(p, src_array);
-	src_rq->nr_running--;
+	nr_running_dec(src_rq);
 	set_task_cpu(p, this_cpu);
-	this_rq->nr_running++;
+	nr_running_inc(this_rq);
 	enqueue_task(p, this_rq->active);
 	/*
 	 * Note that idle threads have a prio of MAX_PRIO, for this test
@@ -764,7 +930,8 @@
 	struct list_head *head, *curr;
 	task_t *tmp;
 
-	busiest = find_busiest_queue(this_rq, this_cpu, idle, &imbalance);
+	busiest = find_busiest_queue(this_rq, this_cpu, idle, &imbalance,
+					cpus_to_balance(this_cpu, this_rq));
 	if (!busiest)
 		goto out;
 
@@ -2231,6 +2398,7 @@
 		spin_lock_init(&rq->lock);
 		INIT_LIST_HEAD(&rq->migration_queue);
 		atomic_set(&rq->nr_iowait, 0);
+		nr_running_init(rq);
 
 		for (j = 0; j < 2; j++) {
 			array = rq->arrays + j;
diff -Nru a/lib/kobject.c b/lib/kobject.c
--- a/lib/kobject.c	Thu Jan 16 18:23:06 2003
+++ b/lib/kobject.c	Thu Jan 16 18:23:06 2003
@@ -295,7 +295,7 @@
  *	looking for a matching kobject. Return object if found.
  */
 
-struct kobject * kset_find_obj(struct kset * kset, char * name)
+struct kobject * kset_find_obj(struct kset * kset, const char * name)
 {
 	struct list_head * entry;
 	struct kobject * ret = NULL;
@@ -386,6 +386,8 @@
 EXPORT_SYMBOL(kobject_unregister);
 EXPORT_SYMBOL(kobject_get);
 EXPORT_SYMBOL(kobject_put);
+
+EXPORT_SYMBOL(kset_find_obj);
 
 EXPORT_SYMBOL(subsystem_init);
 EXPORT_SYMBOL(subsystem_register);
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Thu Jan 16 18:23:06 2003
+++ b/mm/mmap.c	Thu Jan 16 18:23:06 2003
@@ -72,7 +72,6 @@
 int vm_enough_memory(long pages)
 {
 	unsigned long free, allowed;
-	struct sysinfo i;
 
 	atomic_add(pages, &vm_committed_space);
 
@@ -113,12 +112,7 @@
 		return 0;
 	}
 
-	/*
-	 * FIXME: need to add arch hooks to get the bits we need
-	 * without this higher overhead crap
-	 */
-	si_meminfo(&i);
-	allowed = i.totalram * sysctl_overcommit_ratio / 100;
+	allowed = totalram_pages * sysctl_overcommit_ratio / 100;
 	allowed += total_swap_pages;
 
 	if (atomic_read(&vm_committed_space) < allowed)
diff -Nru a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c	Thu Jan 16 18:23:05 2003
+++ b/mm/page_alloc.c	Thu Jan 16 18:23:05 2003
@@ -776,15 +776,18 @@
 	__get_page_state(ret, sizeof(*ret) / sizeof(unsigned long));
 }
 
-void get_zone_counts(unsigned long *active, unsigned long *inactive)
+void get_zone_counts(unsigned long *active,
+		unsigned long *inactive, unsigned long *free)
 {
 	struct zone *zone;
 
 	*active = 0;
 	*inactive = 0;
+	*free = 0;
 	for_each_zone(zone) {
 		*active += zone->nr_active;
 		*inactive += zone->nr_inactive;
+		*free += zone->free_pages;
 	}
 }
 
@@ -838,6 +841,7 @@
 	int cpu, temperature;
 	unsigned long active;
 	unsigned long inactive;
+	unsigned long free;
 	struct zone *zone;
 
 	for_each_zone(zone) {
@@ -863,7 +867,7 @@
 	}
 
 	get_page_state(&ps);
-	get_zone_counts(&active, &inactive);
+	get_zone_counts(&active, &inactive, &free);
 
 	printk("\nFree pages: %11ukB (%ukB HighMem)\n",
 		K(nr_free_pages()),
diff -Nru a/mm/readahead.c b/mm/readahead.c
--- a/mm/readahead.c	Thu Jan 16 18:23:05 2003
+++ b/mm/readahead.c	Thu Jan 16 18:23:05 2003
@@ -477,7 +477,8 @@
 {
 	unsigned long active;
 	unsigned long inactive;
+	unsigned long free;
 
-	get_zone_counts(&active, &inactive);
-	return min(nr, inactive / 2);
+	get_zone_counts(&active, &inactive, &free);
+	return min(nr, (inactive + free) / 2);
 }
diff -Nru a/net/atm/mpc.c b/net/atm/mpc.c
--- a/net/atm/mpc.c	Thu Jan 16 18:23:06 2003
+++ b/net/atm/mpc.c	Thu Jan 16 18:23:06 2003
@@ -1424,10 +1424,6 @@
 	struct atm_mpoa_qos *qos, *nextqos;
 	struct lec_priv *priv;
 
-	if (MOD_IN_USE) {
-		printk("mpc.c: module in use\n");
-		return;
-	}
 #ifdef CONFIG_PROC_FS
 	mpc_proc_clean();
 #endif
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Thu Jan 16 18:23:06 2003
+++ b/net/core/dev.c	Thu Jan 16 18:23:06 2003
@@ -877,6 +877,18 @@
 	return notifier_chain_unregister(&netdev_chain, nb);
 }
 
+/**
+ *	call_netdevice_notifiers - call all network notifier blocks
+ *
+ *	Call all network notifier blocks.  Parameters and return value
+ *	are as for notifier_call_chain().
+ */
+
+int call_netdevice_notifiers(unsigned long val, void *v)
+{
+	return notifier_call_chain(&netdev_chain, val, v);
+}
+
 /*
  *	Support routine. Sends outgoing frames to any network
  *	taps currently in use.
diff -Nru a/net/core/rtnetlink.c b/net/core/rtnetlink.c
--- a/net/core/rtnetlink.c	Thu Jan 16 18:23:07 2003
+++ b/net/core/rtnetlink.c	Thu Jan 16 18:23:07 2003
@@ -234,10 +234,20 @@
 	err = -EINVAL;
 
 	if (ida[IFLA_ADDRESS - 1]) {
+		if (!dev->set_mac_address) {
+			err = -EOPNOTSUPP;
+			goto out;
+		}
+		if (!netif_device_present(dev)) {
+			err = -ENODEV;
+			goto out;
+		}
 		if (ida[IFLA_ADDRESS - 1]->rta_len != RTA_LENGTH(dev->addr_len))
 			goto out;
-		memcpy(dev->dev_addr, RTA_DATA(ida[IFLA_ADDRESS - 1]),
-		       dev->addr_len);
+
+		err = dev->set_mac_address(dev, RTA_DATA(ida[IFLA_ADDRESS - 1]));
+		if (err)
+			goto out;
 	}
 
 	if (ida[IFLA_BROADCAST - 1]) {
@@ -250,6 +260,9 @@
 	err = 0;
 
 out:
+	if (!err)
+		call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+
 	dev_put(dev);
 	return err;
 }
diff -Nru a/net/netsyms.c b/net/netsyms.c
--- a/net/netsyms.c	Thu Jan 16 18:23:05 2003
+++ b/net/netsyms.c	Thu Jan 16 18:23:05 2003
@@ -508,6 +508,7 @@
 /* Device callback registration */
 EXPORT_SYMBOL(register_netdevice_notifier);
 EXPORT_SYMBOL(unregister_netdevice_notifier);
+EXPORT_SYMBOL(call_netdevice_notifiers);
 
 /* support for loadable net drivers */
 #ifdef CONFIG_NET
@@ -534,6 +535,7 @@
 EXPORT_SYMBOL(__kfree_skb);
 EXPORT_SYMBOL(skb_clone);
 EXPORT_SYMBOL(skb_copy);
+EXPORT_SYMBOL(skb_pad);
 EXPORT_SYMBOL(netif_rx);
 EXPORT_SYMBOL(netif_receive_skb);
 EXPORT_SYMBOL(dev_add_pack);
diff -Nru a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
--- a/net/sunrpc/rpc_pipe.c	Thu Jan 16 18:23:05 2003
+++ b/net/sunrpc/rpc_pipe.c	Thu Jan 16 18:23:05 2003
@@ -324,6 +324,7 @@
 enum {
 	RPCAUTH_Root = 1,
 	RPCAUTH_lockd,
+	RPCAUTH_mount,
 	RPCAUTH_nfs,
 	RPCAUTH_portmap,
 	RPCAUTH_statd,
@@ -342,19 +343,23 @@
 static struct rpc_filelist files[] = {
 	[RPCAUTH_lockd] = {
 		.name = "lockd",
-		.mode = S_IFDIR | S_IRUSR | S_IXUSR,
+		.mode = S_IFDIR | S_IRUGO | S_IXUGO,
+	},
+	[RPCAUTH_mount] = {
+		.name = "mount",
+		.mode = S_IFDIR | S_IRUGO | S_IXUGO,
 	},
 	[RPCAUTH_nfs] = {
 		.name = "nfs",
-		.mode = S_IFDIR | S_IRUSR | S_IXUSR,
+		.mode = S_IFDIR | S_IRUGO | S_IXUGO,
 	},
 	[RPCAUTH_portmap] = {
 		.name = "portmap",
-		.mode = S_IFDIR | S_IRUSR | S_IXUSR,
+		.mode = S_IFDIR | S_IRUGO | S_IXUGO,
 	},
 	[RPCAUTH_statd] = {
 		.name = "statd",
-		.mode = S_IFDIR | S_IRUSR | S_IXUSR,
+		.mode = S_IFDIR | S_IRUGO | S_IXUGO,
 	},
 };
 
@@ -425,7 +430,7 @@
 		return -ENODEV;
 	}
 	nd->mnt = mntget(rpc_mount);
-	nd->dentry = dget(rpc_mount->mnt_sb->s_root);
+	nd->dentry = dget(rpc_mount->mnt_root);
 	nd->last_type = LAST_ROOT;
 	nd->flags = flags;
 
diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build
--- a/scripts/Makefile.build	Thu Jan 16 18:23:06 2003
+++ b/scripts/Makefile.build	Thu Jan 16 18:23:06 2003
@@ -176,10 +176,15 @@
 cmd_link_multi-y = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.o=-objs))) $($(subst $(obj)/,,$(@:.o=-y)))),$^)
 
 quiet_cmd_link_multi-m = LD [M]  $@
-cmd_link_multi-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.ko=-objs))) $($(subst $(obj)/,,$(@:.ko=-y)))),$^)
+cmd_link_multi-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.ko=-objs))) $($(subst $(obj)/,,$(@:.ko=-y)))),$^) init/vermagic.o
 
 quiet_cmd_link_single-m = LD [M]  $@
-cmd_link_single-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $<
+cmd_link_single-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o
+
+# Don't rebuilt vermagic.o unless we actually are in the init/ dir
+ifneq ($(obj),init)
+init/vermagic.o: ;
+endif
 
 # We would rather have a list of rules like
 # 	foo.o: $(foo-objs)
@@ -188,10 +193,10 @@
 $(multi-used-y) : %.o: $(multi-objs-y) FORCE
 	$(call if_changed,link_multi-y)
 
-$(multi-used-m:.o=.ko) : %.ko: $(multi-objs-m) FORCE
+$(multi-used-m:.o=.ko) : %.ko: $(multi-objs-m) init/vermagic.o FORCE
 	$(call if_changed,link_multi-m)
 
-$(single-used-m:.o=.ko) : %.ko: %.o FORCE
+$(single-used-m:.o=.ko) : %.ko: %.o init/vermagic.o FORCE
 	$(call if_changed,link_single-m)
 
 targets += $(multi-used-y) $(multi-used-m:.o=.ko) $(single-used-m:.o=.ko)
diff -Nru a/scripts/kallsyms.c b/scripts/kallsyms.c
--- a/scripts/kallsyms.c	Thu Jan 16 18:23:07 2003
+++ b/scripts/kallsyms.c	Thu Jan 16 18:23:07 2003
@@ -144,7 +144,7 @@
 		for (k = 0; table[i].sym[k] && table[i].sym[k] == prev[k]; ++k)
 			; 
 
-		printf("\t.byte 0x%02x ; .asciz\t\"%s\"\n", k, table[i].sym + k);
+		printf("\t.byte 0x%02x\n\t.asciz\t\"%s\"\n", k, table[i].sym + k);
 		last_addr = table[i].addr;
 		prev = table[i].sym;
 	}
diff -Nru a/scripts/per-cpu-check.awk b/scripts/per-cpu-check.awk
--- a/scripts/per-cpu-check.awk	Thu Jan 16 18:23:06 2003
+++ b/scripts/per-cpu-check.awk	Thu Jan 16 18:23:06 2003
@@ -6,7 +6,7 @@
 	IN_PER_CPU=0
 }
 
-/__per_cpu$$/ && ! / __ksymtab_/ {
+/__per_cpu$$/ && ! ( / __ksymtab_/ || / __kstrtab_/ ) {
 	if (!IN_PER_CPU) {
 		print $$3 " not in per-cpu section" > "/dev/stderr";
 		FOUND=1;
diff -Nru a/sound/Kconfig b/sound/Kconfig
--- a/sound/Kconfig	Thu Jan 16 18:23:06 2003
+++ b/sound/Kconfig	Thu Jan 16 18:23:06 2003
@@ -1,20 +1,6 @@
 # sound/Config.in
 #
 
-menu "Open Sound System"
-	depends on SOUND!=n
-
-config SOUND_PRIME
-	tristate "Open Sound System"
-	depends on SOUND
-	help
-	  Say 'Y' or 'M' to enable Open Sound System drivers.
-
-source "sound/oss/Kconfig"
-
-endmenu
-
-
 menu "Advanced Linux Sound Architecture"
 	depends on SOUND!=n
 
@@ -42,3 +28,15 @@
 
 endmenu
 
+menu "Open Sound System"
+	depends on SOUND!=n
+
+config SOUND_PRIME
+	tristate "Open Sound System (DEPRECATED)"
+	depends on SOUND
+	help
+	  Say 'Y' or 'M' to enable Open Sound System drivers.
+
+source "sound/oss/Kconfig"
+
+endmenu
diff -Nru a/sound/oss/soundcard.c b/sound/oss/soundcard.c
--- a/sound/oss/soundcard.c	Thu Jan 16 18:23:05 2003
+++ b/sound/oss/soundcard.c	Thu Jan 16 18:23:06 2003
@@ -599,9 +599,6 @@
 {
 	int i, j;
 
-	if (MOD_IN_USE)
-		return;
-
 	for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
 		devfs_remove("snd/%s", dev_list[i].name);
 		if (!dev_list[i].num)
