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

diff -urN linux-2.4.20-pre7/Documentation/BK-usage/unbz64wrap linux-2.4.20-pre8/Documentation/BK-usage/unbz64wrap
--- linux-2.4.20-pre7/Documentation/BK-usage/unbz64wrap	Wed Sep 25 18:20:32 2002
+++ linux-2.4.20-pre8/Documentation/BK-usage/unbz64wrap	Wed Sep 25 18:21:13 2002
@@ -15,7 +15,7 @@
 		case $LINE in
 		begin-base64*) SHOW=YES ;;
 		====) SHOW= ;;
-		*) [ "$SHOW" ] && echo $LINE ;;
+		*) [ "$SHOW" ] && echo "$LINE" ;;
 		esac
 	done | mimencode -u | bunzip2
 	exit $?
diff -urN linux-2.4.20-pre7/Documentation/Changes linux-2.4.20-pre8/Documentation/Changes
--- linux-2.4.20-pre7/Documentation/Changes	Wed Sep 25 18:20:32 2002
+++ linux-2.4.20-pre8/Documentation/Changes	Wed Sep 25 18:21:13 2002
@@ -55,7 +55,7 @@
 o  modutils               2.4.2                   # insmod -V
 o  e2fsprogs              1.25                    # tune2fs
 o  jfsutils               1.0.12                  # fsck.jfs -V
-o  reiserfsprogs          3.6.3                   # reiserfsck 2>&1|grep reiserfsprogs
+o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
 o  pcmcia-cs              3.1.21                  # cardmgr -V
 o  PPP                    2.4.0                   # pppd --version
 o  isdn4k-utils           3.1pre1                 # isdnctrl 2>&1|grep version
@@ -325,7 +325,7 @@
 
 Reiserfsprogs
 -------------
-o  <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.1b.tar.gz>
+o  <http://www.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.6.3.tar.gz>
 
 LVM toolset
 -----------
diff -urN linux-2.4.20-pre7/Documentation/Configure.help linux-2.4.20-pre8/Documentation/Configure.help
--- linux-2.4.20-pre7/Documentation/Configure.help	Wed Sep 25 18:20:33 2002
+++ linux-2.4.20-pre8/Documentation/Configure.help	Wed Sep 25 18:21:16 2002
@@ -11799,6 +11799,14 @@
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called sundance.o.
 
+Sundance Alta memory-mapped I/O support
+CONFIG_SUNDANCE_MMIO
+  Enable memory-mapped I/O for interaction with Sundance NIC registers.
+  Do NOT enable this by default, PIO (enabled when MMIO is disabled)
+  is known to solve bugs on certain chips.
+
+  If unsure, say N.
+
 Sun3/Sun3x on-board LANCE support
 CONFIG_SUN3LANCE
   Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
@@ -14360,6 +14368,18 @@
   The module will be called brlvger.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
+USBLCD support
+CONFIG_USB_LCD
+  Say Y here if you want to connect an USBLCD to your computer's
+  USB port. The USBLCD is a small USB interface board for
+  alphanumeric LCD modules. See <http://www.usblcd.de> for more
+  information.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called usblcd.o. If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
+
 D-Link DSB-R100 FM radio support
 CONFIG_USB_DSBR
   Say Y here if you want to connect this type of radio to your
@@ -23778,13 +23798,24 @@
 
 SRM environment variables in procfs
 CONFIG_SRM_ENV
-  If you enable this option, a subdirectory called srm_environment
-  will give you access to the most important SRM environment
-  variables. If you've got an Alpha style system supporting
-  SRC, then it is a good idea to say Yes or Module to this driver.
+  If you enable this option, a subdirectory inside /proc called
+  /proc/srm_environment will give you access to the all important
+  SRM environment variables (those which have a name) and also
+  to all others (by their internal number).
+
+  SRM is something like a BIOS for Alpha machines. There are some
+  other such BIOSes, like AlphaBIOS, which this driver cannot
+  support (hey, that's not SRM!).
+
+  Despite the fact that this driver doesn't work on all Alphas (but
+  only on those which have SRM as their firmware), it's save to
+  build it even if your particular machine doesn't know about SRM
+  (or if you intend to compile a generic kernel). It will simply
+  not create those subdirectory in /proc (and give you some warning,
+  of course).
 
   This driver is also available as a module and will be called
-  srm_env.o if you build it as a module.
+  srm_env.o then.
 
 Footbridge internal watchdog
 CONFIG_21285_WATCHDOG
diff -urN linux-2.4.20-pre7/Documentation/networking/khttpd.txt linux-2.4.20-pre8/Documentation/networking/khttpd.txt
--- linux-2.4.20-pre7/Documentation/networking/khttpd.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre8/Documentation/networking/khttpd.txt	Wed Sep 25 18:21:16 2002
@@ -0,0 +1 @@
+See net/khttpd/README for documentation on khttpd, the kernel http server.
diff -urN linux-2.4.20-pre7/Documentation/sound/Maestro3 linux-2.4.20-pre8/Documentation/sound/Maestro3
--- linux-2.4.20-pre7/Documentation/sound/Maestro3	Sun Feb  4 10:05:29 2001
+++ linux-2.4.20-pre8/Documentation/sound/Maestro3	Wed Sep 25 18:21:16 2002
@@ -71,10 +71,18 @@
 tell the driver to print minimal debugging information as it runs.  This
 can be collected with 'dmesg' or through the klogd daemon.
 
-The other is 'external_amp', which tells the driver to attempt to enable
+One is 'external_amp', which tells the driver to attempt to enable
 an external amplifier.  This defaults to '1', you can tell the driver
 not to bother enabling such an amplifier by setting it to '0'.
 
+And the last is 'gpio_pin', which tells the driver which GPIO pin number
+the external amp uses (0-15), The Allegro uses 8 by default, all others 1.
+If everything loads correctly and seems to be working but you get no sound, 
+try tweaking this value. 
+
+Systems known to need a different value
+        Panasonic ToughBook CF-72: gpio_pin=13 
+
 Power Management
 ----------------
 
diff -urN linux-2.4.20-pre7/Makefile linux-2.4.20-pre8/Makefile
--- linux-2.4.20-pre7/Makefile	Wed Sep 25 18:20:34 2002
+++ linux-2.4.20-pre8/Makefile	Wed Sep 25 18:21:16 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 20
-EXTRAVERSION = -pre7
+EXTRAVERSION = -pre8
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.20-pre7/arch/alpha/kernel/pci.c linux-2.4.20-pre8/arch/alpha/kernel/pci.c
--- linux-2.4.20-pre7/arch/alpha/kernel/pci.c	Wed Sep 25 18:20:34 2002
+++ linux-2.4.20-pre8/arch/alpha/kernel/pci.c	Wed Sep 25 18:21:17 2002
@@ -128,7 +128,8 @@
 #define GB			(1024*MB)
 
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 	struct pci_controller *hose = dev->sysdata;
@@ -168,7 +169,7 @@
 		 */
 
 		/* Align to multiple of size of minimum base.  */
-		alignto = MAX(0x1000, size);
+		alignto = MAX(0x1000, align);
 		start = ALIGN(start, alignto);
 		if (hose->sparse_mem_base && size <= 7 * 16*MB) {
 			if (((start / (16*MB)) & 0x7) == 0) {
@@ -245,25 +246,6 @@
 		/* Root bus */
 		bus->resource[0] = hose->io_space;
 		bus->resource[1] = hose->mem_space;
-	} else {
-		/* This is a bridge. Do not care how it's initialized,
-		   just link its resources to the bus ones */
-		int i;
-
-		for(i=0; i<3; i++) {
-			bus->resource[i] =
-				&dev->resource[PCI_BRIDGE_RESOURCES+i];
-			bus->resource[i]->name = bus->name;
-		}
-		bus->resource[0]->flags |= pci_bridge_check_io(dev);
-		bus->resource[1]->flags |= IORESOURCE_MEM;
-		/* For now, propogate hose limits to the bus;
-		   we'll adjust them later. */
-		bus->resource[0]->end = hose->io_space->end;
-		bus->resource[1]->end = hose->mem_space->end;
-		/* Turn off downstream PF memory address range by default */
-		bus->resource[2]->start = 1024*1024;
-		bus->resource[2]->end = bus->resource[2]->start - 1;
 	}
 
 	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
@@ -348,6 +330,10 @@
 	ranges->io_end -= hose->io_space->start;
 	ranges->mem_start -= hose->mem_space->start;
 	ranges->mem_end -= hose->mem_space->start;
+/* FIXME: On older alphas we could use dense memory space
+	  to access prefetchable resources. */
+	ranges->prefetch_start -= hose->mem_space->start;
+	ranges->prefetch_end -= hose->mem_space->start;
 }
 
 int
diff -urN linux-2.4.20-pre7/arch/alpha/kernel/srm_env.c linux-2.4.20-pre8/arch/alpha/kernel/srm_env.c
--- linux-2.4.20-pre7/arch/alpha/kernel/srm_env.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre8/arch/alpha/kernel/srm_env.c	Wed Sep 25 18:21:17 2002
@@ -33,6 +33,15 @@
  * Changelog
  * ~~~~~~~~~
  *
+ * Thu, 22 Aug 2002 15:10:43 +0200
+ * 	- Update Config.help entry. I got a number of emails asking
+ * 	  me to tell their senders if they could make use of this
+ * 	  piece of code... So: "SRM is something like BIOS for your
+ * 	  Alpha"
+ * 	- Update code formatting a bit to better conform CodingStyle
+ * 	  rules.
+ * 	- So this is v0.0.5, with no changes (except formatting)
+ * 	
  * Wed, 22 May 2002 00:11:21 +0200
  * 	- Fix typo on comment (SRC -> SRM)
  * 	- Call this "Version 0.0.4"
@@ -59,13 +68,12 @@
 #define BASE_DIR	"srm_environment"	/* Subdir in /proc/		*/
 #define NAMED_DIR	"named_variables"	/* Subdir for known variables	*/
 #define NUMBERED_DIR	"numbered_variables"	/* Subdir for all variables	*/
-#define VERSION		"0.0.4"			/* Module version		*/
+#define VERSION		"0.0.5"			/* Module version		*/
 #define NAME		"srm_env"		/* Module name			*/
 
 MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
 MODULE_DESCRIPTION("Accessing Alpha SRM environment through procfs interface");
 MODULE_LICENSE("GPL");
-EXPORT_NO_SYMBOLS;
 
 typedef struct _srm_env {
 	char			*name;
@@ -98,9 +106,12 @@
 };
 static srm_env_t	srm_numbered_entries[256];
 
+
+
 static int
 srm_env_read(char *page, char **start, off_t off, int count, int *eof,
-		void *data) {
+		void *data)
+{
 	int		nbytes;
 	unsigned long	ret;
 	srm_env_t	*entry;
@@ -112,11 +123,11 @@
 		return -EFAULT;
 	}
 
-	entry	= (srm_env_t *)data;
+	entry	= (srm_env_t *) data;
 	ret	= callback_getenv(entry->id, page, count);
 
 	if((ret >> 61) == 0)
-		nbytes = (int)ret;
+		nbytes = (int) ret;
 	else
 		nbytes = -EFAULT;
 
@@ -125,9 +136,11 @@
 	return nbytes;
 }
 
+
 static int
 srm_env_write(struct file *file, const char *buffer, unsigned long count,
-		void *data) {
+		void *data)
+{
 #define BUFLEN	512
 	int		nbytes;
 	srm_env_t	*entry;
@@ -157,7 +170,7 @@
 		do 
 			ret2 = callback_save_env();
 		while((ret2 >> 61) == 1);
-		nbytes = (int)ret1;
+		nbytes = (int) ret1;
 	} else
 		nbytes = -EFAULT;
 
@@ -166,8 +179,10 @@
 	return nbytes;
 }
 
+
 static void
-srm_env_cleanup(void) {
+srm_env_cleanup(void)
+{
 	srm_env_t	*entry;
 	unsigned long	var_num;
 
@@ -211,8 +226,10 @@
 	return;
 }
 
+
 static int __init
-srm_env_init(void) {
+srm_env_init(void)
+{
 	srm_env_t	*entry;
 	unsigned long	var_num;
 
@@ -221,7 +238,9 @@
 	 */
 	if(!alpha_using_srm) {
 		printk(KERN_INFO "%s: This Alpha system doesn't "
-				"know about SRM...\n", __FUNCTION__);
+				"know about SRM (or you've booted "
+				"SRM->MILO->Linux, which gets "
+				"misdetected)...\n", __FUNCTION__);
 		return -ENODEV;
 	}
 
@@ -275,7 +294,7 @@
 		if(entry->proc_entry == NULL)
 			goto cleanup;
 
-		entry->proc_entry->data		= (void *)entry;
+		entry->proc_entry->data		= (void *) entry;
 		entry->proc_entry->owner	= THIS_MODULE;
 		entry->proc_entry->read_proc	= srm_env_read;
 		entry->proc_entry->write_proc	= srm_env_write;
@@ -296,7 +315,7 @@
 			goto cleanup;
 
 		entry->id			= var_num;
-		entry->proc_entry->data		= (void *)entry;
+		entry->proc_entry->data		= (void *) entry;
 		entry->proc_entry->owner	= THIS_MODULE;
 		entry->proc_entry->read_proc	= srm_env_read;
 		entry->proc_entry->write_proc	= srm_env_write;
@@ -304,20 +323,26 @@
 
 	printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
 			VERSION);
+
 	return 0;
 
 cleanup:
 	srm_env_cleanup();
+
 	return -ENOMEM;
 }
 
+
 static void __exit
-srm_env_exit(void) {
+srm_env_exit(void)
+{
 	srm_env_cleanup();
 	printk(KERN_INFO "%s: unloaded successfully\n", NAME);
+
 	return;
 }
 
+
 module_init(srm_env_init);
 module_exit(srm_env_exit);
 
diff -urN linux-2.4.20-pre7/arch/arm/kernel/bios32.c linux-2.4.20-pre8/arch/arm/kernel/bios32.c
--- linux-2.4.20-pre7/arch/arm/kernel/bios32.c	Fri Aug  2 17:39:42 2002
+++ linux-2.4.20-pre8/arch/arm/kernel/bios32.c	Wed Sep 25 18:21:17 2002
@@ -354,25 +354,7 @@
 	struct pci_dev *dev = bus->self;
 	int i;
 
-	if (dev) {
-		for (i = 0; i < 3; i++) {
-			if(root->resource[i]) {
-				bus->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
-				bus->resource[i]->end  = root->resource[i]->end;
-				bus->resource[i]->name = bus->name;
-			}
-		}
-		bus->resource[0]->flags |= pci_bridge_check_io(dev);
-		bus->resource[1]->flags |= IORESOURCE_MEM;
-
-		if (root->resource[2])
-			bus->resource[2]->flags = root->resource[2]->flags;
-		else {
-			/* no prefetchable memory region - disable it */
-			bus->resource[2]->start = 1024*1024;
-			bus->resource[2]->end   = bus->resource[2]->start - 1;
-		}
-	} else {
+	if (!dev) {
 		/*
 		 * Assign root bus resources.
 		 */
@@ -587,7 +569,8 @@
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might be mirrored at 0x0100-0x03ff..
  */
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
 {
 	if (res->flags & IORESOURCE_IO) {
 		unsigned long start = res->start;
diff -urN linux-2.4.20-pre7/arch/i386/kernel/dmi_scan.c linux-2.4.20-pre8/arch/i386/kernel/dmi_scan.c
--- linux-2.4.20-pre7/arch/i386/kernel/dmi_scan.c	Wed Sep 25 18:20:35 2002
+++ linux-2.4.20-pre8/arch/i386/kernel/dmi_scan.c	Wed Sep 25 18:21:17 2002
@@ -648,8 +648,8 @@
 	
 	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
-			MATCH(DMI_BIOS_VERSION, "R0209Z3"),
-			MATCH(DMI_BIOS_DATE, "05/12/01"), NO_MATCH
+			MATCH(DMI_BIOS_VERSION, "WXP01Z3"),
+			MATCH(DMI_BIOS_DATE, "10/26/01"), NO_MATCH
 			} },
 	
 	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-F104K */
diff -urN linux-2.4.20-pre7/arch/i386/kernel/pci-i386.c linux-2.4.20-pre8/arch/i386/kernel/pci-i386.c
--- linux-2.4.20-pre7/arch/i386/kernel/pci-i386.c	Wed Sep 25 18:20:35 2002
+++ linux-2.4.20-pre8/arch/i386/kernel/pci-i386.c	Wed Sep 25 18:21:17 2002
@@ -136,7 +136,8 @@
  * which might have be mirrored at 0x0100-0x03ff..
  */
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
 {
 	if (res->flags & IORESOURCE_IO) {
 		unsigned long start = res->start;
diff -urN linux-2.4.20-pre7/arch/i386/lib/checksum.S linux-2.4.20-pre8/arch/i386/lib/checksum.S
--- linux-2.4.20-pre7/arch/i386/lib/checksum.S	Wed Sep 25 18:20:35 2002
+++ linux-2.4.20-pre8/arch/i386/lib/checksum.S	Wed Sep 25 18:21:17 2002
@@ -55,8 +55,21 @@
 	movl 20(%esp),%eax	# Function arg: unsigned int sum
 	movl 16(%esp),%ecx	# Function arg: int len
 	movl 12(%esp),%esi	# Function arg: unsigned char *buff
-	testl $2, %esi		# Check alignment.
+	testl $3, %esi		# Check alignment.
 	jz 2f			# Jump if alignment is ok.
+	testl $1, %esi		# Check alignment.
+	jz 10f			# Jump if alignment is boundary of 2bytes.
+
+	# buf is odd
+	dec %ecx
+	jl 8f
+	movzbl (%esi), %ebx
+	adcl %ebx, %eax
+	roll $8, %eax
+	inc %esi
+	testl $2, %esi
+	jz 2f
+10:
 	subl $2, %ecx		# Alignment uses up two bytes.
 	jae 1f			# Jump if we had at least two bytes.
 	addl $2, %ecx		# ecx was < 2.  Deal with it.
@@ -111,6 +124,10 @@
 6:	addl %ecx,%eax
 	adcl $0, %eax 
 7:	
+	testl $1, 12(%esp)
+	jz 8f
+	roll $8, %eax
+8:
 	popl %ebx
 	popl %esi
 	ret
@@ -126,8 +143,8 @@
 	movl 16(%esp),%ecx	# Function arg: int len
 	movl 12(%esp),%esi	# Function arg:	const unsigned char *buf
 
-	testl $2, %esi         
-	jnz 30f                 
+	testl $3, %esi         
+	jnz 25f                 
 10:
 	movl %ecx, %edx
 	movl %ecx, %ebx
@@ -145,6 +162,19 @@
 	lea 2(%esi), %esi
 	adcl $0, %eax
 	jmp 10b
+25:
+	testl $1, %esi         
+	jz 30f                 
+	# buf is odd
+	dec %ecx
+	jl 90f
+	movzbl (%esi), %ebx
+	addl %ebx, %eax
+	adcl $0, %eax
+	roll $8, %eax
+	inc %esi
+	testl $2, %esi
+	jz 10b
 
 30:	subl $2, %ecx          
 	ja 20b                 
@@ -211,6 +241,10 @@
 	addl %ebx,%eax
 	adcl $0,%eax
 80: 
+	testl $1, 12(%esp)
+	jz 90f
+	roll $8, %eax
+90: 
 	popl %ebx
 	popl %esi
 	ret
diff -urN linux-2.4.20-pre7/arch/ia64/kernel/pci.c linux-2.4.20-pre8/arch/ia64/kernel/pci.c
--- linux-2.4.20-pre7/arch/ia64/kernel/pci.c	Wed Sep 25 18:20:35 2002
+++ linux-2.4.20-pre8/arch/ia64/kernel/pci.c	Wed Sep 25 18:21:18 2002
@@ -379,7 +379,8 @@
 }
 
 void
-pcibios_align_resource (void *data, struct resource *res, unsigned long size)
+pcibios_align_resource (void *data, struct resource *res,
+		        unsigned long size, unsigned long align)
 {
 }
 
diff -urN linux-2.4.20-pre7/arch/mips/cobalt/pci.c linux-2.4.20-pre8/arch/mips/cobalt/pci.c
--- linux-2.4.20-pre7/arch/mips/cobalt/pci.c	Wed Sep 25 18:20:39 2002
+++ linux-2.4.20-pre8/arch/mips/cobalt/pci.c	Wed Sep 25 18:21:21 2002
@@ -416,7 +416,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-		unsigned long size)
+		unsigned long size, unsigned long align)
 {
 
 	panic("Uhhoh called pcibios_align_resource\n");
diff -urN linux-2.4.20-pre7/arch/mips/ddb5074/pci.c linux-2.4.20-pre8/arch/mips/ddb5074/pci.c
--- linux-2.4.20-pre7/arch/mips/ddb5074/pci.c	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre8/arch/mips/ddb5074/pci.c	Wed Sep 25 18:21:21 2002
@@ -396,7 +396,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
+			    unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -urN linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/pci_bios.c linux-2.4.20-pre8/arch/mips/galileo-boards/ev64120/pci_bios.c
--- linux-2.4.20-pre7/arch/mips/galileo-boards/ev64120/pci_bios.c	Wed Sep 25 18:20:39 2002
+++ linux-2.4.20-pre8/arch/mips/galileo-boards/ev64120/pci_bios.c	Wed Sep 25 18:21:22 2002
@@ -906,7 +906,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
+			    unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -urN linux-2.4.20-pre7/arch/mips/gt64120/common/pci.c linux-2.4.20-pre8/arch/mips/gt64120/common/pci.c
--- linux-2.4.20-pre7/arch/mips/gt64120/common/pci.c	Sun Sep  9 10:43:01 2001
+++ linux-2.4.20-pre8/arch/mips/gt64120/common/pci.c	Wed Sep 25 18:21:22 2002
@@ -886,7 +886,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
+			    unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -urN linux-2.4.20-pre7/arch/mips/kernel/pci.c linux-2.4.20-pre8/arch/mips/kernel/pci.c
--- linux-2.4.20-pre7/arch/mips/kernel/pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/arch/mips/kernel/pci.c	Wed Sep 25 18:21:22 2002
@@ -162,7 +162,8 @@
 }
 
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 	/* this should not be called */
 }
diff -urN linux-2.4.20-pre7/arch/mips/mips-boards/generic/pci.c linux-2.4.20-pre8/arch/mips/mips-boards/generic/pci.c
--- linux-2.4.20-pre7/arch/mips/mips-boards/generic/pci.c	Wed Sep 25 18:20:39 2002
+++ linux-2.4.20-pre8/arch/mips/mips-boards/generic/pci.c	Wed Sep 25 18:21:23 2002
@@ -505,7 +505,8 @@
 }
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 }
 
diff -urN linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/pci.c linux-2.4.20-pre8/arch/mips/momentum/ocelot_g/pci.c
--- linux-2.4.20-pre7/arch/mips/momentum/ocelot_g/pci.c	Wed Sep 25 18:20:39 2002
+++ linux-2.4.20-pre8/arch/mips/momentum/ocelot_g/pci.c	Wed Sep 25 18:21:23 2002
@@ -446,7 +446,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size)
+			    unsigned long size, unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -urN linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-pci.c linux-2.4.20-pre8/arch/mips/sgi-ip27/ip27-pci.c
--- linux-2.4.20-pre7/arch/mips/sgi-ip27/ip27-pci.c	Wed Sep 25 18:20:40 2002
+++ linux-2.4.20-pre8/arch/mips/sgi-ip27/ip27-pci.c	Wed Sep 25 18:21:23 2002
@@ -252,7 +252,8 @@
 }
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 }
 
diff -urN linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-pci.c linux-2.4.20-pre8/arch/mips/sgi-ip32/ip32-pci.c
--- linux-2.4.20-pre7/arch/mips/sgi-ip32/ip32-pci.c	Wed Sep 25 18:20:40 2002
+++ linux-2.4.20-pre8/arch/mips/sgi-ip32/ip32-pci.c	Wed Sep 25 18:21:23 2002
@@ -347,7 +347,7 @@
 }
 
 void __init pcibios_align_resource (void *data, struct resource *res,
-				    unsigned long size)
+				    unsigned long size, unsigned long align)
 {
 }
 
diff -urN linux-2.4.20-pre7/arch/mips/sibyte/sb1250/pci.c linux-2.4.20-pre8/arch/mips/sibyte/sb1250/pci.c
--- linux-2.4.20-pre7/arch/mips/sibyte/sb1250/pci.c	Wed Sep 25 18:20:40 2002
+++ linux-2.4.20-pre8/arch/mips/sibyte/sb1250/pci.c	Wed Sep 25 18:21:23 2002
@@ -297,7 +297,7 @@
 }
 
 void pcibios_align_resource(void *data, struct resource *res,
-		       unsigned long size)
+		       unsigned long size, unsigned long align)
 {
 }
 
diff -urN linux-2.4.20-pre7/arch/mips/sni/pci.c linux-2.4.20-pre8/arch/mips/sni/pci.c
--- linux-2.4.20-pre7/arch/mips/sni/pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/arch/mips/sni/pci.c	Wed Sep 25 18:21:23 2002
@@ -199,7 +199,8 @@
 }
 
 void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 }
 
diff -urN linux-2.4.20-pre7/arch/parisc/kernel/pci.c linux-2.4.20-pre8/arch/parisc/kernel/pci.c
--- linux-2.4.20-pre7/arch/parisc/kernel/pci.c	Wed Sep 25 18:20:41 2002
+++ linux-2.4.20-pre8/arch/parisc/kernel/pci.c	Wed Sep 25 18:21:26 2002
@@ -389,13 +389,15 @@
 ** than res->start.
 */
 void __devinit
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long alignment)
 {
 	unsigned long mask, align;
 
-	DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx)\n",
+	DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n",
 		((struct pci_dev *) data)->slot_name,
-		res->parent, res->start, res->end, (int) res->flags, size);
+		res->parent, res->start, res->end,
+		(int) res->flags, size, alignment);
 
 	/* has resource already been aligned/assigned? */
 	if (res->parent)
diff -urN linux-2.4.20-pre7/arch/ppc/kernel/m8260_setup.c linux-2.4.20-pre8/arch/ppc/kernel/m8260_setup.c
--- linux-2.4.20-pre7/arch/ppc/kernel/m8260_setup.c	Wed Sep 25 18:20:44 2002
+++ linux-2.4.20-pre8/arch/ppc/kernel/m8260_setup.c	Wed Sep 25 18:21:28 2002
@@ -220,6 +220,7 @@
 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 	      unsigned long r6, unsigned long r7)
 {
+	parse_bootinfo(find_bootinfo());
 
 	if ( r3 )
 		memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
diff -urN linux-2.4.20-pre7/arch/ppc/kernel/m8xx_setup.c linux-2.4.20-pre8/arch/ppc/kernel/m8xx_setup.c
--- linux-2.4.20-pre7/arch/ppc/kernel/m8xx_setup.c	Wed Sep 25 18:20:44 2002
+++ linux-2.4.20-pre8/arch/ppc/kernel/m8xx_setup.c	Wed Sep 25 18:21:28 2002
@@ -344,6 +344,8 @@
 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 		unsigned long r6, unsigned long r7)
 {
+	parse_bootinfo(find_bootinfo());
+
 	if ( r3 )
 		memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
 	
diff -urN linux-2.4.20-pre7/arch/ppc/kernel/pci.c linux-2.4.20-pre8/arch/ppc/kernel/pci.c
--- linux-2.4.20-pre7/arch/ppc/kernel/pci.c	Wed Sep 25 18:20:44 2002
+++ linux-2.4.20-pre8/arch/ppc/kernel/pci.c	Wed Sep 25 18:21:28 2002
@@ -237,7 +237,8 @@
  * which might have be mirrored at 0x0100-0x03ff..
  */
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -urN linux-2.4.20-pre7/arch/ppc64/kernel/pci.c linux-2.4.20-pre8/arch/ppc64/kernel/pci.c
--- linux-2.4.20-pre7/arch/ppc64/kernel/pci.c	Wed Sep 25 18:20:45 2002
+++ linux-2.4.20-pre8/arch/ppc64/kernel/pci.c	Wed Sep 25 18:21:28 2002
@@ -180,7 +180,8 @@
  * which might have be mirrored at 0x0100-0x03ff..
  */
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 	struct pci_dev *dev = data;
 
diff -urN linux-2.4.20-pre7/arch/sh/kernel/pcibios.c linux-2.4.20-pre8/arch/sh/kernel/pcibios.c
--- linux-2.4.20-pre7/arch/sh/kernel/pcibios.c	Sat Sep  8 12:29:09 2001
+++ linux-2.4.20-pre8/arch/sh/kernel/pcibios.c	Wed Sep 25 18:21:30 2002
@@ -60,7 +60,8 @@
  * addresses to be allocated in the 0x000-0x0ff region
  * modulo 0x400.
  */
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
 {
 	if (res->flags & IORESOURCE_IO) {
 		unsigned long start = res->start;
diff -urN linux-2.4.20-pre7/arch/sparc/kernel/pcic.c linux-2.4.20-pre8/arch/sparc/kernel/pcic.c
--- linux-2.4.20-pre7/arch/sparc/kernel/pcic.c	Wed Sep 25 18:20:47 2002
+++ linux-2.4.20-pre8/arch/sparc/kernel/pcic.c	Wed Sep 25 18:21:30 2002
@@ -865,7 +865,8 @@
 {
 }
 
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
 {
 }
 
diff -urN linux-2.4.20-pre7/arch/sparc64/defconfig linux-2.4.20-pre8/arch/sparc64/defconfig
--- linux-2.4.20-pre7/arch/sparc64/defconfig	Wed Sep 25 18:20:48 2002
+++ linux-2.4.20-pre8/arch/sparc64/defconfig	Wed Sep 25 18:21:30 2002
@@ -431,7 +431,7 @@
 CONFIG_IEEE1394_DV1394=m
 CONFIG_IEEE1394_RAWIO=m
 CONFIG_IEEE1394_CMP=m
-# CONFIG_IEEE1394_AMDTP is not set
+CONFIG_IEEE1394_AMDTP=m
 # CONFIG_IEEE1394_VERBOSEDEBUG is not set
 
 #
@@ -736,6 +736,7 @@
 # CONFIG_SOUND_ESSSOLO1 is not set
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
 # CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
@@ -858,6 +859,8 @@
 # CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
 CONFIG_USB_SERIAL_MCT_U232=m
 CONFIG_USB_SERIAL_KLSI=m
@@ -873,6 +876,7 @@
 # CONFIG_USB_AUERSWALD is not set
 CONFIG_USB_TIGL=m
 # CONFIG_USB_BRLVGER is not set
+CONFIG_USB_LCD=m
 
 #
 # Bluetooth support
diff -urN linux-2.4.20-pre7/arch/sparc64/kernel/pci.c linux-2.4.20-pre8/arch/sparc64/kernel/pci.c
--- linux-2.4.20-pre7/arch/sparc64/kernel/pci.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/sparc64/kernel/pci.c	Wed Sep 25 18:21:31 2002
@@ -311,7 +311,8 @@
 {
 }
 
-void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
 {
 }
 
diff -urN linux-2.4.20-pre7/arch/sparc64/kernel/traps.c linux-2.4.20-pre8/arch/sparc64/kernel/traps.c
--- linux-2.4.20-pre7/arch/sparc64/kernel/traps.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/sparc64/kernel/traps.c	Wed Sep 25 18:21:32 2002
@@ -1533,17 +1533,14 @@
 	printk("\n");
 }
 
-void show_trace_task(struct task_struct *tsk)
+void show_trace_raw(struct task_struct *tsk, unsigned long ksp)
 {
 	unsigned long pc, fp;
 	unsigned long task_base = (unsigned long)tsk;
 	struct reg_window *rw;
 	int count = 0;
 
-	if (!tsk)
-		return;
-
-	fp = tsk->thread.ksp + STACK_BIAS;
+	fp = ksp + STACK_BIAS;
 	do {
 		/* Bogus frame pointer? */
 		if (fp < (task_base + sizeof(struct task_struct)) ||
@@ -1557,6 +1554,12 @@
 	printk("\n");
 }
 
+void show_trace_task(struct task_struct *tsk)
+{
+	if (tsk)
+		show_trace_raw(tsk, tsk->thread.ksp);
+}
+
 void die_if_kernel(char *str, struct pt_regs *regs)
 {
 	extern void __show_regs(struct pt_regs * regs);
diff -urN linux-2.4.20-pre7/arch/sparc64/mm/fault.c linux-2.4.20-pre8/arch/sparc64/mm/fault.c
--- linux-2.4.20-pre7/arch/sparc64/mm/fault.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/arch/sparc64/mm/fault.c	Wed Sep 25 18:21:32 2002
@@ -129,8 +129,8 @@
 	return tally;
 }
 
-void unhandled_fault(unsigned long address, struct task_struct *tsk,
-                     struct pt_regs *regs)
+static void unhandled_fault(unsigned long address, struct task_struct *tsk,
+			    struct pt_regs *regs)
 {
 	if ((unsigned long) address < PAGE_SIZE) {
 		printk(KERN_ALERT "Unable to handle kernel NULL "
@@ -147,6 +147,19 @@
 	die_if_kernel("Oops", regs);
 }
 
+extern void show_trace_raw(struct task_struct *, unsigned long);
+
+static void bad_kernel_pc(struct pt_regs *regs)
+{
+	unsigned long ksp;
+
+	printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
+	       regs->tpc);
+	__asm__("mov %%sp, %0" : "=r" (ksp));
+	show_trace_raw(current, ksp);
+	unhandled_fault(regs->tpc, current, regs);
+}
+
 /*
  * We now make sure that mmap_sem is held in all paths that call 
  * this. Additionally, to prevent kswapd from ripping ptes from
@@ -211,7 +224,7 @@
 		if (!regs->tpc || (regs->tpc & 0x3))
 			return 0;
 		if (regs->tstate & TSTATE_PRIV) {
-			insn = *(unsigned int *)regs->tpc;
+			insn = *(unsigned int *) regs->tpc;
 		} else {
 			insn = get_user_insn(regs->tpc);
 		}
@@ -302,6 +315,20 @@
 	    (fault_code & FAULT_CODE_DTLB))
 		BUG();
 
+	if (regs->tstate & TSTATE_PRIV) {
+		unsigned long tpc = regs->tpc;
+		extern unsigned int _etext;
+
+		/* Sanity check the PC. */
+		if ((tpc >= KERNBASE && tpc < (unsigned long) &_etext) ||
+		    (tpc >= MODULES_VADDR && tpc < MODULES_END)) {
+			/* Valid, no problems... */
+		} else {
+			bad_kernel_pc(regs);
+			return;
+		}
+	}
+
 	/*
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
diff -urN linux-2.4.20-pre7/arch/x86_64/config.in linux-2.4.20-pre8/arch/x86_64/config.in
--- linux-2.4.20-pre7/arch/x86_64/config.in	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/config.in	Wed Sep 25 18:21:32 2002
@@ -54,7 +54,6 @@
 define_bool CONFIG_X86_IO_APIC y
 define_bool CONFIG_X86_LOCAL_APIC y
 
-#currently broken:
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
 bool 'HPET timers' CONFIG_HPET_TIMER
@@ -70,6 +69,11 @@
 fi
 
 bool 'Machine check support' CONFIG_MCE
+bool 'K8 NUMA support' CONFIG_K8_NUMA
+if [ "$CONFIG_K8_NUMA" = "y" ]; then
+   define_bool CONFIG_DISCONTIGMEM y 
+   define_bool CONFIG_NUMA y
+fi
 
 endmenu
 
@@ -237,5 +241,7 @@
    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
    bool '  Additional run-time checks' CONFIG_CHECKING
    bool '  Debug __init statements' CONFIG_INIT_DEBUG
+   bool '  IOMMU leak tracing' CONFIG_IOMMU_LEAK
+   bool '  Probalistic stack overflow check' CONFIG_DEBUG_STACKOVERFLOW
 fi
 endmenu
diff -urN linux-2.4.20-pre7/arch/x86_64/defconfig linux-2.4.20-pre8/arch/x86_64/defconfig
--- linux-2.4.20-pre7/arch/x86_64/defconfig	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/defconfig	Wed Sep 25 18:21:32 2002
@@ -42,9 +42,11 @@
 CONFIG_MTRR=y
 # CONFIG_SMP is not set
 CONFIG_HPET_TIMER=y
-CONFIG_GART_IOMMU=y
+# CONFIG_GART_IOMMU is not set
+CONFIG_DUMMY_IOMMU=y
 CONFIG_X86_UP_IOAPIC=y
 CONFIG_MCE=y
+# CONFIG_K8_NUMA is not set
 
 #
 # General setup
@@ -100,6 +102,7 @@
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -299,8 +302,10 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
@@ -328,10 +333,13 @@
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SEAGATE is not set
+# CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
@@ -393,6 +401,7 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -505,8 +514,6 @@
 #
 # CONFIG_FTAPE is not set
 CONFIG_AGP=y
-CONFIG_AGP_AMD_8151=y
-CONFIG_AGP=y
 CONFIG_AGP_INTEL=y
 CONFIG_AGP_I810=y
 CONFIG_AGP_VIA=y
@@ -544,6 +551,8 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
 CONFIG_EXT3_FS=y
 CONFIG_JBD=y
@@ -561,6 +570,9 @@
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -580,7 +592,6 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
-CONFIG_SIMICSFS=y
 
 #
 # Network File Systems
@@ -592,6 +603,7 @@
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -606,7 +618,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -689,3 +700,5 @@
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_CHECKING is not set
 # CONFIG_INIT_DEBUG is not set
+# CONFIG_IOMMU_LEAK is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
diff -urN linux-2.4.20-pre7/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.20-pre8/arch/x86_64/ia32/ia32_ioctl.c
--- linux-2.4.20-pre7/arch/x86_64/ia32/ia32_ioctl.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/ia32/ia32_ioctl.c	Wed Sep 25 18:21:32 2002
@@ -1,4 +1,4 @@
-/* $Id: ia32_ioctl.c,v 1.20 2002/07/27 23:15:22 ak Exp $
+/* $Id: ia32_ioctl.c,v 1.24 2002/09/17 15:23:41 ak Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -3136,6 +3136,16 @@
 	return err;	
 }
 
+
+#define REISERFS_IOC_UNPACK32               _IOW(0xCD,1,int)
+
+static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr) 
+{ 
+	if (cmd == REISERFS_IOC_UNPACK32) 
+		cmd = REISERFS_IOC_UNPACK; 
+	return sys_ioctl(fd,cmd,ptr); 
+} 
+
 struct dirent32 {
 	unsigned int		d_ino;
 	__kernel_off_t32	d_off;
@@ -3173,28 +3183,51 @@
 	return ret;
 }
 
-struct ioctl_trans {
-	unsigned long cmd;
-	int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
-	struct ioctl_trans *next;
-};
+#define RTC_IRQP_READ32	_IOR('p', 0x0b, unsigned int)	 /* Read IRQ rate   */
+#define RTC_IRQP_SET32	_IOW('p', 0x0c, unsigned int)	 /* Set IRQ rate    */
+#define RTC_EPOCH_READ32	_IOR('p', 0x0d, unsigned)	 /* Read epoch      */
+#define RTC_EPOCH_SET32		_IOW('p', 0x0e, unsigned)	 /* Set epoch       */
 
-/* generic function to change a single long put_user to arg to 32bit */
-static int arg2long(unsigned int fd, unsigned int cmd, unsigned long arg)
+static int rtc32_ioctl(unsigned fd, unsigned cmd, unsigned long arg) 
 {
+	unsigned long val;
+	mm_segment_t oldfs = get_fs(); 
 	int ret; 
-	unsigned long val = 0; 
-	mm_segment_t oldseg = get_fs();
+	
+	switch (cmd) { 
+	case RTC_IRQP_READ32: 
 	set_fs(KERNEL_DS);
-	ret = sys_ioctl(fd, cmd, (unsigned long)&val);  
-	set_fs(oldseg); 
-	if (!ret || val) {
-		if (put_user((int)val, (unsigned int *)arg)) 
-			return -EFAULT; 
-	}
+		ret = sys_ioctl(fd, RTC_IRQP_READ, (unsigned long)&val); 
+		set_fs(oldfs); 
+		if (!ret)
+			ret = put_user(val, (unsigned int*) arg); 
 	return ret; 
+
+	case RTC_IRQP_SET32: 
+		cmd = RTC_EPOCH_SET; 
+		break; 
+
+	case RTC_EPOCH_READ32:
+		set_fs(KERNEL_DS); 
+		ret = sys_ioctl(fd, RTC_EPOCH_READ, (unsigned long) &val); 
+		set_fs(oldfs); 
+		if (!ret)
+			ret = put_user(val, (unsigned int*) arg); 
+		return ret; 
+
+	case RTC_EPOCH_SET32:
+		cmd = RTC_EPOCH_SET; 
+		break; 
+	} 
+	return sys_ioctl(fd,cmd,arg); 
 } 
 
+struct ioctl_trans {
+	unsigned long cmd;
+	int (*handler)(unsigned int, unsigned int, unsigned long, struct file * filp);
+	struct ioctl_trans *next;
+};
+
 #define REF_SYMBOL(handler) if (0) (void)handler;
 #define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler);  asm volatile(".quad %c0, " #handler ",0"::"i" (cmd)); 
 #define HANDLE_IOCTL(cmd,handler) HANDLE_IOCTL2(cmd,handler)
@@ -3404,10 +3437,6 @@
 COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+6, int))
 COMPATIBLE_IOCTL(_IOR('v' , BASE_VIDIOCPRIVATE+7, int))
 /* Little p (/dev/rtc, /dev/envctrl, etc.) */
-#if 0
-COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
-COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
-#endif
 COMPATIBLE_IOCTL(RTC_AIE_ON)
 COMPATIBLE_IOCTL(RTC_AIE_OFF)
 COMPATIBLE_IOCTL(RTC_UIE_ON)
@@ -3422,10 +3451,11 @@
 COMPATIBLE_IOCTL(RTC_SET_TIME)
 COMPATIBLE_IOCTL(RTC_WKALM_SET)
 COMPATIBLE_IOCTL(RTC_WKALM_RD)
-HANDLE_IOCTL(RTC_IRQP_READ,arg2long)
-COMPATIBLE_IOCTL(RTC_IRQP_SET)
-COMPATIBLE_IOCTL(RTC_EPOCH_READ)
-COMPATIBLE_IOCTL(RTC_EPOCH_SET)
+HANDLE_IOCTL(RTC_IRQP_READ,  rtc32_ioctl)
+HANDLE_IOCTL(RTC_IRQP_READ32,rtc32_ioctl)
+HANDLE_IOCTL(RTC_IRQP_SET32, rtc32_ioctl)
+HANDLE_IOCTL(RTC_EPOCH_READ32, rtc32_ioctl)
+HANDLE_IOCTL(RTC_EPOCH_SET32, rtc32_ioctl)
 /* Little m */
 COMPATIBLE_IOCTL(MTIOCTOP)
 /* Socket level stuff */
@@ -3787,8 +3817,9 @@
 COMPATIBLE_IOCTL(RTC_WKALM_SET);
 COMPATIBLE_IOCTL(RTC_WKALM_RD);
 #endif
-#define REISERFS_IOC_UNPACK32               _IOW(0xCD,1,int)
-COMPATIBLE_IOCTL(REISERFS_IOC_UNPACK32);
+HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32);
+HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32);
+HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32);
 /* serial driver */ 
 HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl);
 HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl);
@@ -3962,6 +3993,8 @@
 #define IOCTL_HASHSIZE 256
 struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
 
+extern struct ioctl_trans ioctl_start[], ioctl_end[]; 
+
 static inline unsigned long ioctl32_hash(unsigned long cmd)
 {
 	return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE;
@@ -3987,7 +4020,6 @@
 static int __init init_sys32_ioctl(void)
 {
 	int i;
-	extern struct ioctl_trans ioctl_start[], ioctl_end[]; 
 
 	for (i = 0; &ioctl_start[i] < &ioctl_end[0]; i++) {
 		if (ioctl_start[i].next != 0) { 
@@ -4002,70 +4034,108 @@
 
 __initcall(init_sys32_ioctl);
 
-static struct ioctl_trans *additional_ioctls;
-
-/* Always call these with kernel lock held! */
+static struct ioctl_trans *ioctl_free_list;
 
-/* XXX should be really dynamic */
-#define ADD_ORDER 2
-#define TAB_SIZE  (PAGE_SIZE<<ADD_ORDER)
+/* Never free them really. This avoids SMP races. With a Read-Copy-Update
+   enabled kernel we could just use the RCU infrastructure for this. */
+static void free_ioctl(struct ioctl_trans *t) 
+{ 
+	t->cmd = 0; 
+	mb();
+	t->next = ioctl_free_list;
+	ioctl_free_list = t;
+} 
 
 int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, unsigned int, unsigned long, struct file *))
 {
-	int i, found = 0;
-	if (!additional_ioctls) {
-		additional_ioctls = __get_free_pages(GFP_KERNEL, ADD_ORDER);
-		if (!additional_ioctls)
-			return -ENOMEM;
-		memset(additional_ioctls, 0, PAGE_SIZE<<ADD_ORDER);
-	}
-	for (i = 1; i < TAB_SIZE/sizeof(struct ioctl_trans); i++) {
-		if (!additional_ioctls[i].cmd)
-			found = i;
-		if (additional_ioctls[i].cmd == cmd) { 
-			printk(KERN_ERR "Duplicated ioctl32 handler %d\n", cmd);
+	struct ioctl_trans *t;
+	unsigned long hash = ioctl32_hash(cmd);
+
+	lock_kernel(); 
+	for (t = (struct ioctl_trans *)ioctl32_hash_table[hash];
+	     t;
+	     t = t->next) { 
+		if (t->cmd == cmd) {
+			printk("Trying to register duplicated ioctl32 handler %x\n", cmd);
+			unlock_kernel();
 			return -EINVAL;
 		}
 	}
-	if (i == TAB_SIZE/sizeof(struct ioctl_trans)) { 
-		printk(KERN_ERR "ioctl32 translation table overflow\n"); 
+
+	if (ioctl_free_list) { 
+		t = ioctl_free_list; 
+		ioctl_free_list = t->next; 
+	} else { 
+		t = kmalloc(sizeof(struct ioctl_trans), GFP_KERNEL); 
+		if (!t) { 
+			unlock_kernel();
 		return -ENOMEM;
 	}
-	i = found;
-	additional_ioctls[i].cmd = cmd;
-	if (!handler)
-		additional_ioctls[i].handler = 
-	    (int (*)(unsigned,unsigned,unsigned long, struct file *))sys_ioctl;
-	else
-		additional_ioctls[i].handler = handler;
-	ioctl32_insert_translation(&additional_ioctls[i]);
+	}
+	
+	t->next = NULL;
+	t->cmd = cmd;
+	t->handler = handler; 
+	ioctl32_insert_translation(t);
+
+	unlock_kernel();
 	return 0;
 }
 
+static inline int builtin_ioctl(struct ioctl_trans *t)
+{ 
+	return t >= (struct ioctl_trans *)ioctl_start &&
+	       t < (struct ioctl_trans *)ioctl_end; 
+} 
+
+/* Problem: 
+   This function cannot unregister duplicate ioctls, because they are not
+   unique.
+   When they happen we need to extend the prototype to pass handler too. */
 
 int unregister_ioctl32_conversion(unsigned int cmd)
 {
 	unsigned long hash = ioctl32_hash(cmd);
 	struct ioctl_trans *t, *t1;
 
-	t = (struct ioctl_trans *)(long)ioctl32_hash_table[hash];
-	if (!t) return -EINVAL;
-	if (t->cmd == cmd && t >= additional_ioctls &&
-	    (unsigned long)t < ((unsigned long)additional_ioctls) + TAB_SIZE) {
+	lock_kernel(); 
+
+	t = (struct ioctl_trans *)ioctl32_hash_table[hash];
+	if (!t) { 
+		unlock_kernel();
+		return -EINVAL;
+	} 
+
+	if (t->cmd == cmd) { 
+		if (builtin_ioctl(t)) {
+			printk("%p tried to unregister builtin ioctl %x\n",
+			       __builtin_return_address(0), cmd);
+		} else { 
 		ioctl32_hash_table[hash] = t->next;
-		t->cmd = 0;
+			free_ioctl(t); 
+			unlock_kernel();
 		return 0;
-	} else while (t->next) {
+		}
+	} 
+	while (t->next) {
 		t1 = (struct ioctl_trans *)(long)t->next;
-		if (t1->cmd == cmd && t1 >= additional_ioctls &&
-		    (unsigned long)t1 < ((unsigned long)additional_ioctls) + TAB_SIZE) {
-			t1->cmd = 0;
+		if (t1->cmd == cmd) { 
+			if (builtin_ioctl(t1)) {
+				printk("%p tried to unregister builtin ioctl %x\n",
+				       __builtin_return_address(0), cmd);
+				goto out;
+			} else { 
 			t->next = t1->next;
+				free_ioctl(t1); 
+				unlock_kernel();
 			return 0;
 		}
+		}
 		t = t1;
 	}
-	printk(KERN_ERR "Trying to free unknown 32bit ioctl handler %d\n", cmd);
+	printk(KERN_ERR "Trying to free unknown 32bit ioctl handler %x\n", cmd);
+ out:
+	unlock_kernel();
 	return -EINVAL;
 }
 
@@ -4088,10 +4158,10 @@
 		goto out;
 	}
 
-	t = (struct ioctl_trans *)(long)ioctl32_hash_table [ioctl32_hash (cmd)];
+	t = (struct ioctl_trans *)ioctl32_hash_table [ioctl32_hash (cmd)];
 
 	while (t && t->cmd != cmd)
-		t = (struct ioctl_trans *)(long)t->next;
+		t = (struct ioctl_trans *)t->next;
 	if (t) {
 		handler = t->handler;
 		error = handler(fd, cmd, arg, filp);
diff -urN linux-2.4.20-pre7/arch/x86_64/ia32/ia32entry.S linux-2.4.20-pre8/arch/x86_64/ia32/ia32entry.S
--- linux-2.4.20-pre7/arch/x86_64/ia32/ia32entry.S	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/ia32/ia32entry.S	Wed Sep 25 18:21:32 2002
@@ -3,7 +3,7 @@
  * 		
  * Copyright 2000,2001 Andi Kleen, SuSE Labs.
  * 
- * $Id: ia32entry.S,v 1.35 2002/05/28 21:55:05 ak Exp $ 		
+ * $Id: ia32entry.S,v 1.36 2002/09/12 12:55:05 ak Exp $ 		
  */		 
 
 #include <asm/calling.h>
@@ -331,15 +331,15 @@
 	.quad sys_getgid		/* 200 */
 	.quad sys_geteuid
 	.quad sys_getegid
-	.quad sys32_setreuid
-	.quad sys32_setregid
-	.quad sys32_getgroups	/* 205 */
-	.quad sys32_setgroups
+	.quad sys_setreuid
+	.quad sys_setregid
+	.quad sys_getgroups	/* 205 */
+	.quad sys_setgroups
 	.quad sys_fchown
-	.quad sys32_setresuid
-	.quad sys32_getresuid
-	.quad sys32_setresgid	/* 210 */
-	.quad sys32_getresgid
+	.quad sys_setresuid
+	.quad sys_getresuid
+	.quad sys_setresgid	/* 210 */
+	.quad sys_getresgid
 	.quad sys_chown
 	.quad sys_setuid
 	.quad sys_setgid
@@ -354,6 +354,34 @@
 	.quad sys_ni_syscall    /* security */
 	.quad sys_gettid	
 	.quad sys_readahead	/* 225 */ 
+	.quad sys_setxattr
+	.quad sys_lsetxattr
+	.quad sys_fsetxattr
+	.quad sys_getxattr
+	.quad sys_lgetxattr	/* 230 */
+	.quad sys_fgetxattr
+	.quad sys_listxattr
+	.quad sys_llistxattr
+	.quad sys_flistxattr
+	.quad sys_removexattr	/* 235 */
+	.quad sys_lremovexattr
+	.quad sys_fremovexattr
+	.quad sys_tkill		/* 238 */ 
+	.quad sys_ni_syscall	/* sendfile64 */
+	.quad sys_ni_syscall	/* futex */
+	.quad sys_ni_syscall	/* sched_setaffinity */
+	.quad sys_ni_syscall	/* sched_getaffinity */
+	.quad sys_ni_syscall	/* set_threadarea */
+	.quad sys_ni_syscall	/* get_threadarea */
+	.quad sys_ni_syscall	/* io_setup */
+	.quad sys_ni_syscall	/* io_destroy */
+	.quad sys_ni_syscall	/* io_getevents */
+	.quad sys_ni_syscall	/* io_submit */
+	.quad sys_ni_syscall	/* io_cancel */
+	.quad sys_ni_syscall	/* alloc_hugepages */
+	.quad sys_ni_syscall	/* free_hugepages */
+	.quad sys_ni_syscall	/* exit_group */
+
 ia32_syscall_end:		
 	.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
 		.quad ni_syscall
diff -urN linux-2.4.20-pre7/arch/x86_64/ia32/ipc32.c linux-2.4.20-pre8/arch/x86_64/ia32/ipc32.c
--- linux-2.4.20-pre7/arch/x86_64/ia32/ipc32.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/ia32/ipc32.c	Wed Sep 25 18:21:32 2002
@@ -152,8 +152,8 @@
 };
 
 struct ipc_kludge {
-	struct msgbuf *msgp;
-	int msgtyp;
+	u32 msgp;
+	s32 msgtyp;
 };
 
 
@@ -268,14 +268,19 @@
 	return err;
 }
 
+#define MAXBUF (64*1024)
+
 static int
 do_sys32_msgsnd (int first, int second, int third, void *uptr)
 {
-	struct msgbuf *p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+	struct msgbuf *p;
 	struct msgbuf32 *up = (struct msgbuf32 *)uptr;
 	mm_segment_t old_fs;
 	int err;
 
+	if (second >= MAXBUF-sizeof(struct msgbuf))
+		return -EINVAL; 
+	p = kmalloc(second + sizeof(struct msgbuf), GFP_USER);
 	if (!p)
 		return -ENOMEM;
 	err = get_user(p->mtype, &up->mtype);
@@ -312,13 +317,15 @@
 		uptr = (void *)A(ipck.msgp);
 		msgtyp = ipck.msgtyp;
 	}
+	if (second >= MAXBUF-sizeof(struct msgbuf)) 
+		return -EINVAL; 
 	err = -ENOMEM;
-	p = kmalloc(second + sizeof(struct msgbuf) + 4, GFP_USER);
+	p = kmalloc(second + sizeof(struct msgbuf), GFP_USER);
 	if (!p)
 		goto out;
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
-	err = sys_msgrcv(first, p, second + 4, msgtyp, third);
+	err = sys_msgrcv(first, p, second, msgtyp, third);
 	set_fs(old_fs);
 	if (err < 0)
 		goto free_then_out;
diff -urN linux-2.4.20-pre7/arch/x86_64/ia32/sys_ia32.c linux-2.4.20-pre8/arch/x86_64/ia32/sys_ia32.c
--- linux-2.4.20-pre7/arch/x86_64/ia32/sys_ia32.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/ia32/sys_ia32.c	Wed Sep 25 18:21:32 2002
@@ -15,7 +15,7 @@
  * environment. In 2.5 most of this should be moved to a generic directory. 
  *
  * This file assumes that there is a hole at the end of user address space.
- * $Id: sys_ia32.c,v 1.38 2002/07/18 09:46:54 ak Exp $
+ * $Id: sys_ia32.c,v 1.42 2002/09/17 15:23:41 ak Exp $
  */
 
 #include <linux/config.h>
@@ -1259,6 +1259,8 @@
 }
 
 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
+asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg);
+
 
 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
@@ -1281,6 +1283,11 @@
 				return -EFAULT;
 			return 0;
 		}
+	case F_GETLK64: 
+	case F_SETLK64: 
+	case F_SETLKW64: 
+		return sys32_fcntl64(fd,cmd,arg); 
+
 	default:
 		return sys_fcntl(fd, cmd, (unsigned long)arg);
 	}
@@ -1317,21 +1324,33 @@
 	struct flock fl64;  
 	mm_segment_t oldfs = get_fs(); 
 	int ret = 0; 
+	int oldcmd = cmd;
+	unsigned long oldarg = arg;
 
 	switch (cmd) {
 	case F_GETLK64: 
+		cmd = F_GETLK; 
+		goto cnv;
 	case F_SETLK64: 
+		cmd = F_SETLK; 
+		goto cnv; 
 	case F_SETLKW64:
+		cmd = F_SETLKW; 
+	cnv:
 		ret = get_flock64((struct ia32_flock64 *)arg, &fl64); 
 		arg = (unsigned long)&fl64; 
 		set_fs(KERNEL_DS); 
 		break; 
+	case F_GETLK:
+	case F_SETLK:
+	case F_SETLKW:
+		return sys32_fcntl(fd,cmd,arg); 
 	}
 	if (!ret)
-		ret = sys32_fcntl(fd, cmd, arg);
+		ret = sys_fcntl(fd, cmd, arg);
 	set_fs(oldfs); 
-	if (cmd == F_GETLK64 && !ret)
-		ret = put_flock64((struct ia32_flock64 *)arg, &fl64); 
+	if (oldcmd == F_GETLK64 && !ret)
+		ret = put_flock64((struct ia32_flock64 *)oldarg, &fl64); 
 	return ret; 
 }
 
@@ -1682,136 +1701,6 @@
 	return ret;
 }
 
-extern asmlinkage long sys_setreuid(uid_t ruid, uid_t euid);
-
-asmlinkage long sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
-{
-	uid_t sruid, seuid;
-
-	sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
-	seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
-	return sys_setreuid(sruid, seuid);
-}
-
-extern asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
-
-asmlinkage long
-sys32_setresuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid,
-		__kernel_uid_t32 suid)
-{
-	uid_t sruid, seuid, ssuid;
-
-	sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
-	seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
-	ssuid = (suid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)suid);
-	return sys_setresuid(sruid, seuid, ssuid);
-}
-
-extern asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
-
-asmlinkage long
-sys32_getresuid(__kernel_uid_t32 *ruid, __kernel_uid_t32 *euid,
-		__kernel_uid_t32 *suid)
-{
-	uid_t a, b, c;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-		
-	set_fs (KERNEL_DS);
-	ret = sys_getresuid(&a, &b, &c);
-	set_fs (old_fs);
-	if (put_user (a, ruid) || put_user (b, euid) || put_user (c, suid))
-		return -EFAULT;
-	return ret;
-}
-
-extern asmlinkage long sys_setregid(gid_t rgid, gid_t egid);
-
-asmlinkage long
-sys32_setregid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid)
-{
-	gid_t srgid, segid;
-
-	srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
-	segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
-	return sys_setregid(srgid, segid);
-}
-
-extern asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
-
-asmlinkage long
-sys32_setresgid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid,
-		__kernel_gid_t32 sgid)
-{
-	gid_t srgid, segid, ssgid;
-
-	srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
-	segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
-	ssgid = (sgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)sgid);
-	return sys_setresgid(srgid, segid, ssgid);
-}
-
-extern asmlinkage long sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
-
-asmlinkage long
-sys32_getresgid(__kernel_gid_t32 *rgid, __kernel_gid_t32 *egid,
-		__kernel_gid_t32 *sgid) 
-{
-	gid_t a, b, c;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-		
-	set_fs (KERNEL_DS);
-	ret = sys_getresgid(&a, &b, &c);
-	set_fs (old_fs);
-	if (!ret) {
-		ret = put_user (a, rgid);
-		ret |= put_user (b, egid);
-		ret |= put_user (c, sgid);
-	}
-	return ret;
-}
-
-extern asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist);
-
-asmlinkage long
-sys32_getgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
-{
-	gid_t gl[NGROUPS];
-	int ret, i;
-	mm_segment_t old_fs = get_fs ();
-	
-	set_fs (KERNEL_DS);
-	ret = sys_getgroups(gidsetsize, gl);
-	set_fs (old_fs);
-	if (gidsetsize && ret > 0 && ret <= NGROUPS)
-		for (i = 0; i < ret; i++, grouplist++)
-			if (put_user (gl[i], grouplist))
-				return -EFAULT;
-	return ret;
-}
-
-extern asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist);
-
-asmlinkage long
-sys32_setgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
-{
-	gid_t gl[NGROUPS];
-	int ret, i;
-	mm_segment_t old_fs = get_fs ();
-	
-	if ((unsigned) gidsetsize > NGROUPS)
-		return -EINVAL;
-	for (i = 0; i < gidsetsize; i++, grouplist++)
-		if (get_user (gl[i], grouplist))
-			return -EFAULT;
-        set_fs (KERNEL_DS);
-	ret = sys_setgroups(gidsetsize, gl);
-	set_fs (old_fs);
-	return ret;
-}
-
-
 extern void check_pending(int signum);
 
 asmlinkage long sys_utimes(char *, struct timeval *);
@@ -2110,7 +1999,7 @@
 	 __put_user(0,name->version+__OLD_UTS_LEN);
 	 { 
 		 char *arch = (personality(current->personality) == PER_LINUX32)
-			 ? "i386" : "x86_64"; 
+			 ? "i686" : "x86_64"; 
 		 
 		 __copy_to_user(&name->machine,arch,strlen(arch)+1);
 	 }
@@ -2129,7 +2018,7 @@
 	err=copy_to_user(name, &system_utsname, sizeof (*name));
 	up_read(&uts_sem);
 	if (personality(current->personality) == PER_LINUX32)
-		err = copy_to_user(name->machine, "i386", 5);
+		err = copy_to_user(name->machine, "i686", 5);
 	return err?-EFAULT:0;
 }
 
@@ -2628,7 +2517,7 @@
 
 static int __init ia32_init (void)
 {
-	printk("IA32 emulation $Id: sys_ia32.c,v 1.38 2002/07/18 09:46:54 ak Exp $\n");  
+	printk("IA32 emulation $Id: sys_ia32.c,v 1.42 2002/09/17 15:23:41 ak Exp $\n");  
 	ia32_exec_domain.signal_map = default_exec_domain.signal_map;
 	ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
 	register_exec_domain(&ia32_exec_domain);
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/Makefile linux-2.4.20-pre8/arch/x86_64/kernel/Makefile
--- linux-2.4.20-pre7/arch/x86_64/kernel/Makefile	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/Makefile	Wed Sep 25 18:21:32 2002
@@ -20,7 +20,7 @@
 obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o \
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
 		pci-dma.o x8664_ksyms.o i387.o syscall.o vsyscall.o \
-		setup64.o acpitable.o
+		setup64.o acpitable.o e820.o
 
 ifdef CONFIG_PCI
 obj-y			+= pci-x86_64.o
@@ -34,7 +34,7 @@
 obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o  nmi.o
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o mpparse.o
 obj-$(CONFIG_EARLY_PRINTK) +=  early_printk.o
-obj-$(CONFIG_GART_IOMMU) += pci-gart.o
+obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
 obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o
 obj-$(CONFIG_MCE) += bluesmoke.o
 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/acpitable.c linux-2.4.20-pre8/arch/x86_64/kernel/acpitable.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/acpitable.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/acpitable.c	Wed Sep 25 18:21:32 2002
@@ -28,6 +28,14 @@
 
 static acpi_table_handler acpi_boot_ops[ACPI_TABLE_COUNT];
 
+extern unsigned long end_pfn;
+static inline int bad_ptr(void *p) 
+{ 
+	if ((unsigned long)p  >> PAGE_SHIFT >= end_pfn) 
+		return 1; 
+	return 0; 	
+} 
+
 /*
  * Checksum an ACPI table.
  */
@@ -145,6 +153,8 @@
 	if (!acpi_checksum(rsdp, RSDP2_CHECKSUM_LENGTH)
 		&& rsdp->length >= RSDP2_CHECKSUM_LENGTH) {	/* ACPI 2.0 might be present */
 		xsdt = __va(rsdp->xsdt_address);
+		if (bad_ptr(xsdt))
+			return -1; 
 		if (!strncmp(xsdt->header.signature, "XSDT", 4)) {
 			acpi_print_table_header(&xsdt->header);
 			for (i = 0; i < (xsdt->header.length - sizeof(struct acpi_table_header)) / sizeof(u64); i++)
@@ -155,6 +165,8 @@
 	}
 
 	rsdt = __va(rsdp->rsdt_address);
+	if (bad_ptr(rsdt))
+		return -1;
 	if (!strncmp(rsdt->header.signature, "RSDT", 4)) {
 		acpi_print_table_header(&rsdt->header);
 		for (i = 0; i < (rsdt->header.length - sizeof(struct acpi_table_header)) / sizeof(u32); i++)
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/aperture.c linux-2.4.20-pre8/arch/x86_64/kernel/aperture.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/aperture.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre8/arch/x86_64/kernel/aperture.c	Wed Sep 25 18:21:32 2002
@@ -0,0 +1,123 @@
+/* 
+ * Firmware replacement code.
+ * 
+ * Work around broken BIOSes that don't set an aperture. 
+ * The IOMMU code needs an aperture even who no AGP is present in the system.
+ * Map the aperture over some low memory.  This is cheaper than doing bounce 
+ * buffering. The memory is lost. This is done at early boot because only
+ * the bootmem allocator can allocate 32+MB. 
+ * 
+ * Copyright 2002 Andi Kleen, SuSE Labs.
+ * $Id: aperture.c,v 1.2 2002/09/19 19:25:32 ak Exp $
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <linux/pci_ids.h>
+#include <asm/e820.h>
+#include <asm/io.h>
+#include <asm/proto.h>
+#include <asm/pci-direct.h>
+
+int fallback_aper_order __initdata = 1; /* 64MB */
+int fallback_aper_force __initdata = 0; 
+
+extern int no_iommu, force_mmu;
+
+/* This code runs before the PCI subsystem is initialized, so just 
+   access the northbridge directly. */
+
+#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16))
+
+static u32 __init allocate_aperture(void) 
+{
+#ifdef CONFIG_DISCONTIGMEM
+	pg_data_t *nd0 = NODE_DATA(0);
+#else
+	pg_data_t *nd0 = &contig_page_data;
+#endif	
+	u32 aper_size;
+	void *p; 
+
+	if (fallback_aper_order > 7) 
+		fallback_aper_order = 7; 
+	aper_size = (32 * 1024 * 1024) << fallback_aper_order; 
+
+	/* 
+         * Aperture has to be naturally aligned it seems. This means an
+	 * 2GB aperture won't have much changes to succeed in the lower 4GB of 
+	 * memory. Unfortunately we cannot move it up because that would make
+	 * the IOMMU useless.
+	 */
+	p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
+	if (!p || __pa(p)+aper_size > 0xffffffff) {
+		printk("Cannot allocate aperture memory hole (%p,%uK)\n",
+		       p, aper_size>>10);
+		if (p)
+			free_bootmem_generic((unsigned long)p, aper_size); 
+		return 0;
+	}
+	printk("Mapping aperture over %d KB of RAM @ %lx\n",  
+	       aper_size >> 10, __pa(p)); 
+	return (u32)__pa(p); 
+}
+
+void __init iommu_hole_init(void) 
+{ 
+	int fix, num; 
+	u32 aper_size, aper_alloc, aper_order;
+	u64 aper_base; 
+
+	if (no_iommu)
+		return;
+	if (end_pfn < (0xffffffff>>PAGE_SHIFT) && !force_mmu) 
+		return;
+
+	printk("Checking aperture...\n"); 
+
+	fix = 0;
+	for (num = 24; num < 32; num++) {		
+		if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) 
+			continue;	
+
+		aper_order = (read_pci_config(0, num, 3, 0x90) >> 1) & 7; 
+		aper_size = (32 * 1024 * 1024) << aper_order; 
+		aper_base = read_pci_config(0, num, 3, 0x94) & 0x7fff;
+		aper_base <<= 25; 
+
+		printk("CPU %d: aperture @ %Lx size %u KB\n", num-24, 
+		       aper_base, aper_size>>10);
+		if (!aper_base || aper_base + aper_size >= 0xffffffff) {
+			fix = 1; 
+			break; 
+		} 
+		
+		if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) {  
+			printk("Aperture pointing to e820 RAM. Ignoring.\n");
+			fix = 1; 
+			break; 
+		} 
+	} 
+
+	if (!fix && !fallback_aper_force) 
+		return; 
+
+	printk("Your BIOS is broken and doesn't leave a aperture memory hole\n");
+	aper_alloc = allocate_aperture(); 
+	if (!aper_alloc) 
+		return; 
+
+	for (num = 24; num < 32; num++) { 		
+		if (read_pci_config(0, num, 3, 0x00) != NB_ID_3) 
+			continue;	
+
+		/* Don't enable translation yet. That is done later. 
+		   Assume this BIOS didn't initialise the GART so 
+		   just overwrite all previous bits */ 
+		write_pci_config(0, num, 3, 0x90, fallback_aper_order<<1); 
+		write_pci_config(0, num, 3, 0x94, aper_alloc>>25); 
+	} 
+} 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/bluesmoke.c linux-2.4.20-pre8/arch/x86_64/kernel/bluesmoke.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/bluesmoke.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/bluesmoke.c	Wed Sep 25 18:21:32 2002
@@ -205,7 +205,7 @@
 static void mcheck_timer_trampoline(unsigned long data)
 { 
 	static struct tq_struct mcheck_task = { 
-		routine: mcheck_timer_handler
+		routine: mcheck_timer_dist
 	}; 
 	schedule_task(&mcheck_task); 
 } 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/e820.c linux-2.4.20-pre8/arch/x86_64/kernel/e820.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/e820.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre8/arch/x86_64/kernel/e820.c	Wed Sep 25 18:21:32 2002
@@ -0,0 +1,554 @@
+/* 
+ * Handle the memory map.
+ * The functions here do the job until bootmem takes over.
+ * $Id: e820.c,v 1.4 2002/09/19 19:25:32 ak Exp $
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <asm/page.h>
+#include <asm/e820.h>
+#include <asm/proto.h>
+#include <asm/bootsetup.h>
+
+extern unsigned long table_start, table_end;
+extern char _end[];
+
+extern struct resource code_resource, data_resource, vram_resource;
+
+/* Check for some hardcoded bad areas that early boot is not allowed to touch */ 
+static inline int bad_addr(unsigned long *addrp, unsigned long size)
+{ 
+	unsigned long addr = *addrp, last = addr + size; 
+
+	/* various gunk below that needed for SMP startup */
+	if (addr < 7*PAGE_SIZE) { 
+		*addrp = 7*PAGE_SIZE; 
+		return 1; 
+	}
+	/* direct mapping tables of the kernel */
+	if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) { 
+		*addrp = table_end << PAGE_SHIFT; 
+		return 1;
+	} 
+	/* initrd */ 
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (LOADER_TYPE && INITRD_START && last >= INITRD_START && 
+	    addr < INITRD_START+INITRD_SIZE) { 
+		*addrp = INITRD_START + INITRD_SIZE; 
+		return 1;
+	} 
+#endif
+	/* kernel code + 640k memory hole (later should not be needed, but 
+	   be paranoid for now) */
+	if (last >= 640*1024 && addr < __pa_symbol(&_end)) { 
+		*addrp = __pa_symbol(&_end);
+		return 1;
+	}
+	/* XXX ramdisk image here? */ 
+	return 0;
+} 
+
+int __init e820_mapped(unsigned long start, unsigned long end, int type) 
+{ 
+	int i;
+	for (i = 0; i < e820.nr_map; i++) { 
+		struct e820entry *ei = &e820.map[i]; 
+		if (type && ei->type != type) 
+			continue;
+		if (ei->addr >= end || ei->addr + ei->size < start) 
+			continue; 
+		return 1; 
+	} 
+	return 0;
+}
+
+/* 
+ * Find a free area in a specific range. 
+ */ 
+unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsigned size) 
+{ 
+	int i; 
+	for (i = 0; i < e820.nr_map; i++) { 
+		struct e820entry *ei = &e820.map[i]; 
+		unsigned long addr = ei->addr, last; 
+		if (ei->type != E820_RAM) 
+			continue; 
+		if (addr < start) 
+			addr = start;
+		if (addr > ei->addr + ei->size) 
+			continue; 
+		while (bad_addr(&addr, size) && addr+size < ei->addr + ei->size)
+			;
+		last = addr + size;
+		if (last > ei->addr + ei->size)
+			continue;
+		if (last > end) 
+			continue;
+		return addr; 
+	} 
+	return -1UL;		
+} 
+
+/* 
+ * Free bootmem based on the e820 table for a node.
+ */
+void __init e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end)
+{
+	int i;
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i]; 
+		unsigned long last, addr;
+
+		if (ei->type != E820_RAM || 
+		    ei->addr+ei->size <= start || 
+		    ei->addr > end)
+			continue;
+
+		addr = round_up(ei->addr, PAGE_SIZE);
+		if (addr < start) 
+			addr = start;
+
+		last = round_down(ei->addr + ei->size, PAGE_SIZE); 
+		if (last >= end)
+			last = end; 
+
+		if (last > addr && last-addr >= PAGE_SIZE)
+			free_bootmem_node(pgdat, addr, last-addr);
+	}
+}
+
+/*
+ * Find the highest page frame number we have available
+ */
+void __init e820_end_of_ram(void)
+{
+	int i;
+	end_pfn = 0;
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i]; 
+		unsigned long start, end;
+
+		/* count all types of areas for now to map ACPI easily */
+		start = round_up(ei->addr, PAGE_SIZE); 
+		end = round_down(ei->addr + ei->size, PAGE_SIZE); 
+		if (start >= end)
+			continue;
+		if (end > end_pfn<<PAGE_SHIFT)
+			end_pfn = end>>PAGE_SHIFT;
+	}
+
+	if (end_pfn > MAXMEM >> PAGE_SHIFT)
+		end_pfn = MAXMEM >> PAGE_SHIFT;
+}
+
+/* 
+ * Mark e820 reserved areas as busy for the resource manager.
+ */
+void __init e820_reserve_resources(void)
+{
+	int i;
+	for (i = 0; i < e820.nr_map; i++) {
+		struct resource *res;
+		if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
+			continue;
+		res = alloc_bootmem_low(sizeof(struct resource));
+		switch (e820.map[i].type) {
+		case E820_RAM:	res->name = "System RAM"; break;
+		case E820_ACPI:	res->name = "ACPI Tables"; break;
+		case E820_NVS:	res->name = "ACPI Non-volatile Storage"; break;
+		default:	res->name = "reserved";
+		}
+		res->start = e820.map[i].addr;
+		res->end = res->start + e820.map[i].size - 1;
+		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+		request_resource(&iomem_resource, res);
+		if (e820.map[i].type == E820_RAM) {
+			/*
+			 *  We dont't know which RAM region contains kernel data,
+			 *  so we try it repeatedly and let the resource manager
+			 *  test it.
+			 */
+			request_resource(res, &code_resource);
+			request_resource(res, &data_resource);
+		}
+	}
+}
+
+/* 
+ * Add a memory region to the kernel e820 map.
+ */ 
+void __init add_memory_region(unsigned long start, unsigned long size, int type)
+{
+	int x = e820.nr_map;
+
+	if (x == E820MAX) {
+		printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
+		return;
+	}
+
+	e820.map[x].addr = start;
+	e820.map[x].size = size;
+	e820.map[x].type = type;
+	e820.nr_map++;
+}
+
+void __init e820_print_map(char *who)
+{
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		printk(" %s: %016Lx - %016Lx ", who,
+			(unsigned long long) e820.map[i].addr,
+			(unsigned long long) (e820.map[i].addr + e820.map[i].size));
+		switch (e820.map[i].type) {
+		case E820_RAM:	printk("(usable)\n");
+				break;
+		case E820_RESERVED:
+				printk("(reserved)\n");
+				break;
+		case E820_ACPI:
+				printk("(ACPI data)\n");
+				break;
+		case E820_NVS:
+				printk("(ACPI NVS)\n");
+				break;
+		default:	printk("type %u\n", e820.map[i].type);
+				break;
+		}
+	}
+}
+
+/*
+ * Sanitize the BIOS e820 map.
+ *
+ * Some e820 responses include overlapping entries.  The following 
+ * replaces the original e820 map with a new one, removing overlaps.
+ *
+ */
+static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
+{
+	struct change_member {
+		struct e820entry *pbios; /* pointer to original bios entry */
+		unsigned long long addr; /* address for this change point */
+	};
+	static struct change_member change_point_list[2*E820MAX] __initdata;
+	static struct change_member *change_point[2*E820MAX] __initdata;
+	static struct e820entry *overlap_list[E820MAX] __initdata;
+	static struct e820entry new_bios[E820MAX] __initdata;
+	struct change_member *change_tmp;
+	unsigned long current_type, last_type;
+	unsigned long long last_addr;
+	int chgidx, still_changing;
+	int overlap_entries;
+	int new_bios_entry;
+	int old_nr, new_nr;
+	int i;
+
+	/*
+		Visually we're performing the following (1,2,3,4 = memory types)...
+
+		Sample memory map (w/overlaps):
+		   ____22__________________
+		   ______________________4_
+		   ____1111________________
+		   _44_____________________
+		   11111111________________
+		   ____________________33__
+		   ___________44___________
+		   __________33333_________
+		   ______________22________
+		   ___________________2222_
+		   _________111111111______
+		   _____________________11_
+		   _________________4______
+
+		Sanitized equivalent (no overlap):
+		   1_______________________
+		   _44_____________________
+		   ___1____________________
+		   ____22__________________
+		   ______11________________
+		   _________1______________
+		   __________3_____________
+		   ___________44___________
+		   _____________33_________
+		   _______________2________
+		   ________________1_______
+		   _________________4______
+		   ___________________2____
+		   ____________________33__
+		   ______________________4_
+	*/
+
+	/* if there's only one memory region, don't bother */
+	if (*pnr_map < 2)
+		return -1;
+
+	old_nr = *pnr_map;
+
+	/* bail out if we find any unreasonable addresses in bios map */
+	for (i=0; i<old_nr; i++)
+		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
+			return -1;
+
+	/* create pointers for initial change-point information (for sorting) */
+	for (i=0; i < 2*old_nr; i++)
+		change_point[i] = &change_point_list[i];
+
+	/* record all known change-points (starting and ending addresses) */
+	chgidx = 0;
+	for (i=0; i < old_nr; i++)	{
+		change_point[chgidx]->addr = biosmap[i].addr;
+		change_point[chgidx++]->pbios = &biosmap[i];
+		change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
+		change_point[chgidx++]->pbios = &biosmap[i];
+	}
+
+	/* sort change-point list by memory addresses (low -> high) */
+	still_changing = 1;
+	while (still_changing)	{
+		still_changing = 0;
+		for (i=1; i < 2*old_nr; i++)  {
+			/* if <current_addr> > <last_addr>, swap */
+			/* or, if current=<start_addr> & last=<end_addr>, swap */
+			if ((change_point[i]->addr < change_point[i-1]->addr) ||
+				((change_point[i]->addr == change_point[i-1]->addr) &&
+				 (change_point[i]->addr == change_point[i]->pbios->addr) &&
+				 (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
+			   )
+			{
+				change_tmp = change_point[i];
+				change_point[i] = change_point[i-1];
+				change_point[i-1] = change_tmp;
+				still_changing=1;
+			}
+		}
+	}
+
+	/* create a new bios memory map, removing overlaps */
+	overlap_entries=0;	 /* number of entries in the overlap table */
+	new_bios_entry=0;	 /* index for creating new bios map entries */
+	last_type = 0;		 /* start with undefined memory type */
+	last_addr = 0;		 /* start with 0 as last starting address */
+	/* loop through change-points, determining affect on the new bios map */
+	for (chgidx=0; chgidx < 2*old_nr; chgidx++)
+	{
+		/* keep track of all overlapping bios entries */
+		if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
+		{
+			/* add map entry to overlap list (> 1 entry implies an overlap) */
+			overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
+		}
+		else
+		{
+			/* remove entry from list (order independent, so swap with last) */
+			for (i=0; i<overlap_entries; i++)
+			{
+				if (overlap_list[i] == change_point[chgidx]->pbios)
+					overlap_list[i] = overlap_list[overlap_entries-1];
+			}
+			overlap_entries--;
+		}
+		/* if there are overlapping entries, decide which "type" to use */
+		/* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
+		current_type = 0;
+		for (i=0; i<overlap_entries; i++)
+			if (overlap_list[i]->type > current_type)
+				current_type = overlap_list[i]->type;
+		/* continue building up new bios map based on this information */
+		if (current_type != last_type)	{
+			if (last_type != 0)	 {
+				new_bios[new_bios_entry].size =
+					change_point[chgidx]->addr - last_addr;
+				/* move forward only if the new size was non-zero */
+				if (new_bios[new_bios_entry].size != 0)
+					if (++new_bios_entry >= E820MAX)
+						break; 	/* no more space left for new bios entries */
+			}
+			if (current_type != 0)	{
+				new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
+				new_bios[new_bios_entry].type = current_type;
+				last_addr=change_point[chgidx]->addr;
+			}
+			last_type = current_type;
+		}
+	}
+	new_nr = new_bios_entry;   /* retain count for new bios entries */
+
+	/* copy new bios mapping into original location */
+	memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
+	*pnr_map = new_nr;
+
+	return 0;
+}
+
+/*
+ * Copy the BIOS e820 map into a safe place.
+ *
+ * Sanity-check it while we're at it..
+ *
+ * If we're lucky and live on a modern system, the setup code
+ * will have given us a memory map that we can use to properly
+ * set up memory.  If we aren't, we'll fake a memory map.
+ *
+ * We check to see that the memory map contains at least 2 elements
+ * before we'll use it, because the detection code in setup.S may
+ * not be perfect and most every PC known to man has two memory
+ * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
+ * thinkpad 560x, for example, does not cooperate with the memory
+ * detection code.)
+ */
+static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
+{
+	/* Only one memory region (or negative)? Ignore it */
+	if (nr_map < 2)
+		return -1;
+
+	do {
+		unsigned long start = biosmap->addr;
+		unsigned long size = biosmap->size;
+		unsigned long end = start + size;
+		unsigned long type = biosmap->type;
+
+		/* Overflow in 64 bits? Ignore the memory map. */
+		if (start > end)
+			return -1;
+
+		/*
+		 * Some BIOSes claim RAM in the 640k - 1M region.
+		 * Not right. Fix it up.
+		 * 
+		 * This should be removed on Hammer which is supposed to not
+		 * have non e820 covered ISA mappings there, but I had some strange
+		 * problems so it stays for now.  -AK
+		 */
+		if (type == E820_RAM) {
+			if (start < 0x100000ULL && end > 0xA0000ULL) {
+				if (start < 0xA0000ULL)
+					add_memory_region(start, 0xA0000ULL-start, type);
+				if (end <= 0x100000ULL)
+					continue;
+				start = 0x100000ULL;
+				size = end - start;
+			}
+		}
+
+		add_memory_region(start, size, type);
+	} while (biosmap++,--nr_map);
+	return 0;
+}
+
+void __init setup_memory_region(void)
+{
+	char *who = "BIOS-e820";
+
+	/*
+	 * Try to copy the BIOS-supplied E820-map.
+	 *
+	 * Otherwise fake a memory map; one section from 0k->640k,
+	 * the next section from 1mb->appropriate_mem_k
+	 */
+	sanitize_e820_map(E820_MAP, &E820_MAP_NR);
+	if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
+		unsigned long mem_size;
+
+		/* compare results from other methods and take the greater */
+		if (ALT_MEM_K < EXT_MEM_K) {
+			mem_size = EXT_MEM_K;
+			who = "BIOS-88";
+		} else {
+			mem_size = ALT_MEM_K;
+			who = "BIOS-e801";
+		}
+
+		e820.nr_map = 0;
+		add_memory_region(0, LOWMEMSIZE(), E820_RAM);
+		add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
+  	}
+	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
+	e820_print_map(who);
+}
+
+extern char command_line[], saved_command_line[];
+extern int fallback_aper_order;
+extern int iommu_setup(char *opt);
+
+void __init parse_mem_cmdline (char ** cmdline_p)
+{
+	char c = ' ', *to = command_line, *from = COMMAND_LINE;
+	int len = 0;
+	int usermem = 0;
+
+	/* Save unparsed command line copy for /proc/cmdline */
+	memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
+	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+
+	for (;;) {
+		if (c != ' ') 
+			goto next;
+
+		/*
+		 * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
+		 * to <mem>, overriding the bios size.
+		 * "mem=XXX[KkmM]@XXX[KkmM]" defines a memory region from
+		 * <start> to <start>+<mem>, overriding the bios size.
+		 */
+		if (!memcmp(from, "mem=", 4)) {
+			if (to != command_line)
+				to--;
+			else if (!memcmp(from+4, "exactmap", 8)) {
+				from += 8+4;
+				e820.nr_map = 0;
+				usermem = 1;
+			} else {
+				/* If the user specifies memory size, we
+				 * blow away any automatically generated
+				 * size
+				 */
+				unsigned long long start_at, mem_size;
+ 
+				if (usermem == 0) {
+					/* first time in: zap the whitelist
+					 * and reinitialize it with the
+					 * standard low-memory region.
+					 */
+					e820.nr_map = 0;
+					usermem = 1;
+					add_memory_region(0, LOWMEMSIZE(), E820_RAM);
+				}
+				mem_size = memparse(from+4, &from);
+				if (*from == '@')
+					start_at = memparse(from+1, &from);
+				else {
+					start_at = HIGH_MEMORY;
+					mem_size -= HIGH_MEMORY;
+					usermem=0;
+				}
+				add_memory_region(start_at, mem_size, E820_RAM);
+			}
+		}
+#ifdef CONFIG_GART_IOMMU 
+		else if (!memcmp(from,"iommu=",6)) { 
+			iommu_setup(from+6); 
+		} 	
+		
+#endif
+	next:
+		c = *(from++);
+		if (!c)
+			break;
+		if (COMMAND_LINE_SIZE <= ++len)
+			break;
+		*(to++) = c;
+	}
+	*to = '\0';
+	*cmdline_p = command_line;
+	if (usermem) {
+		printk(KERN_INFO "user-defined physical RAM map:\n");
+		e820_print_map("user");
+	}
+}
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/entry.S linux-2.4.20-pre8/arch/x86_64/kernel/entry.S
--- linux-2.4.20-pre7/arch/x86_64/kernel/entry.S	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/entry.S	Wed Sep 25 18:21:32 2002
@@ -5,7 +5,7 @@
  *  Copyright (C) 2000, 2001, 2002  Andi Kleen SuSE Labs
  *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>
  * 
- *  $Id: entry.S,v 1.79 2002/07/01 07:55:17 ak Exp $		
+ *  $Id: entry.S,v 1.81 2002/09/12 12:55:25 ak Exp $		
  */
 
 /*
@@ -333,7 +333,18 @@
 	swapgs
 retint_restore_args:				
 	RESTORE_ARGS 0,8						
+iret_label:	
 	iretq
+	.section __ex_table,"a"
+	.align 8
+	.quad iret_label,bad_iret
+	.previous
+	.section .fixup,"ax"
+	/* force a signal here? this matches i386 behaviour */
+bad_iret:
+	movq $-9999,%rdi	/* better code? */
+	jmp do_exit			
+	.previous	
 
 retint_signal:	
 	sti
@@ -417,8 +428,8 @@
 error_restore_swapgs:					
 	swapgs
 error_restore:	
-	RESTORE_ALL 8
-	iretq
+	RESTORE_REST
+	jmp retint_restore_args
 	
 error_reschedule:
 	sti
@@ -441,6 +452,10 @@
 	
 error_kernelspace:	
 	xorl %r15d,%r15d
+	cmpq $iret_label,RIP(%rsp)
+	jne  error_action
+	movl $1,%r15d
+	swapgs
 	jmp error_action
 
 /*
@@ -564,7 +579,9 @@
 	pushq $-1
 	SAVE_ALL
 	/* NMI could happen inside the critical section of a swapgs,
-	   so it is needed to use this expensive way to check. */
+	   so it is needed to use this expensive way to check.
+	   Rely on arch_prctl forbiding user space from setting a negative
+	   GS. Only the kernel value is negative. */
 	movl  $MSR_GS_BASE,%ecx
 	rdmsr
 	xorl  %ebx,%ebx
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/io_apic.c linux-2.4.20-pre8/arch/x86_64/kernel/io_apic.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/io_apic.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/io_apic.c	Wed Sep 25 18:21:32 2002
@@ -775,7 +775,8 @@
 		(reg_01.entries != 0x1f) && /* dual Xeon boards */
 		(reg_01.entries != 0x22) && /* bigger Xeon boards */
 		(reg_01.entries != 0x2E) &&
-		(reg_01.entries != 0x3F)
+		(reg_01.entries != 0x3F) &&
+		(reg_01.entries != 0x03)    /* Golem */
 	)
 		UNEXPECTED_IO_APIC();
 
@@ -784,7 +785,7 @@
 	if (	(reg_01.version != 0x01) && /* 82489DX IO-APICs */
 		(reg_01.version != 0x02) && /* 82801BA IO-APICs (ICH2) */
 		(reg_01.version != 0x10) && /* oldest IO-APICs */
-		(reg_01.version != 0x11) && /* Pentium/Pro IO-APICs */
+		(reg_01.version != 0x11) && /* Pentium/Pro IO-APICs / GOLEM */
 		(reg_01.version != 0x13) && /* Xeon IO-APICs */
 		(reg_01.version != 0x20)    /* Intel P64H (82806 AA) */
 	)
@@ -1405,10 +1406,12 @@
 	end_lapic_irq
 };
 
-static void enable_NMI_through_LVT0 (void * dummy)
+void enable_NMI_through_LVT0 (void * dummy)
 {
 	unsigned int v, ver;
 
+	printk("enable NMI through LVT0 on cpu %d\n", smp_processor_id());
+
 	ver = apic_read(APIC_LVR);
 	ver = GET_APIC_VERSION(ver);
 	v = APIC_DM_NMI;			/* unmask and set to NMI */
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/irq.c linux-2.4.20-pre8/arch/x86_64/kernel/irq.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/irq.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/irq.c	Wed Sep 25 18:21:32 2002
@@ -45,7 +45,29 @@
 #include <asm/irq.h>
 #include <asm/proto.h>
 
-
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+/* 
+ * Probalistic stack overflow check: 
+ * 
+ * Only check the stack in process context, because everything else
+ * runs on the big interrupt stacks. Checking reliably is too expensive,
+ * so we just check from interrupts. 
+ */ 
+static inline void stack_overflow_check(struct pt_regs *regs)
+{ 
+	u64 curbase = (u64) current;
+	static unsigned long warned = -60*HZ; 
+
+	if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE &&
+	    regs->rsp <  curbase + sizeof(struct task_struct) + 128 && 
+	    warned + 60*HZ >= jiffies) { 
+		printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n",
+		       current->comm, curbase, regs->rsp); 
+		show_stack(NULL);
+		warned = jiffies;
+	}
+}
+#endif
 
 /*
  * Linux has a controller-independent x86 interrupt architecture.
@@ -196,7 +218,8 @@
 extern void show_stack(unsigned long* esp);
 
 
-/* XXX: this unfortunately doesn't support irqstacks currently, should check the other PDAs */
+/* XXX: this unfortunately doesn't support irqs/exception stacks currently, 
+   should check the other PDAs */
 static void show(char * str)
 {
 	int i;
@@ -581,13 +604,17 @@
 	struct irqaction * action;
 	unsigned int status;
 
+
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	stack_overflow_check(regs); 
+#endif
+	       
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
 	desc->handler->ack(irq);
 	/*
 	   REPLAY is when Linux resends an IRQ that was dropped earlier
-	   WAITING is used by probe to mark irqs that are being tested
-	   */
+	   WAITING is used by probe to mark irqs that are being tested */
 	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
 	status |= IRQ_PENDING; /* we _want_ to handle it */
 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/mpparse.c linux-2.4.20-pre8/arch/x86_64/kernel/mpparse.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/mpparse.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/mpparse.c	Wed Sep 25 18:21:32 2002
@@ -26,6 +26,8 @@
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
 #include <asm/pgalloc.h>
+#include <asm/e820.h>
+#include <asm/proto.h>
 
 /* Have we found an MP table */
 int smp_found_config = 0;
@@ -133,7 +135,9 @@
 	str[6] = 0;
 	Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
 
-	if (strncmp(str, "ISA", 3) == 0) {
+	if (m->mpc_busid >= MAX_MP_BUSSES) {
+		printk(KERN_ERR "MAX_MP_BUSSES ERROR mpc_busid %d, max %d\n", m->mpc_busid, MAX_MP_BUSSES);
+	} else if (strncmp(str, "ISA", 3) == 0) {
 		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
 	} else if (strncmp(str, "EISA", 4) == 0) {
 		mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
@@ -489,12 +493,11 @@
 		construct_default_ISA_mptable(mpf->mpf_feature1);
 
 	} else if (mpf->mpf_physptr) {
-
 		/*
 		 * Read the physical hardware table.  Anything here will
 		 * override the defaults.
 		 */
-		if (!smp_read_mpc((void *)(unsigned long)mpf->mpf_physptr)) {
+		if (!smp_read_mpc(__va(mpf->mpf_physptr))) {
 			smp_found_config = 0;
 			printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
 			printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
@@ -532,7 +535,7 @@
 	unsigned int *bp = phys_to_virt(base);
 	struct intel_mp_floating *mpf;
 
-	Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
+	printk("Scan SMP from %p for %ld bytes.\n", bp,length);
 	if (sizeof(*mpf) != 16)
 		printk("Error: MPF size\n");
 
@@ -545,11 +548,11 @@
 				|| (mpf->mpf_specification == 4)) ) {
 
 			smp_found_config = 1;
-			printk("found SMP MP-table at %08lx\n",
+			printk(KERN_INFO "found SMP MP-table at %016lx\n",
 						virt_to_phys(mpf));
-			reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
+			reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE); 
 			if (mpf->mpf_physptr)
-				reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE);
+				reserve_bootmem_generic(mpf->mpf_physptr, PAGE_SIZE); 
 			mpf_found = mpf;
 			return 1;
 		}
@@ -561,7 +564,7 @@
 
 void __init find_intel_smp (void)
 {
-	unsigned int address;
+	unsigned long address;
 
 	/*
 	 * FIXME: Linux assumes you have 640K of base ram..
@@ -575,6 +578,8 @@
 		smp_scan_config(639*0x400,0x400) ||
 			smp_scan_config(0xF0000,0x10000))
 		return;
+		printk("ok\n");
+		
 	/*
 	 * If it is an SMP machine we should know now, unless the
 	 * configuration is in an EISA/MCA bus machine with an
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/mtrr.c linux-2.4.20-pre8/arch/x86_64/kernel/mtrr.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/mtrr.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/mtrr.c	Wed Sep 25 18:21:32 2002
@@ -70,6 +70,10 @@
 
 #define MTRR_VERSION "2.02 (20020716)"
 
+#undef Dprintk
+
+#define Dprintk(...) 
+
 #define TRUE  1
 #define FALSE 0
 
@@ -312,30 +316,30 @@
 	int i;
 	u32 lo, hi;
 
-	printk (KERN_INFO "mtrr: rdmsr 64K_00000\n");
+	Dprintk (KERN_INFO "mtrr: rdmsr 64K_00000\n");
 	rdmsr (MSR_MTRRfix64K_00000, lo, hi);
 	if (p[0] != lo || p[1] != hi) {
-		printk (KERN_INFO "mtrr: Writing %x:%x to 64K MSR. lohi were %x:%x\n", p[0], p[1], lo, hi);
+		Dprintk (KERN_INFO "mtrr: Writing %x:%x to 64K MSR. lohi were %x:%x\n", p[0], p[1], lo, hi);
 		wrmsr (MSR_MTRRfix64K_00000, p[0], p[1]);
 		changed = TRUE;
 	}
 
-	printk (KERN_INFO "mtrr: rdmsr 16K_80000\n");
+	Dprintk (KERN_INFO "mtrr: rdmsr 16K_80000\n");
 	for (i = 0; i < 2; i++) {
 		rdmsr (MSR_MTRRfix16K_80000 + i, lo, hi);
 		if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) {
-			printk (KERN_INFO "mtrr: Writing %x:%x to 16K MSR%d. lohi were %x:%x\n", p[2 + i * 2], p[3 + i * 2], i, lo, hi );
+			Dprintk (KERN_INFO "mtrr: Writing %x:%x to 16K MSR%d. lohi were %x:%x\n", p[2 + i * 2], p[3 + i * 2], i, lo, hi );
 			wrmsr (MSR_MTRRfix16K_80000 + i, p[2 + i * 2], p[3 + i * 2]);
 			changed = TRUE;
 		}
 	}
 
-	printk (KERN_INFO "mtrr: rdmsr 4K_C0000\n");
+	Dprintk (KERN_INFO "mtrr: rdmsr 4K_C0000\n");
 	for (i = 0; i < 8; i++) {
 		rdmsr (MSR_MTRRfix4K_C0000 + i, lo, hi);
-		printk (KERN_INFO "mtrr: MTRRfix4K_C0000+%d = %x:%x\n", i, lo, hi);
+		Dprintk (KERN_INFO "mtrr: MTRRfix4K_C0000+%d = %x:%x\n", i, lo, hi);
 		if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) {
-			printk (KERN_INFO "mtrr: Writing %x:%x to 4K MSR%d. lohi were %x:%x\n", p[6 + i * 2], p[7 + i * 2], i, lo, hi);
+			Dprintk (KERN_INFO "mtrr: Writing %x:%x to 4K MSR%d. lohi were %x:%x\n", p[6 + i * 2], p[7 + i * 2], i, lo, hi);
 			wrmsr (MSR_MTRRfix4K_C0000 + i, p[6 + i * 2], p[7 + i * 2]);
 			changed = TRUE;
 		}
@@ -501,12 +505,12 @@
 	if (!mask)
 		return;
 	if (mask & MTRR_CHANGE_MASK_FIXED)
-		printk ("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
+		printk (KERN_INFO "mtrr: your CPUs had inconsistent fixed MTRR settings\n");
 	if (mask & MTRR_CHANGE_MASK_VARIABLE)
-		printk ("mtrr: your CPUs had inconsistent variable MTRR settings\n");
+		printk (KERN_INFO "mtrr: your CPUs had inconsistent variable MTRR settings\n");
 	if (mask & MTRR_CHANGE_MASK_DEFTYPE)
-		printk ("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
-	printk ("mtrr: probably your BIOS does not setup all CPUs\n");
+		printk (KERN_INFO "mtrr: your CPUs had inconsistent MTRRdefType settings\n");
+	printk (KERN_INFO "mtrr: probably your BIOS does not setup all CPUs\n");
 }
 
 #endif	/*  CONFIG_SMP  */
@@ -609,15 +613,15 @@
 		return -EINVAL;
 	}
 
-#if defined(__x86_64__) && defined(CONFIG_AGP) 
-/*	{
+#if 0 && defined(__x86_64__) && defined(CONFIG_AGP) 
+	{
 	agp_kern_info info; 
 	if (type != MTRR_TYPE_UNCACHABLE && agp_copy_info(&info) >= 0 && 
 	    base<<PAGE_SHIFT >= info.aper_base && 
             (base<<PAGE_SHIFT)+(size<<PAGE_SHIFT) >= 
 			info.aper_base+info.aper_size*1024*1024)
 		printk(KERN_INFO "%s[%d] setting conflicting mtrr into agp aperture\n",current->comm,current->pid); 
-	}*/
+	}
 #endif
 
 	/*  Check upper bits of base and last are equal and lower bits are 0
@@ -646,7 +650,7 @@
 	}
 
 	if (base & (size_or_mask>>PAGE_SHIFT)) {
-		printk (KERN_WARNING "mtrr: base(%lx) exceeds the MTRR width(%lx)\n",
+		printk (KERN_WARNING "mtrr: base(%Lx) exceeds the MTRR width(%Lx)\n",
 				base, (size_or_mask>>PAGE_SHIFT));
 		return -EINVAL;
 	}
@@ -868,8 +872,8 @@
 	if (!page) {
 		if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
 			printk
-			    ("mtrr: size and base must be multiples of 4 kiB\n");
-			printk ("mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
+			    (KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");
+			printk (KERN_INFO "mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
 			return -EINVAL;
 		}
 		base >>= PAGE_SHIFT;
@@ -893,8 +897,8 @@
 	if (!page) {
 		if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
 			printk
-			    ("mtrr: size and base must be multiples of 4 kiB\n");
-			printk ("mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
+			    (KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");
+			printk (KERN_INFO "mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
 			return -EINVAL;
 		}
 		base >>= PAGE_SHIFT;
@@ -969,7 +973,7 @@
 	}
 
 	if (strncmp (line, "base=", 5)) {
-		printk ("mtrr: no \"base=\" in line: \"%s\"\n", line);
+		printk (KERN_INFO "mtrr: no \"base=\" in line: \"%s\"\n", line);
 		return -EINVAL;
 	}
 
@@ -978,22 +982,22 @@
 	for (; isspace (*ptr); ++ptr) ;
 
 	if (strncmp (ptr, "size=", 5)) {
-		printk ("mtrr: no \"size=\" in line: \"%s\"\n", line);
+		printk (KERN_INFO "mtrr: no \"size=\" in line: \"%s\"\n", line);
 		return -EINVAL;
 	}
 
 	size = simple_strtoull (ptr + 5, &ptr, 0);
 
 	if ((base & 0xfff) || (size & 0xfff)) {
-		printk ("mtrr: size and base must be multiples of 4 kiB\n");
-		printk ("mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
+		printk (KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");
+		printk (KERN_INFO "mtrr: size: 0x%x  base: 0x%Lx\n", size, base);
 		return -EINVAL;
 	}
 
 	for (; isspace (*ptr); ++ptr) ;
 
 	if (strncmp (ptr, "type=", 5)) {
-		printk ("mtrr: no \"type=\" in line: \"%s\"\n", line);
+		printk (KERN_INFO "mtrr: no \"type=\" in line: \"%s\"\n", line);
 		return -EINVAL;
 	}
 	ptr += 5;
@@ -1010,7 +1014,7 @@
 			return err;
 		return len;
 	}
-	printk ("mtrr: illegal type: \"%s\"\n", ptr);
+	printk (KERN_INFO "mtrr: illegal type: \"%s\"\n", ptr);
 	return -EINVAL;
 }
 
@@ -1243,7 +1247,6 @@
 			 */
 			size_and_mask = (~size_or_mask) & 0x000ffffffffff000L;
 		}
-		printk ("mtrr: detected mtrr type: x86-64\n");
 	}
 }
 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/pci-dma.c linux-2.4.20-pre8/arch/x86_64/kernel/pci-dma.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/pci-dma.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/pci-dma.c	Wed Sep 25 18:21:32 2002
@@ -8,6 +8,8 @@
 #include <linux/pci.h>
 #include <asm/io.h>
 
+dma_addr_t bad_dma_address = -1UL; 
+
 /* Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scather-gather version of the
  * above pci_map_single interface.  Here the scatter gather list
@@ -37,14 +39,22 @@
 		struct scatterlist *s = &sg[i];
  		if (s->address) {
 			BUG_ON(s->page || s->offset); 
- 			s->dma_address = pci_map_single(hwdev, s->address, s->length, 0); 
+ 			s->dma_address = pci_map_single(hwdev, s->address, s->length, 
+							direction); 
  		} else if (s->page) { 
 			s->dma_address = pci_map_page(hwdev, s->page, s->offset,
-											s->length,0); 
+						      s->length, direction); 
 		} else
 			BUG(); 
+
+		if (unlikely(s->dma_address == bad_dma_address))
+			goto error; 
  	}
 	return nents;
+
+ error: 
+	pci_unmap_sg(hwdev, sg, i, direction); 
+	return 0; 
 }
 
 /* Unmap a set of streaming mode DMA translations.
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/pci-gart.c linux-2.4.20-pre8/arch/x86_64/kernel/pci-gart.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/pci-gart.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/pci-gart.c	Wed Sep 25 18:21:32 2002
@@ -8,7 +8,7 @@
  * See Documentation/DMA-mapping.txt for the interface specification.
  * 
  * Copyright 2002 Andi Kleen, SuSE Labs.
- * $Id: pci-gart.c,v 1.8 2002/07/16 15:30:04 ak Exp $
+ * $Id: pci-gart.c,v 1.12 2002/09/19 19:25:32 ak Exp $
  */
 
 /* 
@@ -24,6 +24,7 @@
  could use exact fit in the gart in alloc_consistent, not order of two.
 */ 
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/ctype.h>
 #include <linux/agp_backend.h>
@@ -37,28 +38,26 @@
 #include <asm/mtrr.h>
 #include <asm/bitops.h>
 #include <asm/pgtable.h>
+#include <asm/proto.h>
 #include "pci-x86_64.h"
 
-extern unsigned long start_pfn, end_pfn; 
-
 unsigned long iommu_bus_base;	/* GART remapping area (physical) */
 static unsigned long iommu_size; 	/* size of remapping area bytes */
 static unsigned long iommu_pages;	/* .. and in pages */
 
 u32 *iommu_gatt_base; 		/* Remapping table */
 
-static int no_iommu; 
+int no_iommu; 
 static int no_agp; 
-static int force_mmu = 1;
+int force_mmu = 1;
+
+extern int fallback_aper_order;
+extern int fallback_aper_force;
 
 /* Allocation bitmap for the remapping area */ 
 static spinlock_t iommu_bitmap_lock = SPIN_LOCK_UNLOCKED;
 static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */
 
-/* y must be power of two */
-#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
-#define round_down(x,y) ((x) & ~((y)-1))
-
 #define GPTE_MASK 0xfffffff000
 #define GPTE_VALID    1
 #define GPTE_COHERENT 2
@@ -72,13 +71,16 @@
 
 #define EMERGENCY_PAGES 32 /* = 128KB */ 
 
-/* backdoor interface to AGP driver */
-extern void amd_x86_64_tlbflush(void *); 
+#ifdef CONFIG_AGP
 extern int agp_init(void);
-extern u64 amd_x86_64_configure (struct pci_dev *hammer, u64);
+#define AGPEXTERN extern
+#else
+#define AGPEXTERN
+#endif
 
-extern int agp_memory_reserved;
-extern __u32 *agp_gatt_table;
+/* backdoor interface to AGP driver */
+AGPEXTERN int agp_memory_reserved;
+AGPEXTERN __u32 *agp_gatt_table;
 
 static unsigned long next_bit;  /* protected by iommu_bitmap_lock */
 
@@ -112,7 +114,14 @@
 
 static inline void flush_gart(void) 
 { 
-	amd_x86_64_tlbflush(NULL); 	
+	struct pci_dev *nb; 
+	for_all_nb(nb) { 
+		u32 flag; 
+		pci_read_config_dword(nb, 0x9c, &flag); /* could cache this */ 
+		/* could complain for PTE walk errors here (bit 1 of flag) */ 
+		flag |= 1; 
+		pci_write_config_dword(nb, 0x9c, flag); 
+	} 
 } 
 
 void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
@@ -202,6 +211,26 @@
 	free_iommu(iommu_page, 1<<order);
 }
 
+#ifdef CONFIG_IOMMU_LEAK
+/* Debugging aid for drivers that don't free their IOMMU tables */
+static void **iommu_leak_tab; 
+static int leak_trace;
+int iommu_leak_dumppages = 20; 
+void dump_leak(void)
+{
+	int i;
+	static int dump; 
+	if (dump || !iommu_leak_tab) return;
+	dump = 1;
+	show_stack(NULL);
+	printk("Dumping %d pages from end of IOMMU:\n", iommu_leak_dumppages); 
+	for (i = 0; i < iommu_leak_dumppages; i++) 
+		printk("[%lu: %lx] ",
+		       iommu_pages-i,(unsigned long) iommu_leak_tab[iommu_pages-i]); 
+	printk("\n");
+}
+#endif
+
 static void iommu_full(struct pci_dev *dev, void *addr, size_t size, int dir)
 {
 	/* 
@@ -220,10 +249,14 @@
 
 	if (size > PAGE_SIZE*EMERGENCY_PAGES) {
 		if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
-			printk(KERN_ERR "PCI-DMA: Memory will be corrupted\n");
+			panic("PCI-DMA: Memory will be corrupted\n");
 		if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL) 
-			printk(KERN_ERR "PCI-DMA: Random memory will be DMAed\n"); 
+			panic("PCI-DMA: Random memory will be DMAed\n"); 
 	} 
+
+#ifdef CONFIG_IOMMU_LEAK
+	dump_leak(); 
+#endif
 } 
 
 static inline int need_iommu(struct pci_dev *dev, unsigned long addr, size_t size)
@@ -270,6 +303,12 @@
 		 * the caches on mapping.
 		 */
 		iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem, GPTE_COHERENT);
+
+#ifdef CONFIG_IOMMU_LEAK
+		/* XXX need eventually caller of pci_map_sg */
+		if (iommu_leak_tab) 
+			iommu_leak_tab[iommu_page + i] = __builtin_return_address(0); 
+#endif
 	}
 	flush_gart(); 
 
@@ -292,6 +331,10 @@
 	npages = round_up(size, PAGE_SIZE) >> PAGE_SHIFT;
 	for (i = 0; i < npages; i++) { 
 		iommu_gatt_base[iommu_page + i] = 0; 
+#ifdef CONFIG_IOMMU_LEAK
+		if (iommu_leak_tab)
+			iommu_leak_tab[iommu_page + i] = 0; 
+#endif
 	}
 	flush_gart(); 
 	free_iommu(iommu_page, npages);
@@ -300,9 +343,7 @@
 EXPORT_SYMBOL(pci_map_single);
 EXPORT_SYMBOL(pci_unmap_single);
 
-static inline unsigned long check_iommu_size(unsigned long aper,
-					     unsigned long aper_size, 
-					     unsigned long iommu_size)
+static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
 { 
 	unsigned long a; 
 	if (!iommu_size) { 
@@ -314,42 +355,64 @@
 	a = aper + iommu_size; 
 	iommu_size -= round_up(a, LARGE_PAGE_SIZE) - a;
 
-	if (iommu_size < 128*1024*1024) 
+	if (iommu_size < 64*1024*1024) 
 		printk(KERN_WARNING
   "PCI-DMA: Warning: Small IOMMU %luMB. Consider increasing the AGP aperture in BIOS\n",iommu_size>>20); 
 	
 	return iommu_size;
 } 
 
+static __init unsigned read_aperture(struct pci_dev *dev, u32 *size) 
+{ 
+	unsigned aper_size = 0, aper_base_32;
+	u64 aper_base;
+	unsigned aper_order;
+
+	pci_read_config_dword(dev, 0x94, &aper_base_32); 
+	pci_read_config_dword(dev, 0x90, &aper_order);
+	aper_order = (aper_order >> 1) & 7;	
+
+	aper_base = aper_base_32 & 0x7fff; 
+	aper_base <<= 25;
+
+	aper_size = (32 * 1024 * 1024) << aper_order; 
+	if (aper_base + aper_size >= 0xffffffff || !aper_size)
+		aper_base = 0;
+
+	*size = aper_size;
+	return aper_base;
+} 
+
 /* 
- * Private Northbridge GATT initialization in case we cannot use the AGP driver for 
- * some reason. 
+ * Private Northbridge GATT initialization in case we cannot use the
+ * AGP driver for some reason.  
  */
 static __init int init_k8_gatt(agp_kern_info *info)
 { 
 	struct pci_dev *dev;
 	void *gatt;
-	u32 aper_size;
-	u32 gatt_size;
+	unsigned aper_base, new_aper_base;
+	unsigned aper_size, gatt_size, new_aper_size;
 
-#if 1 /* BIOS bug workaround for now */
+	aper_size = aper_base = info->aper_size = 0;
+	for_all_nb(dev) { 
+		new_aper_base = read_aperture(dev, &new_aper_size); 
+		if (!new_aper_base) 
 	goto nommu; 
-#endif
 
-	aper_size = 0;
-	for_all_nb(dev) { 
-		pci_read_config_dword(dev, 0x90, &aper_size);
-		aper_size = 32 << ((aper_size>>1) & 7);
-		break;
+		if (!aper_base) { 
+			aper_size = new_aper_size;
+			aper_base = new_aper_base;
 	}
-
-	info->aper_size = aper_size; 
-	if (!aper_size) { 
-		printk("PCI-DMA: Cannot fetch aperture size\n"); 
+		if (aper_size != new_aper_size || aper_base != new_aper_base) 
 		goto nommu;
 	} 
+	if (!aper_base)
+		goto nommu; 
+	info->aper_base = aper_base;
+	info->aper_size = aper_size>>20; 
 
-	gatt_size = ((aper_size * 1024 * 1024) / PAGE_SIZE) * sizeof(u32); 
+	gatt_size = (aper_size >> PAGE_SHIFT) * sizeof(u32); 
 	gatt = (void *)__get_free_pages(GFP_KERNEL, get_order(gatt_size)); 
 	if (!gatt) 
 		panic("Cannot allocate GATT table"); 
@@ -358,16 +421,29 @@
 	agp_gatt_table = gatt;
 
 	for_all_nb(dev) { 
-		info->aper_base = amd_x86_64_configure(dev, virt_to_bus(gatt));
+		u32 ctl; 
+		u32 gatt_reg; 
+
+		gatt_reg = ((u64)gatt) >> 12; 
+		gatt_reg <<= 4; 
+		pci_write_config_dword(dev, 0x98, gatt_reg);
+		pci_read_config_dword(dev, 0x90, &ctl); 
+
+		ctl |= 1;
+		ctl &= ~((1<<4) | (1<<5));
+
+		pci_write_config_dword(dev, 0x90, ctl); 
 	}
-	if (info->aper_base)
+	flush_gart(); 
+	
+		
+	printk("PCI-DMA: aperture base @ %x size %u KB\n", aper_base, aper_size>>10); 
 		return 0;
-	printk("Cannot find an K8\n"); 
 
  nommu:
-	if (end_pfn >= 0xffffffff>>PAGE_SHIFT)
+	/* XXX: reject 0xffffffff mask now in pci mapping functions */
 		printk(KERN_ERR "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
-		       KERN_ERR "32bit PCI IO may malfunction."); 
+	       KERN_ERR "PCI-DMA: 32bit PCI IO may malfunction."); 
 	return -1; 
 } 
 
@@ -377,10 +453,25 @@
 	unsigned long aper_size;
 	unsigned long iommu_start;
 
-	if (no_agp || (agp_init() < 0) || (agp_copy_info(&info) < 0)) { 
+#ifndef CONFIG_AGP
+	no_agp = 1; 
+#else
+	no_agp = no_agp || (agp_init() < 0) || (agp_copy_info(&info) < 0); 
+#endif	
+
+	if (no_iommu || (!force_mmu && end_pfn < 0xffffffff>>PAGE_SHIFT)) { 
+		printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); 
+		no_iommu = 1;
+		return;
+	}
+
+	if (no_agp) { 
+		int err = -1;
 		printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
 		no_agp = 1;
-		if (init_k8_gatt(&info) < 0) { 
+		if (force_mmu || end_pfn >= 0xffffffff>>PAGE_SHIFT)
+			err = init_k8_gatt(&info);
+		if (err < 0) { 
 			printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); 
 			no_iommu = 1;
 			return; 
@@ -388,7 +479,7 @@
 	} 
 	
 	aper_size = info.aper_size * 1024 * 1024;
-	iommu_size = check_iommu_size(info.aper_base, aper_size, iommu_size); 
+	iommu_size = check_iommu_size(info.aper_base, aper_size); 
 	iommu_pages = iommu_size >> PAGE_SHIFT; 
 
 	iommu_gart_bitmap = (void*)__get_free_pages(GFP_KERNEL, 
@@ -397,6 +488,17 @@
 		panic("Cannot allocate iommu bitmap\n"); 
 	memset(iommu_gart_bitmap, 0, iommu_pages/8);
 
+#ifdef CONFIG_IOMMU_LEAK
+	if (leak_trace) { 
+		iommu_leak_tab = (void *)__get_free_pages(GFP_KERNEL, 
+				  get_order(iommu_pages*sizeof(void *)));
+		if (iommu_leak_tab) 
+			memset(iommu_leak_tab, 0, iommu_pages * 8); 
+		else
+			printk("PCI-DMA: Cannot allocate leak trace area\n"); 
+	} 
+#endif
+
 	/* 
 	 * Out of IOMMU space handling.
 	 * Reserve some invalid pages at the beginning of the GART. 
@@ -410,31 +512,49 @@
 	iommu_start = aper_size - iommu_size;	
 	iommu_bus_base = info.aper_base + iommu_start; 
 	iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
+	bad_dma_address = iommu_bus_base;
 
 	asm volatile("wbinvd" ::: "memory");
 } 
 
-/* iommu=[size][,noagp][,off][,force][,noforce] 
+/* iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]]
+   size  set size of iommu (in bytes) 
    noagp don't initialize the AGP driver and use full aperture.
    off   don't use the IOMMU
+   leak  turn on simple iommu leak tracing (only when CONFIG_IOMMU_LEAK is on)
+   memaper[=order] allocate an own aperture over RAM with size 32MB^order.
 */
-static __init int iommu_setup(char *opt) 
+__init int iommu_setup(char *opt) 
 { 
     int arg;
-    char *p;
-    while ((p = strsep(&opt, ",")) != NULL) { 
-	    if (strcmp(p,"noagp"))
+    char *p = opt;
+    
+    for (;;) { 
+	    if (!memcmp(p,"noagp", 5))
 		    no_agp = 1; 
-	    if (strcmp(p,"off"))
+	    if (!memcmp(p,"off", 3))
 		    no_iommu = 1;
-	    if (strcmp(p,"force"))
+	    if (!memcmp(p,"force", 5))
 		    force_mmu = 1;
-	    if (strcmp(p,"noforce"))
+	    if (!memcmp(p,"noforce", 7))
 		    force_mmu = 0;
+	    if (!memcmp(p, "memaper", 7)) { 
+		    fallback_aper_force = 1; 
+		    p += 7; 
+		    if (*p == '=' && get_option(&p, &arg))
+			    fallback_aper_order = arg;
+	    } 
+#ifdef CONFIG_IOMMU_LEAK
+	    if (!memcmp(p,"leak", 4))
+		    leak_trace = 1;
+#endif
 	    if (isdigit(*p) && get_option(&p, &arg)) 
 		    iommu_size = arg;
+	    do {
+		    if (*p == ' ' || *p == 0) 
+			    return 0; 
+	    } while (*p++ != ','); 
     }	
     return 1;
 } 
 
-__setup("iommu=", iommu_setup); 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/pci-pc.c linux-2.4.20-pre8/arch/x86_64/kernel/pci-pc.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/pci-pc.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/pci-pc.c	Wed Sep 25 18:21:32 2002
@@ -334,10 +334,13 @@
 
 	/* Handle ACPI here */
 	if (!smp_found_config) { 
-		printk(KERN_WARNING "PCI: Warning: no mptable. Scanning busses upto 0xfe\n"); 
-		pcibios_last_bus = 0xfe; 
+		printk(KERN_WARNING "PCI: Warning: no mptable. Scanning busses upto 0xff\n"); 
+		pcibios_last_bus = 0xff; 
 		return;
 	} 
+
+	pcibios_last_bus = 0xff;
+
 	for (i = 0; i < MAX_MP_BUSSES; i++) {
 		int n = mp_bus_id_to_pci_bus[i]; 
 		if (n < 0 || n >= 0xff)
@@ -460,11 +463,11 @@
 	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
-int pcibios_enable_device(struct pci_dev *dev)
+int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	int err;
 
-	if ((err = pcibios_enable_resources(dev)) < 0)
+	if ((err = pcibios_enable_resources(dev, mask)) < 0)
 		return err;
 	pcibios_enable_irq(dev);
 	return 0;
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/pci-x86_64.c linux-2.4.20-pre8/arch/x86_64/kernel/pci-x86_64.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/pci-x86_64.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/pci-x86_64.c	Wed Sep 25 18:21:32 2002
@@ -136,7 +136,8 @@
  * which might have be mirrored at 0x0100-0x03ff..
  */
 void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+		       unsigned long align)
 {
 	if (res->flags & IORESOURCE_IO) {
 		unsigned long start = res->start;
@@ -303,7 +304,7 @@
 	pcibios_assign_resources();
 }
 
-int pcibios_enable_resources(struct pci_dev *dev)
+int pcibios_enable_resources(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
 	int idx;
@@ -312,6 +313,8 @@
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
 	for(idx=0; idx<6; idx++) {
+		if (!(mask & (1<<idx)))
+			continue;
 		r = &dev->resource[idx];
 		if (!r->start && r->end) {
 			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/pci-x86_64.h linux-2.4.20-pre8/arch/x86_64/kernel/pci-x86_64.h
--- linux-2.4.20-pre7/arch/x86_64/kernel/pci-x86_64.h	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/pci-x86_64.h	Wed Sep 25 18:21:32 2002
@@ -29,7 +29,7 @@
 extern unsigned int pcibios_max_latency;
 
 void pcibios_resource_survey(void);
-int pcibios_enable_resources(struct pci_dev *);
+int pcibios_enable_resources(struct pci_dev *, int);
 
 /* pci-pc.c */
 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/process.c linux-2.4.20-pre8/arch/x86_64/kernel/process.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/process.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/process.c	Wed Sep 25 18:21:32 2002
@@ -9,7 +9,7 @@
  *  X86-64 port
  *	Andi Kleen.
  * 
- *  $Id: process.c,v 1.56 2002/08/03 17:42:35 ak Exp $
+ *  $Id: process.c,v 1.57 2002/09/12 12:56:36 ak Exp $
  */
 
 /*
@@ -285,7 +285,7 @@
 	printk("\n");
 	printk("Pid: %d, comm: %.20s %s\n", current->pid, current->comm, print_tainted());
 	printk("RIP: %04lx:[<%016lx>]\n", regs->cs & 0xffff, regs->rip);
-	printk("RSP: %016lx  EFLAGS: %08lx\n", regs->rsp, regs->eflags);
+	printk("RSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp, regs->eflags);
 	printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
 	       regs->rax, regs->rbx, regs->rcx);
 	printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
@@ -500,7 +500,6 @@
 				 *next = &next_p->thread;
 	struct tss_struct *tss = init_tss + smp_processor_id();
 
-
 	unlazy_fpu(prev_p);
 
 	/*
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/setup.c linux-2.4.20-pre8/arch/x86_64/kernel/setup.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/setup.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/setup.c	Wed Sep 25 18:21:32 2002
@@ -78,8 +78,8 @@
 
 static int disable_x86_fxsr __initdata = 0;
 
-static char command_line[COMMAND_LINE_SIZE];
-       char saved_command_line[COMMAND_LINE_SIZE];
+char command_line[COMMAND_LINE_SIZE];
+char saved_command_line[COMMAND_LINE_SIZE];
 
 struct resource standard_io_resources[] = {
 	{ "dma1", 0x00, 0x1f, IORESOURCE_BUSY },
@@ -94,9 +94,10 @@
 
 #define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
 
-static struct resource code_resource = { "Kernel code", 0x100000, 0 };
-static struct resource data_resource = { "Kernel data", 0, 0 };
-static struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY };
+struct resource code_resource = { "Kernel code", 0x100000, 0 };
+struct resource data_resource = { "Kernel data", 0, 0 };
+struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY };
+
 
 /* System ROM resources */
 #define MAXROMS 6
@@ -170,379 +171,27 @@
 	}
 }
 
-void __init add_memory_region(unsigned long long start,
-                                  unsigned long long size, int type)
-{
-	int x = e820.nr_map;
-
-	if (x == E820MAX) {
-	    printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
-	    return;
-	}
-
-	e820.map[x].addr = start;
-	e820.map[x].size = size;
-	e820.map[x].type = type;
-	e820.nr_map++;
-} /* add_memory_region */
-
-#define E820_DEBUG	1
-
-static void __init print_memory_map(char *who)
-{
-	int i;
-
-	for (i = 0; i < e820.nr_map; i++) {
-		printk(" %s: %016Lx - %016Lx ", who,
-			(unsigned long long) e820.map[i].addr,
-			(unsigned long long) (e820.map[i].addr + e820.map[i].size));
-		switch (e820.map[i].type) {
-		case E820_RAM:	printk("(usable)\n");
-				break;
-		case E820_RESERVED:
-				printk("(reserved)\n");
-				break;
-		case E820_ACPI:
-				printk("(ACPI data)\n");
-				break;
-		case E820_NVS:
-				printk("(ACPI NVS)\n");
-				break;
-		default:	printk("type %u\n", e820.map[i].type);
-				break;
-		}
-	}
-}
-
-/*
- * Sanitize the BIOS e820 map.
- *
- * Some e820 responses include overlapping entries.  The following 
- * replaces the original e820 map with a new one, removing overlaps.
- *
- */
-static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
-{
-	struct change_member {
-		struct e820entry *pbios; /* pointer to original bios entry */
-		unsigned long long addr; /* address for this change point */
-	};
-	struct change_member change_point_list[2*E820MAX];
-	struct change_member *change_point[2*E820MAX];
-	struct e820entry *overlap_list[E820MAX];
-	struct e820entry new_bios[E820MAX];
-	struct change_member *change_tmp;
-	unsigned long current_type, last_type;
-	unsigned long long last_addr;
-	int chgidx, still_changing;
-	int overlap_entries;
-	int new_bios_entry;
-	int old_nr, new_nr;
-	int i;
-
-	/*
-		Visually we're performing the following (1,2,3,4 = memory types)...
-
-		Sample memory map (w/overlaps):
-		   ____22__________________
-		   ______________________4_
-		   ____1111________________
-		   _44_____________________
-		   11111111________________
-		   ____________________33__
-		   ___________44___________
-		   __________33333_________
-		   ______________22________
-		   ___________________2222_
-		   _________111111111______
-		   _____________________11_
-		   _________________4______
-
-		Sanitized equivalent (no overlap):
-		   1_______________________
-		   _44_____________________
-		   ___1____________________
-		   ____22__________________
-		   ______11________________
-		   _________1______________
-		   __________3_____________
-		   ___________44___________
-		   _____________33_________
-		   _______________2________
-		   ________________1_______
-		   _________________4______
-		   ___________________2____
-		   ____________________33__
-		   ______________________4_
-	*/
-
-	/* if there's only one memory region, don't bother */
-	if (*pnr_map < 2)
-		return -1;
-
-	old_nr = *pnr_map;
-
-	/* bail out if we find any unreasonable addresses in bios map */
-	for (i=0; i<old_nr; i++)
-		if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
-			return -1;
-
-	/* create pointers for initial change-point information (for sorting) */
-	for (i=0; i < 2*old_nr; i++)
-		change_point[i] = &change_point_list[i];
-
-	/* record all known change-points (starting and ending addresses) */
-	chgidx = 0;
-	for (i=0; i < old_nr; i++)	{
-		change_point[chgidx]->addr = biosmap[i].addr;
-		change_point[chgidx++]->pbios = &biosmap[i];
-		change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
-		change_point[chgidx++]->pbios = &biosmap[i];
-	}
-
-	/* sort change-point list by memory addresses (low -> high) */
-	still_changing = 1;
-	while (still_changing)	{
-		still_changing = 0;
-		for (i=1; i < 2*old_nr; i++)  {
-			/* if <current_addr> > <last_addr>, swap */
-			/* or, if current=<start_addr> & last=<end_addr>, swap */
-			if ((change_point[i]->addr < change_point[i-1]->addr) ||
-				((change_point[i]->addr == change_point[i-1]->addr) &&
-				 (change_point[i]->addr == change_point[i]->pbios->addr) &&
-				 (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
-			   )
-			{
-				change_tmp = change_point[i];
-				change_point[i] = change_point[i-1];
-				change_point[i-1] = change_tmp;
-				still_changing=1;
-			}
-		}
-	}
-
-	/* create a new bios memory map, removing overlaps */
-	overlap_entries=0;	 /* number of entries in the overlap table */
-	new_bios_entry=0;	 /* index for creating new bios map entries */
-	last_type = 0;		 /* start with undefined memory type */
-	last_addr = 0;		 /* start with 0 as last starting address */
-	/* loop through change-points, determining affect on the new bios map */
-	for (chgidx=0; chgidx < 2*old_nr; chgidx++)
-	{
-		/* keep track of all overlapping bios entries */
-		if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
-		{
-			/* add map entry to overlap list (> 1 entry implies an overlap) */
-			overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
-		}
-		else
-		{
-			/* remove entry from list (order independent, so swap with last) */
-			for (i=0; i<overlap_entries; i++)
-			{
-				if (overlap_list[i] == change_point[chgidx]->pbios)
-					overlap_list[i] = overlap_list[overlap_entries-1];
-			}
-			overlap_entries--;
-		}
-		/* if there are overlapping entries, decide which "type" to use */
-		/* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
-		current_type = 0;
-		for (i=0; i<overlap_entries; i++)
-			if (overlap_list[i]->type > current_type)
-				current_type = overlap_list[i]->type;
-		/* continue building up new bios map based on this information */
-		if (current_type != last_type)	{
-			if (last_type != 0)	 {
-				new_bios[new_bios_entry].size =
-					change_point[chgidx]->addr - last_addr;
-				/* move forward only if the new size was non-zero */
-				if (new_bios[new_bios_entry].size != 0)
-					if (++new_bios_entry >= E820MAX)
-						break; 	/* no more space left for new bios entries */
-			}
-			if (current_type != 0)	{
-				new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
-				new_bios[new_bios_entry].type = current_type;
-				last_addr=change_point[chgidx]->addr;
-			}
-			last_type = current_type;
-		}
-	}
-	new_nr = new_bios_entry;   /* retain count for new bios entries */
-
-	/* copy new bios mapping into original location */
-	memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
-	*pnr_map = new_nr;
-
-	return 0;
-}
-
-/*
- * Copy the BIOS e820 map into a safe place.
- *
- * Sanity-check it while we're at it..
- *
- * If we're lucky and live on a modern system, the setup code
- * will have given us a memory map that we can use to properly
- * set up memory.  If we aren't, we'll fake a memory map.
- *
- * We check to see that the memory map contains at least 2 elements
- * before we'll use it, because the detection code in setup.S may
- * not be perfect and most every PC known to man has two memory
- * regions: one from 0 to 640k, and one from 1mb up.  (The IBM
- * thinkpad 560x, for example, does not cooperate with the memory
- * detection code.)
- */
-static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
-{
-	/* Only one memory region (or negative)? Ignore it */
-	if (nr_map < 2)
-		return -1;
-
-	do {
-		unsigned long long start = biosmap->addr;
-		unsigned long long size = biosmap->size;
-		unsigned long long end = start + size;
-		unsigned long type = biosmap->type;
-
-		/* Overflow in 64 bits? Ignore the memory map. */
-		if (start > end)
-			return -1;
-
-		/*
-		 * Some BIOSes claim RAM in the 640k - 1M region.
-		 * Not right. Fix it up.
-		 */
-		if (type == E820_RAM) {
-			if (start < 0x100000ULL && end > 0xA0000ULL) {
-				if (start < 0xA0000ULL)
-					add_memory_region(start, 0xA0000ULL-start, type);
-				if (end <= 0x100000ULL)
-					continue;
-				start = 0x100000ULL;
-				size = end - start;
-			}
-		}
-		add_memory_region(start, size, type);
-	} while (biosmap++,--nr_map);
-	return 0;
-}
-
-/*
- * Do NOT EVER look at the BIOS memory size location.
- * It does not work on many machines.
- */
-#define LOWMEMSIZE()	(0x9f000)
-
-void __init setup_memory_region(void)
-{
-	char *who = "BIOS-e820";
-
-	/*
-	 * Try to copy the BIOS-supplied E820-map.
-	 *
-	 * Otherwise fake a memory map; one section from 0k->640k,
-	 * the next section from 1mb->appropriate_mem_k
-	 */
-	sanitize_e820_map(E820_MAP, &E820_MAP_NR);
-	if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) {
-		unsigned long mem_size;
-
-		/* compare results from other methods and take the greater */
-		if (ALT_MEM_K < EXT_MEM_K) {
-			mem_size = EXT_MEM_K;
-			who = "BIOS-88";
-		} else {
-			mem_size = ALT_MEM_K;
-			who = "BIOS-e801";
-		}
-
-		e820.nr_map = 0;
-		add_memory_region(0, LOWMEMSIZE(), E820_RAM);
-		add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
-  	}
-	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
-	print_memory_map(who);
-} /* setup_memory_region */
-
+unsigned long start_pfn, end_pfn; 
+extern unsigned long table_start, table_end;
 
-static inline void parse_mem_cmdline (char ** cmdline_p)
+#ifndef CONFIG_DISCONTIGMEM
+static void __init contig_initmem_init(void)
 {
-	char c = ' ', *to = command_line, *from = COMMAND_LINE;
-	int len = 0;
-	int usermem = 0;
-
-	/* Save unparsed command line copy for /proc/cmdline */
-	memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
-	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
-
-	for (;;) {
-		/*
-		 * "mem=nopentium" disables the 4MB page tables.
-		 * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
-		 * to <mem>, overriding the bios size.
-		 * "mem=XXX[KkmM]@XXX[KkmM]" defines a memory region from
-		 * <start> to <start>+<mem>, overriding the bios size.
-		 */
-		if (c == ' ' && !memcmp(from, "mem=", 4)) {
-			if (to != command_line)
-				to--;
-			if (!memcmp(from+4, "nopentium", 9)) {
-				from += 9+4;
-				clear_bit(X86_FEATURE_PSE, &boot_cpu_data.x86_capability);
-			} else if (!memcmp(from+4, "exactmap", 8)) {
-				from += 8+4;
-				e820.nr_map = 0;
-				usermem = 1;
-			} else {
-				/* If the user specifies memory size, we
-				 * blow away any automatically generated
-				 * size
-				 */
-				unsigned long long start_at, mem_size;
- 
-				if (usermem == 0) {
-					/* first time in: zap the whitelist
-					 * and reinitialize it with the
-					 * standard low-memory region.
-					 */
-					e820.nr_map = 0;
-					usermem = 1;
-					add_memory_region(0, LOWMEMSIZE(), E820_RAM);
-				}
-				mem_size = memparse(from+4, &from);
-				if (*from == '@')
-					start_at = memparse(from+1, &from);
-				else {
-					start_at = HIGH_MEMORY;
-					mem_size -= HIGH_MEMORY;
-					usermem=0;
-				}
-				add_memory_region(start_at, mem_size, E820_RAM);
-			}
-		}
-		c = *(from++);
-		if (!c)
-			break;
-		if (COMMAND_LINE_SIZE <= ++len)
-			break;
-		*(to++) = c;
-	}
-	*to = '\0';
-	*cmdline_p = command_line;
-	if (usermem) {
-		printk(KERN_INFO "user-defined physical RAM map:\n");
-		print_memory_map("user");
-	}
+	unsigned long bootmap_size, bootmap; 
+	bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
+	bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
+	if (bootmap == -1L) 
+		panic("Cannot find bootmem map of size %ld\n",bootmap_size);
+	bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
+	e820_bootmem_free(&contig_page_data, 0, end_pfn << PAGE_SHIFT); 
+	reserve_bootmem(bootmap, bootmap_size);
 }
-
-unsigned long start_pfn, end_pfn; 
+#endif
 
 void __init setup_arch(char **cmdline_p)
 {
-	unsigned long bootmap_size, low_mem_size;
 	int i;
+	unsigned long kernel_end; 
 
  	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
  	drive_info = DRIVE_INFO;
@@ -570,96 +219,44 @@
 
 	parse_mem_cmdline(cmdline_p);
 
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
-
-#define MAXMEM		(120UL * 1024 * 1024 * 1024 * 1024)  /* 120TB */ 
-#define MAXMEM_PFN	PFN_DOWN(MAXMEM)
-#define MAX_NONPAE_PFN	(1 << 20)
+	e820_end_of_ram();
 
-	/*
-	 * partially used pages are not usable - thus
-	 * we are rounding upwards:
-	 */
-	start_pfn = PFN_UP(__pa_symbol(&_end));
+	init_memory_mapping(); 
 
-	/*
-	 * Find the highest page frame number we have available
-	 */
-	end_pfn = 0;
-	for (i = 0; i < e820.nr_map; i++) {
-		unsigned long start, end;
-		/* RAM? */
-		if (e820.map[i].type != E820_RAM)
-			continue;
-		start = PFN_UP(e820.map[i].addr);
-		end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
-		if (start >= end)
-			continue;
-		if (end > end_pfn)
-			end_pfn = end;
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (LOADER_TYPE && INITRD_START) {
+		if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) {
+			initrd_start =
+				INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
+			initrd_end = initrd_start+INITRD_SIZE;
 	}
-
-	if (end_pfn > MAXMEM_PFN) {
-		end_pfn = MAXMEM_PFN;
+		else {
+			printk(KERN_ERR "initrd extends beyond end of memory "
+			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+			    (unsigned long)INITRD_START + INITRD_SIZE,
+			    (unsigned long)(end_pfn << PAGE_SHIFT));
+			initrd_start = 0;
 	}
+	}
+#endif
 
-	init_memory_mapping(); 
-
-	/*
-	 * Initialize the boot-time allocator (with low memory only):
-	 */
-	bootmap_size = init_bootmem(start_pfn, end_pfn);
+#ifdef CONFIG_DISCONTIGMEM
+	numa_initmem_init(0, end_pfn); 	
+#else
+	contig_initmem_init(); 
+#endif	
+
+	/* Reserve direct mapping */
+	reserve_bootmem_generic(table_start << PAGE_SHIFT, 
+				(table_end - table_start) << PAGE_SHIFT);
 
-	/*
-	 * Register fully available low RAM pages with the bootmem allocator.
-	 */
-	for (i = 0; i < e820.nr_map; i++) {
-		unsigned long curr_pfn, last_pfn, size;
- 		/*
-		 * Reserve usable low memory
-		 */
-		if (e820.map[i].type != E820_RAM)
-			continue;
-		/*
-		 * We are rounding up the start address of usable memory:
-		 */
-		curr_pfn = PFN_UP(e820.map[i].addr);
-		if (curr_pfn >= end_pfn)
-			continue;
-		/*
-		 * ... and at the end of the usable range downwards:
-		 */
-		last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
-
-		if (last_pfn > end_pfn)
-			last_pfn = end_pfn;
-
-		/*
-		 * .. finally, did all the rounding and playing
-		 * around just make the area go away?
-		 */
-		if (last_pfn <= curr_pfn)
-			continue;
-
-		size = last_pfn - curr_pfn;
-		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
-	}
-	/*
-	 * Reserve the bootmem bitmap itself as well. We do this in two
-	 * steps (first step was init_bootmem()) because this catches
-	 * the (very unlikely) case of us accidentally initializing the
-	 * bootmem allocator with an invalid RAM area.
-	 */
-	reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
-			 bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start) 
+		reserve_bootmem_generic(INITRD_START, INITRD_SIZE);
+#endif
 
-	/*
-	 * reserve physical page 0 - it's a special BIOS page on many boxes,
-	 * enabling clean reboots, SMP operation, laptop functions.
-	 */
-	reserve_bootmem(0, PAGE_SIZE);
+	/* Reserve BIOS data page. Some things still need it */
+	reserve_bootmem_generic(0, PAGE_SIZE);
 
 #ifdef CONFIG_SMP
 	/*
@@ -667,8 +264,14 @@
 	 * FIXME: Don't need the extra page at 4K, but need to fix
 	 * trampoline before removing it. (see the GDT stuff)
 	 */
-	reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
+	reserve_bootmem_generic(PAGE_SIZE, PAGE_SIZE); 
+
+	/* Reserve SMP trampoline */
+	reserve_bootmem_generic(0x6000, PAGE_SIZE);
 #endif
+	/* Reserve Kernel */
+	kernel_end = round_up(__pa_symbol(&_end), PAGE_SIZE);
+	reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY);
 
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
@@ -676,32 +279,12 @@
 	 */
 	find_smp_config();
 #endif
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (LOADER_TYPE && INITRD_START) {
-		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
-			reserve_bootmem(INITRD_START, INITRD_SIZE);
-			initrd_start =
-				INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
-			initrd_end = initrd_start+INITRD_SIZE;
-		}
-		else {
-			printk(KERN_ERR "initrd extends beyond end of memory "
-			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-			    (unsigned long)INITRD_START + INITRD_SIZE,
-			    (unsigned long)(max_low_pfn << PAGE_SHIFT));
-			initrd_start = 0;
-		}
-	}
-#endif
-
-	/*
-	 * NOTE: before this point _nobody_ is allowed to allocate
-	 * any memory using the bootmem allocator.
-	 */
 
 #ifdef CONFIG_SMP
-	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
+	/* AP processor realmode stacks in low memory*/
+	smp_alloc_memory();
 #endif
+
 	paging_init();
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
@@ -717,42 +300,22 @@
 	 * and also for regions reported as reserved by the e820.
 	 */
 	probe_roms();
-	for (i = 0; i < e820.nr_map; i++) {
-		struct resource *res;
-		if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
-			continue;
-		res = alloc_bootmem_low(sizeof(struct resource));
-		switch (e820.map[i].type) {
-		case E820_RAM:	res->name = "System RAM"; break;
-		case E820_ACPI:	res->name = "ACPI Tables"; break;
-		case E820_NVS:	res->name = "ACPI Non-volatile Storage"; break;
-		default:	res->name = "reserved";
-		}
-		res->start = e820.map[i].addr;
-		res->end = res->start + e820.map[i].size - 1;
-		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-		request_resource(&iomem_resource, res);
-		if (e820.map[i].type == E820_RAM) {
-			/*
-			 *  We dont't know which RAM region contains kernel data,
-			 *  so we try it repeatedly and let the resource manager
-			 *  test it.
-			 */
-			request_resource(res, &code_resource);
-			request_resource(res, &data_resource);
-		}
-	}
+	e820_reserve_resources(); 
 	request_resource(&iomem_resource, &vram_resource);
 
 	/* request I/O space for devices used on all i[345]86 PCs */
 	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
 		request_resource(&ioport_resource, standard_io_resources+i);
 
+	/* We put PCI memory up to make sure VALID_PAGE with DISCONTIGMEM
+	   never returns true for it */ 
+
 	/* Tell the PCI layer not to allocate too close to the RAM area.. */
-	/* ??? move this up on x86-64 */
-	low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
-	if (low_mem_size > pci_mem_start)
-		pci_mem_start = low_mem_size;
+	pci_mem_start = IOMAP_START;
+
+#ifdef CONFIG_GART_IOMMU
+	iommu_hole_init();
+#endif
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
@@ -762,7 +325,7 @@
 #endif
 #endif
 
-	num_mappedpages = max_low_pfn; 
+	num_mappedpages = end_pfn;
 }
 
 #ifndef CONFIG_X86_TSC
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/setup64.c linux-2.4.20-pre8/arch/x86_64/kernel/setup64.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/setup64.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/setup64.c	Wed Sep 25 18:21:32 2002
@@ -3,7 +3,7 @@
  * Copyright (C) 1995  Linus Torvalds
  * Copyright 2001, 2002 SuSE Labs / Andi Kleen.
  * See setup.c for older changelog.
- * $Id: setup64.c,v 1.14 2002/07/18 09:49:42 ak Exp $
+ * $Id: setup64.c,v 1.15 2002/09/05 15:25:43 ak Exp $
  */ 
 #include <linux/config.h>
 #include <linux/init.h>
@@ -152,6 +152,9 @@
 		} 
 	}
 
+	t->io_map_base = INVALID_IO_BITMAP_OFFSET;	
+	memset(t->io_bitmap, 0xff, sizeof(t->io_bitmap));
+
 	/* Flags to clear on syscall */
 	wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE); 
 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/smpboot.c linux-2.4.20-pre8/arch/x86_64/kernel/smpboot.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/smpboot.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/smpboot.c	Wed Sep 25 18:21:32 2002
@@ -51,12 +51,11 @@
 #include <asm/timex.h>
 #include <asm/proto.h>
 
-/* Set if we find a B stepping CPU			*/
-static int smp_b_stepping;
-
 /* Setup configured maximum number of CPUs to activate */
 static int max_cpus = -1;
 
+static int cpu_mask = -1; 
+
 /* Total count of live CPUs */
 int smp_num_cpus = 1;
 
@@ -104,6 +103,15 @@
 
 __setup("maxcpus=", maxcpus);
 
+
+static int __init cpumask(char *str)
+{
+	get_option(&str, &cpu_mask);
+	return 1;
+}
+
+__setup("cpumask=", cpumask); 
+
 /*
  * Trampoline 80x86 program as an array.
  */
@@ -132,13 +140,7 @@
  */
 void __init smp_alloc_memory(void)
 {
-	trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE);
-	/*
-	 * Has to be in very low memory so we can execute
-	 * real-mode AP code.
-	 */
-	if (__pa(trampoline_base) >= 0x9F000)
-		BUG();
+	trampoline_base = __va(0x6000); /* reserved in setup.c */
 }
 
 /*
@@ -152,17 +154,6 @@
 
 	*c = boot_cpu_data;
 	identify_cpu(c);
-	/*
-	 * Mask B, Pentium, but not Pentium MMX
-	 */
-	if (c->x86_vendor == X86_VENDOR_INTEL &&
-	    c->x86 == 5 &&
-	    c->x86_mask >= 1 && c->x86_mask <= 4 &&
-	    c->x86_model <= 3)
-		/*
-		 * Remember we have B step Pentia with bugs
-		 */
-		smp_b_stepping = 1;
 }
 
 /*
@@ -387,6 +378,12 @@
 	Dprintk("CALLIN, before setup_local_APIC().\n");
 	setup_local_APIC();
 
+	if (nmi_watchdog == NMI_IO_APIC) {
+		disable_8259A_irq(0);
+		enable_NMI_through_LVT0(NULL);
+		enable_8259A_irq(0);
+	}
+
 	sti();
 
 #ifdef CONFIG_MTRR
@@ -519,17 +516,15 @@
 }
 #endif
 
-static void __init do_boot_cpu (int apicid)
+static int __init do_boot_cpu (int apicid)
 {
 	struct task_struct *idle;
 	unsigned long send_status, accept_status, boot_status, maxlvt;
 	int timeout, num_starts, j, cpu;
 	unsigned long start_eip;
 
- 
-	printk("do_boot_cpu cpucount = %d\n", cpucount); 
-
 	cpu = ++cpucount;
+
 	/*
 	 * We can't use kernel_thread since we must avoid to
 	 * reschedule the child.
@@ -549,6 +544,7 @@
 	x86_cpu_to_apicid[cpu] = apicid;
 	x86_apicid_to_cpu[apicid] = cpu;
 	idle->cpus_runnable = 1<<cpu; 
+	idle->cpus_allowed = 1<<cpu;
 	idle->thread.rip = (unsigned long)start_secondary;
 	idle->thread.rsp = (unsigned long)idle + THREAD_SIZE - 8;
 
@@ -560,8 +556,8 @@
 	start_eip = setup_trampoline();
 
 	/* So we see what's up   */
-	printk("Booting processor %d/%d rip %lx\n", cpu, apicid, start_eip);
-	init_rsp = (void *) (THREAD_SIZE + (char *)idle - 8);
+	printk("Booting processor %d/%d rip %lx page %p\n", cpu, apicid, start_eip, idle);
+	init_rsp = (void *) (THREAD_SIZE + (char *)idle - 16);
 	initial_code = initialize_secondary; 
 
 	/*
@@ -673,13 +669,18 @@
 		 */
 
 		/* Target chip */
+		Dprintk("target apic %x\n", SET_APIC_DEST_FIELD(apicid));
 		apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid));
 
+		Dprintk("after target chip\n"); 
+
 		/* Boot on the stack */
 		/* Kick the second */
 		apic_write_around(APIC_ICR, APIC_DM_STARTUP
 					| (start_eip >> 12));
 
+		Dprintk("after eip write\n"); 
+
 		/*
 		 * Give the other CPU some time to accept the IPI.
 		 */
@@ -761,12 +762,14 @@
 	}
 
 	/* mark "stuck" area as not stuck */
-	*((volatile unsigned long *)phys_to_virt(8192)) = 0;
+	*((volatile unsigned int *)phys_to_virt(8192)) = 0;
+	
+	return cpu; 
 }
 
 cycles_t cacheflush_time;
 
-static void smp_tune_scheduling (void)
+static __init void smp_tune_scheduling (void)
 {
 	unsigned long cachesize;       /* kB   */
 	unsigned long bandwidth = 350; /* MB/s */
@@ -813,7 +816,7 @@
 
 void __init smp_boot_cpus(void)
 {
-	int apicid, cpu;
+	int apicid, cpu, maxcpu;
 
 #ifdef CONFIG_MTRR
 	/*  Must be done before other processors booted  */
@@ -882,9 +885,7 @@
 		printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
 			boot_cpu_id);
 		printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
-#ifndef CONFIG_VISWS
 		io_apic_irqs = 0;
-#endif
 		cpu_online_map = phys_cpu_present_map = 1;
 		smp_num_cpus = 1;
 		goto smp_done;
@@ -898,9 +899,7 @@
 	if (!max_cpus) {
 		smp_found_config = 0;
 		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
-#ifndef CONFIG_VISWS
 		io_apic_irqs = 0;
-#endif
 		cpu_online_map = phys_cpu_present_map = 1;
 		smp_num_cpus = 1;
 		goto smp_done;
@@ -917,6 +916,7 @@
 	 */
 	Dprintk("CPU present map: %lx\n", phys_cpu_present_map);
 
+	maxcpu = 0;
 	for (apicid = 0; apicid < NR_CPUS; apicid++) {
 		/*
 		 * Don't even attempt to start the boot CPU!
@@ -926,10 +926,12 @@
 
 		if (!(phys_cpu_present_map & (1 << apicid)))
 			continue;
+		if (((1<<apicid) & cpu_mask) == 0) 
+			continue;
 		if ((max_cpus >= 0) && (max_cpus <= cpucount+1))
 			continue;
 
-		do_boot_cpu(apicid);
+		cpu = do_boot_cpu(apicid);
 
 		/*
 		 * Make sure we unmap all failed CPUs
@@ -937,12 +939,13 @@
 		if ((x86_apicid_to_cpu[apicid] == -1) &&
 				(phys_cpu_present_map & (1 << apicid)))
 			printk("phys CPU #%d not responding - cannot use it.\n",apicid);
+		else if (cpu > maxcpu) 
+			maxcpu = cpu; 
 	}
 
 	/*
 	 * Cleanup possible dangling ends...
 	 */
-#ifndef CONFIG_VISWS
 	{
 		/*
 		 * Install writable page 0 entry to set BIOS data area.
@@ -955,9 +958,8 @@
 		 */
 		CMOS_WRITE(0, 0xf);
 
-		*((volatile long *) phys_to_virt(0x467)) = 0;
+		*((volatile int *) phys_to_virt(0x467)) = 0;
 	}
-#endif
 
 	/*
 	 * Allow the user to impress friends.
@@ -965,7 +967,7 @@
 
 	Dprintk("Before bogomips.\n");
 	if (!cpucount) {
-		printk(KERN_ERR "Error: only one processor found.\n");
+		printk(KERN_ERR "Only one processor found.\n");
 	} else {
 		unsigned long bogosum = 0;
 		for (cpu = 0; cpu < NR_CPUS; cpu++)
@@ -977,20 +979,16 @@
 			(bogosum/(5000/HZ))%100);
 		Dprintk("Before bogocount - setting activated=1.\n");
 	}
-	smp_num_cpus = cpucount + 1;
+	smp_num_cpus = maxcpu + 1;
 
-	if (smp_b_stepping)
-		printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
 	Dprintk("Boot done.\n");
 
-#ifndef CONFIG_VISWS
 	/*
 	 * Here we can be sure that there is an IO-APIC in the system. Let's
 	 * go and set it up:
 	 */
 	if (!skip_ioapic_setup && nr_ioapics)
 		setup_IO_APIC();
-#endif
 
 	/*
 	 * Set up all local APIC timers in the system:
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/sys_x86_64.c linux-2.4.20-pre8/arch/x86_64/kernel/sys_x86_64.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/sys_x86_64.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/sys_x86_64.c	Wed Sep 25 18:21:32 2002
@@ -101,7 +101,7 @@
 	err=copy_to_user(name, &system_utsname, sizeof (*name));
 	up_read(&uts_sem);
 	if (personality(current->personality) == PER_LINUX32)
-		err = copy_to_user(name->machine, "i386", 5);
+		err = copy_to_user(name->machine, "i686", 5);
 	return err?-EFAULT:0;
 }
 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/time.c linux-2.4.20-pre8/arch/x86_64/kernel/time.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/time.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/time.c	Wed Sep 25 18:21:32 2002
@@ -12,6 +12,8 @@
  *
  */
 
+#define HPET_BIOS_SUPPORT_WORKING
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
@@ -47,9 +49,14 @@
  * together by xtime_lock.
  */
 
+static spinlock_t time_offset_lock = SPIN_LOCK_UNLOCKED;
+static unsigned long timeoffset = 0;
+
 inline unsigned int do_gettimeoffset(void)
 {
-	return hpet.address ? (((hpet_readl(HPET_COUNTER) - hpet.trigger) * hpet.quotient) >> 32) : 0;
+	unsigned long t;
+	rdtscll(t);	
+	return (t  - hpet.last_tsc) * (1000000L / HZ) / hpet.ticks + hpet.offset;
 }
 
 /*
@@ -60,15 +67,20 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned long flags;
-	unsigned int usec, sec;
+	unsigned long flags, t;
+ 	unsigned int sec, usec;
 
 	read_lock_irqsave(&xtime_lock, flags);
+	spin_lock(&time_offset_lock);
 
 	sec = xtime.tv_sec;
-	usec = xtime.tv_usec + do_gettimeoffset() +
-		(jiffies - wall_jiffies) * tick;
+	usec = xtime.tv_usec;
+
+	t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset();
+	if (t > timeoffset) timeoffset = t;
+	usec += timeoffset;
 
+	spin_unlock(&time_offset_lock);
 	read_unlock_irqrestore(&xtime_lock, flags);
 
 	tv->tv_sec = sec + usec / 1000000;
@@ -154,8 +166,8 @@
 	if (abs(real_minutes - cmos_minutes) < 30) {
 		BIN_TO_BCD(real_seconds);
 		BIN_TO_BCD(real_minutes);
-		CMOS_WRITE(real_seconds,RTC_SECONDS);
-		CMOS_WRITE(real_minutes,RTC_MINUTES);
+		CMOS_WRITE(real_seconds, RTC_SECONDS);
+		CMOS_WRITE(real_minutes, RTC_MINUTES);
 	} else
 		printk(KERN_WARNING "time.c: can't update CMOS clock from %d to %d\n",
 			cmos_minutes, real_minutes);
@@ -188,23 +200,16 @@
 	write_lock(&xtime_lock);
 	vxtime_lock();
 
-/*
- * register, that'd get us the current time - but we want to know the exact
- * moment the interrupt was triggered by the hardware. HPET_T0_CMP always
- * contains the value when the next tick will happen - by subtracting the tick
- * size, we know the exact time when this interrupt was triggered.
- */
-
-	if (hpet.address) {
-		int t = hpet_readl(HPET_T0_CMP) - hpet_tick;
-
-		if (t - hpet.trigger > hpet_tick) {
-			if (hpet_report_lost_ticks)
-				printk(KERN_WARNING "time.c: Lost timer tick(s)! (rip %016lx)\n", regs->rip);
-			jiffies += (t - hpet.trigger) / hpet_tick - 1;
-		}
+	{
+		unsigned long t;
 
-		hpet.trigger = t;
+		rdtscll(t);
+		hpet.offset = (t  - hpet.last_tsc) * (1000000L / HZ) / hpet.ticks + hpet.offset - 1000000L / HZ;
+		if (hpet.offset >= 1000000L / HZ)
+			hpet.offset = 0;
+		hpet.ticks = min_t(long, max_t(long, (t  - hpet.last_tsc) * (1000000L / HZ) / (1000000L / HZ - hpet.offset),
+				cpu_khz * 1000/HZ * 15 / 16), cpu_khz * 1000/HZ * 16 / 15); 
+		hpet.last_tsc = t;
 	}
 
 /*
@@ -374,7 +379,6 @@
 		return -1;
 
 	hpet_tick = (1000000000L * tick + hpet_period / 2) / hpet_period;
-	hpet.quotient = (hpet_period << 32) / 1000000000L;
 
 /*
  * Stop the timers and reset the main counter.
@@ -424,41 +428,9 @@
 
 void __init time_init(void)
 {
-
-	config_acpi_tables();
-
-#ifndef HPET_BIOS_SUPPORT_WORKING
-/*
- * Enable HPET in PCI config space of the LPC bridge - cannot use PCI
- * functions, because PCI isn't initialized yet, do it manually.
- */
-
-	if (!hpet.address) {
-		outl(0x800038a0, 0xcf8);
-		outl(0xff000001, 0xcfc);
-		outl(0x800038a0, 0xcf8);
-		hpet.address = inl(0xcfc) & 0xfffffffe;
-		printk(KERN_INFO "time.c: Enabled HPET base manually at %#lx.\n", hpet.address);
-	}
-
-#endif
-
-#ifndef CONFIG_HPET_TIMER
-	hpet.address = 0;
-#endif
-
 	xtime.tv_sec = get_cmos_time();
 	xtime.tv_usec = 0;
 
-	if (!hpet_init()) {
-		setup_irq(0, &irq0);
-		hpet.hz = (1000000000000000L + hpet_period / 2) / hpet_period;
-		printk(KERN_INFO "time.c: Using %ld.%06ld MHz HPET timer.\n",
-			hpet.hz / 1000000, hpet.hz % 1000000);
-		cpu_khz = hpet_calibrate_tsc();
-		printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
-			cpu_khz / 1000, cpu_khz % 1000);
-	} else {
 		printk(KERN_WARNING "time.c: HPET timer not found, precise timing unavailable.\n");
 		pit_init();
 		printk(KERN_INFO "time.c: Using 1.1931816 MHz PIT timer.\n");
@@ -466,7 +438,8 @@
 		cpu_khz = pit_calibrate_tsc();
 		printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
 			cpu_khz / 1000, cpu_khz % 1000);
-	}
+	hpet.ticks = cpu_khz * (1000 / HZ);
+	rdtscll(hpet.last_tsc);
 }
 
 __setup("report_lost_ticks", time_setup);
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/traps.c linux-2.4.20-pre8/arch/x86_64/kernel/traps.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/traps.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/traps.c	Wed Sep 25 18:21:32 2002
@@ -7,7 +7,7 @@
  *  Pentium III FXSR, SSE support
  *	Gareth Hughes <gareth@valinux.com>, May 2000
  *
- *  $Id: traps.c,v 1.48 2002/08/03 19:09:41 ak Exp $
+ *  $Id: traps.c,v 1.51 2002/09/12 12:57:46 ak Exp $
  */
 
 /*
@@ -75,7 +75,7 @@
 
 struct notifier_block *die_chain;
 
-int kstack_depth_to_print = 80;
+int kstack_depth_to_print = 40;
 
 #ifdef CONFIG_KALLSYMS
 #include <linux/kallsyms.h> 
@@ -271,6 +271,11 @@
 	show_trace((unsigned long *)rsp);
 }
 
+void dump_stack(void)
+{
+	show_stack(0);
+} 
+
 void show_registers(struct pt_regs *regs)
 {
 	int i;
@@ -386,10 +391,10 @@
 static void do_trap(int trapnr, int signr, char *str, 
 		    struct pt_regs * regs, long error_code, siginfo_t *info)
 {
-#ifdef CONFIG_CHECKING
+#if defined(CONFIG_CHECKING) && defined(CONFIG_LOCAL_APIC)
 	{ 
 		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); 
@@ -547,8 +552,8 @@
 {
 	unsigned char reason = inb(0x61);
 
-
 	++nmi_count(smp_processor_id());
+	
 	if (!(reason & 0xc0)) {
 #if CONFIG_X86_LOCAL_APIC
 		/*
@@ -560,6 +565,8 @@
 			return;
 		}
 #endif
+		if (notify_die(DIE_NMI, "nmi", regs, reason) == NOTIFY_BAD)
+			return;
 		unknown_nmi_error(reason, regs);
 		return;
 	}
@@ -569,6 +576,7 @@
 		mem_parity_error(reason, regs);
 	if (reason & 0x40)
 		io_check_error(reason, regs);
+
 	/*
 	 * Reassert NMI in case it became active meanwhile
 	 * as it's edge-triggered.
@@ -602,6 +610,11 @@
 	if (notify_die(DIE_DEBUG, "debug", regs, error_code) == NOTIFY_BAD)
 		return; 
 
+	/* If the user set TF, it's simplest to clear it right away. */
+	/* AK: dubious check, likely wrong */
+	if ((regs->cs & 3) == 0 && (regs->eflags & TF_MASK))
+		goto clear_TF;
+
 	/* Mask out spurious debug traps due to lazy DR7 setting */
 	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
 		if (!tsk->thread.debugreg[7]) { 
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/vsyscall.c linux-2.4.20-pre8/arch/x86_64/kernel/vsyscall.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/vsyscall.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/vsyscall.c	Wed Sep 25 18:21:32 2002
@@ -44,48 +44,36 @@
 #include <asm/fixmap.h>
 #include <asm/errno.h>
 #include <asm/io.h>
+#include <asm/msr.h>
 
 #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
 
 long __vxtime_sequence[2] __section_vxtime_sequence;
 
-#define USE_VSYSCALL
+#undef USE_VSYSCALL
 
 #ifdef USE_VSYSCALL
 
-static inline void timeval_normalize(struct timeval * tv)
-{
-	time_t __sec;
-
-	__sec = tv->tv_usec / 1000000;
-
-	if (__sec) {
-		tv->tv_usec %= 1000000;
-		tv->tv_sec += __sec;
-	}
-}
-
 static inline void do_vgettimeofday(struct timeval * tv)
 {
-	long sequence;
-	unsigned long usec, sec;
+	long sequence, t;
+	unsigned long sec, usec;
 
 	do {
 		sequence = __vxtime_sequence[1];
 		rmb();
 
+		rdtscll(t);
 		sec = __xtime.tv_sec;
-		usec = __xtime.tv_usec;
-		usec +=	(__jiffies - __wall_jiffies) * (1000000 / HZ);
-		if (__hpet.address)
-			usec += ((readl(fix_to_virt(VSYSCALL_HPET) + 0xf0) - __hpet.trigger) * __hpet.quotient) >> 32;
+		usec = __xtime.tv_usec +
+			(__jiffies - __wall_jiffies) * (1000000 / HZ) +
+			(t  - __hpet.last_tsc) * (1000000 / HZ) / __hpet.ticks + __hpet.offset;
 
 		rmb();
 	} while (sequence != __vxtime_sequence[0]);
 
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
-	timeval_normalize(tv);
+	tv->tv_sec = sec + usec / 1000000;
+	tv->tv_usec = usec % 1000000;
 }
 
 static inline void do_get_tz(struct timezone * tz)
diff -urN linux-2.4.20-pre7/arch/x86_64/kernel/x8664_ksyms.c linux-2.4.20-pre8/arch/x86_64/kernel/x8664_ksyms.c
--- linux-2.4.20-pre7/arch/x86_64/kernel/x8664_ksyms.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/kernel/x8664_ksyms.c	Wed Sep 25 18:21:32 2002
@@ -213,3 +213,10 @@
 
 EXPORT_SYMBOL(ip_compute_csum);
 
+
+#ifdef CONFIG_DISCONTIGMEM
+EXPORT_SYMBOL(memnode_shift);
+EXPORT_SYMBOL(memnodemap);
+EXPORT_SYMBOL(plat_node_data);
+EXPORT_SYMBOL(fake_node);
+#endif
diff -urN linux-2.4.20-pre7/arch/x86_64/mm/Makefile linux-2.4.20-pre8/arch/x86_64/mm/Makefile
--- linux-2.4.20-pre7/arch/x86_64/mm/Makefile	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/mm/Makefile	Wed Sep 25 18:21:32 2002
@@ -9,6 +9,8 @@
 
 O_TARGET := mm.o
 obj-y	 := init.o fault.o ioremap.o extable.o modutil.o pageattr.o
+obj-$(CONFIG_DISCONTIGMEM) += numa.o
+obj-$(CONFIG_K8_NUMA) += k8topology.o
 
 export-objs := pageattr.o
 
diff -urN linux-2.4.20-pre7/arch/x86_64/mm/fault.c linux-2.4.20-pre8/arch/x86_64/mm/fault.c
--- linux-2.4.20-pre7/arch/x86_64/mm/fault.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/mm/fault.c	Wed Sep 25 18:21:32 2002
@@ -30,6 +30,9 @@
 #include <asm/proto.h>
 #include <asm/kdebug.h>
 
+spinlock_t pcrash_lock; 
+int crashing_cpu;
+
 extern spinlock_t console_lock, timerlist_lock;
 
 void bust_spinlocks(int yes)
@@ -109,11 +112,12 @@
 	/* get the address */
 	__asm__("movq %%cr2,%0":"=r" (address));
 
+#ifdef CONFIG_CHECKING
 	if (page_fault_trace) 
-		printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n",
-		       regs->rip,regs->rsp,regs->cs,regs->ss,address,error_code); 
+		printk("pfault %d rip:%lx rsp:%lx cs:%lu ss:%lu addr %lx error %lx\n",
+		       stack_smp_processor_id(), regs->rip,regs->rsp,regs->cs,
+			   regs->ss,address,error_code); 
 
-#ifdef CONFIG_CHECKING
 	{ 
 		unsigned long gs; 
 		struct x8664_pda *pda = cpu_pda + stack_smp_processor_id(); 
@@ -125,8 +129,6 @@
 	}
 #endif
 			
-
-
 	tsk = current;
 	mm = tsk->mm;
 	info.si_code = SEGV_MAPERR;
@@ -144,8 +146,9 @@
 	if (in_interrupt() || !mm)
 		goto no_context;
 
-	down_read(&mm->mmap_sem);
 again:
+	down_read(&mm->mmap_sem);
+
 	vma = find_vma(mm, address);
 	if (!vma)
 		goto bad_area;
@@ -214,11 +217,14 @@
 
 	/* User mode accesses just cause a SIGSEGV */
 	if (error_code & 4) {
-		if (exception_trace) 
+		if (exception_trace) {
+#if 1
+			dump_pagetable(address);
+#endif	
 			printk("%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
 					current->comm, current->pid, address, regs->rip,
 					regs->rsp, error_code);
-	
+		}
 		tsk->thread.cr2 = address;
 		tsk->thread.error_code = error_code;
 		tsk->thread.trap_no = 14;
@@ -250,6 +256,14 @@
 	console_verbose();
 	bust_spinlocks(1); 
 
+	if (!in_interrupt()) { 
+		if (!spin_trylock(&pcrash_lock)) { 
+			if (crashing_cpu != smp_processor_id()) 
+				spin_lock(&pcrash_lock);  		    
+		} 
+		crashing_cpu = smp_processor_id();
+	} 
+
 	if (address < PAGE_SIZE)
 		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
 	else
@@ -258,7 +272,14 @@
 	printk(" printing rip:\n");
 	printk("%016lx\n", regs->rip);
 	dump_pagetable(address);
+
 	die("Oops", regs, error_code);
+
+	if (!in_interrupt()) { 
+		crashing_cpu = -1;  /* small harmless window */ 
+		spin_unlock(&pcrash_lock);
+	}
+
 	bust_spinlocks(0); 
 	do_exit(SIGKILL);
 
@@ -267,11 +288,12 @@
  * us unable to handle the page fault gracefully.
  */
 out_of_memory:
+	up_read(&mm->mmap_sem);
 	if (current->pid == 1) { 
-		yield();
+		tsk->policy |= SCHED_YIELD;
+		schedule();
 		goto again;
 	}
-	up_read(&mm->mmap_sem);
 	printk("VM: killing process %s\n", tsk->comm);
 	if (error_code & 4)
 		do_exit(SIGKILL);
diff -urN linux-2.4.20-pre7/arch/x86_64/mm/init.c linux-2.4.20-pre8/arch/x86_64/mm/init.c
--- linux-2.4.20-pre7/arch/x86_64/mm/init.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/mm/init.c	Wed Sep 25 18:21:32 2002
@@ -35,6 +35,7 @@
 #include <asm/tlb.h>
 #include <asm/pda.h>
 #include <asm/mmu_context.h>
+#include <asm/proto.h>
 
 mmu_gather_t mmu_gathers[NR_CPUS];
 
@@ -62,6 +63,7 @@
 	return freed;
 }
 
+#ifndef CONFIG_DISCONTIGMEM
 /*
  * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
  * physical space so we can cache the place of the first one and move
@@ -93,6 +95,7 @@
 	printk("%ld pages in page table cache\n",read_pda(pgtable_cache_sz));
 	show_buffers();
 }
+#endif
 
 /* References to section boundaries */
 
@@ -107,7 +110,7 @@
 	if (after_bootmem)
 		ptr = (void *) get_free_page(GFP_ATOMIC); 
 	else
-		ptr = alloc_bootmem_low(PAGE_SIZE); 
+		ptr = alloc_bootmem_low_pages(PAGE_SIZE); 
 	if (!ptr)
 		panic("set_pte_phys: cannot allocate page data %s\n", after_bootmem?"after bootmem":"");
 	return ptr;
@@ -165,9 +168,10 @@
 	set_pte_phys(address, phys, prot);
 }
 
-extern unsigned long start_pfn, end_pfn; 
 extern pmd_t temp_boot_pmds[]; 
 
+unsigned long __initdata table_start, table_end; 
+
 static  struct temp_map { 
 	pmd_t *pmd; 
 	void  *address; 
@@ -182,21 +186,21 @@
 { 
 	struct temp_map *ti;
 	int i; 
-	unsigned long pfn = start_pfn++, paddr; 
+	unsigned long pfn = table_end++, paddr; 
 	void *adr;
 
-	if (pfn >= end_pfn) 
-		panic("alloc_low_page: ran out of memory"); 
+	if (table_end >= end_pfn) 
+		panic("alloc_low_page: ran out of page mappings"); 
 	for (i = 0; temp_mappings[i].allocated; i++) {
 		if (!temp_mappings[i].pmd) 
 			panic("alloc_low_page: ran out of temp mappings"); 
 	} 
 	ti = &temp_mappings[i];
-	paddr = (pfn & (~511)) << PAGE_SHIFT; 
+	paddr = (pfn << PAGE_SHIFT) & PMD_MASK; 
 	set_pmd(ti->pmd, __pmd(paddr | _KERNPG_TABLE | _PAGE_PSE)); 
 	ti->allocated = 1; 
 	__flush_tlb(); 	       
-	adr = ti->address + (pfn & 511)*PAGE_SIZE; 
+	adr = ti->address + ((pfn << PAGE_SHIFT) & ~PMD_MASK); 
 	*index = i; 
 	*phys  = pfn * PAGE_SIZE;  
 	return adr; 
@@ -217,20 +221,26 @@
 	pgd = pgd + i;
 	for (; i < PTRS_PER_PGD; pgd++, i++) {
 		int map; 
-		unsigned long paddr = i*PGDIR_SIZE, pmd_phys;
+		unsigned long paddr, pmd_phys;
 		pmd_t *pmd;
 
+		paddr = (address & PML4_MASK) + i*PGDIR_SIZE; 
 		if (paddr >= end) { 
 			for (; i < PTRS_PER_PGD; i++, pgd++) 
 				set_pgd(pgd, __pgd(0)); 
 			break;
 		} 
+
+		if (!e820_mapped(paddr, paddr+PGDIR_SIZE, 0)) { 
+			set_pgd(pgd, __pgd(0)); 
+			continue;
+		} 
+
 		pmd = alloc_low_page(&map, &pmd_phys);
 		set_pgd(pgd, __pgd(pmd_phys | _KERNPG_TABLE));
-		for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
+		for (j = 0; j < PTRS_PER_PMD; pmd++, j++ , paddr += PMD_SIZE) {
 			unsigned long pe;
 
-			paddr = i*PGDIR_SIZE + j*PMD_SIZE;
 			if (paddr >= end) { 
 				for (; j < PTRS_PER_PMD; j++, pmd++)
 					set_pmd(pmd,  __pmd(0)); 
@@ -252,15 +262,42 @@
 	unsigned long adr;	       
 	unsigned long end;
 	unsigned long next; 
+	unsigned long pgds, pmds, tables; 
+
+	end = end_pfn << PAGE_SHIFT; 
+
+	/* 
+	 * Find space for the kernel direct mapping tables.
+	 * Later we should allocate these tables in the local node of the memory
+	 * mapped.  Unfortunately this is done currently before the nodes are 
+	 * discovered.
+	 */
+
+	pgds = (end + PGDIR_SIZE - 1) >> PGDIR_SHIFT;
+	pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; 
+	tables = round_up(pgds*8, PAGE_SIZE) + round_up(pmds * 8, PAGE_SIZE); 
+
+	/* Direct mapping must currently fit below the kernel in the first MB.
+	   This is because we have no way to tell the later passes to not reuse
+	   the memory, until bootmem is initialised */
+	/* Should limit MAXMEM for this */
+	table_start = find_e820_area(/*0*/ 0x8000, __pa_symbol(&_text), tables); 
+	if (table_start == -1UL) 
+		panic("Cannot find space for the kernel page tables"); 
+
+	table_start >>= PAGE_SHIFT; 
+	table_end = table_start;
+       
+	end += __PAGE_OFFSET; /* turn virtual */  
 
-	end = PAGE_OFFSET + (end_pfn * PAGE_SIZE); 
 	for (adr = PAGE_OFFSET; adr < end; adr = next) { 
 		int map;
 		unsigned long pgd_phys; 
 		pgd_t *pgd = alloc_low_page(&map, &pgd_phys);
-		next = adr + (512UL * 1024 * 1024 * 1024);
+		next = adr + PML4_SIZE;
 		if (next > end) 
 			next = end; 
+
 		phys_pgd_init(pgd, adr-PAGE_OFFSET, next-PAGE_OFFSET); 
 		set_pml4(init_level4_pgt + pml4_index(adr), 
 			 mk_kernel_pml4(pgd_phys, KERNPG_TABLE));
@@ -268,6 +305,9 @@
 	} 
 	asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features));
 	__flush_tlb_all();
+	printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", end, 
+	       table_start<<PAGE_SHIFT, 
+	       table_end<<PAGE_SHIFT);
 } 
 
 void __init zap_low_mappings (void)
@@ -277,27 +317,26 @@
 		if (cpu_pda[i].level4_pgt) 
 			cpu_pda[i].level4_pgt[0] = 0; 
 	}
+
 	flush_tlb_all();
 }
 
+#ifndef CONFIG_DISCONTIGMEM
 void __init paging_init(void)
 {
 	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
-	unsigned int max_dma, low;
+	unsigned int max_dma;
 	
 	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-	low = max_low_pfn;
-	
-	if (low < max_dma)
-		zones_size[ZONE_DMA] = low;
+	if (end_pfn < max_dma)
+		zones_size[ZONE_DMA] = end_pfn;
 	else {
 		zones_size[ZONE_DMA] = max_dma;
-		zones_size[ZONE_NORMAL] = low - max_dma;
+		zones_size[ZONE_NORMAL] = end_pfn - max_dma;
 	}
 	free_area_init(zones_size);
 }
 
-
 static inline int page_is_ram (unsigned long pagenr)
 {
 	int i;
@@ -319,38 +358,47 @@
 	}
 	return 0;
 }
+#endif
 
 void __init mem_init(void)
 {
-	int codesize, reservedpages, datasize, initsize;
-	int tmp;
-
-	if (!mem_map)
-		BUG();
+	unsigned long codesize, reservedpages, datasize, initsize;
+	unsigned long tmp;
 
-	max_mapnr = num_physpages = max_low_pfn;
-	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+	max_mapnr = end_pfn; 
+	num_physpages = end_pfn; /* XXX not true because of holes */
+	high_memory = (void *) __va(end_pfn << PAGE_SHIFT);
 
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
 
+	reservedpages = 0;
+
 	/* this will put all low memory onto the freelists */
-	totalram_pages += free_all_bootmem();
+#ifdef CONFIG_DISCONTIGMEM
+	totalram_pages += numa_free_all_bootmem();
+	tmp = 0;
+	/* should count reserved pages here for all nodes */ 
+#else
+	if (!mem_map) BUG();
 
-	after_bootmem = 1;
+	totalram_pages += free_all_bootmem();
 
-	reservedpages = 0;
-	for (tmp = 0; tmp < max_low_pfn; tmp++)
+	for (tmp = 0; tmp < end_pfn; tmp++)
 		/*
 		 * Only count reserved RAM pages
 		 */
 		if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
 			reservedpages++;
+#endif
+
+	after_bootmem = 1;
+
 	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
+	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, %ldk data, %ldk init)\n",
 		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 		max_mapnr << (PAGE_SHIFT-10),
 		codesize >> 10,
@@ -404,16 +452,16 @@
 
 void free_initmem(void)
 {
-	unsigned long addr;
+	void *addr;
 
-	addr = (unsigned long)(&__init_begin);
-	for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+	addr = (&__init_begin);
+	for (; addr < (void *)(&__init_end); addr += PAGE_SIZE) {
 		ClearPageReserved(virt_to_page(addr));
 		set_page_count(virt_to_page(addr), 1);
 #ifdef CONFIG_INIT_DEBUG
-		memset(addr & ~(PAGE_SIZE-1), 0xcc, PAGE_SIZE); 
+		memset((unsigned long)addr & ~(PAGE_SIZE-1), 0xcc, PAGE_SIZE); 
 #endif
-		free_page(addr);
+		free_page((unsigned long)addr);
 		totalram_pages++;
 	}
 	printk ("Freeing unused kernel memory: %luk freed\n", (&__init_end - &__init_begin) >> 10);
@@ -445,3 +493,23 @@
 	val->mem_unit = PAGE_SIZE;
 	return;
 }
+
+void reserve_bootmem_generic(unsigned long phys, unsigned len) 
+{ 
+	/* Should check here against the e820 map to avoid double free */ 
+#ifdef CONFIG_DISCONTIGMEM
+	reserve_bootmem_node(NODE_DATA(phys_to_nid(phys)), phys, len);
+#else       		
+	reserve_bootmem(phys, len);    
+#endif
+}
+
+
+void free_bootmem_generic(unsigned long phys, unsigned len) 
+{ 
+#ifdef CONFIG_DISCONTIGMEM
+	free_bootmem_node(NODE_DATA(phys_to_nid(phys)), phys, len);
+#else       		
+	free_bootmem(phys, len);    
+#endif
+}
diff -urN linux-2.4.20-pre7/arch/x86_64/mm/ioremap.c linux-2.4.20-pre8/arch/x86_64/mm/ioremap.c
--- linux-2.4.20-pre7/arch/x86_64/mm/ioremap.c	Wed Sep 25 18:20:49 2002
+++ linux-2.4.20-pre8/arch/x86_64/mm/ioremap.c	Wed Sep 25 18:21:32 2002
@@ -130,9 +130,11 @@
 		t_addr = __va(phys_addr);
 		t_end = t_addr + (size - 1);
 	   
+#ifndef CONFIG_DISCONTIGMEM
 		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
 			if(!PageReserved(page))
 				return NULL;
+#endif
 	}
 
 	/*
diff -urN linux-2.4.20-pre7/arch/x86_64/mm/k8topology.c linux-2.4.20-pre8/arch/x86_64/mm/k8topology.c
--- linux-2.4.20-pre7/arch/x86_64/mm/k8topology.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre8/arch/x86_64/mm/k8topology.c	Wed Sep 25 18:21:32 2002
@@ -0,0 +1,185 @@
+/* 
+ * AMD K8 NUMA support.
+ * Discover the memory map and associated nodes.
+ * 
+ * Doesn't use the ACPI SRAT table because it has a questionable license.
+ * Instead the northbridge registers are read directly. 
+ * 
+ * Copyright 2002 Andi Kleen, SuSE Labs.
+ * $Id: k8topology.c,v 1.3 2002/09/12 12:51:39 ak Exp $
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <linux/pci_ids.h>
+#include <asm/types.h>
+#include <asm/mmzone.h>
+#include <asm/proto.h>
+#include <asm/e820.h>
+#include <asm/pci-direct.h>
+
+int memnode_shift;
+u8  memnodemap[NODEMAPSIZE];
+
+static int find_northbridge(void)
+{
+	int num; 
+
+	for (num = 0; num < 32; num++) { 
+		u32 header;
+		
+		header = read_pci_config(0, num, 0, 0x00);  
+		if (header != (PCI_VENDOR_ID_AMD | (0x1100<<16)))
+			continue; 	
+
+		header = read_pci_config(0, num, 1, 0x00); 
+		if (header != (PCI_VENDOR_ID_AMD | (0x1101<<16)))
+			continue;	
+		return num; 
+	} 
+
+	return -1; 	
+}
+
+#define MAXNODE 8 
+#define NODEMASK 0xff
+
+struct node { 
+	u64 start,end; 
+};
+
+#define for_all_nodes(n) \
+	for (n=0; n<MAXNODE;n++) if (nodes[n].start!=nodes[n].end)
+
+static int compute_hash_shift(struct node *nodes, int numnodes, u64 maxmem)
+{
+	int i; 
+	int shift = 24;
+	u64 addr;
+	
+	/* When in doubt use brute force. */
+	while (shift < 48) { 
+		memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); 
+		for_all_nodes (i) { 
+			for (addr = nodes[i].start; 
+			     addr < nodes[i].end; 
+			     addr += (1UL << shift)) {
+				if (memnodemap[addr >> shift] != 0xff) { 
+					printk("node %d shift %d addr %Lx conflict %d\n", 
+					       i, shift, addr, memnodemap[addr>>shift]);
+					goto next; 
+				} 
+				memnodemap[addr >> shift] = i; 
+			} 
+		} 
+		return shift; 
+	next:
+		shift++; 
+	} 
+	memset(memnodemap,0,sizeof(*memnodemap) * NODEMAPSIZE); 
+	return -1; 
+}
+
+extern unsigned long nodes_present;
+extern unsigned long end_pfn;
+
+int __init k8_scan_nodes(unsigned long start, unsigned long end)
+{ 
+	unsigned long prevbase;
+	struct node nodes[MAXNODE];
+	int nodeid, numnodes, maxnode, i, nb; 
+
+	nb = find_northbridge(); 
+	if (nb < 0) 
+		return nb;
+
+	printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); 
+
+	numnodes = (read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3; 
+
+	memset(&nodes,0,sizeof(nodes)); 
+	prevbase = 0;
+	maxnode = -1; 
+	for (i = 0; i < MAXNODE; i++) { 
+		unsigned long base,limit; 
+
+		base = read_pci_config(0, nb, 1, 0x40 + i*8);
+		limit = read_pci_config(0, nb, 1, 0x44 + i*8);
+
+		nodeid = limit & 3; 
+		if (!limit) { 
+			printk(KERN_INFO "Skipping node entry %d (base %lx)\n", i,			       base);
+			continue;
+		}
+		if ((base >> 8) & 3 || (limit >> 8) & 3) {
+			printk(KERN_ERR "Node %d using interleaving mode %lx/%lx\n", 
+			       nodeid, (base>>8)&3, (limit>>8) & 3); 
+			return -1; 
+		}	
+		if (nodeid > maxnode) 
+			maxnode = nodeid; 
+		if ((1UL << nodeid) & nodes_present) { 
+			printk("Node %d already present. Skipping\n", nodeid);
+			continue;
+		}
+
+		limit >>= 16; 
+		limit <<= 24; 
+
+		if (limit > end_pfn << PAGE_SHIFT) 
+			limit = end_pfn << PAGE_SHIFT; 
+		if (limit <= base) { 
+			printk(KERN_INFO "Node %d beyond memory map\n", nodeid);
+			continue; 
+		} 
+			
+		base >>= 16;
+		base <<= 24; 
+
+		if (base < start) 
+			base = start; 
+		if (limit > end) 
+			limit = end; 
+		if (limit == base) 
+			continue; 
+		if (limit < base) { 
+			printk(KERN_INFO"Node %d bogus settings %lx-%lx. Ignored.\n",
+			       nodeid, base, limit); 			       
+			continue; 
+		} 
+		
+		/* Could sort here, but pun for now. Should not happen anyroads. */
+		if (prevbase > base) { 
+			printk(KERN_INFO "Node map not sorted %lx,%lx\n",
+			       prevbase,base);
+			return -1;
+		}
+			
+		printk(KERN_INFO "Node %d MemBase %016lx Limit %016lx\n", 
+		       nodeid, base, limit); 
+		
+		nodes[nodeid].start = base; 
+		nodes[nodeid].end = limit;
+
+		prevbase = base;
+	} 
+
+	if (maxnode <= 0)
+		return -1; 
+
+	memnode_shift = compute_hash_shift(nodes,maxnode,end);
+	if (memnode_shift < 0) { 
+		printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); 
+		return -1; 
+	} 
+	printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift); 
+
+	for_all_nodes(i) { 
+		setup_node_bootmem(i, nodes[i].start, nodes[i].end); 
+	} 
+
+	return 0;
+} 
+
diff -urN linux-2.4.20-pre7/arch/x86_64/mm/numa.c linux-2.4.20-pre8/arch/x86_64/mm/numa.c
--- linux-2.4.20-pre7/arch/x86_64/mm/numa.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre8/arch/x86_64/mm/numa.c	Wed Sep 25 18:21:32 2002
@@ -0,0 +1,194 @@
+/* 
+ * Generic VM initialization for x86-64 NUMA setups.
+ * Copyright 2002 Andi Kleen, SuSE Labs.
+ * $Id: numa.c,v 1.4 2002/09/05 15:28:12 ak Exp $
+ */ 
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <linux/blk.h>
+#include <asm/e820.h>
+#include <asm/proto.h>
+#include <asm/dma.h>
+
+#undef Dprintk
+#define Dprintk(...) 
+
+plat_pg_data_t *plat_node_data[MAXNODE];
+bootmem_data_t plat_node_bdata[MAX_NUMNODES];
+
+#define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
+
+static int numa_off __initdata; 
+
+unsigned long nodes_present; 
+int maxnode;
+
+/* Initialize bootmem allocator for a node */
+void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
+{ 
+	unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; 
+	unsigned long nodedata_phys;
+	const int pgdat_size = round_up(sizeof(plat_pg_data_t), PAGE_SIZE);
+
+	start = round_up(start, ZONE_ALIGN); 
+
+	printk("Bootmem setup node %d %016lx-%016lx\n", nodeid, start, end);
+
+	start_pfn = start >> PAGE_SHIFT;
+	end_pfn = end >> PAGE_SHIFT;
+
+	nodedata_phys = find_e820_area(start, end, pgdat_size); 
+	if (nodedata_phys == -1L) 
+		panic("Cannot find memory pgdat in node %d\n", nodeid);
+
+	Dprintk("nodedata_phys %lx\n", nodedata_phys); 
+
+	PLAT_NODE_DATA(nodeid) = phys_to_virt(nodedata_phys);
+	memset(PLAT_NODE_DATA(nodeid), 0, sizeof(plat_pg_data_t));
+	NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid];
+
+	/* Find a place for the bootmem map */
+	bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); 
+	bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE);
+	bootmap_start = find_e820_area(bootmap_start, end, bootmap_pages<<PAGE_SHIFT);
+	if (bootmap_start == -1L) 
+		panic("Not enough continuous space for bootmap on node %d", nodeid); 
+	Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages); 
+	
+	bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
+					 bootmap_start >> PAGE_SHIFT, 
+					 start_pfn, end_pfn); 
+
+	e820_bootmem_free(NODE_DATA(nodeid), start, end);
+
+	reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); 
+	reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT);
+
+	PLAT_NODE_DATA(nodeid)->start_pfn = start_pfn;
+	PLAT_NODE_DATA(nodeid)->end_pfn = end_pfn;
+
+	if (nodeid > maxnode) 
+		maxnode = nodeid;
+	nodes_present |= (1UL << nodeid); 
+} 
+
+/* Initialize final allocator for a zone */
+void __init setup_node_zones(int nodeid)
+{ 
+	unsigned long start_pfn, end_pfn; 
+	unsigned long zones[MAX_NR_ZONES];
+	unsigned long dma_end_pfn;
+	unsigned long lmax_mapnr;
+
+	memset(zones, 0, sizeof(unsigned long) * MAX_NR_ZONES); 
+
+	start_pfn = PLAT_NODE_DATA(nodeid)->start_pfn; 
+	end_pfn = PLAT_NODE_DATA(nodeid)->end_pfn; 
+
+	printk("setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn); 
+	
+	/* All nodes > 0 have a zero length zone DMA */ 
+	dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; 
+	if (start_pfn < dma_end_pfn) { 
+		zones[ZONE_DMA] = dma_end_pfn - start_pfn;
+		zones[ZONE_NORMAL] = end_pfn - dma_end_pfn; 
+	} else { 
+		zones[ZONE_NORMAL] = end_pfn - start_pfn; 
+	} 
+    
+	free_area_init_node(nodeid, NODE_DATA(nodeid), NULL, zones, 
+			    start_pfn<<PAGE_SHIFT, NULL); 
+	lmax_mapnr = PLAT_NODE_DATA_STARTNR(nodeid) + PLAT_NODE_DATA_SIZE(nodeid);
+	if (lmax_mapnr > max_mapnr)
+		max_mapnr = lmax_mapnr;
+} 
+
+int fake_node;
+
+int __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+{ 
+#ifdef CONFIG_K8_NUMA
+	if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT))
+		return 0; 
+#endif
+	printk(KERN_INFO "%s\n",
+	       numa_off ? "NUMA turned off" : "No NUMA configuration found");
+		   
+	printk(KERN_INFO "Faking a node at %016lx-%016lx\n", 
+	       start_pfn << PAGE_SHIFT,
+	       end_pfn << PAGE_SHIFT); 
+	/* setup dummy node covering all memory */ 
+	fake_node = 1; 	
+	memnode_shift = 63; 
+	memnodemap[0] = 0;
+	setup_node_bootmem(0, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
+	return -1; 
+} 
+
+#define for_all_nodes(x) for ((x) = 0; (x) <= maxnode; (x)++) \
+				if ((1UL << (x)) & nodes_present)
+
+unsigned long __init numa_free_all_bootmem(void) 
+{ 
+	int i;
+	unsigned long pages = 0;
+	for_all_nodes(i) {
+		pages += free_all_bootmem_node(NODE_DATA(i));
+	}
+	return pages;
+} 
+
+void __init paging_init(void)
+{ 
+	int i;
+	for_all_nodes(i) { 
+		setup_node_zones(i); 
+	}
+} 
+
+void show_mem(void)
+{
+	long i,free = 0,total = 0,reserved = 0;
+	long shared = 0, cached = 0;
+	int nid;
+
+	printk("\nMem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+	for_all_nodes (nid) { 
+		mem_map_t * lmem_map = NODE_MEM_MAP(nid);
+		i = PLAT_NODE_DATA_SIZE(nid);
+		while (i-- > 0) {
+			total++;
+			if (PageReserved(lmem_map+i))
+				reserved++;
+			else if (PageSwapCache(lmem_map+i))
+				cached++;
+			else if (!page_count(lmem_map+i))
+				free++;
+			else
+				shared += atomic_read(&lmem_map[i].count) - 1;
+		}
+	}
+	printk("%ld pages of RAM\n",total);
+	printk("%ld free pages\n",free);
+	printk("%ld reserved pages\n",reserved);
+	printk("%ld pages shared\n",shared);
+	printk("%ld pages swap cached\n",cached);
+	show_buffers();
+}
+
+/* [numa=off] */
+static __init int numa_setup(char *opt) 
+{ 
+	if (!strcmp(opt,"off"))
+		numa_off = 1;
+	return 1;
+} 
+
+__setup("numa=", numa_setup); 
+
diff -urN linux-2.4.20-pre7/drivers/acpi/dispatcher/dsfield.c linux-2.4.20-pre8/drivers/acpi/dispatcher/dsfield.c
--- linux-2.4.20-pre7/drivers/acpi/dispatcher/dsfield.c	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/dispatcher/dsfield.c	Wed Sep 25 18:21:32 2002
@@ -181,7 +181,7 @@
 	acpi_status             status;
 
 
-	FUNCTION_TRACE_U32 ("Ds_get_field_names", info);
+	PROC_NAME("acpi_ds_get_field_names"); 
 
 
 	/* First field starts at bit zero */
diff -urN linux-2.4.20-pre7/drivers/acpi/dispatcher/dswexec.c linux-2.4.20-pre8/drivers/acpi/dispatcher/dswexec.c
--- linux-2.4.20-pre7/drivers/acpi/dispatcher/dswexec.c	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/dispatcher/dswexec.c	Wed Sep 25 18:21:32 2002
@@ -577,7 +577,7 @@
 		(walk_state->control_state->common.state ==
 			CONTROL_PREDICATE_EXECUTING) &&
 		(walk_state->control_state->control.predicate_op == op)) {
-		status = acpi_ds_get_predicate_value (walk_state, (u32) walk_state->result_obj);
+		status = acpi_ds_get_predicate_value (walk_state, !! walk_state->result_obj);
 		walk_state->result_obj = NULL;
 	}
 
diff -urN linux-2.4.20-pre7/drivers/acpi/events/evevent.c linux-2.4.20-pre8/drivers/acpi/events/evevent.c
--- linux-2.4.20-pre7/drivers/acpi/events/evevent.c	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/events/evevent.c	Wed Sep 25 18:21:32 2002
@@ -683,7 +683,7 @@
 acpi_ev_asynch_execute_gpe_method (
 	void                    *context)
 {
-	u32                     gpe_number = (u32) context;
+	unsigned long           gpe_number = (unsigned long) context;
 	acpi_gpe_level_info     gpe_info;
 
 
@@ -800,7 +800,7 @@
 	 */
 	else if (gpe_info.method_handle) {
 		if (ACPI_FAILURE(acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
-			acpi_ev_asynch_execute_gpe_method, (void*) gpe_number))) {
+			acpi_ev_asynch_execute_gpe_method, (void*) (u64)gpe_number))) {
 			/*
 			 * Shoudn't occur, but if it does report an error. Note that
 			 * the GPE will remain disabled until the ACPI Core Subsystem
diff -urN linux-2.4.20-pre7/drivers/acpi/executer/exstore.c linux-2.4.20-pre8/drivers/acpi/executer/exstore.c
--- linux-2.4.20-pre7/drivers/acpi/executer/exstore.c	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/executer/exstore.c	Wed Sep 25 18:21:32 2002
@@ -181,8 +181,8 @@
 
 		case ACPI_TYPE_PACKAGE:
 
-			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Elements - 0x%X\n",
-				(u32) source_desc->package.elements));
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "Elements - %p\n",
+				source_desc->package.elements));
 			break;
 
 
diff -urN linux-2.4.20-pre7/drivers/acpi/include/acglobal.h linux-2.4.20-pre8/drivers/acpi/include/acglobal.h
--- linux-2.4.20-pre7/drivers/acpi/include/acglobal.h	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/include/acglobal.h	Wed Sep 25 18:21:32 2002
@@ -156,7 +156,7 @@
 ACPI_EXTERN u32                         acpi_gbl_current_node_count;
 ACPI_EXTERN u32                         acpi_gbl_current_node_size;
 ACPI_EXTERN u32                         acpi_gbl_max_concurrent_node_count;
-ACPI_EXTERN u32                         acpi_gbl_entry_stack_pointer;
+ACPI_EXTERN unsigned long               acpi_gbl_entry_stack_pointer;
 ACPI_EXTERN u32                         acpi_gbl_lowest_stack_pointer;
 ACPI_EXTERN u32                         acpi_gbl_deepest_nesting;
 #endif
diff -urN linux-2.4.20-pre7/drivers/acpi/include/actypes.h linux-2.4.20-pre8/drivers/acpi/include/actypes.h
--- linux-2.4.20-pre7/drivers/acpi/include/actypes.h	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/include/actypes.h	Wed Sep 25 18:21:32 2002
@@ -48,8 +48,11 @@
  * UCHAR        Character. 1 byte unsigned value.
  */
 
+#ifndef BITS_PER_LONG
+#error "define BITS_PER_LONG"
+#endif
 
-#ifdef _IA64
+#if BITS_PER_LONG == 64
 /*
  * 64-bit type definitions
  */
@@ -62,7 +65,7 @@
 typedef COMPILER_DEPENDENT_UINT64       UINT64;
 
 typedef UINT64                          NATIVE_UINT;
-typedef INT64                           NATIVE_INT;
+typedef long long                          NATIVE_INT;
 
 typedef NATIVE_UINT                     ACPI_TBLPTR;
 typedef UINT64                          ACPI_IO_ADDRESS;
@@ -72,7 +75,7 @@
 #define ACPI_USE_NATIVE_DIVIDE                          /* Native 64-bit integer support */
 
 
-#elif _IA16
+#elif BITS_PER_LONG == 16
 /*
  * 16-bit type definitions
  */
@@ -109,7 +112,7 @@
 #define ACPI_NO_INTEGER64_SUPPORT
 
 
-#else
+#elif BITS_PER_LONG == 32
 /*
  * 32-bit type definitions (default)
  */
@@ -130,6 +133,9 @@
 
 #define ALIGNED_ADDRESS_BOUNDARY        0x00000004
 #define _HW_ALIGNMENT_SUPPORT
+
+#else
+#error "unknown BITS_PER_LONG"
 #endif
 
 
diff -urN linux-2.4.20-pre7/drivers/acpi/include/platform/acgcc.h linux-2.4.20-pre8/drivers/acpi/include/platform/acgcc.h
--- linux-2.4.20-pre7/drivers/acpi/include/platform/acgcc.h	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/include/platform/acgcc.h	Wed Sep 25 18:21:32 2002
@@ -92,8 +92,7 @@
 /*! [End] no source code translation !*/
 
 
-#else /* DO IA32 */
-
+#elif __i386__ /* DO IA32 */
 #define COMPILER_DEPENDENT_UINT64   unsigned long long
 #define ACPI_ASM_MACROS
 #define causeinterrupt(level)
@@ -138,31 +137,60 @@
 			"andl   $0x1,%%eax" \
 			:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \
 	} while(0)
+#elif __x86_64__ 
+#define COMPILER_DEPENDENT_UINT64   unsigned long long
+#define ACPI_ASM_MACROS
+#define causeinterrupt(level)
+#define BREAKPOINT3
+#define disable() __cli()
+#define enable()  __sti()
+#define halt()    __asm__ __volatile__ ("sti; hlt":::"memory")
 
-
-/*
- * Math helper asm macros
+/*! [Begin] no source code translation
+ *
+ * A brief explanation as GNU inline assembly is a bit hairy
+ *  %0 is the output parameter in RAX ("=a")
+ *  %1 and %2 are the input parameters in RCX ("c")
+ *  and an immediate value ("i") respectively
+ *  All actual register references are preceded with "%%" as in "%%edx"
+ *  Immediate values in the assembly are preceded by "$" as in "$0x1"
+ *  The final asm parameter are the operation altered non-output registers.
  */
-#define ACPI_DIV_64_BY_32(n_hi, n_lo, d32, q32, r32) \
-		asm("divl %2;"        \
-		:"=a"(q32), "=d"(r32) \
-		:"r"(d32),            \
-		"0"(n_lo), "1"(n_hi))
-
+#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+		unsigned long dummy; \
+		asm("1:     movl (%2),%%eax;" \
+			"movl   %%eax,%%edx;" \
+			"andq   %2,%%rdx;" \
+			"btsl   $0x1,%%edx;" \
+			"adcl   $0x0,%%edx;" \
+			"lock;  cmpxchgl %%edx,(%1);" \
+			"jnz    1b;" \
+			"cmpb   $0x3,%%dl;" \
+			"sbbl   %%eax,%%eax" \
+			:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \
+	} while(0)
 
-#define ACPI_SHIFT_RIGHT_64(n_hi, n_lo) \
-	asm("shrl   $1,%2;"             \
-	    "rcrl   $1,%3;"             \
-	    :"=r"(n_hi), "=r"(n_lo)     \
-	    :"0"(n_hi), "1"(n_lo))
+#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
+	do { \
+		unsigned long dummy; \
+		asm("1:     movl (%2),%%eax;" \
+			"movl   %%eax,%%edx;" \
+			"andq   %2,%%rdx;" \
+			"lock;  cmpxchgl %%edx,(%1);" \
+			"jnz    1b;" \
+			"andl   $0x1,%%eax" \
+			:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \
+	} while(0)
 
 /*! [End] no source code translation !*/
 
-#endif /* IA 32 */
+#endif
 
 /* This macro is used to tag functions as "printf-like" because
  * some compilers (like GCC) can catch printf format string problems.
  */
 #define ACPI_PRINTF_LIKE_FUNC __attribute__ ((__format__ (__printf__, 4, 5)))
 
+
 #endif /* __ACGCC_H__ */
diff -urN linux-2.4.20-pre7/drivers/acpi/include/platform/aclinux.h linux-2.4.20-pre8/drivers/acpi/include/platform/aclinux.h
--- linux-2.4.20-pre7/drivers/acpi/include/platform/aclinux.h	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/include/platform/aclinux.h	Wed Sep 25 18:21:32 2002
@@ -58,5 +58,14 @@
 #undef DEBUGGER_THREADING
 #define DEBUGGER_THREADING          DEBUGGER_SINGLE_THREADED
 
+#if BITS_PER_LONG < 64
+/* Linux ia32 can't do int64 well */
+#define ACPI_NO_INTEGER64_SUPPORT
+/* And the ia32 kernel doesn't include 64-bit divide support */
+#define ACPI_DIV64(dividend, divisor) do_div(dividend, divisor)
+#else
+#define ACPI_DIV64(dividend, divisor) ACPI_DIVIDE(dividend, divisor)
+#endif
+
 
 #endif /* __ACLINUX_H__ */
diff -urN linux-2.4.20-pre7/drivers/acpi/namespace/nsdump.c linux-2.4.20-pre8/drivers/acpi/namespace/nsdump.c
--- linux-2.4.20-pre7/drivers/acpi/namespace/nsdump.c	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/namespace/nsdump.c	Wed Sep 25 18:21:32 2002
@@ -226,7 +226,7 @@
 			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ID %d Addr %.4X Len %.4X\n",
 					 obj_desc->processor.proc_id,
 					 obj_desc->processor.address,
-					 obj_desc->processor.length));
+					 (unsigned)obj_desc->processor.length));
 			break;
 
 		case ACPI_TYPE_DEVICE:
diff -urN linux-2.4.20-pre7/drivers/acpi/os.c linux-2.4.20-pre8/drivers/acpi/os.c
--- linux-2.4.20-pre7/drivers/acpi/os.c	Fri Nov  9 13:39:25 2001
+++ linux-2.4.20-pre8/drivers/acpi/os.c	Wed Sep 25 18:21:32 2002
@@ -42,7 +42,7 @@
 #include <acpi.h>
 
 #ifdef CONFIG_ACPI_EFI
-#include <asm/efi.h>
+#include <linux/efi.h>
 #endif
 
 #ifdef _IA64
@@ -361,7 +361,7 @@
 acpi_status
 acpi_os_write_memory(
 	ACPI_PHYSICAL_ADDRESS	phys_addr,
-	u32			value,
+	NATIVE_UINT		value,
 	u32			width)
 {
 	switch (width)
@@ -421,7 +421,7 @@
 	return (result ? AE_ERROR : AE_OK);
 }
 
-acpi_status
+ACPI_STATUS
 acpi_os_write_pci_configuration (
 	acpi_pci_id             *pci_id,
 	u32                     reg,
@@ -491,7 +491,7 @@
 acpi_os_write_pci_configuration (
 	acpi_pci_id	*pci_id,
 	u32		reg,
-	u32		value,
+	NATIVE_UINT	value,
 	u32		width)
 {
 	int devfn = PCI_DEVFN(pci_id->device, pci_id->function);
diff -urN linux-2.4.20-pre7/drivers/acpi/ospm/busmgr/bm_osl.c linux-2.4.20-pre8/drivers/acpi/ospm/busmgr/bm_osl.c
--- linux-2.4.20-pre7/drivers/acpi/ospm/busmgr/bm_osl.c	Fri Dec 21 09:41:53 2001
+++ linux-2.4.20-pre8/drivers/acpi/ospm/busmgr/bm_osl.c	Wed Sep 25 18:21:32 2002
@@ -108,7 +108,7 @@
 	u32			event_data)
 {
 	BM_OSL_EVENT		*event = NULL;
-	u32			flags = 0;
+	unsigned long		flags = 0;
 
 	/* drop event on the floor if no one's listening */
 	if (!event_is_open)
diff -urN linux-2.4.20-pre7/drivers/acpi/ospm/ec/ectransx.c linux-2.4.20-pre8/drivers/acpi/ospm/ec/ectransx.c
--- linux-2.4.20-pre7/drivers/acpi/ospm/ec/ectransx.c	Sun Sep 23 09:42:32 2001
+++ linux-2.4.20-pre8/drivers/acpi/ospm/ec/ectransx.c	Wed Sep 25 18:21:32 2002
@@ -104,7 +104,7 @@
 acpi_status
 ec_io_read (
 	EC_CONTEXT              *ec,
-	ACPI_IO_ADDRESS         io_port,
+	u32		        io_port,
 	u8                      *data,
 	EC_EVENT                wait_event)
 {
@@ -139,7 +139,7 @@
 acpi_status
 ec_io_write (
 	EC_CONTEXT              *ec,
-	ACPI_IO_ADDRESS         io_port,
+	u32		       io_port,
 	u8                      data,
 	EC_EVENT                wait_event)
 {
diff -urN linux-2.4.20-pre7/drivers/acpi/ospm/thermal/tzpolicy.c linux-2.4.20-pre8/drivers/acpi/ospm/thermal/tzpolicy.c
--- linux-2.4.20-pre7/drivers/acpi/ospm/thermal/tzpolicy.c	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/ospm/thermal/tzpolicy.c	Wed Sep 25 18:21:32 2002
@@ -413,7 +413,7 @@
 		if (timer_pending(&(policy->timer)))
 			mod_timer(&(policy->timer), (HZ*sleep_time)/1000);
 		else {
-			policy->timer.data = (u32)tz;
+			policy->timer.data = (unsigned long)tz;
 			policy->timer.function = tz_policy_run;
 			policy->timer.expires = jiffies + (HZ*sleep_time)/1000;
 			add_timer(&(policy->timer));
diff -urN linux-2.4.20-pre7/drivers/acpi/utilities/utdebug.c linux-2.4.20-pre8/drivers/acpi/utilities/utdebug.c
--- linux-2.4.20-pre7/drivers/acpi/utilities/utdebug.c	Wed Oct 24 14:06:22 2001
+++ linux-2.4.20-pre8/drivers/acpi/utilities/utdebug.c	Wed Sep 25 18:21:32 2002
@@ -57,7 +57,7 @@
 	u32                 current_sp;
 
 
-	acpi_gbl_entry_stack_pointer = (u32) &current_sp;
+	acpi_gbl_entry_stack_pointer = (unsigned long) &current_sp;
 }
 
 
diff -urN linux-2.4.20-pre7/drivers/block/elevator.c linux-2.4.20-pre8/drivers/block/elevator.c
--- linux-2.4.20-pre7/drivers/block/elevator.c	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/block/elevator.c	Wed Sep 25 18:21:33 2002
@@ -83,7 +83,6 @@
 	struct list_head *entry = &q->queue_head;
 	unsigned int count = bh->b_size >> 9, ret = ELEVATOR_NO_MERGE;
 	struct request *__rq;
-	int merge_only = 0;
 
 	while ((entry = entry->prev) != head) {
 		__rq = blkdev_entry_to_request(entry);
@@ -92,13 +91,13 @@
 		 * we can't insert beyond a zero sequence point
 		 */
 		if (__rq->elevator_sequence <= 0)
-			merge_only = 1;
+			break;
 
 		if (__rq->waiting)
 			continue;
 		if (__rq->rq_dev != bh->b_rdev)
 			continue;
-		if (!*req && !merge_only && bh_rq_in_between(bh, __rq, &q->queue_head))
+		if (!*req && bh_rq_in_between(bh, __rq, &q->queue_head))
 			*req = __rq;
 		if (__rq->cmd != rw)
 			continue;
diff -urN linux-2.4.20-pre7/drivers/char/Config.in linux-2.4.20-pre8/drivers/char/Config.in
--- linux-2.4.20-pre7/drivers/char/Config.in	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/char/Config.in	Wed Sep 25 18:21:34 2002
@@ -266,12 +266,20 @@
 fi
 endmenu
 
-tristate '/dev/agpgart (AGP Support)' CONFIG_AGP
+if [ "$CONFIG_GART_IOMMU" = "y" ]; then
+	bool '/dev/agpgart (AGP Support)' CONFIG_AGP
+	define_bool CONFIG_AGP_AMD_8151 y
+else
+	tristate '/dev/agpgart (AGP Support)' CONFIG_AGP
+fi      
 if [ "$CONFIG_AGP" != "n" ]; then
    bool '  Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support' CONFIG_AGP_INTEL
    bool '  Intel I810/I815/I830M (on-board) support' CONFIG_AGP_I810
    bool '  VIA chipset support' CONFIG_AGP_VIA
    bool '  AMD Irongate, 761, and 762 support' CONFIG_AGP_AMD
+   if [ "$CONFIG_GART_IOMMU" != "y" ]; then
+      bool '  AMD 8151 support' CONFIG_AGP_AMD_8151
+   fi   
    bool '  Generic SiS support' CONFIG_AGP_SIS
    bool '  ALI chipset support' CONFIG_AGP_ALI
    bool '  Serverworks LE/HE support' CONFIG_AGP_SWORKS
diff -urN linux-2.4.20-pre7/drivers/char/advantechwdt.c linux-2.4.20-pre8/drivers/char/advantechwdt.c
--- linux-2.4.20-pre7/drivers/char/advantechwdt.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/advantechwdt.c	Wed Sep 25 18:21:34 2002
@@ -114,7 +114,10 @@
 		adv_expect_close = 0;
 
 		for (i = 0; i != count; i++) {
-			if (buf[i] == 'V')
+			char c;
+			if(get_user(c, buf+i))
+				return -EFAULT;
+			if (c == 'V')
 				adv_expect_close = 42;
 		}
 #endif
diff -urN linux-2.4.20-pre7/drivers/char/agp/agp.h linux-2.4.20-pre8/drivers/char/agp/agp.h
--- linux-2.4.20-pre7/drivers/char/agp/agp.h	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/agp/agp.h	Wed Sep 25 18:21:34 2002
@@ -84,8 +84,8 @@
 	void *dev_private_data;
 	struct pci_dev *dev;
 	gatt_mask *masks;
-	unsigned long *gatt_table;
-	unsigned long *gatt_table_real;
+	u32 *gatt_table;
+	u32 *gatt_table_real;
 	unsigned long scratch_page;
 	unsigned long gart_bus_addr;
 	unsigned long gatt_bus_addr;
@@ -238,6 +238,9 @@
 #ifndef PCI_DEVICE_ID_AMD_762_0
 #define PCI_DEVICE_ID_AMD_762_0		0x700C
 #endif
+#ifndef PCI_DEVICE_ID_AMD_8151_0
+#define PCI_DEVICE_ID_AMD_8151_0	0x7454
+#endif
 #ifndef PCI_VENDOR_ID_AL
 #define PCI_VENDOR_ID_AL		0x10b9
 #endif
@@ -364,6 +367,22 @@
 #define AMD_TLBFLUSH    0x0c	/* In mmio region (32-bit register) */
 #define AMD_CACHEENTRY  0x10	/* In mmio region (32-bit register) */
 
+#define AMD_8151_APSIZE	0xb4
+#define AMD_8151_GARTBLOCK	0xb8
+
+#define AMD_X86_64_GARTAPERTURECTL	0x90
+#define AMD_X86_64_GARTAPERTUREBASE	0x94
+#define AMD_X86_64_GARTTABLEBASE	0x98
+#define AMD_X86_64_GARTCACHECTL		0x9c
+#define AMD_X86_64_GARTEN	1<<0
+
+#define AMD_8151_VMAPERTURE		0x10
+#define AMD_8151_AGP_CTL		0xb0
+#define AMD_8151_APERTURESIZE	0xb4
+#define AMD_8151_GARTPTR		0xb8
+#define AMD_8151_GTLBEN	1<<7
+#define AMD_8151_APEREN	1<<8
+
 /* ALi registers */
 #define ALI_APBASE	0x10
 #define ALI_AGPCTRL	0xb8
diff -urN linux-2.4.20-pre7/drivers/char/agp/agpgart_be.c linux-2.4.20-pre8/drivers/char/agp/agpgart_be.c
--- linux-2.4.20-pre7/drivers/char/agp/agpgart_be.c	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/char/agp/agpgart_be.c	Wed Sep 25 18:21:34 2002
@@ -64,6 +64,8 @@
 static struct agp_bridge_data agp_bridge;
 static int agp_try_unsupported __initdata = 0;
 
+int agp_memory_reserved;
+__u32 *agp_gatt_table;
 
 static inline void flush_cache(void)
 {
@@ -300,12 +302,14 @@
 		break;
 	}
 
+	current_size -= (agp_memory_reserved / (1024*1024));
+
 	return current_size;
 }
 
 /* Routine to copy over information structure */
 
-void agp_copy_info(agp_kern_info * info)
+int agp_copy_info(agp_kern_info * info)
 {
 	unsigned long page_mask = 0;
 	int i;
@@ -313,7 +317,7 @@
 	memset(info, 0, sizeof(agp_kern_info));
 	if (agp_bridge.type == NOT_SUPPORTED) {
 		info->chipset = agp_bridge.type;
-		return;
+		return -1;
 	}
 	info->version.major = agp_bridge.version->major;
 	info->version.minor = agp_bridge.version->minor;
@@ -330,6 +334,7 @@
 		page_mask |= agp_bridge.mask_memory(page_mask, i);
 
 	info->page_mask = ~page_mask;
+	return 0;
 }
 
 /* End - Routine to copy over information structure */
@@ -584,6 +589,7 @@
 		SetPageReserved(page);
 
 	agp_bridge.gatt_table_real = (unsigned long *) table;
+	agp_gatt_table = (void *)table;
 #ifdef CONFIG_X86
 	err = change_page_attr(virt_to_page(table), 1<<page_order, PAGE_KERNEL_NOCACHE);
 #endif
@@ -701,6 +707,9 @@
 		break;
 	}
 
+	num_entries -= agp_memory_reserved/PAGE_SIZE;
+	if (num_entries < 0) num_entries = 0;
+
 	if (type != 0 || mem->type != 0) {
 		/* The generic routines know nothing of memory types */
 		return -EINVAL;
@@ -2712,6 +2721,472 @@
 
 #endif /* CONFIG_AGP_AMD */
 
+#ifdef CONFIG_AGP_AMD_8151
+
+/* Begin AMD-8151 support */
+
+static u_int64_t pci_read64 (struct pci_dev *dev, int reg)
+{
+	union {
+		u64 full;
+		struct {
+			u32 high;
+			u32 low;
+		} split;
+	} tmp;
+	pci_read_config_dword(dev, reg, &tmp.split.high);
+	pci_read_config_dword(dev, reg+4, &tmp.split.low);
+	return tmp.full;
+}
+
+static void pci_write64 (struct pci_dev *dev, int reg, u64 value)
+{
+	union {
+		u64 full;
+		struct {
+			u32 high;
+			u32 low;
+		} split;
+	} tmp;
+	tmp.full = value;
+	pci_write_config_dword(dev, reg, tmp.split.high);
+	pci_write_config_dword(dev, reg+4, tmp.split.low);
+}
+
+
+static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
+{
+	int i, j, num_entries;
+	void *temp;
+	long tmp;
+	u32 pte;
+	u64 addr;
+
+	temp = agp_bridge.current_size;
+
+	num_entries = A_SIZE_32(temp)->num_entries;
+
+	num_entries -= agp_memory_reserved>>PAGE_SHIFT;
+
+	if (type != 0 || mem->type != 0)
+		return -EINVAL;
+
+	/* Make sure we can fit the range in the gatt table. */
+	if ((pg_start + mem->page_count) > num_entries)
+		return -EINVAL;
+
+	j = pg_start;
+
+	/* gatt table should be empty. */
+	while (j < (pg_start + mem->page_count)) {
+		if (!PGE_EMPTY(agp_bridge.gatt_table[j]))
+			return -EBUSY;
+		j++;
+	}
+
+	if (mem->is_flushed == FALSE) {
+		CACHE_FLUSH();
+		mem->is_flushed = TRUE;
+	}
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		addr = mem->memory[i];
+
+		tmp = addr;
+		BUG_ON(tmp & 0xffffff0000000ffc);
+		pte = (tmp & 0x000000ff00000000) >> 28;
+		pte |=(tmp & 0x00000000fffff000);
+		pte |= 1<<1|1<<0;
+
+		agp_bridge.gatt_table[j] = pte;
+	}
+	agp_bridge.tlb_flush(mem);
+	return 0;
+}
+
+/*
+ * This hack alters the order element according
+ * to the size of a long. It sucks. I totally disown this, even
+ * though it does appear to work for the most part.
+ */
+static aper_size_info_32 x86_64_aperture_sizes[7] =
+{
+	{32,   8192,   3+(sizeof(long)/8), 0 },
+	{64,   16384,  4+(sizeof(long)/8), 1<<1 },
+	{128,  32768,  5+(sizeof(long)/8), 1<<2 },
+	{256,  65536,  6+(sizeof(long)/8), 1<<1 | 1<<2 },
+	{512,  131072, 7+(sizeof(long)/8), 1<<3 },
+	{1024, 262144, 8+(sizeof(long)/8), 1<<1 | 1<<3},
+	{2048, 524288, 9+(sizeof(long)/8), 1<<2 | 1<<3}
+};
+
+
+/*
+ * Get the current Aperture size from the x86-64.
+ * Note, that there may be multiple x86-64's, but we just return
+ * the value from the first one we find. The set_size functions
+ * keep the rest coherent anyway. Or at least should do.
+ */
+static int amd_x86_64_fetch_size(void)
+{
+	struct pci_dev *dev;
+	int i;
+	u32 temp;
+	aper_size_info_32 *values;
+
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 &&
+			PCI_FUNC(dev->devfn)==3 &&
+			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
+
+			pci_read_config_dword(dev, AMD_X86_64_GARTAPERTURECTL, &temp);
+			temp = (temp & 0xe);
+			values = A_SIZE_32(x86_64_aperture_sizes);
+
+			for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+				if (temp == values[i].size_value) {
+					agp_bridge.previous_size =
+					    agp_bridge.current_size = (void *) (values + i);
+
+					agp_bridge.aperture_size_idx = i;
+					return values[i].size;
+				}
+			}
+		}
+	}
+	/* erk, couldn't find an x86-64 ? */
+	return 0;
+}
+
+
+static void inline flush_x86_64_tlb(struct pci_dev *dev)
+{
+	u32 tmp;
+
+	pci_read_config_dword (dev, AMD_X86_64_GARTCACHECTL, &tmp);
+	tmp |= 1<<0;
+	pci_write_config_dword (dev, AMD_X86_64_GARTCACHECTL, tmp);
+}
+
+
+void amd_x86_64_tlbflush(agp_memory * temp)
+{
+	struct pci_dev *dev;
+
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
+		    PCI_SLOT(dev->devfn) >=24 && PCI_SLOT(dev->devfn) <=31) {
+			flush_x86_64_tlb (dev);
+		}
+	}
+}
+
+
+/*
+ * In a multiprocessor x86-64 system, this function gets
+ * called once for each CPU.
+ */
+u64 amd_x86_64_configure (struct pci_dev *hammer, u64 gatt_table)
+{
+	u64 aperturebase;
+	u32 tmp;
+	u64 addr, aper_base;
+
+	/* Address to map to */
+	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
+	aperturebase = tmp << 25;
+	aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* address of the mappings table */
+	addr = (u64) gatt_table;
+	addr >>= 12;
+	tmp = (u32) addr<<4;
+	tmp &= ~0xf;
+	pci_write_config_dword (hammer, AMD_X86_64_GARTTABLEBASE, tmp);
+
+	/* Enable GART translation for this hammer. */
+	pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp);
+	tmp &= 0x3f;
+	tmp |= 1<<0;
+	pci_write_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, tmp);
+
+	/* keep CPU's coherent. */
+	flush_x86_64_tlb (hammer);
+	
+	return aper_base;
+}
+
+
+static aper_size_info_32 amd_8151_sizes[7] =
+{
+	{2048, 524288, 9, 0x00000000 },	/* 0 0 0 0 0 0 */
+	{1024, 262144, 8, 0x00000400 },	/* 1 0 0 0 0 0 */
+	{512,  131072, 7, 0x00000600 },	/* 1 1 0 0 0 0 */
+	{256,  65536,  6, 0x00000700 },	/* 1 1 1 0 0 0 */
+	{128,  32768,  5, 0x00000720 },	/* 1 1 1 1 0 0 */
+	{64,   16384,  4, 0x00000730 },	/* 1 1 1 1 1 0 */
+	{32,   8192,   3, 0x00000738 } 	/* 1 1 1 1 1 1 */
+};
+
+static int amd_8151_configure(void)
+{
+	struct pci_dev *dev, *hammer=NULL;
+	int current_size;
+	int tmp, tmp2, i;
+	u64 aperbar;
+	unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real);
+
+	/* Configure AGP regs in each x86-64 host bridge. */
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 &&
+			PCI_FUNC(dev->devfn)==3 &&
+			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
+			agp_bridge.gart_bus_addr = amd_x86_64_configure(dev,gatt_bus);
+			hammer = dev;
+
+			/*
+			 * TODO: Cache pci_dev's of x86-64's in private struct to save us
+			 * having to scan the pci list each time.
+			 */
+		}
+	}
+
+	if (hammer == NULL) {
+		return -ENODEV;
+	}
+
+	/* Shadow x86-64 registers into 8151 registers. */
+
+	dev = agp_bridge.dev;
+	if (!dev) 
+		return -ENODEV;
+
+	current_size = amd_x86_64_fetch_size();
+
+	pci_read_config_dword(dev, AMD_8151_APERTURESIZE, &tmp);
+	tmp &= ~(0xfff);
+
+	/* translate x86-64 size bits to 8151 size bits*/
+	for (i=0 ; i<7; i++) {
+		if (amd_8151_sizes[i].size == current_size)
+			tmp |= (amd_8151_sizes[i].size_value) << 3;
+	}
+	pci_write_config_dword(dev, AMD_8151_APERTURESIZE, tmp);
+
+	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
+	aperbar = pci_read64 (dev, AMD_8151_VMAPERTURE);
+	aperbar |= (tmp & 0x7fff) <<25;
+	aperbar &= 0x000000ffffffffff;
+	aperbar |= 1<<2;	/* This address is a 64bit ptr FIXME: Make conditional in 32bit mode */
+	pci_write64 (dev, AMD_8151_VMAPERTURE, aperbar);
+
+	pci_read_config_dword(dev, AMD_8151_AGP_CTL , &tmp);
+	tmp &= ~(AMD_8151_GTLBEN | AMD_8151_APEREN);
+	
+	pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp2);
+	if (tmp2 & AMD_X86_64_GARTEN)
+		tmp |= AMD_8151_APEREN;
+	// FIXME: bit 7 of AMD_8151_AGP_CTL (GTLBEN) must be copied if set.
+	// But where is it set ?
+	pci_write_config_dword(dev, AMD_8151_AGP_CTL, tmp);
+
+	return 0;
+}
+
+
+static void amd_8151_cleanup(void)
+{
+	struct pci_dev *dev;
+	u32 tmp;
+
+	pci_for_each_dev(dev) {
+		/* disable gart translation */
+		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
+		    (PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) {
+
+			pci_read_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, &tmp);
+			tmp &= ~(AMD_X86_64_GARTEN);
+			pci_write_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, tmp);
+		}
+
+		/* Now shadow the disable in the 8151 */
+		if (dev->vendor == PCI_VENDOR_ID_AMD &&
+			dev->device == PCI_DEVICE_ID_AMD_8151_0) {
+
+			pci_read_config_dword (dev, AMD_8151_AGP_CTL, &tmp);
+			tmp &= ~(AMD_8151_APEREN);	
+			pci_write_config_dword (dev, AMD_8151_AGP_CTL, tmp);
+		}
+	}
+}
+
+
+
+static unsigned long amd_8151_mask_memory(unsigned long addr, int type)
+{
+	return addr | agp_bridge.masks[0].mask;
+}
+
+
+static gatt_mask amd_8151_masks[] =
+{
+	{0x00000001, 0}
+};
+
+
+/*
+ * Try to configure an AGP v3 capable setup.
+ * If we fail (typically because we don't have an AGP v3
+ * card in the system) we fall back to the generic AGP v2
+ * routines.
+ */
+static void agp_x86_64_agp_enable(u32 mode)
+{
+	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 ?
+	 * Messy, as some AGPv3 cards can only do x4 as a minimum.
+	 */
+
+	/* PASS1: Count # of devs capable of AGPv3 mode. */
+	pci_for_each_dev(device) {
+		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (cap_ptr != 0x00) {
+			pci_read_config_dword(device, cap_ptr, &scratch);
+			scratch &= (1<<20|1<<21|1<<22|1<<23);
+			scratch = scratch>>20;
+			/* AGP v3 capable ? */
+			if (scratch>=3) {
+				v3_devs++;
+				printk (KERN_INFO "AGP: Found AGPv3 capable device at %d:%d:%d\n",
+					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
+			} else {
+				printk (KERN_INFO "AGP: Meh. version %x AGP device found.\n", scratch);
+			}
+		}
+	}
+	/* If not enough, go to AGP v2 setup */
+	if (v3_devs<2) {
+		printk (KERN_INFO "AGP: Only %d devices found, not enough, trying AGPv2\n", v3_devs);
+		return agp_generic_agp_enable(mode);
+	} else {
+		printk (KERN_INFO "AGP: Enough AGPv3 devices found, setting up...\n");
+	}
+
+
+	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 */
+
+	command |= 0x100;
+
+	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx + 8, 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);
+	}
+}
+
+
+static int __init amd_8151_setup (struct pci_dev *pdev)
+{
+	agp_bridge.masks = amd_8151_masks;
+	agp_bridge.num_of_masks = 1;
+	agp_bridge.aperture_sizes = (void *) amd_8151_sizes;
+	agp_bridge.size_type = U32_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 7;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = amd_8151_configure;
+	agp_bridge.fetch_size = amd_x86_64_fetch_size;
+	agp_bridge.cleanup = amd_8151_cleanup;
+	agp_bridge.tlb_flush = amd_x86_64_tlbflush;
+	agp_bridge.mask_memory = amd_8151_mask_memory;
+	agp_bridge.agp_enable = agp_x86_64_agp_enable;
+	agp_bridge.cache_flush = global_cache_flush;
+	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge.insert_memory = x86_64_insert_memory;
+	agp_bridge.remove_memory = agp_generic_remove_memory;
+	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge.free_by_type = agp_generic_free_by_type;
+	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.suspend = agp_generic_suspend;
+	agp_bridge.resume = agp_generic_resume;
+	agp_bridge.cant_use_aperture = 0;
+
+	return 0;
+	
+	(void) pdev; /* unused */
+}
+
+#endif /* CONFIG_AGP_AMD_8151 */
+
 #ifdef CONFIG_AGP_ALI
 
 static int ali_fetch_size(void)
@@ -4024,6 +4499,15 @@
 		amd_irongate_setup },
 #endif /* CONFIG_AGP_AMD */
 
+#ifdef CONFIG_AGP_AMD_8151
+	{ PCI_DEVICE_ID_AMD_8151_0,
+		PCI_VENDOR_ID_AMD,
+		AMD_8151,
+		"AMD",
+		"8151",
+		amd_8151_setup },
+#endif /* CONFIG_AGP_AMD */
+
 #ifdef CONFIG_AGP_INTEL
 	{ PCI_DEVICE_ID_INTEL_82443LX_0,
 		PCI_VENDOR_ID_INTEL,
@@ -4692,7 +5176,7 @@
 	&agp_copy_info
 };
 
-static int __init agp_init(void)
+int __init agp_init(void)
 {
 	int ret_val;
 
@@ -4725,5 +5209,7 @@
 	inter_module_unregister("drm_agp");
 }
 
+#ifndef CONFIG_GART_IOMMU
 module_init(agp_init);
 module_exit(agp_cleanup);
+#endif
diff -urN linux-2.4.20-pre7/drivers/char/alim7101_wdt.c linux-2.4.20-pre8/drivers/char/alim7101_wdt.c
--- linux-2.4.20-pre7/drivers/char/alim7101_wdt.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/alim7101_wdt.c	Wed Sep 25 18:21:34 2002
@@ -165,9 +165,13 @@
 
 		/* now scan */
 		for(ofs = 0; ofs != count; ofs++)
-			if(buf[ofs] == 'V')
+		{
+			char c;
+			if(get_user(c, buf+ofs))
+				return -EFAULT;
+			if(c == 'V')
 				wdt_expect_close = 1;
-
+		}
 		/* someone wrote to us, we should restart timer */
 		next_heartbeat = jiffies + WDT_HEARTBEAT;
 		return 1;
diff -urN linux-2.4.20-pre7/drivers/char/drm/drm_agpsupport.h linux-2.4.20-pre8/drivers/char/drm/drm_agpsupport.h
--- linux-2.4.20-pre7/drivers/char/drm/drm_agpsupport.h	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/char/drm/drm_agpsupport.h	Wed Sep 25 18:21:35 2002
@@ -285,6 +285,7 @@
 		case SIS_GENERIC:	head->chipset = "SiS";           break;
 		case AMD_GENERIC:	head->chipset = "AMD";           break;
 		case AMD_IRONGATE:	head->chipset = "AMD Irongate";  break;
+		case AMD_8151:		head->chipset = "AMD 8151";      break;
 		case ALI_GENERIC:	head->chipset = "ALi";           break;
 		case ALI_M1541: 	head->chipset = "ALi M1541";     break;
 
diff -urN linux-2.4.20-pre7/drivers/char/drm/drm_vm.h linux-2.4.20-pre8/drivers/char/drm/drm_vm.h
--- linux-2.4.20-pre7/drivers/char/drm/drm_vm.h	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/char/drm/drm_vm.h	Wed Sep 25 18:21:35 2002
@@ -141,7 +141,9 @@
 		return NOPAGE_OOM;
 	get_page(page);
 
+#if 0	/* XXX page_to_bus is not a portable interface available on all platforms. */
 	DRM_DEBUG("0x%08lx => 0x%08llx\n", address, (u64)page_to_bus(page));
+#endif
 	return page;
 }
 
@@ -243,8 +245,10 @@
 
 	get_page(page);
 
+#if 0	/* XXX page_to_bus is not a portable interface available on all platforms. */
 	DRM_DEBUG("0x%08lx (page %lu) => 0x%08llx\n", address, page_nr, 
 		  (u64)page_to_bus(page));
+#endif
 	return page;
 }
 
diff -urN linux-2.4.20-pre7/drivers/char/drm/mga_dma.c linux-2.4.20-pre8/drivers/char/drm/mga_dma.c
--- linux-2.4.20-pre7/drivers/char/drm/mga_dma.c	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/char/drm/mga_dma.c	Wed Sep 25 18:21:35 2002
@@ -158,9 +158,18 @@
 {
 	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
 	u32 head, tail;
+	u32 status = 0;
+	int i;
 	DMA_LOCALS;
 	DRM_DEBUG( "%s:\n", __FUNCTION__ );
 
+        /* We need to wait so that we can do an safe flush */
+	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
+		status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
+		if ( status == MGA_ENDPRDMASTS ) break;
+		udelay( 1 );
+	}
+
 	if ( primary->tail == primary->last_flush ) {
 		DRM_DEBUG( "   bailing out...\n" );
 		return;
diff -urN linux-2.4.20-pre7/drivers/char/efirtc.c linux-2.4.20-pre8/drivers/char/efirtc.c
--- linux-2.4.20-pre7/drivers/char/efirtc.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/efirtc.c	Wed Sep 25 18:21:35 2002
@@ -35,8 +35,8 @@
 #include <linux/init.h>
 #include <linux/rtc.h>
 #include <linux/proc_fs.h>
+#include <linux/efi.h>
 
-#include <asm/efi.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
diff -urN linux-2.4.20-pre7/drivers/char/hcdp_serial.c linux-2.4.20-pre8/drivers/char/hcdp_serial.c
--- linux-2.4.20-pre7/drivers/char/hcdp_serial.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/hcdp_serial.c	Wed Sep 25 18:21:36 2002
@@ -15,9 +15,9 @@
 #include <linux/init.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
+#include <linux/efi.h>
 #include <asm/serial.h>
 #include <asm/io.h>
-#include <asm/efi.h>
 #include <linux/hcdp_serial.h>
 
 #undef SERIAL_DEBUG_HCDP
diff -urN linux-2.4.20-pre7/drivers/char/joystick/Makefile linux-2.4.20-pre8/drivers/char/joystick/Makefile
--- linux-2.4.20-pre7/drivers/char/joystick/Makefile	Wed Sep 12 15:34:06 2001
+++ linux-2.4.20-pre8/drivers/char/joystick/Makefile	Wed Sep 25 18:21:36 2002
@@ -6,7 +6,7 @@
 
 # Objects that export symbols.
 
-export-objs	:= serio.o gameport.o
+export-objs	:= serio.o gameport.o pcigame.o
 
 # I-Force may need both USB and RS-232
 
diff -urN linux-2.4.20-pre7/drivers/char/joystick/pcigame.c linux-2.4.20-pre8/drivers/char/joystick/pcigame.c
--- linux-2.4.20-pre7/drivers/char/joystick/pcigame.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/joystick/pcigame.c	Wed Sep 25 18:21:36 2002
@@ -43,35 +43,18 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/gameport.h>
+#include <linux/pci_gameport.h>
 
 #define PCI_VENDOR_ID_AUREAL	0x12eb
 
 #define PCIGAME_DATA_WAIT	20	/* 20 ms */
 
-#define PCIGAME_4DWAVE		0
-#define PCIGAME_VORTEX		1
-#define PCIGAME_VORTEX2		2
-
-struct pcigame_data {
-	int gcr;	/* Gameport control register */
-	int legacy;	/* Legacy port location */
-	int axes;	/* Axes start */
-	int axsize;	/* Axis field size */
-	int axmax;	/* Axis field max value */
-	int adcmode;	/* Value to enable ADC mode in GCR */
-};
-
-static struct pcigame_data pcigame_data[] __devinitdata =
-{{ 0x00030, 0x00031, 0x00034, 2, 0xffff, 0x80 },
- { 0x1100c, 0x11008, 0x11010, 4, 0x1fff, 0x40 },
- { 0x2880c, 0x28808, 0x28810, 4, 0x1fff, 0x40 },
- { 0 }};
 
-struct pcigame {
-	struct gameport gameport;
-	struct pci_dev *dev;
-        unsigned char *base;
-	struct pcigame_data *data;
+static struct pcigame_data pcigame_data[] __devinitdata = {
+	{ 0x00030, 0x00031, 0x00034, 2, 0xffff, 0x80 },
+	{ 0x1100c, 0x11008, 0x11010, 4, 0x1fff, 0x40 },
+	{ 0x2880c, 0x28808, 0x28810, 4, 0x1fff, 0x40 },
+	{ 0 }
 };
 
 static unsigned char pcigame_read(struct gameport *gameport)
@@ -120,20 +103,19 @@
 	return 0;
 }
 
-static int __devinit pcigame_probe(struct pci_dev *dev, const struct pci_device_id *id)
+struct pcigame *pcigame_attach(struct pci_dev *dev, int type)
 {
 	struct pcigame *pcigame;
 	int i;
 
 	if (!(pcigame = kmalloc(sizeof(struct pcigame), GFP_KERNEL)))
-		return -1;
+		return NULL;
         memset(pcigame, 0, sizeof(struct pcigame));
 
 
-	pcigame->data = pcigame_data + id->driver_data;
+	pcigame->data = pcigame_data + type;
 
 	pcigame->dev = dev;
-	pci_set_drvdata(dev, pcigame);
 
 	pcigame->gameport.driver = pcigame;
 	pcigame->gameport.fuzz = 64;
@@ -146,6 +128,8 @@
 	for (i = 0; i < 6; i++)
 		if (~pci_resource_flags(dev, i) & IORESOURCE_IO)
 			break;
+	if(i==6)
+		return NULL;
 
 	pci_enable_device(dev);
 
@@ -158,20 +142,46 @@
 		pcigame->gameport.number, dev->name, dev->bus->number,
 			PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), pcigame->gameport.speed);
 
+	return pcigame;
+}
+
+EXPORT_SYMBOL_GPL(pcigame_attach);
+
+
+void pcigame_detach(struct pcigame *game)
+{
+	gameport_unregister_port(&game->gameport);
+	iounmap(game->base);
+	kfree(game);
+}
+
+EXPORT_SYMBOL_GPL(pcigame_detach);
+
+static __devinit int pcigame_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct pcigame *r = pcigame_attach(dev, id->driver_data);
+	if(r == NULL)
+		return -1;
+	pci_set_drvdata(dev, r);
 	return 0;
 }
 
 static void __devexit pcigame_remove(struct pci_dev *dev)
 {
 	struct pcigame *pcigame = pci_get_drvdata(dev);
-	gameport_unregister_port(&pcigame->gameport);
-	iounmap(pcigame->base);
-	kfree(pcigame);
+	pcigame_detach(pcigame);
 }
 
+
 static struct pci_device_id pcigame_id_table[] __devinitdata =
-{{ PCI_VENDOR_ID_TRIDENT, 0x2000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_4DWAVE  },
+{
+/* If the trident is configured in audio grabs it and we get called by
+   that */
+#if !defined(CONFIG_SOUND_TRIDENT) && !defined(CONFIG_SOUND_TRIDENT_MODULE)
+ { PCI_VENDOR_ID_TRIDENT, 0x2000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_4DWAVE  },
  { PCI_VENDOR_ID_TRIDENT, 0x2001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_4DWAVE  },
+ { PCI_VENDOR_ID_AL,      0x5451, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_4DWAVE  },
+#endif 
  { PCI_VENDOR_ID_AUREAL,  0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_VORTEX  },
  { PCI_VENDOR_ID_AUREAL,  0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCIGAME_VORTEX2 },
  { 0 }};
@@ -185,7 +195,9 @@
 
 int __init pcigame_init(void)
 {
-	return pci_module_init(&pcigame_driver);
+	pci_module_init(&pcigame_driver);
+	/* Needed by other modules */
+	return 0;
 }
 
 void __exit pcigame_exit(void)
diff -urN linux-2.4.20-pre7/drivers/char/machzwd.c linux-2.4.20-pre8/drivers/char/machzwd.c
--- linux-2.4.20-pre7/drivers/char/machzwd.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/machzwd.c	Wed Sep 25 18:21:36 2002
@@ -303,10 +303,10 @@
 	/* See if we got the magic character */
 	if(count){
 
-/*
- * no need to check for close confirmation
- * no way to disable watchdog ;)
- */
+		/*
+		 * no need to check for close confirmation
+		 * no way to disable watchdog ;)
+		 */
 #ifndef CONFIG_WATCHDOG_NOWAYOUT
 		size_t ofs;
 
@@ -318,7 +318,10 @@
 
 		/* now scan */
 		for(ofs = 0; ofs != count; ofs++){
-			if(buf[ofs] == 'V'){
+			char c;
+			if(get_user(c, buf+ofs))
+				return -EFAULT;
+			if(c == 'V'){
 				zf_expect_close = 1;
 				dprintk("zf_expect_close 1\n");
 			}
diff -urN linux-2.4.20-pre7/drivers/char/mwave/smapi.c linux-2.4.20-pre8/drivers/char/mwave/smapi.c
--- linux-2.4.20-pre7/drivers/char/mwave/smapi.c	Sun Sep 30 12:26:05 2001
+++ linux-2.4.20-pre8/drivers/char/mwave/smapi.c	Wed Sep 25 18:21:36 2002
@@ -280,10 +280,11 @@
 				if ((usSI & 0xFF) == mwave_uart_irq) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 					PRINTK_ERROR(KERN_ERR_MWAVE
+						"smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
 #else
 					PRINTK_3(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
 #endif
-						"smapi::smapi_set_DSP_cfg: Serial port A irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 					PRINTK_1(TRACE_SMAPI,
 						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
@@ -300,13 +301,14 @@
 					if ((usSI >> 8) == uartio_index) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 						PRINTK_ERROR(KERN_ERR_MWAVE
+							"smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
 #else
 						PRINTK_3(TRACE_SMAPI,
+							"smapi::smapi_set_DSP_cfg: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
 #endif
-							"smapi::smapi_set_DSP_cfg: Serial port A base I/O address index %x conflicts with uartio_index %x\n", usSI >> 8, uartio_index);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 						PRINTK_1(TRACE_SMAPI,
-							"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+							"smapi::smapi_set_DSP_cfg Disabling conflicting serial port A\n");
 						bRC = smapi_request (0x1403, 0x0100, 0, usSI,
 							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
 						if (bRC) goto exit_smapi_request_error;
@@ -331,13 +333,14 @@
 				if ((usSI & 0xFF) == mwave_uart_irq) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 					PRINTK_ERROR(KERN_ERR_MWAVE
+						"smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
 #else
 					PRINTK_3(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI & 0xFF, mwave_uart_irq);
 #endif
-						"smapi::smapi_set_DSP_cfg: Serial port B irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 					PRINTK_1(TRACE_SMAPI,
-						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+						"smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
 					bRC = smapi_request(0x1405, 0x0100, 0, usSI,
 						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
 					if (bRC) goto exit_smapi_request_error;
@@ -351,13 +354,14 @@
 					if ((usSI >> 8) == uartio_index) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 						PRINTK_ERROR(KERN_ERR_MWAVE
+							"smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
 #else
 						PRINTK_3(TRACE_SMAPI,
+							"smapi::smapi_set_DSP_cfg: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI >> 8], ausUartBases[uartio_index]);
 #endif
-							"smapi::smapi_set_DSP_cfg: Serial port B base I/O address index %x conflicts with uartio_index %x\n", usSI >> 8, uartio_index);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 						PRINTK_1 (TRACE_SMAPI,
-						    "smapi::smapi_set_DSP_cfg Disabling conflicting serial port\n");
+						    "smapi::smapi_set_DSP_cfg Disabling conflicting serial port B\n");
 						bRC = smapi_request (0x1405, 0x0100, 0, usSI,
 							&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
 						if (bRC) goto exit_smapi_request_error;
@@ -380,39 +384,15 @@
 			&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
 		if (bRC) goto exit_smapi_request_error;
 		/* bRC == 0 */
-		if ((usCX & 0xff) == mwave_uart_irq) {	/* serial port is enabled */
-#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
-			PRINTK_ERROR(KERN_ERR_MWAVE
-#else
-			PRINTK_3(TRACE_SMAPI,
-#endif
-				"smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usSI, mwave_uart_irq);
-#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
-			PRINTK_1(TRACE_SMAPI,
-				"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
-			bRC = smapi_request(0x1701, 0x0100, 0, 0,
-				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
-			if (bRC) goto exit_smapi_request_error;
-			bRC = smapi_request(0x1700, 0, 0, 0,
-				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
-			if (bRC) goto exit_smapi_request_error;
-			bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
-				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
-			if (bRC) goto exit_smapi_request_error;
-			bRC = smapi_request(0x1704, 0x0000, 0, 0,
-				&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
-			if (bRC) goto exit_smapi_request_error;
-#else
-			goto exit_conflict;
-#endif
-		} else {
-			if ((usSI & 0xff) == uartio_index) {
+		if ((usCX & 0xff) != 0xff) { /* IR port not disabled */
+			if ((usCX & 0xff) == mwave_uart_irq) {
 #ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
 				PRINTK_ERROR(KERN_ERR_MWAVE
+					"smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
 #else
 				PRINTK_3(TRACE_SMAPI,
+					"smapi::smapi_set_DSP_cfg: IR port irq %x conflicts with mwave_uart_irq %x\n", usCX & 0xff, mwave_uart_irq);
 #endif
-					"smapi::smapi_set_DSP_cfg: IR port base I/O address index %x conflicts with uartio_index %x\n", usSI & 0xff, uartio_index);
 #ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
 				PRINTK_1(TRACE_SMAPI,
 					"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
@@ -431,6 +411,34 @@
 #else
 				goto exit_conflict;
 #endif
+			} else {
+				if ((usSI & 0xff) == uartio_index) {
+#ifndef MWAVE_FUTZ_WITH_OTHER_DEVICES
+					PRINTK_ERROR(KERN_ERR_MWAVE
+						"smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]);
+#else
+					PRINTK_3(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg: IR port base I/O address %x conflicts with mwave uart I/O %x\n", ausUartBases[usSI & 0xff], ausUartBases[uartio_index]);
+#endif
+#ifdef MWAVE_FUTZ_WITH_OTHER_DEVICES
+					PRINTK_1(TRACE_SMAPI,
+						"smapi::smapi_set_DSP_cfg Disabling conflicting IR port\n");
+					bRC = smapi_request(0x1701, 0x0100, 0, 0,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+					bRC = smapi_request(0x1700, 0, 0, 0,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+					bRC = smapi_request(0x1705, 0x01ff, 0, usSI,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+					bRC = smapi_request(0x1704, 0x0000, 0, 0,
+						&usAX, &usBX, &usCX, &usDX, &usDI, &usSI);
+					if (bRC) goto exit_smapi_request_error;
+#else
+					goto exit_conflict;
+#endif
+				}
 			}
 		}
 	}
diff -urN linux-2.4.20-pre7/drivers/char/sbc60xxwdt.c linux-2.4.20-pre8/drivers/char/sbc60xxwdt.c
--- linux-2.4.20-pre7/drivers/char/sbc60xxwdt.c	Thu Sep 13 15:21:32 2001
+++ linux-2.4.20-pre8/drivers/char/sbc60xxwdt.c	Wed Sep 25 18:21:38 2002
@@ -300,15 +300,16 @@
 
 	unregister_reboot_notifier(&wdt_notifier);
 	release_region(WDT_START,1);
-	release_region(WDT_STOP,1);
+//	release_region(WDT_STOP,1);
 }
 
 static int __init sbc60xxwdt_init(void)
 {
 	int rc = -EBUSY;
 
-	if (!request_region(WDT_STOP, 1, "SBC 60XX WDT"))
-		goto err_out;
+//	We cannot reserve 0x45 - the kernel already has!
+//	if (!request_region(WDT_STOP, 1, "SBC 60XX WDT"))
+//		goto err_out;
 	if (!request_region(WDT_START, 1, "SBC 60XX WDT"))
 		goto err_out_region1;
 
diff -urN linux-2.4.20-pre7/drivers/char/sc1200wdt.c linux-2.4.20-pre8/drivers/char/sc1200wdt.c
--- linux-2.4.20-pre7/drivers/char/sc1200wdt.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/sc1200wdt.c	Wed Sep 25 18:21:38 2002
@@ -253,7 +253,10 @@
 
 		for (i = 0; i != len; i++)
 		{
-			if (data[i] == 'V')
+			char c;
+			if(get_user(c, data+i))
+				return -EFAULT;
+			if (c == 'V')
 				expect_close = 42;
 		}
 #endif
diff -urN linux-2.4.20-pre7/drivers/char/sc520_wdt.c linux-2.4.20-pre8/drivers/char/sc520_wdt.c
--- linux-2.4.20-pre7/drivers/char/sc520_wdt.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/sc520_wdt.c	Wed Sep 25 18:21:38 2002
@@ -201,9 +201,13 @@
 		wdt_expect_close = 0;
 
 		/* now scan */
-		for(ofs = 0; ofs != count; ofs++) 
-			if(buf[ofs] == 'V')
+		for(ofs = 0; ofs != count; ofs++) {
+			char c;
+			if (get_user(c, buf + ofs))
+				return -EFAULT;
+			if(c == 'V')
 				wdt_expect_close = 1;
+		}
 
 		/* Well, anyhow someone wrote to us, we should return that favour */
 		next_heartbeat = jiffies + WDT_HEARTBEAT;
diff -urN linux-2.4.20-pre7/drivers/char/shwdt.c linux-2.4.20-pre8/drivers/char/shwdt.c
--- linux-2.4.20-pre7/drivers/char/shwdt.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/shwdt.c	Wed Sep 25 18:21:38 2002
@@ -237,7 +237,10 @@
 		shwdt_expect_close = 0;
 
 		for (i = 0; i != count; i++) {
-			if (buf[i] == 'V')
+			char c;
+			if (get_user(c, buf + i))
+				return -EFAULT;
+			if (c == 'V')
 				shwdt_expect_close = 42;
 		}
 		next_heartbeat = jiffies + (sh_heartbeat * HZ);
diff -urN linux-2.4.20-pre7/drivers/char/w83877f_wdt.c linux-2.4.20-pre8/drivers/char/w83877f_wdt.c
--- linux-2.4.20-pre7/drivers/char/w83877f_wdt.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/w83877f_wdt.c	Wed Sep 25 18:21:39 2002
@@ -192,8 +192,13 @@
 
 		/* now scan */
 		for(ofs = 0; ofs != count; ofs++)
-			if(buf[ofs] == 'V')
+		{
+			char c;
+			if(get_user(c, buf + ofs))
+				return -EFAULT;
+			if(c == 'V')
 				wdt_expect_close = 1;
+		}
 
 		/* someone wrote to us, we should restart timer */
 		next_heartbeat = jiffies + WDT_HEARTBEAT;
diff -urN linux-2.4.20-pre7/drivers/char/wafer5823wdt.c linux-2.4.20-pre8/drivers/char/wafer5823wdt.c
--- linux-2.4.20-pre7/drivers/char/wafer5823wdt.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/wafer5823wdt.c	Wed Sep 25 18:21:39 2002
@@ -54,6 +54,7 @@
 #define WDT_STOP 0x843
 
 #define WD_TIMO 60		/* 1 minute */
+static int wd_margin = WD_TIMO;
 
 static void wafwdt_ping(void)
 {
@@ -67,7 +68,7 @@
 static void wafwdt_start(void)
 {
 	/* start up watchdog */
-	outb_p(WD_TIMO, WDT_START);
+	outb_p(wd_margin, WDT_START);
 	inb_p(WDT_START);
 }
 
@@ -94,8 +95,10 @@
 static int wafwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	     unsigned long arg)
 {
+	int new_margin;
 	static struct watchdog_info ident = {
-		WDIOF_KEEPALIVEPING, 1, "Wafer 5823 WDT"
+		WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+		1, "Wafer 5823 WDT"
 	};
 	int one=1;
 
@@ -115,6 +118,18 @@
 		wafwdt_ping();
 		break;
 
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_margin, (int *)arg))
+			return -EFAULT;
+		if ((new_margin < 1) || (new_margin > 255))
+			return -EINVAL;
+		wd_margin = new_margin;
+		wafwdt_stop();
+		wafwdt_start();
+		/* Fall */
+	case WDIOC_GETTIMEOUT:
+		return put_user(wd_margin, (int *)arg);
+
 	default:
 		return -ENOTTY;
 	}
diff -urN linux-2.4.20-pre7/drivers/char/wdt_pci.c linux-2.4.20-pre8/drivers/char/wdt_pci.c
--- linux-2.4.20-pre7/drivers/char/wdt_pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/char/wdt_pci.c	Wed Sep 25 18:21:39 2002
@@ -237,7 +237,10 @@
 		expect_close = 0;
 
 		for (i = 0; i != count; i++) {
-			if (buf[i] == 'V')
+			char c;
+			if(get_user(c, buf+i))
+				return -EFAULT;
+			if (c == 'V')
 				expect_close = 1;
 		}
 #endif
diff -urN linux-2.4.20-pre7/drivers/hotplug/cpqphp.h linux-2.4.20-pre8/drivers/hotplug/cpqphp.h
--- linux-2.4.20-pre7/drivers/hotplug/cpqphp.h	Fri Nov  9 14:01:21 2001
+++ linux-2.4.20-pre8/drivers/hotplug/cpqphp.h	Wed Sep 25 18:21:39 2002
@@ -307,8 +307,8 @@
 	u8 first_slot;
 	u8 add_support;
 	u8 push_flag;
-	u8 speed;			/* 0 = 33MHz, 1 = 66MHz */
-	u8 speed_capability;		/* 0 = 33MHz, 1 = 66MHz */
+	enum pci_bus_speed speed;
+	enum pci_bus_speed speed_capability;
 	u8 push_button;			/* 0 = no pushbutton, 1 = pushbutton present */
 	u8 slot_switch_type;		/* 0 = no switch, 1 = switch present */
 	u8 defeature_PHP;		/* 0 = PHP not supported, 1 = PHP supported */
@@ -323,9 +323,6 @@
 	wait_queue_head_t queue;	/* sleep & wake process */
 };
 
-#define CTRL_SPEED_33MHz	0
-#define CTRL_SPEED_66MHz	1
-
 struct irq_mapping {
 	u8 barber_pole;
 	u8 valid_INT;
@@ -637,7 +634,7 @@
 	u16 misc;
 	
 	misc = readw(ctrl->hpc_reg + MISC);
-	return (misc & 0x0800) ? 1 : 0;
+	return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
 }
 
 
diff -urN linux-2.4.20-pre7/drivers/hotplug/cpqphp_core.c linux-2.4.20-pre8/drivers/hotplug/cpqphp_core.c
--- linux-2.4.20-pre7/drivers/hotplug/cpqphp_core.c	Mon Feb 25 11:37:57 2002
+++ linux-2.4.20-pre8/drivers/hotplug/cpqphp_core.c	Wed Sep 25 18:21:40 2002
@@ -78,17 +78,21 @@
 static int get_attention_status	(struct hotplug_slot *slot, u8 *value);
 static int get_latch_status	(struct hotplug_slot *slot, u8 *value);
 static int get_adapter_status	(struct hotplug_slot *slot, u8 *value);
+static int get_max_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
+static int get_cur_bus_speed	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 
 static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = {
-	owner:			THIS_MODULE,
-	set_attention_status:	set_attention_status,
-	enable_slot:		process_SI,
-	disable_slot:		process_SS,
-	hardware_test:		hardware_test,
-	get_power_status:	get_power_status,
-	get_attention_status:	get_attention_status,
-	get_latch_status:	get_latch_status,
-	get_adapter_status:	get_adapter_status,
+	.owner =		THIS_MODULE,
+	.set_attention_status =	set_attention_status,
+	.enable_slot =		process_SI,
+	.disable_slot =		process_SS,
+	.hardware_test =	hardware_test,
+	.get_power_status =	get_power_status,
+	.get_attention_status =	get_attention_status,
+	.get_latch_status =	get_latch_status,
+	.get_adapter_status =	get_adapter_status,
+ 	.get_max_bus_speed =	get_max_bus_speed,
+ 	.get_cur_bus_speed =	get_cur_bus_speed,
 };
 
 
@@ -377,7 +381,7 @@
 			new_slot->capabilities |= PCISLOT_64_BIT_SUPPORTED;
 		if (is_slot66mhz(new_slot))
 			new_slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED;
-		if (ctrl->speed == 1)
+		if (ctrl->speed == PCI_SPEED_66MHz)
 			new_slot->capabilities |= PCISLOT_66_MHZ_OPERATION;
 
 		ctrl_slot = slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4);
@@ -781,6 +785,44 @@
 	return 0;
 }
 
+static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	*value = ctrl->speed_capability;
+
+	return 0;
+}
+
+static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
+{
+	struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
+	struct controller *ctrl;
+	
+	if (slot == NULL)
+		return -ENODEV;
+
+	dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
+
+	ctrl = slot->ctrl;
+	if (ctrl == NULL)
+		return -ENODEV;
+	
+	*value = ctrl->speed;
+
+	return 0;
+}
+
 static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	u8 num_of_slots = 0;
@@ -852,28 +894,28 @@
 					case PCI_SUB_HPC_ID:
 						/* Original 6500/7000 implementation */
 						ctrl->slot_switch_type = 1;		// Switch is present
-						ctrl->speed_capability = CTRL_SPEED_33MHz;
+						ctrl->speed_capability = PCI_SPEED_33MHz;
 						ctrl->push_button = 0;			// No pushbutton
 						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
-						ctrl->defeature_PHP = 1;			// PHP is supported
+						ctrl->defeature_PHP = 1;		// PHP is supported
 						ctrl->pcix_support = 0;			// PCI-X not supported
-						ctrl->pcix_speed_capability = 0;		// N/A since PCI-X not supported
+						ctrl->pcix_speed_capability = 0;	// N/A since PCI-X not supported
 						break;
 					case PCI_SUB_HPC_ID2:
 						/* First Pushbutton implementation */
 						ctrl->push_flag = 1;
 						ctrl->slot_switch_type = 1;		// Switch is present
-						ctrl->speed_capability = CTRL_SPEED_33MHz;
+						ctrl->speed_capability = PCI_SPEED_33MHz;
 						ctrl->push_button = 1;			// Pushbutton is present
 						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
-						ctrl->defeature_PHP = 1;			// PHP is supported
+						ctrl->defeature_PHP = 1;		// PHP is supported
 						ctrl->pcix_support = 0;			// PCI-X not supported
-						ctrl->pcix_speed_capability = 0;		// N/A since PCI-X not supported
+						ctrl->pcix_speed_capability = 0;	// N/A since PCI-X not supported
 						break;
 					case PCI_SUB_HPC_ID_INTC:
 						/* Third party (6500/7000) */
 						ctrl->slot_switch_type = 1;		// Switch is present
-						ctrl->speed_capability = CTRL_SPEED_33MHz;
+						ctrl->speed_capability = PCI_SPEED_33MHz;
 						ctrl->push_button = 0;			// No pushbutton
 						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
 						ctrl->defeature_PHP = 1;			// PHP is supported
@@ -884,7 +926,7 @@
 						/* First 66 Mhz implementation */
 						ctrl->push_flag = 1;
 						ctrl->slot_switch_type = 1;		// Switch is present
-						ctrl->speed_capability = CTRL_SPEED_66MHz;
+						ctrl->speed_capability = PCI_SPEED_66MHz;
 						ctrl->push_button = 1;			// Pushbutton is present
 						ctrl->pci_config_space = 1;		// Index/data access to working registers 0 = not supported, 1 = supported
 						ctrl->defeature_PHP = 1;		// PHP is supported
@@ -902,9 +944,9 @@
 			case PCI_VENDOR_ID_INTEL:
 				/* Check for speed capability (0=33, 1=66) */
 				if (subsystem_deviceid & 0x0001) {
-					ctrl->speed_capability = CTRL_SPEED_66MHz;
+					ctrl->speed_capability = PCI_SPEED_66MHz;
 				} else {
-					ctrl->speed_capability = CTRL_SPEED_33MHz;
+					ctrl->speed_capability = PCI_SPEED_33MHz;
 				}
 
 				/* Check for push button */
@@ -981,7 +1023,7 @@
 	info("Initializing the PCI hot plug controller residing on PCI bus %d\n", pdev->bus->number);
 
 	dbg ("Hotplug controller capabilities:\n");
-	dbg ("    speed_capability       %s\n", ctrl->speed_capability == CTRL_SPEED_33MHz ? "33MHz" : "66Mhz");
+	dbg ("    speed_capability       %s\n", ctrl->speed_capability == PCI_SPEED_33MHz ? "33MHz" : "66Mhz");
 	dbg ("    slot_switch_type       %s\n", ctrl->slot_switch_type == 0 ? "no switch" : "switch present");
 	dbg ("    defeature_PHP          %s\n", ctrl->defeature_PHP == 0 ? "PHP not supported" : "PHP supported");
 	dbg ("    alternate_base_address %s\n", ctrl->alternate_base_address == 0 ? "not supported" : "supported");
diff -urN linux-2.4.20-pre7/drivers/hotplug/cpqphp_ctrl.c linux-2.4.20-pre8/drivers/hotplug/cpqphp_ctrl.c
--- linux-2.4.20-pre7/drivers/hotplug/cpqphp_ctrl.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/hotplug/cpqphp_ctrl.c	Wed Sep 25 18:21:40 2002
@@ -1186,7 +1186,7 @@
 		//*********************************
 		rc = CARD_FUNCTIONING;
 	} else {
-		if (ctrl->speed == 1) {
+		if (ctrl->speed == PCI_SPEED_66MHz) {
 			// Wait for exclusive access to hardware
 			down(&ctrl->crit_sect);
 
@@ -1384,7 +1384,7 @@
 	dbg(__FUNCTION__": func->device, slot_offset, hp_slot = %d, %d ,%d\n",
 	    func->device, ctrl->slot_device_offset, hp_slot);
 
-	if (ctrl->speed == 1) {
+	if (ctrl->speed == PCI_SPEED_66MHz) {
 		// Wait for exclusive access to hardware
 		down(&ctrl->crit_sect);
 
diff -urN linux-2.4.20-pre7/drivers/hotplug/ibmphp.h linux-2.4.20-pre8/drivers/hotplug/ibmphp.h
--- linux-2.4.20-pre7/drivers/hotplug/ibmphp.h	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/hotplug/ibmphp.h	Wed Sep 25 18:21:40 2002
@@ -39,7 +39,8 @@
 #else
 	#define MY_NAME THIS_MODULE->name
 #endif
-#define debug(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
+#define debug(fmt, arg...) do { if (ibmphp_debug == 1) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
+#define debug_pci(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
@@ -121,6 +122,7 @@
 	u8 port1_port_connect;
 	u8 port2_node_connect;
 	u8 port2_port_connect;
+	u8 chassis_num;
 //	struct list_head scal_detail_list;
 };
 
@@ -139,9 +141,27 @@
 	u8 port1_port_connect;
 	u8 first_slot_num;
 	u8 status;
-//	struct list_head rio_detail_list;
+	u8 wpindex;
+	u8 chassis_num;
+	struct list_head rio_detail_list;
 };
 
+struct opt_rio {
+	u8 rio_type;
+	u8 chassis_num;
+	u8 first_slot_num;
+	u8 middle_num;
+	struct list_head opt_rio_list;
+};	
+
+struct opt_rio_lo {
+	u8 rio_type;
+	u8 chassis_num;
+	u8 first_slot_num;
+	u8 middle_num;
+	u8 pack_count;
+	struct list_head opt_rio_lo_list;
+};	
 
 /****************************************************************
 *  HPC DESCRIPTOR NODE                                          *
@@ -153,7 +173,6 @@
 	short phys_addr;
 //      struct list_head ebda_hpc_list;
 };
-
 /*****************************************************************
 *   IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS           *
 *   STRUCTURE                                                    *
@@ -195,6 +214,9 @@
 	u8 i2c_addr;
 };
 
+#define HPC_DEVICE_ID		0x0246
+#define HPC_SUBSYSTEM_ID	0x0247
+#define HPC_PCI_OFFSET		0x40
 /*************************************************************************
 *   RSTC DESCRIPTOR NODE                                                 *
 *************************************************************************/
@@ -215,8 +237,9 @@
 	u8 rsrc_type;
 	u8 bus_num;
 	u8 dev_fun;
-	ulong start_addr;
-	ulong end_addr;
+	u32 start_addr;
+	u32 end_addr;
+	u8 marked;	/* for NVRAM */
 	struct list_head ebda_pci_rsrc_list;
 };
 
@@ -248,7 +271,7 @@
 ***********************************************************/
 extern struct list_head ibmphp_ebda_pci_rsrc_head;
 extern struct list_head ibmphp_slot_head;
-
+extern struct list_head ibmphp_res_head;
 /***********************************************************
 * FUNCTION PROTOTYPES                                      *
 ***********************************************************/
@@ -263,6 +286,7 @@
 extern struct bus_info *ibmphp_find_same_bus_num (u32);
 extern int ibmphp_get_bus_index (u8);
 extern u16 ibmphp_get_total_controllers (void);
+extern int ibmphp_register_pci (void);
 
 /* passed parameters */
 #define MEM		0
@@ -713,6 +737,7 @@
 struct controller {
 	struct ebda_hpc_slot *slots;
 	struct ebda_hpc_bus *buses;
+	struct pci_dev *ctrl_dev; /* in case where controller is PCI */
 	u8 starting_slot_num;	/* starting and ending slot #'s this ctrl controls*/
 	u8 ending_slot_num;
 	u8 revision;
diff -urN linux-2.4.20-pre7/drivers/hotplug/ibmphp_core.c linux-2.4.20-pre8/drivers/hotplug/ibmphp_core.c
--- linux-2.4.20-pre7/drivers/hotplug/ibmphp_core.c	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/hotplug/ibmphp_core.c	Wed Sep 25 18:21:40 2002
@@ -44,7 +44,7 @@
 #define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
 #define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
 
-#define DRIVER_VERSION	"0.3"
+#define DRIVER_VERSION	"0.6"
 #define DRIVER_DESC	"IBM Hot Plug PCI Controller Driver"
 
 int ibmphp_debug;
@@ -88,6 +88,8 @@
 	slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus);
 	if (READ_BUS_MODE (slot_cur->ctrl))
 		slot_cur->bus_on->current_bus_mode = CURRENT_BUS_MODE (slot_cur->busstatus);
+	else
+		slot_cur->bus_on->current_bus_mode = 0xFF;
 
 	debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode);
 	
@@ -106,13 +108,17 @@
 	return rc;
 }
 
-static int get_max_slots (void)
+static int __init get_max_slots (void)
 {
+	struct slot * slot_cur;
 	struct list_head * tmp;
-	int slot_count = 0;
+	u8 slot_count = 0;
 
-	list_for_each (tmp, &ibmphp_slot_head) 
-		++slot_count;
+	list_for_each (tmp, &ibmphp_slot_head) {
+		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
+		/* sometimes the hot-pluggable slots start with 4 (not always from 1 */
+		slot_count = max (slot_count, slot_cur->number);
+	}
 	return slot_count;
 }
 
@@ -330,7 +336,7 @@
 			memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
 			hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
 			if (!hpcrc) {
-				*value = SLOT_POWER (myslot.status);
+				*value = SLOT_PWRGD (myslot.status);
 				rc = 0;
 			}
 		}
@@ -378,14 +384,15 @@
 	debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
 	return rc;
 }
-/*
-static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
+
+static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot;
 	u8 mode = 0;
 
-	debug ("get_max_bus_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
+	debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
+		hotplug_slot, value);
 
 	ibmphp_lock_operations ();
 
@@ -394,31 +401,39 @@
 		if (pslot) {
 			rc = 0;
 			mode = pslot->supported_bus_mode;
-			*value = pslot->supported_speed;
-			*value &= 0x0f;
-
-			if (mode == BUS_MODE_PCIX)
-				*value |= 0x80;
-			else if (mode == BUS_MODE_PCI)
-				*value |= 0x40;
-			else
-				*value |= 0x20;
+			*value = pslot->supported_speed; 
+			switch (*value) {
+			case BUS_SPEED_33:
+				break;
+			case BUS_SPEED_66:
+				if (mode == BUS_MODE_PCIX) 
+					*value += 0x01;
+				break;
+			case BUS_SPEED_100:
+			case BUS_SPEED_133:
+				*value = pslot->supported_speed + 0x01;
+				break;
+			default:
+				/* Note (will need to change): there would be soon 256, 512 also */
+				rc = -ENODEV;
+			}
 		}
 	} else
 		rc = -ENODEV;
 
 	ibmphp_unlock_operations ();
-	debug ("get_max_bus_speed - Exit rc[%d] value[%x]\n", rc, *value);
+	debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
 	return rc;
 }
 
-static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
+static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot;
 	u8 mode = 0;
 
-	debug ("get_cur_bus_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
+	debug ("%s - Entry hotplug_slot[%p] pvalue[%p]\n", __FUNCTION__,
+		hotplug_slot, value);
 
 	ibmphp_lock_operations ();
 
@@ -429,24 +444,35 @@
 			if (!rc) {
 				mode = pslot->bus_on->current_bus_mode;
 				*value = pslot->bus_on->current_speed;
-				*value &= 0x0f;
-				
-				if (mode == BUS_MODE_PCIX)
-					*value |= 0x80;
-				else if (mode == BUS_MODE_PCI)
-					*value |= 0x40;
-				else
-					*value |= 0x20;	
+				switch (*value) {
+				case BUS_SPEED_33:
+					break;
+				case BUS_SPEED_66:
+					if (mode == BUS_MODE_PCIX) 
+						*value += 0x01;
+					else if (mode == BUS_MODE_PCI)
+						;
+					else
+						*value = PCI_SPEED_UNKNOWN;
+					break;
+				case BUS_SPEED_100:
+				case BUS_SPEED_133:
+					*value += 0x01;
+					break;
+				default:
+					/* Note of change: there would also be 256, 512 soon */
+					rc = -ENODEV;
+				}
 			}
 		}
 	} else
 		rc = -ENODEV;
 
 	ibmphp_unlock_operations ();
-	debug ("get_cur_bus_speed - Exit rc[%d] value[%x]\n", rc, *value);
+	debug ("%s - Exit rc[%d] value[%x]\n", __FUNCTION__, rc, *value);
 	return rc;
 }
-
+/*
 static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * value, u8 flag)
 {
 	int rc = -ENODEV;
@@ -454,7 +480,7 @@
 	int hpcrc = 0;
 	struct slot myslot;
 
-	debug ("get_max_adapter_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
+	debug ("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
 
 	if (flag)
 		ibmphp_lock_operations ();
@@ -485,17 +511,16 @@
 	if (flag)
 		ibmphp_unlock_operations ();
 
-	debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
+	debug ("get_max_adapter_speed_1 - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
 	return rc;
 }
 
-static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value)
+static int get_bus_name (struct hotplug_slot *hotplug_slot, char * value)
 {
 	int rc = -ENODEV;
 	struct slot *pslot = NULL;
-	struct pci_dev * dev = NULL;
 
-	debug ("get_card_bus_names - Entry hotplug_slot[%lx] \n", (ulong)hotplug_slot);
+	debug ("get_bus_name - Entry hotplug_slot[%lx] \n", (ulong)hotplug_slot);
 
 	ibmphp_lock_operations ();
 
@@ -503,40 +528,33 @@
 		pslot = (struct slot *) hotplug_slot->private;
 		if (pslot) {
 			rc = 0;
-			if (pslot->func)
-				dev = pslot->func->dev;
-			else
-                		dev = pci_find_slot (pslot->bus, (pslot->device << 3) | (0x00 & 0x7));
-			if (dev) 
-				snprintf (value, 100, "Bus %d : %s", pslot->bus,dev->name);
-			else
-				snprintf (value, 100, "Bus %d", pslot->bus);
-			
-				
+			snprintf (value, 100, "Bus %x", pslot->bus);
 		}
 	} else
 		rc = -ENODEV;
 
 	ibmphp_unlock_operations ();
-	debug ("get_card_bus_names - Exit rc[%d] value[%x]\n", rc, *value);
+	debug ("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
 	return rc;
 }
-
 */
+
 /*******************************************************************************
  * This routine will initialize the ops data structure used in the validate
  * function. It will also power off empty slots that are powered on since BIOS
  * leaves those on, albeit disconnected
  ******************************************************************************/
-static int init_ops (void)
+static int __init init_ops (void)
 {
 	struct slot *slot_cur;
+	struct list_head *tmp;
 	int retval;
-	int j;
 	int rc;
+	int j;
 
 	for (j = 0; j < MAX_OPS; j++) {
 		ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL);
+		memset (ops[j], 0, (max_slots + 1) * sizeof (int));
 		if (!ops[j]) {
 			err ("out of system memory \n");
 			return -ENOMEM;
@@ -547,12 +565,13 @@
 	ops[REMOVE][0] = 0;
 	ops[DETAIL][0] = 0;
 
-	for (j = 1; j <= max_slots; j++) {
+	list_for_each (tmp, &ibmphp_slot_head) {
+		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
 
-		slot_cur = ibmphp_get_slot_from_physical_num (j);
+		if (!slot_cur)
+			return -ENODEV;
 
 		debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number);
-
 		if (slot_cur->ctrl->revision == 0xFF) 
 			if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))
 				return -1;
@@ -572,21 +591,21 @@
 		debug ("status = %x, ext_status = %x\n", slot_cur->status, slot_cur->ext_status);
 		debug ("SLOT_POWER = %x, SLOT_PRESENT = %x, SLOT_LATCH = %x\n", SLOT_POWER (slot_cur->status), SLOT_PRESENT (slot_cur->status), SLOT_LATCH (slot_cur->status));
 
-		if (!(SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
+		if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
 			/* No power, adapter, and latch closed */
-			ops[ADD][j] = 1;
+			ops[ADD][slot_cur->number] = 1;
 		else
-			ops[ADD][j] = 0;
+			ops[ADD][slot_cur->number] = 0;
 
-		ops[DETAIL][j] = 1;
+		ops[DETAIL][slot_cur->number] = 1;
 
-		if ((SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
+		if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
 			/*Power,adapter,latch closed */
-			ops[REMOVE][j] = 1;
+			ops[REMOVE][slot_cur->number] = 1;
 		else
-			ops[REMOVE][j] = 0;
+			ops[REMOVE][slot_cur->number] = 0;
 
-		if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) {
+		if ((SLOT_PWRGD (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) {
 			debug ("BEFORE POWER OFF COMMAND\n");
 				rc = power_off (slot_cur);
 				if (rc)
@@ -624,7 +643,7 @@
 	if (retval)
 		return retval;
 
-	if (!(SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
+	if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
 	    && !(SLOT_LATCH (slot_cur->status)))
 		ops[ADD][number] = 1;
 	else
@@ -632,7 +651,7 @@
 
 	ops[DETAIL][number] = 1;
 
-	if ((SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
+	if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
 	    && !(SLOT_LATCH (slot_cur->status)))
 		ops[REMOVE][number] = 1;
 	else
@@ -678,7 +697,7 @@
 	}
         
 	snprintf (buffer, 10, "%d", slot_cur->number);
-	info->power_status = SLOT_POWER (slot_cur->status);
+	info->power_status = SLOT_PWRGD (slot_cur->status);
 	info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
 	info->latch_status = SLOT_LATCH (slot_cur->status);
         if (!SLOT_PRESENT (slot_cur->status)) {
@@ -688,8 +707,8 @@
                 info->adapter_status = 1;
 //		get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
 	}
-/*
-	bus_speed = slot_cur->bus_on->current_speed;
+	/* !!!!!!!!!TO DO: THIS NEEDS TO CHANGE!!!!!!!!!!!!! */
+/*	bus_speed = slot_cur->bus_on->current_speed;
 	bus_speed &= 0x0f;
                         
 	if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
@@ -701,7 +720,7 @@
 
 	info->cur_bus_speed_status = bus_speed;
 	info->max_bus_speed_status = slot_cur->hotplug_slot->info->max_bus_speed_status;
-	// To do: card_bus_names 
+	// To do: bus_names 
 */	
 	rc = pci_hp_change_slot_info (buffer, info);
 	kfree (info);
@@ -775,8 +794,10 @@
 	struct list_head * tmp;
 	struct list_head * next;
 
-	list_for_each_safe (tmp, next, &ibmphp_slot_head) {
+	debug ("%s -- enter\n", __FUNCTION__);
 
+	list_for_each_safe (tmp, next, &ibmphp_slot_head) {
+	
 		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
 
 		pci_hp_deregister (slot_cur->hotplug_slot);
@@ -795,7 +816,9 @@
 		ibmphp_unconfigure_card (&slot_cur, -1);  /* we don't want to actually remove the resources, since free_resources will do just that */
 
 		kfree (slot_cur);
+		slot_cur = NULL;
 	}
+	debug ("%s -- exit\n", __FUNCTION__);
 }
 
 static int ibm_is_pci_dev_in_use (struct pci_dev *dev)
@@ -851,7 +874,7 @@
 	if (temp_func)
 		temp_func->dev = NULL;
 	else
-		err ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
+		debug ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
 
 	return 0;
 }
@@ -893,12 +916,12 @@
 }
 
 static struct pci_visit ibm_unconfigure_functions_phase1 = {
-	post_visit_pci_dev:	ibm_unconfigure_visit_pci_dev_phase1,
+	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase1,
 };
 
 static struct pci_visit ibm_unconfigure_functions_phase2 = {
-	post_visit_pci_bus:	ibm_unconfigure_visit_pci_bus_phase2,
-	post_visit_pci_dev:	ibm_unconfigure_visit_pci_dev_phase2,
+	.post_visit_pci_bus =	ibm_unconfigure_visit_pci_bus_phase2,
+	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase2,
 };
 
 static int ibm_unconfigure_device (struct pci_func *func)
@@ -962,9 +985,37 @@
 }
 
 static struct pci_visit configure_functions = {
-	visit_pci_dev:	configure_visit_pci_dev,
+	.visit_pci_dev =configure_visit_pci_dev,
 };
 
+
+/*
+ * The following function is to fix kernel bug regarding 
+ * getting bus entries, here we manually add those primary 
+ * bus entries to kernel bus structure whenever apply
+ */
+
+static u8 bus_structure_fixup (u8 busno)
+{
+	struct pci_bus bus_t;
+	struct pci_dev dev_t;
+	u16 l;
+
+	if (!find_bus (busno) || !(ibmphp_find_same_bus_num (busno)))
+		return 1;
+	bus_t.number = busno;
+	bus_t.ops = ibmphp_pci_root_ops;
+	dev_t.bus = &bus_t;
+	for (dev_t.devfn=0; dev_t.devfn<256; dev_t.devfn += 8) {
+		if (!pci_read_config_word (&dev_t, PCI_VENDOR_ID, &l) &&  l != 0x0000 && l != 0xffff) {
+			debug ("%s - Inside bus_struture_fixup() \n", __FUNCTION__);
+			pci_scan_bus (busno, ibmphp_pci_root_ops, NULL);
+			break;
+		}
+	}
+	return 0;
+}
+
 static int ibm_configure_device (struct pci_func *func)
 {
 	unsigned char bus;
@@ -972,6 +1023,7 @@
 	struct pci_bus *child;
 	struct pci_dev *temp;
 	int rc = 0;
+	int flag = 0;	/* this is to make sure we don't double scan the bus, for bridged devices primarily */
 
 	struct pci_dev_wrapped wrapped_dev;
 	struct pci_bus_wrapped wrapped_bus;
@@ -980,6 +1032,8 @@
 	memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
 	memset (&dev0, 0, sizeof (struct pci_dev));
 
+	if (!(bus_structure_fixup (func->busno)))
+		flag = 1;
 	if (func->dev == NULL)
 		func->dev = pci_find_slot (func->busno, (func->device << 3) | (func->function & 0x7));
 
@@ -995,7 +1049,7 @@
 			return 0;
 		}
 	}
-	if (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+	if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
 		pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus);
 		child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);
 		pci_do_scan_bus (child);
@@ -1028,7 +1082,7 @@
 		rc = slot_update (&tmp_slot);
 		if (rc)
 			return 0;
-		if (SLOT_PRESENT (tmp_slot->status) && SLOT_POWER (tmp_slot->status))
+		if (SLOT_PRESENT (tmp_slot->status) && SLOT_PWRGD (tmp_slot->status))
 			return 0;
 		i++;
 	}
@@ -1046,6 +1100,9 @@
 	int rc;
 	u8 speed;
 	u8 cmd = 0x0;
+	const struct list_head *tmp;
+	struct pci_dev * dev;
+	int retval;
 
 	debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number);
 	if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
@@ -1091,6 +1148,14 @@
 				cmd = HPC_BUS_100PCIXMODE;
 				break;
 			case BUS_SPEED_133:
+				/* This is to take care of the bug in CIOBX chip*/
+				list_for_each (tmp, &pci_devices) {
+					dev = (struct pci_dev *) pci_dev_g (tmp);
+					if (dev) {
+						if ((dev->vendor == 0x1166) && (dev->device == 0x0101))
+							ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
+					}
+				}
 				cmd = HPC_BUS_133PCIXMODE;
 				break;
 			default:
@@ -1103,9 +1168,17 @@
 			return -ENODEV;
 		}
 		debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd);
-		ibmphp_hpc_writeslot (slot_cur, cmd);
+		retval = ibmphp_hpc_writeslot (slot_cur, cmd);
+		if (retval) {
+			err ("setting bus speed failed\n");
+			return retval;
+		}
+		if (CTLR_RESULT (slot_cur->ctrl->status)) {
+			err ("command not completed successfully in set_bus \n");
+			return -EIO;
+		}
 	}
-	/* This is for x400, once Brandon fixes the firmware, 
+	/* This is for x440, once Brandon fixes the firmware, 
 	will not need this delay */
 	long_delay (1 * HZ);
 	debug ("%s -Exit \n", __FUNCTION__);
@@ -1128,7 +1201,7 @@
 
 	for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
 		tmp_slot = ibmphp_get_slot_from_physical_num (i);
-		if ((SLOT_POWER (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) 
+		if ((SLOT_PWRGD (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) 
 			count++;
 	}
 	get_cur_bus_info (&slot_cur);
@@ -1384,11 +1457,15 @@
 
 	debug ("DISABLING SLOT... \n"); 
 		
-	if (slot_cur == NULL) 
+	if (slot_cur == NULL) {
+		ibmphp_unlock_operations (); 
 		return -ENODEV;
+	}
 	
-	if (slot_cur->ctrl == NULL) 
+	if (slot_cur->ctrl == NULL) {
+		ibmphp_unlock_operations ();
 		return -ENODEV;
+	}
 	
 	flag = slot_cur->flag;	/* to see if got here from polling */
 	
@@ -1463,7 +1540,8 @@
 			return -EFAULT;
 		}
 
-		ibmphp_update_slot_info (slot_cur);
+		if (flag)
+			ibmphp_update_slot_info (slot_cur);
 		ibmphp_unlock_operations ();
 		return -EFAULT;
 	}
@@ -1494,19 +1572,19 @@
 }
 
 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
-	owner:				THIS_MODULE,
-	set_attention_status:		set_attention_status,
-	enable_slot:			enable_slot,
-	disable_slot:			ibmphp_disable_slot,
-	hardware_test:			NULL,
-	get_power_status:		get_power_status,
-	get_attention_status:		get_attention_status,
-	get_latch_status:		get_latch_status,
-	get_adapter_status:		get_adapter_present,
-/*	get_max_bus_speed_status:	get_max_bus_speed,
-	get_max_adapter_speed_status:	get_max_adapter_speed,
-	get_cur_bus_speed_status:	get_cur_bus_speed,
-	get_card_bus_names_status:	get_card_bus_names,
+	.owner =			THIS_MODULE,
+	.set_attention_status =		set_attention_status,
+	.enable_slot =			enable_slot,
+	.disable_slot =			ibmphp_disable_slot,
+	.hardware_test =		NULL,
+	.get_power_status =		get_power_status,
+	.get_attention_status =		get_attention_status,
+	.get_latch_status =		get_latch_status,
+	.get_adapter_status =		get_adapter_present,
+	.get_max_bus_speed =		get_max_bus_speed,
+	.get_cur_bus_speed =		get_cur_bus_speed,
+/*	.get_max_adapter_speed =	get_max_adapter_speed,
+	.get_bus_name_status =		get_bus_name,
 */
 };
 
@@ -1559,6 +1637,11 @@
 	debug ("AFTER Resource & EBDA INITIALIZATIONS\n");
 
 	max_slots = get_max_slots ();
+	
+	if ((rc = ibmphp_register_pci ())) {
+		ibmphp_unload ();
+		return rc;
+	}
 
 	if (init_ops ()) {
 		ibmphp_unload ();
@@ -1570,11 +1653,9 @@
 		return -ENODEV;
 	}
 
-	/* lock ourselves into memory with a module count of -1 
-	 * so that no one can unload us. */
+	/* if no NVRAM module selected, lock ourselves into memory with a 
+	 * module count of -1 so that no one can unload us. */
 	MOD_DEC_USE_COUNT;
-
-
 	return 0;
 }
 
diff -urN linux-2.4.20-pre7/drivers/hotplug/ibmphp_ebda.c linux-2.4.20-pre8/drivers/hotplug/ibmphp_ebda.c
--- linux-2.4.20-pre7/drivers/hotplug/ibmphp_ebda.c	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/hotplug/ibmphp_ebda.c	Wed Sep 25 18:21:40 2002
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/list.h>
+#include <linux/init.h>
 #include "ibmphp.h"
 
 /*
@@ -55,11 +56,17 @@
 /* Local variables */
 static struct ebda_hpc_list *hpc_list_ptr;
 static struct ebda_rsrc_list *rsrc_list_ptr;
-static struct rio_table_hdr *rio_table_ptr;
+static struct rio_table_hdr *rio_table_ptr = NULL;
 static LIST_HEAD (ebda_hpc_head);
 static LIST_HEAD (bus_info_head);
+static LIST_HEAD (rio_vg_head);
+static LIST_HEAD (rio_lo_head);
+static LIST_HEAD (opt_vg_head);
+static LIST_HEAD (opt_lo_head);
 static void *io_mem;
 
+char *chassis_str, *rxe_str, *str;
+
 /* Local functions */
 static int ebda_rsrc_controller (void);
 static int ebda_rsrc_rsrc (void);
@@ -76,7 +83,7 @@
 	return slot;
 }
 
-static struct ebda_hpc_list *alloc_ebda_hpc_list (void)
+static struct ebda_hpc_list * __init alloc_ebda_hpc_list (void)
 {
 	struct ebda_hpc_list *list;
 
@@ -124,10 +131,11 @@
 	controller->slots = NULL;
 	kfree (controller->buses);
 	controller->buses = NULL;
+	controller->ctrl_dev = NULL;
 	kfree (controller);
 }
 
-static struct ebda_rsrc_list *alloc_ebda_rsrc_list (void)
+static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list (void)
 {
 	struct ebda_rsrc_list *list;
 
@@ -149,7 +157,7 @@
 	return resource;
 }
 
-static void print_bus_info (void)
+static void __init print_bus_info (void)
 {
 	struct bus_info *ptr;
 	struct list_head *ptr1;
@@ -172,19 +180,78 @@
 	}
 }
 
-static void print_ebda_pci_rsrc (void)
+static void print_lo_info (void)
+{
+	struct rio_detail *ptr;
+	struct list_head *ptr1;
+	debug ("print_lo_info ---- \n");	
+	list_for_each (ptr1, &rio_lo_head) {
+		ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
+		debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
+		debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
+		debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
+		debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
+		debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
+		debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
+
+	}
+}
+
+static void print_vg_info (void)
+{
+	struct rio_detail *ptr;
+	struct list_head *ptr1;
+	debug ("%s --- \n", __FUNCTION__);
+	list_for_each (ptr1, &rio_vg_head) {
+		ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
+		debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
+		debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
+		debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
+		debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
+		debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
+		debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
+
+	}
+}
+
+static void __init print_ebda_pci_rsrc (void)
 {
 	struct ebda_pci_rsrc *ptr;
 	struct list_head *ptr1;
 
 	list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
 		ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
-		debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", 
+		debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", 
 			__FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
 	}
 }
 
-static void print_ebda_hpc (void)
+static void __init print_ibm_slot (void)
+{
+	struct slot *ptr;
+	struct list_head *ptr1;
+
+	list_for_each (ptr1, &ibmphp_slot_head) {
+		ptr = list_entry (ptr1, struct slot, ibm_slot_list);
+		debug ("%s - slot_number: %x \n", __FUNCTION__, ptr->number); 
+	}
+}
+
+static void __init print_opt_vg (void)
+{
+	struct opt_rio *ptr;
+	struct list_head *ptr1;
+	debug ("%s --- \n", __FUNCTION__);
+	list_for_each (ptr1, &opt_vg_head) {
+		ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
+		debug ("%s - rio_type %x \n", __FUNCTION__, ptr->rio_type); 
+		debug ("%s - chassis_num: %x \n", __FUNCTION__, ptr->chassis_num); 
+		debug ("%s - first_slot_num: %x \n", __FUNCTION__, ptr->first_slot_num); 
+		debug ("%s - middle_num: %x \n", __FUNCTION__, ptr->middle_num); 
+	}
+}
+
+static void __init print_ebda_hpc (void)
 {
 	struct controller *hpc_ptr;
 	struct list_head *ptr1;
@@ -220,6 +287,7 @@
 			break;
 
 		case 2:
+		case 4:
 			debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
 			debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
 			debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
@@ -228,7 +296,7 @@
 	}
 }
 
-int ibmphp_access_ebda (void)
+int __init ibmphp_access_ebda (void)
 {
 	u8 format, num_ctlrs, rio_complete, hs_complete;
 	u16 ebda_seg, num_entries, next_offset, offset, blk_id, sub_addr, rc, re, rc_id, re_id, base;
@@ -356,38 +424,389 @@
 
 			rio_complete = 1;
 		}
+	}
 
-		if (hs_complete && rio_complete) {
-			rc = ebda_rsrc_controller ();
-			if (rc) {
-				iounmap(io_mem);
-				return rc;
-			}
-			rc = ebda_rsrc_rsrc ();
-			if (rc) {
-				iounmap(io_mem);
-				return rc;
-			}
+	if (!hs_complete && !rio_complete) {
+		iounmap (io_mem);
+		return -ENODEV;
+	}
+
+	if (rio_table_ptr) {
+		if (rio_complete == 1 && rio_table_ptr->ver_num == 3) {
 			rc = ebda_rio_table ();
 			if (rc) {
-				iounmap(io_mem);
+				iounmap (io_mem);
 				return rc;
-			}	
-			iounmap (io_mem);
-			return 0;
+			}
 		}
 	}
+	rc = ebda_rsrc_controller ();
+	if (rc) {
+		iounmap (io_mem);
+		return rc;
+	}
+
+	rc = ebda_rsrc_rsrc ();
+	if (rc) {
+		iounmap (io_mem);
+		return rc;
+	}
+
 	iounmap (io_mem);
-	return -ENODEV;
+	return 0;
+}
+
+/*
+ * map info of scalability details and rio details from physical address
+ */
+static int __init ebda_rio_table (void)
+{
+	u16 offset;
+	u8 i;
+	struct rio_detail *rio_detail_ptr;
+
+	offset = rio_table_ptr->offset;
+	offset += 12 * rio_table_ptr->scal_count;
+
+	// we do concern about rio details
+	for (i = 0; i < rio_table_ptr->riodev_count; i++) {
+		rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL);
+		if (!rio_detail_ptr)
+			return -ENOMEM;
+		memset (rio_detail_ptr, 0, sizeof (struct rio_detail));
+		rio_detail_ptr->rio_node_id = readb (io_mem + offset);
+		rio_detail_ptr->bbar = readl (io_mem + offset + 1);
+		rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
+		rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
+		rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
+		rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
+		rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
+		rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
+		rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
+		rio_detail_ptr->status = readb (io_mem + offset + 12);
+		rio_detail_ptr->wpindex = readb (io_mem + offset + 13);
+		rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);
+//		debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
+		//create linked list of chassis
+		if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5) 
+			list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head);
+		//create linked list of expansion box				
+		else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7) 
+			list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head);
+		else 
+			// not in my concern
+			kfree (rio_detail_ptr);
+		offset += 15;
+	}
+	print_lo_info ();
+	print_vg_info ();
+	return 0;
+}
+
+/*
+ * reorganizing linked list of chassis	 
+ */
+static struct opt_rio *search_opt_vg (u8 chassis_num)
+{
+	struct opt_rio *ptr;
+	struct list_head *ptr1;
+	list_for_each (ptr1, &opt_vg_head) {
+		ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
+		if (ptr->chassis_num == chassis_num)
+			return ptr;
+	}		
+	return NULL;
+}
+
+static int __init combine_wpg_for_chassis (void)
+{
+	struct opt_rio *opt_rio_ptr = NULL;
+	struct rio_detail *rio_detail_ptr = NULL;
+	struct list_head *list_head_ptr = NULL;
+	
+	list_for_each (list_head_ptr, &rio_vg_head) {
+		rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
+		opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
+		if (!opt_rio_ptr) {
+			opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL);
+			if (!opt_rio_ptr)
+				return -ENOMEM;
+			memset (opt_rio_ptr, 0, sizeof (struct opt_rio));
+			opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
+			opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
+			opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
+			opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;
+			list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head);
+		} else {	
+			opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
+			opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
+		}	
+	}
+	print_opt_vg ();
+	return 0;	
+}	
+
+/*
+ * reorgnizing linked list of expansion box	 
+ */
+static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
+{
+	struct opt_rio_lo *ptr;
+	struct list_head *ptr1;
+	list_for_each (ptr1, &opt_lo_head) {
+		ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
+		if (ptr->chassis_num == chassis_num)
+			return ptr;
+	}		
+	return NULL;
+}
+
+static int combine_wpg_for_expansion (void)
+{
+	struct opt_rio_lo *opt_rio_lo_ptr = NULL;
+	struct rio_detail *rio_detail_ptr = NULL;
+	struct list_head *list_head_ptr = NULL;
+	
+	list_for_each (list_head_ptr, &rio_lo_head) {
+		rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
+		opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
+		if (!opt_rio_lo_ptr) {
+			opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL);
+			if (!opt_rio_lo_ptr)
+				return -ENOMEM;
+			memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo));
+			opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
+			opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
+			opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
+			opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;
+			opt_rio_lo_ptr->pack_count = 1;
+			
+			list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
+		} else {	
+			opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
+			opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
+			opt_rio_lo_ptr->pack_count = 2;
+		}	
+	}
+	return 0;	
+}
+	
+static char *convert_2digits_to_char (int var)
+{
+	int bit;	
+	char *str1;
+
+	str = (char *) kmalloc (3, GFP_KERNEL);
+	memset (str, 0, 3);
+	str1 = (char *) kmalloc (2, GFP_KERNEL);
+	memset (str, 0, 3);
+	bit = (int)(var / 10);
+	switch (bit) {
+	case 0:
+		//one digit number
+		*str = (char)(var + 48);
+		return str;
+	default: 	
+		//2 digits number
+		*str1 = (char)(bit + 48);
+		strncpy (str, str1, 1);
+		memset (str1, 0, 3);
+		*str1 = (char)((var % 10) + 48);
+		strcat (str, str1);
+		return str;
+	}	
+	return NULL;	
+}
+
+/* Since we don't know the max slot number per each chassis, hence go
+ * through the list of all chassis to find out the range
+ * Arguments: slot_num, 1st slot number of the chassis we think we are on, 
+ * var (0 = chassis, 1 = expansion box) 
+ */
+static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
+{
+	struct opt_rio *opt_vg_ptr = NULL;
+	struct opt_rio_lo *opt_lo_ptr = NULL;
+	struct list_head *ptr = NULL;
+	int rc = 0;
+
+	if (!var) {
+		list_for_each (ptr, &opt_vg_head) {
+			opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
+			if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) { 
+				rc = -ENODEV;
+				break;
+			}
+		}
+	} else {
+		list_for_each (ptr, &opt_lo_head) {
+			opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
+			if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
+				rc = -ENODEV;
+				break;
+			}
+		}
+	}
+	return rc;
+}
+
+static struct opt_rio_lo * find_rxe_num (u8 slot_num)
+{
+	struct opt_rio_lo *opt_lo_ptr;
+	struct list_head *ptr;
+
+	list_for_each (ptr, &opt_lo_head) {
+		opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
+		//check to see if this slot_num belongs to expansion box
+		if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1))) 
+			return opt_lo_ptr;
+	}
+	return NULL;
+}
+
+static struct opt_rio * find_chassis_num (u8 slot_num)
+{
+	struct opt_rio *opt_vg_ptr;
+	struct list_head *ptr;
+
+	list_for_each (ptr, &opt_vg_head) {
+		opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
+		//check to see if this slot_num belongs to chassis 
+		if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0))) 
+			return opt_vg_ptr;
+	}
+	return NULL;
+}
+
+/* This routine will find out how many slots are in the chassis, so that
+ * the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc
+ */
+static u8 calculate_first_slot (u8 slot_num)
+{
+	u8 first_slot = 1;
+	struct list_head * list;
+	struct slot * slot_cur;
+	
+	list_for_each (list, &ibmphp_slot_head) {
+		slot_cur = list_entry (list, struct slot, ibm_slot_list);
+		if (slot_cur->ctrl) {
+			if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num)) 
+				first_slot = slot_cur->ctrl->ending_slot_num;
+		}
+	}			
+	return first_slot + 1;
+
+}
+static char *create_file_name (struct slot * slot_cur)
+{
+	struct opt_rio *opt_vg_ptr = NULL;
+	struct opt_rio_lo *opt_lo_ptr = NULL;
+	char *ptr_chassis_num, *ptr_rxe_num, *ptr_slot_num;
+	int which = 0; /* rxe = 1, chassis = 0 */
+	u8 number = 1; /* either chassis or rxe # */
+	u8 first_slot = 1;
+	u8 slot_num;
+	u8 flag = 0;
+
+	if (!slot_cur) {
+		err ("Structure passed is empty \n");
+		return NULL;
+	}
+	
+	slot_num = slot_cur->number;
+
+	chassis_str = (char *) kmalloc (30, GFP_KERNEL);
+	memset (chassis_str, 0, 30);
+	rxe_str = (char *) kmalloc (30, GFP_KERNEL);
+	memset (rxe_str, 0, 30);
+	ptr_chassis_num = (char *) kmalloc (3, GFP_KERNEL);
+	memset (ptr_chassis_num, 0, 3);
+	ptr_rxe_num = (char *) kmalloc (3, GFP_KERNEL);
+	memset (ptr_rxe_num, 0, 3);
+	ptr_slot_num = (char *) kmalloc (3, GFP_KERNEL);
+	memset (ptr_slot_num, 0, 3);
+	
+	strcpy (chassis_str, "chassis");
+	strcpy (rxe_str, "rxe");
+	
+	if (rio_table_ptr) {
+		if (rio_table_ptr->ver_num == 3) {
+			opt_vg_ptr = find_chassis_num (slot_num);
+			opt_lo_ptr = find_rxe_num (slot_num);
+		}
+	}
+	if (opt_vg_ptr) {
+		if (opt_lo_ptr) {
+			if ((slot_num - opt_vg_ptr->first_slot_num) > (slot_num - opt_lo_ptr->first_slot_num)) {
+				number = opt_lo_ptr->chassis_num;
+				first_slot = opt_lo_ptr->first_slot_num;
+				which = 1; /* it is RXE */
+			} else {
+				first_slot = opt_vg_ptr->first_slot_num;
+				number = opt_vg_ptr->chassis_num;
+				which = 0;
+			}
+		} else {
+			first_slot = opt_vg_ptr->first_slot_num;
+			number = opt_vg_ptr->chassis_num;
+			which = 0;
+		}
+		++flag;
+	} else if (opt_lo_ptr) {
+		number = opt_lo_ptr->chassis_num;
+		first_slot = opt_lo_ptr->first_slot_num;
+		which = 1;
+		++flag;
+	} else if (rio_table_ptr) {
+		if (rio_table_ptr->ver_num == 3) {
+			/* if both NULL and we DO have correct RIO table in BIOS */
+			return NULL;
+		}
+	} 
+	if (!flag) {
+		if (slot_cur->ctrl->ctlr_type == 4) {
+			first_slot = calculate_first_slot (slot_num);
+			which = 1;
+		} else {
+			which = 0;
+		}
+	}
+
+	switch (which) {
+	case 0:
+		/* Chassis */
+		*ptr_chassis_num = (char)(number + 48);
+		strcat (chassis_str, ptr_chassis_num);
+		kfree (ptr_chassis_num);
+		strcat (chassis_str, "slot");
+		ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1);
+		strcat (chassis_str, ptr_slot_num);
+		kfree (ptr_slot_num);
+		return chassis_str;
+		break;
+	case 1:
+		/* RXE */
+		*ptr_rxe_num = (char)(number + 48);
+		strcat (rxe_str, ptr_rxe_num);
+		kfree (ptr_rxe_num);
+		strcat (rxe_str, "slot");
+		ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1);
+		strcat (rxe_str, ptr_slot_num);
+		kfree (ptr_slot_num);
+		return rxe_str;
+		break;
+	}	
+	return NULL;
 }
 
+static struct pci_driver ibmphp_driver;
 
 /*
  * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
  * each hpc from physical address to a list of hot plug controllers based on
  * hpc descriptors.
  */
-static int ebda_rsrc_controller (void)
+static int __init ebda_rsrc_controller (void)
 {
 	u16 addr, addr_slot, addr_bus;
 	u8 ctlr_id, temp, bus_index;
@@ -399,6 +818,9 @@
 	struct ebda_hpc_slot *slot_ptr;
 	struct bus_info *bus_info_ptr1, *bus_info_ptr2;
 	int rc;
+	int retval;
+	struct slot *slot_cur;
+	struct list_head *list;
 
 	addr = hpc_list_ptr->phys_addr;
 	for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
@@ -509,23 +931,22 @@
 				hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr);
 				hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
 				hpc_ptr->irq = readb (io_mem + addr + 2);
-				addr += 3; 
+				addr += 3;
+				debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", hpc_ptr->u.pci_ctlr.bus, hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
 				break;
 
 			case 0:
 				hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
 				hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
+				retval = check_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1));
+				if (retval)
+					return -ENODEV;
+				request_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1), "ibmphp");
 				hpc_ptr->irq = readb (io_mem + addr + 4);
 				addr += 5;
 				break;
 
 			case 2:
-				hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
-				hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
-
-				hpc_ptr->irq = readb (io_mem + addr + 5);
-				addr += 6;
-				break;
 			case 4:
 				hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
 				hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
@@ -536,12 +957,10 @@
 				iounmap (io_mem);
 				return -ENODEV;
 		}
-		/* following 3 line: Now our driver only supports I2c ctlrType */
-		if ((hpc_ptr->ctlr_type != 2) && (hpc_ptr->ctlr_type != 4)) {
-			err ("Please run this driver on ibm xseries440\n ");
-			return -ENODEV;
-		}
 
+		//reorganize chassis' linked list
+		combine_wpg_for_chassis ();
+		combine_wpg_for_expansion ();
 		hpc_ptr->revision = 0xff;
 		hpc_ptr->options = 0xff;
 		hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
@@ -565,7 +984,7 @@
 			}
 			memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info));
 
-			hp_slot_ptr->name = (char *) kmalloc (10, GFP_KERNEL);
+			hp_slot_ptr->name = (char *) kmalloc (30, GFP_KERNEL);
 			if (!hp_slot_ptr->name) {
 				iounmap (io_mem);
 				kfree (hp_slot_ptr->info);
@@ -582,9 +1001,7 @@
 				return -ENOMEM;
 			}
 
-
 			((struct slot *)hp_slot_ptr->private)->flag = TRUE;
-			snprintf (hp_slot_ptr->name, 10, "%d", hpc_ptr->slots[index].slot_num);
 
 			((struct slot *) hp_slot_ptr->private)->capabilities = hpc_ptr->slots[index].slot_cap;
 			if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
@@ -616,7 +1033,6 @@
 			((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num;
 			
 			((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr;
-
 			rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr);
 			if (rc) {
 				iounmap (io_mem);
@@ -630,8 +1046,6 @@
 			}
 			hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
 
-			pci_hp_register (hp_slot_ptr);
-
 			// end of registering ibm slot with hotplug core
 
 			list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
@@ -641,7 +1055,20 @@
 		list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
 
 	}			/* each hpc  */
+
+	list_for_each (list, &ibmphp_slot_head) {
+		slot_cur = list_entry (list, struct slot, ibm_slot_list);
+
+		snprintf (slot_cur->hotplug_slot->name, 30, "%s", create_file_name (slot_cur));
+		if (chassis_str) 
+			kfree (chassis_str);
+		if (rxe_str)
+			kfree (rxe_str);
+		pci_hp_register (slot_cur->hotplug_slot);
+	}
+
 	print_ebda_hpc ();
+	print_ibm_slot ();
 	return 0;
 }
 
@@ -649,7 +1076,7 @@
  * map info (bus, devfun, start addr, end addr..) of i/o, memory,
  * pfm from the physical addr to a list of resource.
  */
-static int ebda_rsrc_rsrc (void)
+static int __init ebda_rsrc_rsrc (void)
 {
 	u16 addr;
 	short rsrc;
@@ -681,7 +1108,7 @@
 			addr += 6;
 
 			debug ("rsrc from io type ----\n");
-			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n",
+			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
 				rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
 
 			list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
@@ -702,7 +1129,7 @@
 			addr += 10;
 
 			debug ("rsrc from mem or pfm ---\n");
-			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", 
+			debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", 
 				rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
 
 			list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
@@ -714,56 +1141,6 @@
 	return 0;
 }
 
-/*
- * map info of scalability details and rio details from physical address
- */
-static int ebda_rio_table(void)
-{
-	u16 offset;
-	u8 i;
-	struct scal_detail *scal_detail_ptr;
-	struct rio_detail *rio_detail_ptr;
-
-	offset = rio_table_ptr->offset;
-	for (i = 0; i < rio_table_ptr->scal_count; i++) {
-		
-		scal_detail_ptr = kmalloc (sizeof (struct scal_detail), GFP_KERNEL );
-		if (!scal_detail_ptr )
-			return -ENOMEM;
-		memset (scal_detail_ptr, 0, sizeof (struct scal_detail) );
-		scal_detail_ptr->node_id = readb (io_mem + offset);
-		scal_detail_ptr->cbar = readl (io_mem+ offset + 1);
-		scal_detail_ptr->port0_node_connect = readb (io_mem + 5);
-		scal_detail_ptr->port0_port_connect = readb (io_mem + 6);
-		scal_detail_ptr->port1_node_connect = readb (io_mem + 7);
-		scal_detail_ptr->port1_port_connect = readb (io_mem + 8);
-		scal_detail_ptr->port2_node_connect = readb (io_mem + 9);
-		scal_detail_ptr->port2_port_connect = readb (io_mem + 10);
-		debug ("node_id: %x\ncbar: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nport2_node: %x\nport2_port: %x\n", scal_detail_ptr->node_id, scal_detail_ptr->cbar, scal_detail_ptr->port0_node_connect, scal_detail_ptr->port0_port_connect, scal_detail_ptr->port1_node_connect, scal_detail_ptr->port1_port_connect, scal_detail_ptr->port2_node_connect, scal_detail_ptr->port2_port_connect);
-//		list_add (&scal_detail_ptr->scal_detail_list, &scal_detail_head);
-		offset += 11;
-	}
-	for (i=0; i < rio_table_ptr->riodev_count; i++) {
-		rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL );
-		if (!rio_detail_ptr )
-			return -ENOMEM;
-		memset (rio_detail_ptr, 0, sizeof (struct rio_detail) );
-		rio_detail_ptr->rio_node_id = readb (io_mem + offset );
-		rio_detail_ptr->bbar = readl (io_mem + offset + 1);
-		rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
-		rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
-		rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
-		rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
-		rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
-		rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
-		rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
-		rio_detail_ptr->status = readb (io_mem + offset + 12);
-		debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
-		offset += 13;
-	}
-	return 0;
-}
-
 u16 ibmphp_get_total_controllers (void)
 {
 	return hpc_list_ptr->num_ctlrs;
@@ -829,32 +1206,21 @@
 	}
 }
 
-/*
- * Calculate the total hot pluggable slots controlled by total hpcs
- */
-/*
-int ibmphp_get_total_hp_slots (void)
-{
-	struct ebda_hpc *ptr;
-	int slot_num = 0;
-
-	ptr = ebda_hpc_head;
-	while (ptr != NULL) {
-		slot_num += ptr->slot_count;
-		ptr = ptr->next;
-	}
-	return slot_num;
-}
-*/
-
 void ibmphp_free_ebda_hpc_queue (void)
 {
-	struct controller *controller;
+	struct controller *controller = NULL;
 	struct list_head *list;
 	struct list_head *next;
+	int pci_flag = 0;
 
 	list_for_each_safe (list, next, &ebda_hpc_head) {
 		controller = list_entry (list, struct controller, ebda_hpc_list);
+		if (controller->ctlr_type == 0)
+			release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
+		else if ((controller->ctlr_type == 1) && (!pci_flag)) {
+			++pci_flag;
+			pci_unregister_driver (&ibmphp_driver);
+		}
 		free_ebda_hpc (controller);
 	}
 }
@@ -872,3 +1238,58 @@
 	}
 }
 
+static struct pci_device_id id_table[] __devinitdata = {
+	{
+		vendor:		PCI_VENDOR_ID_IBM,
+		device:		HPC_DEVICE_ID,
+		subvendor:	PCI_VENDOR_ID_IBM,
+		subdevice:	HPC_SUBSYSTEM_ID,
+		class:		((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
+	}, {}
+};		
+
+MODULE_DEVICE_TABLE(pci, id_table);
+
+static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);
+static struct pci_driver ibmphp_driver = {
+	name:		"ibmphp",
+	id_table:	id_table,
+	probe:		ibmphp_probe,
+};
+
+int ibmphp_register_pci (void)
+{
+	struct controller *ctrl;
+	struct list_head *tmp;
+	int rc = 0;
+
+	list_for_each (tmp, &ebda_hpc_head) {
+		ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
+		if (ctrl->ctlr_type == 1) {
+			rc = pci_module_init (&ibmphp_driver);
+			break;
+		}
+	}
+	return rc;
+}
+static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
+{
+	struct controller *ctrl;
+	struct list_head *tmp;
+
+	debug ("inside ibmphp_probe \n");
+	
+	list_for_each (tmp, &ebda_hpc_head) {
+		ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
+		if (ctrl->ctlr_type == 1) {
+			if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
+				ctrl->ctrl_dev = dev;
+				debug ("found device!!! \n");
+				debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
+				return 0;
+			}
+		}
+	}
+	return -ENODEV;
+}
+
diff -urN linux-2.4.20-pre7/drivers/hotplug/ibmphp_hpc.c linux-2.4.20-pre8/drivers/hotplug/ibmphp_hpc.c
--- linux-2.4.20-pre7/drivers/hotplug/ibmphp_hpc.c	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/hotplug/ibmphp_hpc.c	Wed Sep 25 18:21:40 2002
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/smp_lock.h>
+#include <linux/init.h>
 #include "ibmphp.h"
 
 static int to_debug = FALSE;
@@ -106,8 +107,8 @@
 //----------------------------------------------------------------------------
 // local function prototypes
 //----------------------------------------------------------------------------
-static u8 ctrl_read (struct controller *, void *, u8);
-static u8 ctrl_write (struct controller *, void *, u8, u8);
+static u8 i2c_ctrl_read (struct controller *, void *, u8);
+static u8 i2c_ctrl_write (struct controller *, void *, u8, u8);
 static u8 hpc_writecmdtoindex (u8, u8);
 static u8 hpc_readcmdtoindex (u8, u8);
 static void get_hpc_access (void);
@@ -126,7 +127,7 @@
 *
 * Action:  initialize semaphores and variables
 *---------------------------------------------------------------------*/
-void ibmphp_hpc_initvars (void)
+void __init ibmphp_hpc_initvars (void)
 {
 	debug ("%s - Entry\n", __FUNCTION__);
 
@@ -141,12 +142,12 @@
 }
 
 /*----------------------------------------------------------------------
-* Name:    ctrl_read
+* Name:    i2c_ctrl_read
 *
 * Action:  read from HPC over I2C
 *
 *---------------------------------------------------------------------*/
-static u8 ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
+static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
 {
 	u8 status;
 	int i;
@@ -248,13 +249,13 @@
 }
 
 /*----------------------------------------------------------------------
-* Name:    ctrl_write
+* Name:    i2c_ctrl_write
 *
 * Action:  write to HPC over I2C
 *
 * Return   0 or error codes
 *---------------------------------------------------------------------*/
-static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
+static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
 {
 	u8 rc;
 	void *wpg_addr;		// base addr + offset
@@ -350,6 +351,93 @@
 	return (rc);
 }
 
+//------------------------------------------------------------
+//  Read from ISA type HPC 
+//------------------------------------------------------------
+static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
+{
+	u16 start_address;
+	u16 end_address;
+	u8 data;
+
+	start_address = ctlr_ptr->u.isa_ctlr.io_start;
+	end_address = ctlr_ptr->u.isa_ctlr.io_end;
+	data = inb (start_address + offset);
+	return data;
+}
+
+//--------------------------------------------------------------
+// Write to ISA type HPC
+//--------------------------------------------------------------
+static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)
+{
+	u16 start_address;
+	u16 port_address;
+	
+	start_address = ctlr_ptr->u.isa_ctlr.io_start;
+	port_address = start_address + (u16) offset;
+	outb (data, port_address);
+}
+
+static u8 pci_ctrl_read (struct controller *ctrl, u8 offset)
+{
+	u8 data = 0x00;
+	debug ("inside pci_ctrl_read\n");
+	if (ctrl->ctrl_dev)
+		pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
+	return data;
+}
+
+static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data)
+{
+	u8 rc = -ENODEV;
+	debug ("inside pci_ctrl_write\n");
+	if (ctrl->ctrl_dev) {
+		pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
+		rc = 0;
+	}
+	return rc;
+}
+
+static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset)
+{
+	u8 rc;
+	switch (ctlr->ctlr_type) {
+	case 0:
+		rc = isa_ctrl_read (ctlr, offset);
+		break;
+	case 1:
+		rc = pci_ctrl_read (ctlr, offset);
+		break;
+	case 2:
+	case 4:
+		rc = i2c_ctrl_read (ctlr, base, offset);
+		break;
+	default:
+		return -ENODEV;
+	}
+	return rc;
+}
+
+static u8 ctrl_write (struct controller *ctlr, void *base, u8 offset, u8 data)
+{
+	u8 rc = 0;
+	switch (ctlr->ctlr_type) {
+	case 0:
+		isa_ctrl_write(ctlr, offset, data);
+		break;
+	case 1:
+		rc = pci_ctrl_write (ctlr, offset, data);
+		break;
+	case 2:
+	case 4:
+		rc = i2c_ctrl_write(ctlr, base, offset, data);
+		break;
+	default:
+		return -ENODEV;
+	}
+	return rc;
+}
 /*----------------------------------------------------------------------
 * Name:    hpc_writecmdtoindex()
 *
@@ -448,7 +536,7 @@
 *---------------------------------------------------------------------*/
 int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
 {
-	void *wpg_bbar;
+	void *wpg_bbar = NULL;
 	struct controller *ctlr_ptr;
 	struct list_head *pslotlist;
 	u8 index, status;
@@ -490,7 +578,8 @@
 	//--------------------------------------------------------------------
 	// map physical address to logical address
 	//--------------------------------------------------------------------
-	wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
+		wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 
 	//--------------------------------------------------------------------
 	// check controller status before reading
@@ -568,7 +657,11 @@
 	//--------------------------------------------------------------------
 	// cleanup
 	//--------------------------------------------------------------------
-	iounmap (wpg_bbar);	// remove physical to logical address mapping
+	
+	// remove physical to logical address mapping
+	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
+		iounmap (wpg_bbar);	
+	
 	free_hpc_access ();
 
 	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
@@ -582,7 +675,7 @@
 *---------------------------------------------------------------------*/
 int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
 {
-	void *wpg_bbar;
+	void *wpg_bbar = NULL;
 	struct controller *ctlr_ptr;
 	u8 index, status;
 	int busindex;
@@ -625,12 +718,13 @@
 	//--------------------------------------------------------------------
 	// map physical address to logical address
 	//--------------------------------------------------------------------
-	wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
+	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
+		wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 
-	debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
+		debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
 		ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
 		ctlr_ptr->u.wpeg_ctlr.i2c_addr);
-
+	}
 	//--------------------------------------------------------------------
 	// check controller status before writing
 	//--------------------------------------------------------------------
@@ -667,7 +761,10 @@
 		ctlr_ptr->status = status;
 	}
 	// cleanup
-	iounmap (wpg_bbar);	// remove physical to logical address mapping
+
+	// remove physical to logical address mapping
+	if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
+		iounmap (wpg_bbar);	
 	free_hpc_access ();
 
 	debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
@@ -700,6 +797,7 @@
 void ibmphp_lock_operations (void)
 {
 	down (&semOperations);
+	to_debug = TRUE;
 }
 
 /*----------------------------------------------------------------------
@@ -709,6 +807,7 @@
 {
 	debug ("%s - Entry\n", __FUNCTION__);
 	up (&semOperations);
+	to_debug = FALSE;
 	debug ("%s - Exit\n", __FUNCTION__);
 }
 
@@ -733,82 +832,86 @@
 	debug ("%s - Entry\n", __FUNCTION__);
 
 	while (!ibmphp_shutdown) {
+		if (ibmphp_shutdown) 
+			break;
+		
 		/* try to get the lock to do some kind of harware access */
 		down (&semOperations);
 
 		switch (poll_state) {
-			case POLL_LATCH_REGISTER:
-				oldlatchlow = curlatchlow;
-				ctrl_count = 0x00;
-				list_for_each (pslotlist, &ibmphp_slot_head) {
-					if (ctrl_count >= ibmphp_get_total_controllers())
-						break;
-					pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
-					if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
-						ctrl_count++;
-						if (READ_SLOT_LATCH (pslot->ctrl)) {
-							rc = ibmphp_hpc_readslot (pslot,
-										  READ_SLOTLATCHLOWREG,
-										  &curlatchlow);
-							if (oldlatchlow != curlatchlow)
-								process_changeinlatch (oldlatchlow,
-										       curlatchlow,
-										       pslot->ctrl);
-						}
+		case POLL_LATCH_REGISTER: 
+			oldlatchlow = curlatchlow;
+			ctrl_count = 0x00;
+			list_for_each (pslotlist, &ibmphp_slot_head) {
+				if (ctrl_count >= ibmphp_get_total_controllers())
+					break;
+				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+					ctrl_count++;
+					if (READ_SLOT_LATCH (pslot->ctrl)) {
+						rc = ibmphp_hpc_readslot (pslot,
+									  READ_SLOTLATCHLOWREG,
+									  &curlatchlow);
+						if (oldlatchlow != curlatchlow)
+							process_changeinlatch (oldlatchlow,
+									       curlatchlow,
+									       pslot->ctrl);
 					}
 				}
-				poll_state = POLL_SLOTS;
-				break;
-
-			case POLL_SLOTS:
-				list_for_each (pslotlist, &ibmphp_slot_head) {
-					pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
-					// make a copy of the old status
-					memcpy ((void *) &myslot, (void *) pslot,
-						sizeof (struct slot));
-					rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
-					if ((myslot.status != pslot->status)
-					    || (myslot.ext_status != pslot->ext_status))
-						process_changeinstatus (pslot, &myslot);
+			}
+			++poll_count;
+			poll_state = POLL_SLEEP;
+			break;
+		case POLL_SLOTS:
+			list_for_each (pslotlist, &ibmphp_slot_head) {
+				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+				// make a copy of the old status
+				memcpy ((void *) &myslot, (void *) pslot,
+					sizeof (struct slot));
+				rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
+				if ((myslot.status != pslot->status)
+				    || (myslot.ext_status != pslot->ext_status))
+					process_changeinstatus (pslot, &myslot);
+			}
+			ctrl_count = 0x00;
+			list_for_each (pslotlist, &ibmphp_slot_head) {
+				if (ctrl_count >= ibmphp_get_total_controllers())
+					break;
+				pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+				if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+					ctrl_count++;
+					if (READ_SLOT_LATCH (pslot->ctrl))
+						rc = ibmphp_hpc_readslot (pslot,
+									  READ_SLOTLATCHLOWREG,
+									  &curlatchlow);
 				}
+			}
+			++poll_count;
+			poll_state = POLL_SLEEP;
+			break;
+		case POLL_SLEEP:
+			/* don't sleep with a lock on the hardware */
+			up (&semOperations);
+			long_delay (POLL_INTERVAL_SEC * HZ);
 
-				ctrl_count = 0x00;
-				list_for_each (pslotlist, &ibmphp_slot_head) {
-					if (ctrl_count >= ibmphp_get_total_controllers())
-						break;
-					pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
-					if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
-						ctrl_count++;
-						if (READ_SLOT_LATCH (pslot->ctrl))
-							rc = ibmphp_hpc_readslot (pslot,
-										  READ_SLOTLATCHLOWREG,
-										  &curlatchlow);
-					}
-				}
-				++poll_count;
-				if (poll_count >= POLL_LATCH_CNT) {
-					poll_count = 0;
-					poll_state = POLL_SLEEP;
-				}
+			if (ibmphp_shutdown) 
 				break;
-
-			case POLL_SLEEP:
-				/* don't sleep with a lock on the hardware */
-				up (&semOperations);
-				long_delay (POLL_INTERVAL_SEC * HZ);
-				down (&semOperations);
+			
+			down (&semOperations);
+			
+			if (poll_count >= POLL_LATCH_CNT) {
+				poll_count = 0;
+				poll_state = POLL_SLOTS;
+			} else
 				poll_state = POLL_LATCH_REGISTER;
-				break;
-		}
-
+			break;
+		}	
 		/* give up the harware semaphore */
 		up (&semOperations);
-
 		/* sleep for a short time just for good measure */
 		set_current_state (TASK_INTERRUPTIBLE);
 		schedule_timeout (HZ/10);
 	}
-
 	up (&sem_exit);
 	debug ("%s - Exit\n", __FUNCTION__);
 }
@@ -1044,19 +1147,19 @@
 *
 * Action:  start polling thread
 *---------------------------------------------------------------------*/
-int ibmphp_hpc_start_poll_thread (void)
+int __init ibmphp_hpc_start_poll_thread (void)
 {
 	int rc = 0;
 
-	debug ("ibmphp_hpc_start_poll_thread - Entry\n");
+	debug ("%s - Entry\n", __FUNCTION__);
 
 	tid_poll = kernel_thread (hpc_poll_thread, 0, 0);
 	if (tid_poll < 0) {
-		err ("ibmphp_hpc_start_poll_thread - Error, thread not started\n");
+		err ("%s - Error, thread not started\n", __FUNCTION__);
 		rc = -1;
 	}
 
-	debug ("ibmphp_hpc_start_poll_thread - Exit tid_poll[%d] rc[%d]\n", tid_poll, rc);
+	debug ("%s - Exit tid_poll[%d] rc[%d]\n", __FUNCTION__, tid_poll, rc);
 	return rc;
 }
 
@@ -1065,22 +1168,30 @@
 *
 * Action:  stop polling thread and cleanup
 *---------------------------------------------------------------------*/
-void ibmphp_hpc_stop_poll_thread (void)
+void __exit ibmphp_hpc_stop_poll_thread (void)
 {
-	debug ("ibmphp_hpc_stop_poll_thread - Entry\n");
+	debug ("%s - Entry\n", __FUNCTION__);
 
 	ibmphp_shutdown = TRUE;
+	debug ("before locking operations \n");
 	ibmphp_lock_operations ();
-
+	debug ("after locking operations \n");
+	
 	// wait for poll thread to exit
+	debug ("before sem_exit down \n");
 	down (&sem_exit);
+	debug ("after sem_exit down \n");
 
 	// cleanup
+	debug ("before free_hpc_access \n");
 	free_hpc_access ();
+	debug ("after free_hpc_access \n");
 	ibmphp_unlock_operations ();
+	debug ("after unlock operations \n");
 	up (&sem_exit);
+	debug ("after sem exit up\n");
 
-	debug ("ibmphp_hpc_stop_poll_thread - Exit\n");
+	debug ("%s - Exit\n", __FUNCTION__);
 }
 
 /*----------------------------------------------------------------------
diff -urN linux-2.4.20-pre7/drivers/hotplug/ibmphp_pci.c linux-2.4.20-pre8/drivers/hotplug/ibmphp_pci.c
--- linux-2.4.20-pre7/drivers/hotplug/ibmphp_pci.c	Fri Aug  2 17:39:43 2002
+++ linux-2.4.20-pre8/drivers/hotplug/ibmphp_pci.c	Wed Sep 25 18:21:40 2002
@@ -920,16 +920,30 @@
 	debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
 
 	if (flag_io && flag_mem && flag_pfmem) {
-		bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+		/* If on bootup, there was a bridged card in this slot,
+		 * then card was removed and ibmphp got unloaded and loaded
+		 * back again, there's no way for us to remove the bus
+		 * struct, so no need to kmalloc, can use existing node
+		 */
+		bus = ibmphp_find_res_bus (sec_number);
 		if (!bus) {
-			err ("out of system memory \n");
-			retval = -ENOMEM;
+			bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
+			if (!bus) {
+				err ("out of system memory \n");
+				retval = -ENOMEM;
+				goto error;
+			}
+			memset (bus, 0, sizeof (struct bus_node));
+			bus->busno = sec_number;
+			debug ("b4 adding new bus\n");
+			rc = add_new_bus (bus, io, mem, pfmem, func->busno);
+		} else if (!(bus->rangeIO) && !(bus->rangeMem) && !(bus->rangePFMem))
+			rc = add_new_bus (bus, io, mem, pfmem, 0xFF);
+		else {
+			err ("expected bus structure not empty? \n");
+			retval = -EIO;
 			goto error;
 		}
-		memset (bus, 0, sizeof (struct bus_node));
-		bus->busno = sec_number;
-		debug ("b4 adding new bus\n");
-		rc = add_new_bus (bus, io, mem, pfmem, func->busno);
 		if (rc) {
 			if (rc == -ENOMEM) {
 				ibmphp_remove_bus (bus, func->busno);
@@ -1579,7 +1593,6 @@
 	}
 
 	if (sl->func) {
-		debug ("do we come in here? \n");
 		cur_func = sl->func;
 		while (cur_func) {
 			/* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */
@@ -1619,6 +1632,7 @@
 
 	sl->func = NULL;
 	*slot_cur = sl;
+	debug ("%s - exit\n", __FUNCTION__);
 	return 0;
 }
 
@@ -1638,14 +1652,15 @@
 	struct bus_node *cur_bus = NULL;
 
 	/* Trying to find the parent bus number */
-	cur_bus	= ibmphp_find_res_bus (parent_busno);
-	if (!cur_bus) {
-		err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
-		return -ENODEV;
+	if (parent_busno != 0xFF) {
+		cur_bus	= ibmphp_find_res_bus (parent_busno);
+		if (!cur_bus) {
+			err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
+			return -ENODEV;
+		}
+	
+		list_add (&bus->bus_list, &cur_bus->bus_list);
 	}
-
-	list_add (&bus->bus_list, &cur_bus->bus_list);
-
 	if (io) {
 		io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
 		if (!io_range) {
@@ -1698,6 +1713,7 @@
 	int min, max;
 	u8 busno;
 	struct bus_info *bus;
+	struct bus_node *bus_cur;
 
 	bus = ibmphp_find_same_bus_num (primary_busno);
 	if (!bus) {
@@ -1712,7 +1728,12 @@
 	}
 	busno = (u8) (slotno - (u8) min);
 	busno += primary_busno + 0x01;
-	if (!ibmphp_find_res_bus (busno))
+	bus_cur = ibmphp_find_res_bus (busno);
+	/* either there is no such bus number, or there are no ranges, which
+	 * can only happen if we removed the bridged device in previous load
+	 * of the driver, and now only have the skeleton bus struct
+	 */
+	if ((!bus_cur) || (!(bus_cur->rangeIO) && !(bus_cur->rangeMem) && !(bus_cur->rangePFMem)))
 		return busno;
 	return 0xff;
 }
diff -urN linux-2.4.20-pre7/drivers/hotplug/ibmphp_res.c linux-2.4.20-pre8/drivers/hotplug/ibmphp_res.c
--- linux-2.4.20-pre7/drivers/hotplug/ibmphp_res.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/hotplug/ibmphp_res.c	Wed Sep 25 18:21:40 2002
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/list.h>
+#include <linux/init.h>
 #include "ibmphp.h"
 
 static int flags = 0;		/* for testing */
@@ -44,11 +45,17 @@
 static inline struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
 
 static LIST_HEAD(gbuses);
+LIST_HEAD(ibmphp_res_head);
 
-static struct bus_node * alloc_error_bus (struct ebda_pci_rsrc * curr)
+static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8 busno, int flag)
 {
 	struct bus_node * newbus;
 
+	if (!(curr) && !(flag)) {
+		err ("NULL pointer passed \n");
+		return NULL;
+	}
+
 	newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
 	if (!newbus) {
 		err ("out of system memory \n");
@@ -56,14 +63,24 @@
 	}
 
 	memset (newbus, 0, sizeof (struct bus_node));
-	newbus->busno = curr->bus_num;
+	if (flag)
+		newbus->busno = busno;
+	else
+		newbus->busno = curr->bus_num;
 	list_add_tail (&newbus->bus_list, &gbuses);
 	return newbus;
 }
 
-static struct resource_node * alloc_resources (struct ebda_pci_rsrc * curr)
+static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr)
 {
-	struct resource_node *rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+	struct resource_node *rs;
+	
+	if (!curr) {
+		err ("NULL passed to allocate \n");
+		return NULL;
+	}
+
+	rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
 	if (!rs) {
 		err ("out of system memory \n");
 		return NULL;
@@ -77,7 +94,7 @@
 	return rs;
 }
 
-static int alloc_bus_range (struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)
+static int __init alloc_bus_range (struct bus_node **new_bus, struct range_node **new_range, struct ebda_pci_rsrc *curr, int flag, u8 first_bus)
 {
 	struct bus_node * newbus;
 	struct range_node *newrange;
@@ -184,7 +201,7 @@
  * Input: ptr to the head of the resource list from EBDA
  * Output: 0, -1 or error codes
  ***************************************************************************/
-int ibmphp_rsrc_init (void)
+int __init ibmphp_rsrc_init (void)
 {
 	struct ebda_pci_rsrc *curr;
 	struct range_node *newrange = NULL;
@@ -298,7 +315,7 @@
 				 * actually appears...
 				 */
 				if (ibmphp_add_resource (new_mem) < 0) {
-					newbus = alloc_error_bus (curr);
+					newbus = alloc_error_bus (curr, 0, 0);
 					if (!newbus)
 						return -ENOMEM;
 					newbus->firstMem = new_mem;
@@ -315,7 +332,7 @@
 				new_pfmem->type = PFMEM;
 				new_pfmem->fromMem = FALSE;
 				if (ibmphp_add_resource (new_pfmem) < 0) {
-					newbus = alloc_error_bus (curr);
+					newbus = alloc_error_bus (curr, 0, 0);
 					if (!newbus)
 						return -ENOMEM;
 					newbus->firstPFMem = new_pfmem;
@@ -339,7 +356,7 @@
 				 * range actually appears...
 				 */
 				if (ibmphp_add_resource (new_io) < 0) {
-					newbus = alloc_error_bus (curr);
+					newbus = alloc_error_bus (curr, 0, 0);
 					if (!newbus)
 						return -ENOMEM;
 					newbus->firstIO = new_io;
@@ -351,8 +368,6 @@
 		}
 	}
 
-	debug ("after the while loop in rsrc_init \n");
-
 	list_for_each (tmp, &gbuses) {
 		bus_cur = list_entry (tmp, struct bus_node, bus_list);
 		/* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
@@ -360,11 +375,9 @@
 		if (rc)
 			return rc;
 	}
-	debug ("b4 once_over in rsrc_init \n");
 	rc = once_over ();  /* This is to align ranges (so no -1) */
 	if (rc)
 		return rc;
-	debug ("after once_over in rsrc_init \n");
 	return 0;
 }
 
@@ -579,7 +592,7 @@
  * based on their resource type and sorted by their starting addresses.  It assigns
  * the ptrs to next and nextRange if needed.
  *
- * Input: 3 diff. resources (nulled out if not needed)
+ * Input: resource ptr
  * Output: ptrs assigned (to the node)
  * 0 or -1
  *******************************************************************************/
@@ -592,12 +605,17 @@
 	struct resource_node *res_start = NULL;
 
 	debug ("%s - enter\n", __FUNCTION__);
+
+	if (!res) {
+		err ("NULL passed to add \n");
+		return -ENODEV;
+	}
 	
 	bus_cur = find_bus_wprev (res->busno, NULL, 0);
 	
 	if (!bus_cur) {
 		/* didn't find a bus, smth's wrong!!! */
-		err ("no bus in the system, either pci_dev's wrong or allocation failed\n");
+		debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
 		return -ENODEV;
 	}
 
@@ -768,6 +786,11 @@
 	struct resource_node *mem_cur;
 	char * type = "";
 
+	if (!res)  {
+		err ("resource to remove is NULL \n");
+		return -ENODEV;
+	}
+
 	bus_cur = find_bus_wprev (res->busno, NULL, 0);
 
 	if (!bus_cur) {
@@ -796,7 +819,6 @@
 	res_prev = NULL;
 
 	while (res_cur) {
-		/* ???????????DO WE _NEED_ TO BE CHECKING FOR END AS WELL?????????? */
 		if ((res_cur->start == res->start) && (res_cur->end == res->end))
 			break;
 		res_prev = res_cur;
@@ -980,7 +1002,7 @@
 
 	if (!bus_cur) {
 		/* didn't find a bus, smth's wrong!!! */
-		err ("no bus in the system, either pci_dev's wrong or allocation failed \n");
+		debug ("no bus in the system, either pci_dev's wrong or allocation failed \n");
 		return -EINVAL;
 	}
 
@@ -1339,7 +1361,7 @@
 	prev_bus = find_bus_wprev (parent_busno, NULL, 0);	
 
 	if (!prev_bus) {
-		err ("something terribly wrong. Cannot find parent bus to the one to remove\n");
+		debug ("something terribly wrong. Cannot find parent bus to the one to remove\n");
 		return -ENODEV;
 	}
 
@@ -1466,13 +1488,18 @@
 
 /*
  * find the resource node in the bus 
- * Input: Resource needed, start address of the resource, type or resource
+ * Input: Resource needed, start address of the resource, type of resource
  */
 int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
 {
 	struct resource_node *res_cur = NULL;
 	char * type = "";
 
+	if (!bus) {
+		err ("The bus passed in NULL to find resource \n");
+		return -ENODEV;
+	}
+
 	switch (flag) {
 		case IO:
 			res_cur = bus->firstIO;
@@ -1513,11 +1540,11 @@
 				res_cur = res_cur->next;
 			}
 			if (!res_cur) {
-				err ("SOS...cannot find %s resource in the bus. \n", type);
+				debug ("SOS...cannot find %s resource in the bus. \n", type);
 				return -EINVAL;
 			}
 		} else {
-			err ("SOS... cannot find %s resource in the bus. \n", type);
+			debug ("SOS... cannot find %s resource in the bus. \n", type);
 			return -EINVAL;
 		}
 	}
@@ -1650,7 +1677,7 @@
  * a new Mem node
  * This routine is called right after initialization
  *******************************************************************************/
-static int once_over (void)
+static int __init once_over (void)
 {
 	struct resource_node *pfmem_cur;
 	struct resource_node *pfmem_prev;
@@ -1755,6 +1782,8 @@
 	struct range_node *range;
 	struct resource_node *res;
 	struct list_head *tmp;
+	
+	debug_pci ("*****************START**********************\n");
 
 	if ((!list_empty(&gbuses)) && flags) {
 		err ("The GBUSES is not NULL?!?!?!?!?\n");
@@ -1763,50 +1792,50 @@
 
 	list_for_each (tmp, &gbuses) {
 		bus_cur = list_entry (tmp, struct bus_node, bus_list);
-		debug ("This is bus # %d.  There are \n", bus_cur->busno);
-		debug ("IORanges = %d\t", bus_cur->noIORanges);
-		debug ("MemRanges = %d\t", bus_cur->noMemRanges);
-		debug ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
-		debug ("The IO Ranges are as follows:\n");
+		debug_pci ("This is bus # %d.  There are \n", bus_cur->busno);
+		debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
+		debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
+		debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
+		debug_pci ("The IO Ranges are as follows:\n");
 		if (bus_cur->rangeIO) {
 			range = bus_cur->rangeIO;
 			for (i = 0; i < bus_cur->noIORanges; i++) {
-				debug ("rangeno is %d\n", range->rangeno);
-				debug ("[%x - %x]\n", range->start, range->end);
+				debug_pci ("rangeno is %d\n", range->rangeno);
+				debug_pci ("[%x - %x]\n", range->start, range->end);
 				range = range->next;
 			}
 		}
 
-		debug ("The Mem Ranges are as follows:\n");
+		debug_pci ("The Mem Ranges are as follows:\n");
 		if (bus_cur->rangeMem) {
 			range = bus_cur->rangeMem;
 			for (i = 0; i < bus_cur->noMemRanges; i++) {
-				debug ("rangeno is %d\n", range->rangeno);
-				debug ("[%x - %x]\n", range->start, range->end);
+				debug_pci ("rangeno is %d\n", range->rangeno);
+				debug_pci ("[%x - %x]\n", range->start, range->end);
 				range = range->next;
 			}
 		}
 
-		debug ("The PFMem Ranges are as follows:\n");
+		debug_pci ("The PFMem Ranges are as follows:\n");
 
 		if (bus_cur->rangePFMem) {
 			range = bus_cur->rangePFMem;
 			for (i = 0; i < bus_cur->noPFMemRanges; i++) {
-				debug ("rangeno is %d\n", range->rangeno);
-				debug ("[%x - %x]\n", range->start, range->end);
+				debug_pci ("rangeno is %d\n", range->rangeno);
+				debug_pci ("[%x - %x]\n", range->start, range->end);
 				range = range->next;
 			}
 		}
 
-		debug ("The resources on this bus are as follows\n");
+		debug_pci ("The resources on this bus are as follows\n");
 
-		debug ("IO...\n");
+		debug_pci ("IO...\n");
 		if (bus_cur->firstIO) {
 			res = bus_cur->firstIO;
 			while (res) {
-				debug ("The range # is %d\n", res->rangeno);
-				debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-				debug ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				debug_pci ("The range # is %d\n", res->rangeno);
+				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
 				if (res->next)
 					res = res->next;
 				else if (res->nextRange)
@@ -1815,13 +1844,13 @@
 					break;
 			}
 		}
-		debug ("Mem...\n");
+		debug_pci ("Mem...\n");
 		if (bus_cur->firstMem) {
 			res = bus_cur->firstMem;
 			while (res) {
-				debug ("The range # is %d\n", res->rangeno);
-				debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-				debug ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				debug_pci ("The range # is %d\n", res->rangeno);
+				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
 				if (res->next)
 					res = res->next;
 				else if (res->nextRange)
@@ -1830,13 +1859,13 @@
 					break;
 			}
 		}
-		debug ("PFMem...\n");
+		debug_pci ("PFMem...\n");
 		if (bus_cur->firstPFMem) {
 			res = bus_cur->firstPFMem;
 			while (res) {
-				debug ("The range # is %d\n", res->rangeno);
-				debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-				debug ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				debug_pci ("The range # is %d\n", res->rangeno);
+				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
 				if (res->next)
 					res = res->next;
 				else if (res->nextRange)
@@ -1846,23 +1875,53 @@
 			}
 		}
 
-		debug ("PFMemFromMem...\n");
+		debug_pci ("PFMemFromMem...\n");
 		if (bus_cur->firstPFMemFromMem) {
 			res = bus_cur->firstPFMemFromMem;
 			while (res) {
-				debug ("The range # is %d\n", res->rangeno);
-				debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
-				debug ("[%x - %x], len=%x\n", res->start, res->end, res->len);
+				debug_pci ("The range # is %d\n", res->rangeno);
+				debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
+				debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
 				res = res->next;
 			}
 		}
 	}
+	debug_pci ("***********************END***********************\n");
+}
+
+int static range_exists_already (struct range_node * range, struct bus_node * bus_cur, u8 type)
+{
+	struct range_node * range_cur = NULL;
+	switch (type) {
+		case IO:
+			range_cur = bus_cur->rangeIO;
+			break;
+		case MEM:
+			range_cur = bus_cur->rangeMem;
+			break;
+		case PFMEM:
+			range_cur = bus_cur->rangePFMem;
+			break;
+		default:
+			err ("wrong type passed to find out if range already exists \n");
+			return -ENODEV;
+	}
+
+	while (range_cur) {
+		if ((range_cur->start == range->start) && (range_cur->end == range->end))
+			return 1;
+		range_cur = range_cur->next;
+	}
+	
+	return 0;
 }
 
 /* This routine will read the windows for any PPB we have and update the
  * range info for the secondary bus, and will also input this info into
  * primary bus, since BIOS doesn't. This is for PPB that are in the system
- * on bootup
+ * on bootup.  For bridged cards that were added during previous load of the
+ * driver, only the ranges and the bus structure are added, the devices are
+ * added from NVRAM
  * Input: primary busno
  * Returns: none
  * Note: this function doesn't take into account IO restrictions etc,
@@ -1871,7 +1930,7 @@
  *	 behind them All these are TO DO.
  *	 Also need to add more error checkings... (from fnc returns etc)
  */
-static int update_bridge_ranges (struct bus_node **bus)
+static int __init update_bridge_ranges (struct bus_node **bus)
 {
 	u8 sec_busno, device, function, busno, hdr_type, start_io_address, end_io_address;
 	u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
@@ -1883,9 +1942,11 @@
 	struct resource_node *pfmem;
 	struct range_node *range;
 	bus_cur = *bus;
+	if (!bus_cur)
+		return -ENODEV;
 	busno = bus_cur->busno;
 
-	debug ("inside update_bridge_ranges \n");
+	debug ("inside %s \n", __FUNCTION__);
 	debug ("bus_cur->busno = %x\n", bus_cur->busno);
 
 	for (device = 0; device < 32; device++) {
@@ -1915,6 +1976,12 @@
 						 */
 						pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_busno);
 						bus_sec = find_bus_wprev (sec_busno, NULL, 0); 
+						/* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
+						if (!bus_sec) {
+							bus_sec = alloc_error_bus (NULL, sec_busno, 1);
+							/* the rest will be populated during NVRAM call */
+							return 0;
+						}
 						pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE, &start_io_address);
 						pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_LIMIT, &end_io_address);
 						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE_UPPER16, &upper_io_start);
@@ -1925,9 +1992,7 @@
 						end_address |= (upper_io_end << 16);
 
 						if ((start_address) && (start_address <= end_address)) {
-
 							range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
-
 							if (!range) {
 								err ("out of system memory \n");
 								return -ENOMEM;
@@ -1936,33 +2001,39 @@
 							range->start = start_address;
 							range->end = end_address + 0xfff;
 
-							if (bus_sec->noIORanges > 0) 
-								add_range (IO, range, bus_sec);
-							else {
+							if (bus_sec->noIORanges > 0) {
+								if (!range_exists_already (range, bus_sec, IO)) {
+									add_range (IO, range, bus_sec);
+									++bus_sec->noIORanges;
+								} else {
+									kfree (range);
+									range = NULL;
+								}
+							} else {
 								/* 1st IO Range on the bus */
 								range->rangeno = 1;
 								bus_sec->rangeIO = range;
+								++bus_sec->noIORanges;
 							}
-
-							++bus_sec->noIORanges;
 							fix_resources (bus_sec);
-						
-							io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);							
-							if (!io) {
-								kfree (range);
-								err ("out of system memory \n");
-								return -ENOMEM;
-							}
-							memset (io, 0, sizeof (struct resource_node));
-							io->type = IO;
-							io->busno = bus_cur->busno;
-							io->devfunc = ((device << 3) | (function & 0x7));
-							io->start = start_address;
-							io->end = end_address + 0xfff;
-							io->len = io->end - io->start + 1;
 
-							ibmphp_add_resource (io);
-						}
+							if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
+								io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);							
+								if (!io) {
+									kfree (range);
+									err ("out of system memory \n");
+									return -ENOMEM;
+								}
+								memset (io, 0, sizeof (struct resource_node));
+								io->type = IO;
+								io->busno = bus_cur->busno;
+								io->devfunc = ((device << 3) | (function & 0x7));
+								io->start = start_address;
+								io->end = end_address + 0xfff;
+								io->len = io->end - io->start + 1;
+								ibmphp_add_resource (io);
+							}
+						}	
 
 						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_MEMORY_BASE, &start_mem_address);
 						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_MEMORY_LIMIT, &end_mem_address);
@@ -1981,31 +2052,39 @@
 							range->start = start_address;
 							range->end = end_address + 0xfffff;
 
-							if (bus_sec->noMemRanges > 0) 
-								add_range (MEM, range, bus_sec);
-							else {
+							if (bus_sec->noMemRanges > 0) {
+								if (!range_exists_already (range, bus_sec, MEM)) {
+									add_range (MEM, range, bus_sec);
+									++bus_sec->noMemRanges;
+								} else {
+									kfree (range);
+									range = NULL;
+								}
+							} else {
 								/* 1st Mem Range on the bus */
 								range->rangeno = 1;
 								bus_sec->rangeMem = range;
+								++bus_sec->noMemRanges;
 							}
 
-							++bus_sec->noMemRanges;
 							fix_resources (bus_sec);
 
-							mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-							if (!mem) {
-								kfree (range);
-								err ("out of system memory \n");
-								return -ENOMEM;
+							if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
+								mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+								if (!mem) {
+									kfree (range);
+									err ("out of system memory \n");
+									return -ENOMEM;
+								}
+								memset (mem, 0, sizeof (struct resource_node));
+								mem->type = MEM;
+								mem->busno = bus_cur->busno;
+								mem->devfunc = ((device << 3) | (function & 0x7));
+								mem->start = start_address;
+								mem->end = end_address + 0xfffff;
+								mem->len = mem->end - mem->start + 1;
+								ibmphp_add_resource (mem);
 							}
-							memset (mem, 0, sizeof (struct resource_node));
-							mem->type = MEM;
-							mem->busno = bus_cur->busno;
-							mem->devfunc = ((device << 3) | (function & 0x7));
-							mem->start = start_address;
-							mem->end = end_address + 0xfffff;
-							mem->len = mem->end - mem->start + 1;
-							ibmphp_add_resource (mem);
 						}
 						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_MEMORY_BASE, &start_mem_address);
 						pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
@@ -2029,32 +2108,40 @@
 							range->start = start_address;
 							range->end = end_address + 0xfffff;
 
-							if (bus_sec->noPFMemRanges > 0)
-								add_range (PFMEM, range, bus_sec);
-							else {
+							if (bus_sec->noPFMemRanges > 0) {
+								if (!range_exists_already (range, bus_sec, PFMEM)) {
+									add_range (PFMEM, range, bus_sec);
+									++bus_sec->noPFMemRanges;
+								} else {
+									kfree (range);
+									range = NULL;
+								}
+							} else {
 								/* 1st PFMem Range on the bus */
 								range->rangeno = 1;
 								bus_sec->rangePFMem = range;
+								++bus_sec->noPFMemRanges;
 							}
 
-							++bus_sec->noPFMemRanges;
 							fix_resources (bus_sec);
+							if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
+								pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
+								if (!pfmem) {
+									kfree (range);
+									err ("out of system memory \n");
+									return -ENOMEM;
+								}
+								memset (pfmem, 0, sizeof (struct resource_node));
+								pfmem->type = PFMEM;
+								pfmem->busno = bus_cur->busno;
+								pfmem->devfunc = ((device << 3) | (function & 0x7));
+								pfmem->start = start_address;
+								pfmem->end = end_address + 0xfffff;
+								pfmem->len = pfmem->end - pfmem->start + 1;
+								pfmem->fromMem = FALSE;
 
-							pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
-							if (!pfmem) {
-								kfree (range);
-								err ("out of system memory \n");
-								return -ENOMEM;
+								ibmphp_add_resource (pfmem);
 							}
-							memset (pfmem, 0, sizeof (struct resource_node));
-							pfmem->type = PFMEM;
-							pfmem->busno = bus_cur->busno;
-							pfmem->devfunc = ((device << 3) | (function & 0x7));
-							pfmem->start = start_address;
-							pfmem->end = end_address + 0xfffff;
-							pfmem->len = pfmem->end - pfmem->start + 1;
-							pfmem->fromMem = FALSE;
-							ibmphp_add_resource (pfmem);
 						}
 						break;
 				}	/* end of switch */
diff -urN linux-2.4.20-pre7/drivers/hotplug/pci_hotplug.h linux-2.4.20-pre8/drivers/hotplug/pci_hotplug.h
--- linux-2.4.20-pre7/drivers/hotplug/pci_hotplug.h	Fri Nov  9 14:01:22 2001
+++ linux-2.4.20-pre8/drivers/hotplug/pci_hotplug.h	Wed Sep 25 18:21:40 2002
@@ -29,6 +29,22 @@
 #define _PCI_HOTPLUG_H
 
 
+/* These values come from the PCI Hotplug Spec */
+enum pci_bus_speed {
+	PCI_SPEED_33MHz			= 0x00,
+	PCI_SPEED_66MHz			= 0x01,
+	PCI_SPEED_66MHz_PCIX		= 0x02,
+	PCI_SPEED_100MHz_PCIX		= 0x03,
+	PCI_SPEED_133MHz_PCIX		= 0x04,
+	PCI_SPEED_66MHz_PCIX_266	= 0x09,
+	PCI_SPEED_100MHz_PCIX_266	= 0x0a,
+	PCI_SPEED_133MHz_PCIX_266	= 0x0b,
+	PCI_SPEED_66MHz_PCIX_533	= 0x11,
+	PCI_SPEED_100MHz_PCIX_533	= 0X12,
+	PCI_SPEED_133MHz_PCIX_533	= 0x13,
+	PCI_SPEED_UNKNOWN		= 0xff,
+};
+
 struct hotplug_slot;
 struct hotplug_slot_core;
 
@@ -50,7 +66,13 @@
  * @get_latch_status: Called to get the current latch status of a slot.
  *	If this field is NULL, the value passed in the struct hotplug_slot_info
  *	will be used when this value is requested by a user.
- * @get_adapter_present: Called to get see if an adapter is present in the slot or not.
+ * @get_adapter_status: Called to get see if an adapter is present in the slot or not.
+ *	If this field is NULL, the value passed in the struct hotplug_slot_info
+ *	will be used when this value is requested by a user.
+ * @get_max_bus_speed: Called to get the max bus speed for a slot.
+ *	If this field is NULL, the value passed in the struct hotplug_slot_info
+ *	will be used when this value is requested by a user.
+ * @get_cur_bus_speed: Called to get the current bus speed for a slot.
  *	If this field is NULL, the value passed in the struct hotplug_slot_info
  *	will be used when this value is requested by a user.
  *
@@ -69,6 +91,8 @@
 	int (*get_attention_status)	(struct hotplug_slot *slot, u8 *value);
 	int (*get_latch_status)		(struct hotplug_slot *slot, u8 *value);
 	int (*get_adapter_status)	(struct hotplug_slot *slot, u8 *value);
+	int (*get_max_bus_speed)	(struct hotplug_slot *slot, enum pci_bus_speed *value);
+	int (*get_cur_bus_speed)	(struct hotplug_slot *slot, enum pci_bus_speed *value);
 };
 
 /**
@@ -85,6 +109,8 @@
 	u8	attention_status;
 	u8	latch_status;
 	u8	adapter_status;
+	enum pci_bus_speed	max_bus_speed;
+	enum pci_bus_speed	cur_bus_speed;
 };
 
 /**
diff -urN linux-2.4.20-pre7/drivers/hotplug/pci_hotplug_core.c linux-2.4.20-pre8/drivers/hotplug/pci_hotplug_core.c
--- linux-2.4.20-pre7/drivers/hotplug/pci_hotplug_core.c	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/hotplug/pci_hotplug_core.c	Wed Sep 25 18:21:40 2002
@@ -37,6 +37,8 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/dnotify.h>
+#include <linux/proc_fs.h>
 #include <asm/uaccess.h>
 #include "pci_hotplug.h"
 
@@ -56,7 +58,7 @@
 /* local variables */
 static int debug;
 
-#define DRIVER_VERSION	"0.4"
+#define DRIVER_VERSION	"0.5"
 #define DRIVER_AUTHOR	"Greg Kroah-Hartman <greg@kroah.com>"
 #define DRIVER_DESC	"PCI Hot Plug PCI Core"
 
@@ -73,6 +75,8 @@
 	struct dentry	*latch_dentry;
 	struct dentry	*adapter_dentry;
 	struct dentry	*test_dentry;
+	struct dentry	*max_bus_speed_dentry;
+	struct dentry	*cur_bus_speed_dentry;
 };
 
 static struct super_operations pcihpfs_ops;
@@ -85,6 +89,29 @@
 
 LIST_HEAD(pci_hotplug_slot_list);
 
+/* these strings match up with the values in pci_bus_speed */
+static char *pci_bus_speed_strings[] = {
+	"33 MHz PCI",		/* 0x00 */
+	"66 MHz PCI",		/* 0x01 */
+	"66 MHz PCIX", 		/* 0x02 */
+	"100 MHz PCIX",		/* 0x03 */
+	"133 MHz PCIX",		/* 0x04 */
+	NULL,			/* 0x05 */
+	NULL,			/* 0x06 */
+	NULL,			/* 0x07 */
+	NULL,			/* 0x08 */
+	"66 MHz PCIX 266",	/* 0x09 */
+	"100 MHz PCIX 266",	/* 0x0a */
+	"133 MHz PCIX 266",	/* 0x0b */
+	NULL,			/* 0x0c */
+	NULL,			/* 0x0d */
+	NULL,			/* 0x0e */
+	NULL,			/* 0x0f */
+	NULL,			/* 0x10 */
+	"66 MHz PCIX 533",	/* 0x11 */
+	"100 MHz PCIX 533",	/* 0x12 */
+	"133 MHz PCIX 533",	/* 0x13 */
+};
 
 static int pcihpfs_statfs (struct super_block *sb, struct statfs *buf)
 {
@@ -100,6 +127,12 @@
 	return NULL;
 }
 
+#ifdef CONFIG_PROC_FS		
+extern struct proc_dir_entry *proc_bus_pci_dir;
+static struct proc_dir_entry *slotdir = NULL;
+static const char *slotdir_name = "slots";
+#endif
+
 static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, int dev)
 {
 	struct inode *inode = new_inode(sb);
@@ -279,6 +312,24 @@
 	llseek:		default_file_lseek,
 };
 
+/* file ops for the "max bus speed" files */
+static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
+static struct file_operations max_bus_speed_file_operations = {
+	read:		max_bus_speed_read_file,
+	write:		default_write_file,
+	open:		default_open,
+	llseek:		default_file_lseek,
+};
+
+/* file ops for the "current bus speed" files */
+static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
+static struct file_operations cur_bus_speed_file_operations = {
+	read:		cur_bus_speed_read_file,
+	write:		default_write_file,
+	open:		default_open,
+	llseek:		default_file_lseek,
+};
+
 /* file ops for the "test" files */
 static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
 static struct file_operations test_file_operations = {
@@ -495,26 +546,28 @@
 	up(&parent->d_inode->i_sem);
 }
 
-#define GET_STATUS(name)	\
-static int get_##name##_status (struct hotplug_slot *slot, u8 *value)	\
+#define GET_STATUS(name,type)	\
+static int get_##name (struct hotplug_slot *slot, type *value)		\
 {									\
 	struct hotplug_slot_ops *ops = slot->ops;			\
 	int retval = 0;							\
 	if (ops->owner)							\
 		__MOD_INC_USE_COUNT(ops->owner);			\
-	if (ops->get_##name##_status)					\
-		retval = ops->get_##name##_status (slot, value);	\
+	if (ops->get_##name)						\
+		retval = ops->get_##name (slot, value);			\
 	else								\
-		*value = slot->info->name##_status;			\
+		*value = slot->info->name;				\
 	if (ops->owner)							\
 		__MOD_DEC_USE_COUNT(ops->owner);			\
 	return retval;							\
 }
 
-GET_STATUS(power)
-GET_STATUS(attention)
-GET_STATUS(latch)
-GET_STATUS(adapter)
+GET_STATUS(power_status, u8)
+GET_STATUS(attention_status, u8)
+GET_STATUS(latch_status, u8)
+GET_STATUS(adapter_status, u8)
+GET_STATUS(max_bus_speed, enum pci_bus_speed)
+GET_STATUS(cur_bus_speed, enum pci_bus_speed)
 
 static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
 {
@@ -569,7 +622,7 @@
 
 	if (*offset < 0)
 		return -EINVAL;
-	if (count <= 0)
+	if (count == 0 || count > 16384)
 		return 0;
 	if (*offset != 0)
 		return 0;
@@ -680,7 +733,7 @@
 
 	if (*offset < 0)
 		return -EINVAL;
-	if (count <= 0)
+	if (count == 0 || count > 16384)
 		return 0;
 	if (*offset != 0)
 		return 0;
@@ -763,7 +816,6 @@
 	return retval;
 }
 
-
 static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
 {
 	struct hotplug_slot *slot = file->private_data;
@@ -807,6 +859,108 @@
 	return retval;
 }
 
+static char *unknown_speed = "Unknown bus speed";
+
+static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+{
+	struct hotplug_slot *slot = file->private_data;
+	unsigned char *page;
+	char *speed_string;
+	int retval;
+	int len = 0;
+	enum pci_bus_speed value;
+	
+	dbg ("count = %d, offset = %lld\n", count, *offset);
+
+	if (*offset < 0)
+		return -EINVAL;
+	if (count <= 0)
+		return 0;
+	if (*offset != 0)
+		return 0;
+
+	if (slot == NULL) {
+		dbg("slot == NULL???\n");
+		return -ENODEV;
+	}
+
+	page = (unsigned char *)__get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	retval = get_max_bus_speed (slot, &value);
+	if (retval)
+		goto exit;
+
+	if (value == PCI_SPEED_UNKNOWN)
+		speed_string = unknown_speed;
+	else
+		speed_string = pci_bus_speed_strings[value];
+	
+	len = sprintf (page, "%s\n", speed_string);
+
+	if (copy_to_user (buf, page, len)) {
+		retval = -EFAULT;
+		goto exit;
+	}
+	*offset += len;
+	retval = len;
+
+exit:
+	free_page((unsigned long)page);
+	return retval;
+}
+
+static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+{
+	struct hotplug_slot *slot = file->private_data;
+	unsigned char *page;
+	char *speed_string;
+	int retval;
+	int len = 0;
+	enum pci_bus_speed value;
+
+	dbg ("count = %d, offset = %lld\n", count, *offset);
+
+	if (*offset < 0)
+		return -EINVAL;
+	if (count <= 0)
+		return 0;
+	if (*offset != 0)
+		return 0;
+
+	if (slot == NULL) {
+		dbg("slot == NULL???\n");
+		return -ENODEV;
+	}
+
+	page = (unsigned char *)__get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	retval = get_cur_bus_speed (slot, &value);
+	if (retval)
+		goto exit;
+
+	if (value == PCI_SPEED_UNKNOWN)
+		speed_string = unknown_speed;
+	else
+		speed_string = pci_bus_speed_strings[value];
+	
+	len = sprintf (page, "%s\n", speed_string);
+
+	if (copy_to_user (buf, page, len)) {
+		retval = -EFAULT;
+		goto exit;
+	}
+	*offset += len;
+	retval = len;
+
+exit:
+	free_page((unsigned long)page);
+	return retval;
+}
+
 static ssize_t test_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
 {
 	struct hotplug_slot *slot = file->private_data;
@@ -817,7 +971,7 @@
 
 	if (*offset < 0)
 		return -EINVAL;
-	if (count <= 0)
+	if (count == 0 || count > 16384)
 		return 0;
 	if (*offset != 0)
 		return 0;
@@ -870,30 +1024,57 @@
 					   S_IFDIR | S_IXUGO | S_IRUGO,
 					   NULL, NULL, NULL);
 	if (core->dir_dentry != NULL) {
-		core->power_dentry = fs_create_file ("power",
-						     S_IFREG | S_IRUGO | S_IWUSR,
-						     core->dir_dentry, slot,
-						     &power_file_operations);
-
-		core->attention_dentry = fs_create_file ("attention",
-							 S_IFREG | S_IRUGO | S_IWUSR,
-							 core->dir_dentry, slot,
-							 &attention_file_operations);
-
-		core->latch_dentry = fs_create_file ("latch",
-						     S_IFREG | S_IRUGO,
-						     core->dir_dentry, slot,
-						     &latch_file_operations);
-
-		core->adapter_dentry = fs_create_file ("adapter",
-						       S_IFREG | S_IRUGO,
-						       core->dir_dentry, slot,
-						       &presence_file_operations);
-
-		core->test_dentry = fs_create_file ("test",
-						    S_IFREG | S_IRUGO | S_IWUSR,
-						    core->dir_dentry, slot,
-						    &test_file_operations);
+		if ((slot->ops->enable_slot) ||
+		    (slot->ops->disable_slot) ||
+		    (slot->ops->get_power_status))
+			core->power_dentry = 
+				fs_create_file ("power",
+						S_IFREG | S_IRUGO | S_IWUSR,
+						core->dir_dentry, slot,
+						&power_file_operations);
+
+		if ((slot->ops->set_attention_status) ||
+		    (slot->ops->get_attention_status))
+			core->attention_dentry =
+				fs_create_file ("attention",
+						S_IFREG | S_IRUGO | S_IWUSR,
+						core->dir_dentry, slot,
+						&attention_file_operations);
+
+		if (slot->ops->get_latch_status)
+			core->latch_dentry = 
+				fs_create_file ("latch",
+						S_IFREG | S_IRUGO,
+						core->dir_dentry, slot,
+						&latch_file_operations);
+
+		if (slot->ops->get_adapter_status)
+			core->adapter_dentry = 
+				fs_create_file ("adapter",
+						S_IFREG | S_IRUGO,
+						core->dir_dentry, slot,
+						&presence_file_operations);
+
+		if (slot->ops->get_max_bus_speed)
+			core->max_bus_speed_dentry = 
+				fs_create_file ("max_bus_speed",
+						S_IFREG | S_IRUGO,
+						core->dir_dentry, slot,
+						&max_bus_speed_file_operations);
+
+		if (slot->ops->get_cur_bus_speed)
+			core->cur_bus_speed_dentry =
+				fs_create_file ("cur_bus_speed",
+						S_IFREG | S_IRUGO,
+						core->dir_dentry, slot,
+						&cur_bus_speed_file_operations);
+
+		if (slot->ops->hardware_test)
+			core->test_dentry =
+				fs_create_file ("test",
+						S_IFREG | S_IRUGO | S_IWUSR,
+						core->dir_dentry, slot,
+						&test_file_operations);
 	}
 	return 0;
 }
@@ -911,6 +1092,10 @@
 			fs_remove_file (core->latch_dentry);
 		if (core->adapter_dentry)
 			fs_remove_file (core->adapter_dentry);
+		if (core->max_bus_speed_dentry)
+			fs_remove_file (core->max_bus_speed_dentry);
+		if (core->cur_bus_speed_dentry)
+			fs_remove_file (core->cur_bus_speed_dentry);
 		if (core->test_dentry)
 			fs_remove_file (core->test_dentry);
 		fs_remove_file (core->dir_dentry);
@@ -963,6 +1148,7 @@
 		return -EEXIST;
 	}
 
+	memset (core, 0, sizeof (struct hotplug_slot_core));
 	slot->core_priv = core;
 
 	list_add (&slot->slot_list, &pci_hotplug_slot_list);
@@ -1006,10 +1192,13 @@
 	return 0;
 }
 
-static inline void update_inode_time (struct inode *inode)
+static inline void update_dentry_inode_time (struct dentry *dentry)
 {
-	if (inode)
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	struct inode *inode = dentry->d_inode;
+	if (inode) {
+		inode->i_mtime = CURRENT_TIME;
+		dnotify_parent(dentry, DN_MODIFY);
+	}
 }
 
 /**
@@ -1044,16 +1233,19 @@
 	core = temp->core_priv;
 	if ((core->power_dentry) &&
 	    (temp->info->power_status != info->power_status))
-		update_inode_time (core->power_dentry->d_inode);
+		update_dentry_inode_time (core->power_dentry);
 	if ((core->attention_dentry) &&
 	    (temp->info->attention_status != info->attention_status))
-		update_inode_time (core->attention_dentry->d_inode);
+		update_dentry_inode_time (core->attention_dentry);
 	if ((core->latch_dentry) &&
 	    (temp->info->latch_status != info->latch_status))
-		update_inode_time (core->latch_dentry->d_inode);
+		update_dentry_inode_time (core->latch_dentry);
 	if ((core->adapter_dentry) &&
 	    (temp->info->adapter_status != info->adapter_status))
-		update_inode_time (core->adapter_dentry->d_inode);
+		update_dentry_inode_time (core->adapter_dentry);
+	if ((core->cur_bus_speed_dentry) &&
+	    (temp->info->cur_bus_speed != info->cur_bus_speed))
+		update_dentry_inode_time (core->cur_bus_speed_dentry);
 
 	memcpy (temp->info, info, sizeof (struct hotplug_slot_info));
 	spin_unlock (&list_lock);
@@ -1074,6 +1266,11 @@
 		goto exit;
 	}
 
+#ifdef CONFIG_PROC_FS
+	/* create mount point for pcihpfs */
+	slotdir = proc_mkdir(slotdir_name, proc_bus_pci_dir);
+#endif
+
 	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
 
 exit:
@@ -1083,6 +1280,11 @@
 static void __exit pci_hotplug_exit (void)
 {
 	unregister_filesystem(&pcihpfs_fs_type);
+
+#ifdef CONFIG_PROC_FS
+	if (slotdir)
+		remove_proc_entry(slotdir_name, proc_bus_pci_dir);
+#endif
 }
 
 module_init(pci_hotplug_init);
diff -urN linux-2.4.20-pre7/drivers/i2c/i2c-core.c linux-2.4.20-pre8/drivers/i2c/i2c-core.c
--- linux-2.4.20-pre7/drivers/i2c/i2c-core.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/i2c/i2c-core.c	Wed Sep 25 18:21:40 2002
@@ -656,7 +656,8 @@
 	struct inode * inode = file->f_dentry->d_inode;
 	char *kbuf;
 	struct i2c_client *client;
-	int i,j,k,order_nr,len=0,len_total;
+	int i,j,k,order_nr,len=0;
+	size_t len_total;
 	int order[I2C_CLIENT_MAX];
 
 	if (count > 4000)
diff -urN linux-2.4.20-pre7/drivers/i2c/i2c-dev.c linux-2.4.20-pre8/drivers/i2c/i2c-dev.c
--- linux-2.4.20-pre7/drivers/i2c/i2c-dev.c	Thu Oct 11 08:05:47 2001
+++ linux-2.4.20-pre8/drivers/i2c/i2c-dev.c	Wed Sep 25 18:21:40 2002
@@ -159,6 +159,9 @@
 
 	struct i2c_client *client = (struct i2c_client *)file->private_data;
 
+	if(count > 8192)
+		count = 8192;
+		
 	/* copy user space data to kernel space. */
 	tmp = kmalloc(count,GFP_KERNEL);
 	if (tmp==NULL)
@@ -187,6 +190,9 @@
 	struct inode *inode = file->f_dentry->d_inode;
 #endif /* DEBUG */
 
+	if(count > 8192)
+		count = 8192;
+		
 	/* copy user space data to kernel space. */
 	tmp = kmalloc(count,GFP_KERNEL);
 	if (tmp==NULL)
diff -urN linux-2.4.20-pre7/drivers/ide/ide-cd.c linux-2.4.20-pre8/drivers/ide/ide-cd.c
--- linux-2.4.20-pre7/drivers/ide/ide-cd.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ide/ide-cd.c	Wed Sep 25 18:21:40 2002
@@ -2194,6 +2194,8 @@
 	   layer. the packet must be complete, as we do not
 	   touch it at all. */
 	memset(&pc, 0, sizeof(pc));
+	if (cgc->sense)
+		memset(cgc->sense, 0, sizeof(struct request_sense));
 	memcpy(pc.c, cgc->cmd, CDROM_PACKET_SIZE);
 	pc.buffer = cgc->buffer;
 	pc.buflen = cgc->buflen;
diff -urN linux-2.4.20-pre7/drivers/ieee1394/amdtp.c linux-2.4.20-pre8/drivers/ieee1394/amdtp.c
--- linux-2.4.20-pre7/drivers/ieee1394/amdtp.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/amdtp.c	Wed Sep 25 18:21:41 2002
@@ -46,8 +46,6 @@
  *
  * - Fix DMA stop after bus reset!
  *
- * - Implement poll.
- *
  * - Clean up iso context handling in ohci1394.
  *
  *
@@ -75,6 +73,7 @@
 #include <linux/wait.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
+#include <linux/poll.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
 
@@ -121,17 +120,40 @@
 	dma_addr_t payload_bus;
 };
 
-#ifdef __BIG_ENDIAN_BITFIELD
+#include <asm/byteorder.h>
 
-#error Big endian bitfields not tested
+#if defined __BIG_ENDIAN_BITFIELD
 
-#else
+struct iso_packet {
+	/* First quadlet */
+	unsigned int dbs      : 8;
+	unsigned int eoh0     : 2;
+	unsigned int sid      : 6;
+
+	unsigned int dbc      : 8;
+	unsigned int fn       : 2;
+	unsigned int qpc      : 3;
+	unsigned int sph      : 1;
+	unsigned int reserved : 2;
+
+	/* Second quadlet */
+	unsigned int fdf      : 8;
+	unsigned int eoh1     : 2;
+	unsigned int fmt      : 6;
+
+	unsigned int syt      : 16;
+
+        quadlet_t data[0];
+};
+
+#elif defined __LITTLE_ENDIAN_BITFIELD
 
 struct iso_packet {
 	/* First quadlet */
 	unsigned int sid      : 6;
 	unsigned int eoh0     : 2;
 	unsigned int dbs      : 8;
+
 	unsigned int reserved : 2;
 	unsigned int sph      : 1;
 	unsigned int qpc      : 3;
@@ -142,11 +164,16 @@
 	unsigned int fmt      : 6;
 	unsigned int eoh1     : 2;
 	unsigned int fdf      : 8;
+
 	unsigned int syt      : 16;
 
 	quadlet_t data[0];
 };
 
+#else
+
+#error Unknown bitfield type
+
 #endif
 
 struct fraction {
@@ -224,7 +251,7 @@
 	struct list_head free_packet_lists;
         wait_queue_head_t packet_list_wait;
 	spinlock_t packet_list_lock;
-	int iso_context;
+	struct ohci1394_iso_tasklet iso_tasklet;
 	struct pci_pool *descriptor_pool, *packet_pool;
 
 	/* Streams at a host controller are chained through this field. */
@@ -252,23 +279,6 @@
 #define OHCI1394_CONTEXT_DEAD        0x00000800
 #define OHCI1394_CONTEXT_ACTIVE      0x00000400
 
-static inline int ohci1394_alloc_it_ctx(struct ti_ohci *ohci)
-{
-	int i;
-
-	for (i = 0; i < ohci->nb_iso_xmit_ctx; i++)
-		if (!test_and_set_bit(i, &ohci->it_ctx_usage))
-			return i;
-
-	return -EBUSY;
-}
-	
-static inline void ohci1394_free_it_ctx(struct ti_ohci *ohci, int ctx)
-{
-	clear_bit(ctx, &ohci->it_ctx_usage);
-}
-
-
 void ohci1394_start_it_ctx(struct ti_ohci *ohci, int ctx,
 			   dma_addr_t first_cmd, int z, int cycle_match)
 {
@@ -347,7 +357,7 @@
 	if ((start_cycle & 0x1fff) >= 8000)
 		start_cycle = start_cycle - 8000 + 0x2000;
 
-	ohci1394_start_it_ctx(s->host->ohci, s->iso_context,
+	ohci1394_start_it_ctx(s->host->ohci, s->iso_tasklet.context,
 			      pl->packets[0].db_bus, 3,
 			      start_cycle & 0x7fff);
 }
@@ -370,14 +380,16 @@
 	if (pl->link.prev != &s->dma_packet_lists) {
 		struct packet *last = &prev->packets[PACKET_LIST_SIZE - 1];
 		last->db->payload_desc.branch = pl->packets[0].db_bus | 3;
-		ohci1394_wake_it_ctx(s->host->ohci, s->iso_context);
+		last->db->header_desc.skip = pl->packets[0].db_bus | 3;
+		ohci1394_wake_it_ctx(s->host->ohci, s->iso_tasklet.context);
 	}
 	else
 		stream_start_dma(s, pl);
 }
 
-static void stream_shift_packet_lists(struct stream *s)
+static void stream_shift_packet_lists(unsigned long l)
 {
+	struct stream *s = (struct stream *) l;
 	struct packet_list *pl;
 	struct packet *last;
 	int diff;
@@ -511,25 +523,6 @@
 	return frac->integer + (frac->numerator > 0 ? 1 : 0);
 }
 
-static void amdtp_irq_handler(int card, quadlet_t isoRecvIntEvent,
-			      quadlet_t isoXmitIntEvent, void *data)
-{
-	struct amdtp_host *host = data;
-	struct list_head *lh;
-	struct stream *s = NULL;
-
-	spin_lock(&host->stream_list_lock);
-	list_for_each(lh, &host->stream_list) {
-		s = list_entry(lh, struct stream, link);
-		if (isoXmitIntEvent & (1 << s->iso_context))
-			break;
-	}
-	spin_unlock(&host->stream_list_lock);
-
-	if (s != NULL)
-		stream_shift_packet_lists(s);
-}
-
 void packet_initialize(struct packet *p, struct packet *next)
 {
 	/* Here we initialize the dma descriptor block for
@@ -541,18 +534,19 @@
 
 	p->db->header_desc.control =
 		DMA_CTL_OUTPUT_MORE | DMA_CTL_IMMEDIATE | 8;
-	p->db->header_desc.skip = 0;
 
 	if (next) {
 		p->db->payload_desc.control = 
 			DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH;
 		p->db->payload_desc.branch = next->db_bus | 3;
+		p->db->header_desc.skip = next->db_bus | 3;
 	}
 	else {
 		p->db->payload_desc.control = 
 			DMA_CTL_OUTPUT_LAST | DMA_CTL_BRANCH |
 			DMA_CTL_UPDATE | DMA_CTL_IRQ;
 		p->db->payload_desc.branch = 0;
+		p->db->header_desc.skip = 0;
 	}
 	p->db->payload_desc.data_address = p->payload_bus;
 	p->db->payload_desc.status = 0;
@@ -889,7 +883,7 @@
 		stream_start_dma(s, pl);
 	}
 	else {
-		ohci1394_stop_it_ctx(s->host->ohci, s->iso_context, 0);
+		ohci1394_stop_it_ctx(s->host->ohci, s->iso_tasklet.context, 0);
 	}
 }
 
@@ -1039,8 +1033,11 @@
         init_waitqueue_head(&s->packet_list_wait);
         spin_lock_init(&s->packet_list_lock);
 
-	s->iso_context = ohci1394_alloc_it_ctx(host->ohci);
-	if (s->iso_context < 0) {
+	ohci1394_init_iso_tasklet(&s->iso_tasklet, OHCI_ISO_TRANSMIT,
+				  stream_shift_packet_lists,
+				  (unsigned long) s);
+
+	if (ohci1394_register_iso_tasklet(host->ohci, &s->iso_tasklet) < 0) {
 		pci_pool_destroy(s->descriptor_pool);
 		kfree(s->input);
 		kfree(s);
@@ -1067,8 +1064,8 @@
 	wait_event_interruptible(s->packet_list_wait, 
 				 list_empty(&s->dma_packet_lists));
 
-	ohci1394_stop_it_ctx(s->host->ohci, s->iso_context, 1);
-	ohci1394_free_it_ctx(s->host->ohci, s->iso_context);
+	ohci1394_stop_it_ctx(s->host->ohci, s->iso_tasklet.context, 1);
+	ohci1394_unregister_iso_tasklet(s->host->ohci, &s->iso_tasklet);
 
 	if (s->opcr != NULL)
 		cmp_unregister_opcr(s->host->host, s->opcr);
@@ -1092,7 +1089,8 @@
 {
 	struct stream *s = file->private_data;
 	unsigned char *p;
-	int i, length;
+	int i;
+	size_t length;
 	
 	if (s->packet_pool == NULL)
 		return -EBADFD;
@@ -1116,8 +1114,13 @@
 		
 		stream_flush(s);
 		
-		if (s->current_packet_list == NULL &&
-		    wait_event_interruptible(s->packet_list_wait, 
+		if (s->current_packet_list != NULL)
+			continue;
+
+		if (file->f_flags & O_NONBLOCK)
+			return i + length > 0 ? i + length : -EAGAIN;
+
+		if (wait_event_interruptible(s->packet_list_wait, 
 					     !list_empty(&s->free_packet_lists)))
 			return -EINTR;
 	}
@@ -1130,7 +1133,6 @@
 {
 	struct stream *s = file->private_data;
 	struct amdtp_ioctl cfg;
-	int new;
 
 	switch(cmd)
 	{
@@ -1141,23 +1143,23 @@
 		else 
 			return stream_configure(s, cmd, &cfg);
 
-	case AMDTP_IOC_PING:
-		HPSB_INFO("ping: offsetting timpestamps %ld ticks", arg);
-		new = s->cycle_offset.integer + arg;
-		s->cycle_offset.integer = new % 3072;
-		atomic_add(new / 3072, &s->cycle_count);
-		return 0;
-
-	case AMDTP_IOC_ZAP:
-		while (MOD_IN_USE)
-			MOD_DEC_USE_COUNT;
-		return 0;
-
 	default:
 		return -EINVAL;
 	}
 }
 
+static unsigned int amdtp_poll(struct file *file, poll_table *pt)
+{
+	struct stream *s = file->private_data;
+
+	poll_wait(file, &s->packet_list_wait, pt);
+
+	if (!list_empty(&s->free_packet_lists))
+		return POLLOUT | POLLWRNORM;
+	else
+		return 0;
+}
+
 static int amdtp_open(struct inode *inode, struct file *file)
 {
 	struct amdtp_host *host;
@@ -1193,6 +1195,7 @@
 {
 	.owner =	THIS_MODULE,
 	.write =	amdtp_write,
+	.poll =		amdtp_poll,
 	.ioctl =	amdtp_ioctl,
 	.open =		amdtp_open,
 	.release =	amdtp_release
@@ -1204,7 +1207,8 @@
 {
 	struct amdtp_host *ah;
 
-	/* FIXME: check it's an ohci host. */
+	if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME) != 0)
+		return;
 
 	ah = kmalloc(sizeof *ah, SLAB_KERNEL);
 	ah->host = host;
@@ -1215,8 +1219,6 @@
 	spin_lock_irq(&host_list_lock);
 	list_add_tail(&ah->link, &host_list);
 	spin_unlock_irq(&host_list_lock);
-
-	ohci1394_hook_irq(ah->ohci, amdtp_irq_handler, ah);
 }
 
 static void amdtp_remove_host(struct hpsb_host *host)
@@ -1235,7 +1237,6 @@
 	
 	if (lh != &host_list) {
 		ah = list_entry(lh, struct amdtp_host, link);
-		ohci1394_unhook_irq(ah->ohci, amdtp_irq_handler, ah);
 		kfree(ah);
 	}
 	else
diff -urN linux-2.4.20-pre7/drivers/ieee1394/csr.c linux-2.4.20-pre8/drivers/ieee1394/csr.c
--- linux-2.4.20-pre7/drivers/ieee1394/csr.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/csr.c	Wed Sep 25 18:21:41 2002
@@ -70,7 +70,7 @@
 {
         host->csr.lock = SPIN_LOCK_UNLOCKED;
 
-        host->csr.rom_size = host->ops->get_rom(host, &host->csr.rom);
+        host->csr.rom_size = host->driver->get_rom(host, &host->csr.rom);
 
         host->csr.state                 = 0;
         host->csr.node_ids              = 0;
@@ -152,7 +152,7 @@
         case CSR_CYCLE_TIME:
                 oldcycle = host->csr.cycle_time;
                 host->csr.cycle_time =
-                        host->ops->devctl(host, GET_CYCLE_COUNTER, 0);
+                        host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
 
                 if (oldcycle > host->csr.cycle_time) {
                         /* cycle time wrapped around */
@@ -163,7 +163,7 @@
         case CSR_BUS_TIME:
                 oldcycle = host->csr.cycle_time;
                 host->csr.cycle_time =
-                        host->ops->devctl(host, GET_CYCLE_COUNTER, 0);
+                        host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
 
                 if (oldcycle > host->csr.cycle_time) {
                         /* cycle time wrapped around */
@@ -181,32 +181,32 @@
                 return RCODE_ADDRESS_ERROR;
 
         case CSR_BUS_MANAGER_ID:
-                if (host->ops->hw_csr_reg)
-                        ret = host->ops->hw_csr_reg(host, 0, 0, 0);
+                if (host->driver->hw_csr_reg)
+                        ret = host->driver->hw_csr_reg(host, 0, 0, 0);
                 else
                         ret = host->csr.bus_manager_id;
 
                 *(buf++) = cpu_to_be32(ret);
                 out;
         case CSR_BANDWIDTH_AVAILABLE:
-                if (host->ops->hw_csr_reg)
-                        ret = host->ops->hw_csr_reg(host, 1, 0, 0);
+                if (host->driver->hw_csr_reg)
+                        ret = host->driver->hw_csr_reg(host, 1, 0, 0);
                 else
                         ret = host->csr.bandwidth_available;
 
                 *(buf++) = cpu_to_be32(ret);
                 out;
         case CSR_CHANNELS_AVAILABLE_HI:
-                if (host->ops->hw_csr_reg)
-                        ret = host->ops->hw_csr_reg(host, 2, 0, 0);
+                if (host->driver->hw_csr_reg)
+                        ret = host->driver->hw_csr_reg(host, 2, 0, 0);
                 else
                         ret = host->csr.channels_available_hi;
 
                 *(buf++) = cpu_to_be32(ret);
                 out;
         case CSR_CHANNELS_AVAILABLE_LO:
-                if (host->ops->hw_csr_reg)
-                        ret = host->ops->hw_csr_reg(host, 3, 0, 0);
+                if (host->driver->hw_csr_reg)
+                        ret = host->driver->hw_csr_reg(host, 3, 0, 0);
                 else
                         ret = host->csr.channels_available_lo;
 
@@ -244,7 +244,7 @@
                 host->csr.node_ids &= NODE_MASK << 16;
                 host->csr.node_ids |= be32_to_cpu(*(data++)) & (BUS_MASK << 16);
                 host->node_id = host->csr.node_ids >> 16;
-                host->ops->devctl(host, SET_BUS_ID, host->node_id >> 6);
+                host->driver->devctl(host, SET_BUS_ID, host->node_id >> 6);
                 out;
 
         case CSR_RESET_START:
@@ -269,7 +269,7 @@
         case CSR_CYCLE_TIME:
                 /* should only be set by cycle start packet, automatically */
                 host->csr.cycle_time = be32_to_cpu(*data);
-                host->ops->devctl(host, SET_CYCLE_COUNTER,
+                host->driver->devctl(host, SET_CYCLE_COUNTER,
                                        be32_to_cpu(*(data++)));
                 out;
         case CSR_BUS_TIME:
@@ -318,10 +318,10 @@
         data = be32_to_cpu(data);
         arg = be32_to_cpu(arg);
 
-        if (host->ops->hw_csr_reg) {
+        if (host->driver->hw_csr_reg) {
                 quadlet_t old;
 
-                old = host->ops->
+                old = host->driver->
                         hw_csr_reg(host, (csraddr - CSR_BUS_MANAGER_ID) >> 2,
                                    data, arg);
 
diff -urN linux-2.4.20-pre7/drivers/ieee1394/dv1394-private.h linux-2.4.20-pre8/drivers/ieee1394/dv1394-private.h
--- linux-2.4.20-pre7/drivers/ieee1394/dv1394-private.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/dv1394-private.h	Wed Sep 25 18:21:41 2002
@@ -27,6 +27,7 @@
 #define _DV_1394_PRIVATE_H
 
 #include "ieee1394.h"
+#include "ohci1394.h"
 #include <linux/pci.h>
 #include <asm/scatterlist.h>
 
@@ -91,20 +92,20 @@
 					      unsigned char sync_tag,
 					      unsigned int  payload_size)
 {
-	omi->q[0] = 0x02000000 | 8 ; /* OUTPUT_MORE_IMMEDIATE; 8 is the size of the IT header */
+	omi->q[0] = cpu_to_le32(0x02000000 | 8); /* OUTPUT_MORE_IMMEDIATE; 8 is the size of the IT header */
 	omi->q[1] = 0;
 	omi->q[2] = 0;
 	omi->q[3] = 0;
 	
 	/* IT packet header */
-	omi->q[4] = (0x0 << 16)  /* DMA_SPEED_100 */
-			| (tag << 14)
-			| (channel << 8)
-			| (TCODE_ISO_DATA << 4) 
-			| (sync_tag);
+	omi->q[4] = cpu_to_le32(  (0x0 << 16)  /* DMA_SPEED_100 */
+				  | (tag << 14)
+				  | (channel << 8)
+				  | (TCODE_ISO_DATA << 4) 
+				  | (sync_tag) );
 
-	omi->q[5] = payload_size << 16;
-	omi->q[5] |= (0x7F << 8) | 0xA0; /* reserved field; mimic behavior of my Sony DSR-40 */
+	/* reserved field; mimic behavior of my Sony DSR-40 */
+	omi->q[5] = cpu_to_le32((payload_size << 16) | (0x7F << 8) | 0xA0);
 	
 	omi->q[6] = 0;
 	omi->q[7] = 0;
@@ -114,10 +115,8 @@
 				    unsigned int data_size,
 				    unsigned long data_phys_addr)
 {
-	om->q[0] = 0; /* OUTPUT_MORE */
-	om->q[0] |= data_size;
-
-	om->q[1] = data_phys_addr;
+	om->q[0] = cpu_to_le32(data_size);
+	om->q[1] = cpu_to_le32(data_phys_addr);
 	om->q[2] = 0;
 	om->q[3] = 0;
 }
@@ -128,19 +127,20 @@
 				    unsigned int data_size,
 				    unsigned long data_phys_addr)
 {
-	ol->q[0] = 0;
-	ol->q[0] |= 1 << 28; /* OUTPUT_LAST */
+	u32 temp = 0;
+	temp |= 1 << 28; /* OUTPUT_LAST */
 
 	if(want_timestamp) /* controller will update timestamp at DMA time */
-		ol->q[0] |= 1 << 27;
+		temp |= 1 << 27;
 
 	if(want_interrupt)
-		ol->q[0] |= 3 << 20;
+		temp |= 3 << 20;
 
-	ol->q[0] |= 3 << 18; /* must take branch */
-	ol->q[0] |= data_size;
-	
-	ol->q[1] = data_phys_addr;
+	temp |= 3 << 18; /* must take branch */
+	temp |= data_size;
+
+	ol->q[0] = cpu_to_le32(temp);
+	ol->q[1] = cpu_to_le32(data_phys_addr);
 	ol->q[2] = 0;
 	ol->q[3] = 0;
 }
@@ -152,15 +152,16 @@
 				   unsigned int data_size,
 				   unsigned long data_phys_addr)
 {
-	im->q[0] =  2 << 28; /* INPUT_MORE */
-	im->q[0] |= 8 << 24; /* s = 1, update xferStatus and resCount */
+	u32 temp =  2 << 28; /* INPUT_MORE */
+	temp |= 8 << 24; /* s = 1, update xferStatus and resCount */
 	if (want_interrupt)
-		im->q[0] |= 0 << 20; /* interrupts, i=0 in packet-per-buffer mode */
-	im->q[0] |= 0x0 << 16; /* disable branch to address for packet-per-buffer mode */
+		temp |= 0 << 20; /* interrupts, i=0 in packet-per-buffer mode */
+	temp |= 0x0 << 16; /* disable branch to address for packet-per-buffer mode */
 	                       /* disable wait on sync field, not used in DV :-( */
-       	im->q[0] |= data_size;
+       	temp |= data_size;
 
-	im->q[1] = data_phys_addr;
+	im->q[0] = cpu_to_le32(temp);
+	im->q[1] = cpu_to_le32(data_phys_addr);
 	im->q[2] = 0; /* branchAddress and Z not use in packet-per-buffer mode */
 	im->q[3] = 0; /* xferStatus & resCount, resCount must be initialize to data_size */
 }
@@ -169,16 +170,17 @@
 				    unsigned int data_size,
 				    unsigned long data_phys_addr)
 {
-	il->q[0] =  3 << 28; /* INPUT_LAST */
-	il->q[0] |= 8 << 24; /* s = 1, update xferStatus and resCount */
-	il->q[0] |= 3 << 20; /* enable interrupts */
-	il->q[0] |= 0xC << 16; /* enable branch to address */
+	u32 temp =  3 << 28; /* INPUT_LAST */
+	temp |= 8 << 24; /* s = 1, update xferStatus and resCount */
+	temp |= 3 << 20; /* enable interrupts */
+	temp |= 0xC << 16; /* enable branch to address */
 	                       /* disable wait on sync field, not used in DV :-( */
-	il->q[0] |= data_size;
+	temp |= data_size;
 
-	il->q[1] = data_phys_addr;
-	il->q[2] = 1; /* branchAddress (filled in later) and Z = 1 descriptor in next block */
-	il->q[3] = data_size; /* xferStatus & resCount, resCount must be initialize to data_size */
+	il->q[0] = cpu_to_le32(temp);
+	il->q[1] = cpu_to_le32(data_phys_addr);
+	il->q[2] = cpu_to_le32(1); /* branchAddress (filled in later) and Z = 1 descriptor in next block */
+	il->q[3] = cpu_to_le32(data_size); /* xferStatus & resCount, resCount must be initialize to data_size */
 }
 
 
@@ -434,6 +436,7 @@
 
 	/* OHCI card IT DMA context number, -1 if not in use */
 	int ohci_it_ctx;
+	struct ohci1394_iso_tasklet it_tasklet;
 
 	/* register offsets for current IT DMA context, 0 if not in use */
 	u32 ohci_IsoXmitContextControlSet;
@@ -441,6 +444,7 @@
 	u32 ohci_IsoXmitCommandPtr;
 	
 	/* OHCI card IR DMA context number, -1 if not in use */
+	struct ohci1394_iso_tasklet ir_tasklet;
 	int ohci_ir_ctx;
 
 	/* register offsets for current IR DMA context, 0 if not in use */
@@ -476,6 +480,9 @@
 	     immediately. This is safe because the interrupt handler will never
 	     advance active_frame onto a frame that is not READY (and the spinlock
 	     must be held while marking a frame READY).
+
+	     spinlock is also used to protect ohci_it_ctx and ohci_ir_ctx,
+	     which can be accessed from both process and interrupt context
 	 */
 	spinlock_t spinlock;
 
diff -urN linux-2.4.20-pre7/drivers/ieee1394/dv1394.c linux-2.4.20-pre8/drivers/ieee1394/dv1394.c
--- linux-2.4.20-pre7/drivers/ieee1394/dv1394.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/dv1394.c	Wed Sep 25 18:21:41 2002
@@ -159,9 +159,8 @@
 	reg_read(ohci, OHCI1394_IsochronousCycleTimer);
 }
 
-static void irq_handler(int card, quadlet_t isoRecvIntEvent, 
-			quadlet_t isoXmitIntEvent, void *data);
-
+static void it_tasklet_func(unsigned long data);
+static void ir_tasklet_func(unsigned long data);
 
 /* GLOBAL DATA */
 
@@ -188,42 +187,29 @@
 }
 
 
-/* Taken from bttv.c */
 /*******************************/
 /* Memory management functions */
 /*******************************/
 
+/* note: we no longer use mem_map_reserve, because it causes a memory
+   leak, and setting vma->vm_flags to VM_RESERVED should be sufficient
+   to pin the pages in memory anyway. */
+
 static void * rvmalloc(unsigned long size)
 {
 	void * mem;
-	unsigned long adr;
 
-	size = PAGE_ALIGN(size);
-	mem=vmalloc_32(size);
-	if (mem) {
+	mem = vmalloc_32(size);
+
+	if(mem)
 		memset(mem, 0, size); /* Clear the ram out, 
 					 no junk to the user */
-	        adr=(unsigned long) mem;
-		while (size > 0) {
-			mem_map_reserve(vmalloc_to_page((void *)adr));
-			adr+=PAGE_SIZE;
-			size-=PAGE_SIZE;
-		}
-	}
 	return mem;
 }
 
 static void rvfree(void * mem, unsigned long size)
 {
-        unsigned long adr;
-
 	if (mem) {
-	        adr=(unsigned long) mem;
-		while (size > 0) {
-			mem_map_unreserve(vmalloc_to_page((void *)adr));
-			adr+=PAGE_SIZE;
-			size-=PAGE_SIZE;
-		}
 		vfree(mem);
 	}
 }
@@ -594,7 +580,7 @@
 		/* note: we are not linked into the active DMA chain yet */
 
 		if(last_branch_address) {
-			*(last_branch_address) = block_dma | n_descriptors; 
+			*(last_branch_address) = cpu_to_le32(block_dma | n_descriptors);
 		}
 
 		last_branch_address = branch_address;
@@ -606,7 +592,7 @@
 
 	/* when we first assemble a new frame, set the final branch 
 	   to loop back up to the top */
-	*(f->frame_end_branch) = f->descriptor_pool_dma | f->first_n_descriptors;
+	*(f->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | f->first_n_descriptors);
 
 
 	/* make the latest version of the frame buffer visible to the PCI card */
@@ -643,15 +629,18 @@
 		/* if DMA is already active, we are almost done */
 		/* just link us onto the active DMA chain */
 		if(video->frames[last_frame]->frame_end_branch) {
+			u32 temp;
 
 			/* point the previous frame's tail to this frame's head */
-			*(video->frames[last_frame]->frame_end_branch) = f->descriptor_pool_dma | f->first_n_descriptors; 
+			*(video->frames[last_frame]->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | f->first_n_descriptors);
 
 			/* this write MUST precede the next one, or we could silently drop frames */
 			wmb();
 			
 			/* disable the want_status semaphore on the last packet */
-			*(video->frames[last_frame]->frame_end_branch - 2) &= 0xF7CFFFFF;
+			temp = le32_to_cpu(*(video->frames[last_frame]->frame_end_branch - 2));
+			temp &= 0xF7CFFFFF;
+			*(video->frames[last_frame]->frame_end_branch - 2) = cpu_to_le32(temp);
 
 			/* flush these writes to memory ASAP */
 			flush_pci_write(video->ohci);
@@ -914,14 +903,14 @@
 		last_branch_address = f->frame_end_branch;
 
 		if (last_branch_address)
-			*(last_branch_address) = block_dma | 1; /* set Z=1 */
+			*(last_branch_address) = cpu_to_le32(block_dma | 1); /* set Z=1 */
 
 		f->frame_end_branch = &(block->u.in.il.q[2]);
 	}
 	
 	/* loop tail to head */
 	if (f->frame_end_branch)
-		*(f->frame_end_branch) =  f->descriptor_pool_dma | 1; /* set Z=1 */
+		*(f->frame_end_branch) = cpu_to_le32(f->descriptor_pool_dma | 1); /* set Z=1 */
 
 	spin_unlock_irqrestore(&video->spinlock, irq_flags);
 
@@ -992,6 +981,7 @@
 		do_dv1394_shutdown(video, 0);
 
 
+	
 	/* try to claim the ISO channel */
 	spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
 	if(video->ohci->ISO_channel_usage & chan_mask) {
@@ -1004,43 +994,75 @@
 
 	video->channel = init->channel;
 
+	/* initialize misc. fields of video */
+	video->n_frames = init->n_frames;
+	video->pal_or_ntsc = init->format;
 	
-	/* find and claim DMA contexts on the OHCI card */
+
+	video->cip_accum = 0;
+	video->continuity_counter = 0;
+
+	video->active_frame = -1;
+	video->first_clear_frame = 0;
+	video->n_clear_frames = video->n_frames;
+	video->dropped_frames = 0;
+
+	video->write_off = 0;
+
+	video->first_run = 1;
+	video->current_packet = -1;
+	video->first_frame = 0;
+
+
+	if(video->pal_or_ntsc == DV1394_NTSC) {
+		video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_NTSC;
+		video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_NTSC;
+		video->frame_size = DV1394_NTSC_FRAME_SIZE;
+	} else {
+		video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_PAL;
+		video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_PAL;
+		video->frame_size = DV1394_PAL_FRAME_SIZE;
+	}
+
+	video->syt_offset = init->syt_offset;
 	
-	if(video->ohci_it_ctx == -1) {
+	
+	/* find and claim DMA contexts on the OHCI card */
 
-		for(i = 0; i < video->ohci->nb_iso_xmit_ctx; i++) {
+	/* XXX this should be the last step of initialization, since the interrupt
+	   handler uses ohci_i*_ctx to indicate whether or not it is safe to touch
+	   frames. I'm not making this change quite yet, since it would be better
+	   to clean up the init/shutdown process first.*/
 
-			if(! test_and_set_bit(i, &video->ohci->it_ctx_usage)) {
-				video->ohci_it_ctx = i;
-				debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx);
-				break;
-			}
-		}
-				
-		if(i == video->ohci->nb_iso_xmit_ctx) {
+	if(video->ohci_it_ctx == -1) {
+		ohci1394_init_iso_tasklet(&video->it_tasklet, OHCI_ISO_TRANSMIT,
+					  it_tasklet_func, (unsigned long) video);
+
+		if (ohci1394_register_iso_tasklet(video->ohci, &video->it_tasklet) < 0) {	
 			printk(KERN_ERR "dv1394: could not find an available IT DMA context\n");
 			retval = -EBUSY;
 			goto err_ctx;
 		}
+		else {
+			video->ohci_it_ctx = video->it_tasklet.context;
+			debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx);
+		}
 	}
 	
 
 	if(video->ohci_ir_ctx == -1) {
-		for(i = 0; i < video->ohci->nb_iso_rcv_ctx; i++) {
+		ohci1394_init_iso_tasklet(&video->ir_tasklet, OHCI_ISO_RECEIVE,
+					  ir_tasklet_func, (unsigned long) video);
 
-			if(! test_and_set_bit(i, &video->ohci->ir_ctx_usage)) {
-				video->ohci_ir_ctx = i;
-				debug_printk("dv1394: claimed IR DMA context %d\n", video->ohci_ir_ctx);
-				break;
-			}
-		}
-				
-		if(i == video->ohci->nb_iso_rcv_ctx) {
+		if (ohci1394_register_iso_tasklet(video->ohci, &video->ir_tasklet) < 0) {
 			printk(KERN_ERR "dv1394: could not find an available IR DMA context\n");
 			retval = -EBUSY;
 			goto err_ctx;
 		}
+		else {
+			video->ohci_ir_ctx = video->ir_tasklet.context;
+			debug_printk("dv1394: claimed IR DMA context %d\n", video->ohci_ir_ctx);
+		}
 	}
 
 	
@@ -1055,38 +1077,8 @@
 		}
 	}
 
-	/* initialize misc. fields of video */
-	video->n_frames = init->n_frames;
-	video->pal_or_ntsc = init->format;
 	
 
-	video->cip_accum = 0;
-	video->continuity_counter = 0;
-
-	video->active_frame = -1;
-	video->first_clear_frame = 0;
-	video->n_clear_frames = video->n_frames;
-	video->dropped_frames = 0;
-
-	video->write_off = 0;
-
-	video->first_run = 1;
-	video->current_packet = -1;
-	video->first_frame = 0;
-
-
-	if(video->pal_or_ntsc == DV1394_NTSC) {
-		video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_NTSC;
-		video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_NTSC;
-		video->frame_size = DV1394_NTSC_FRAME_SIZE;
-	} else {
-		video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_PAL;
-		video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_PAL;
-		video->frame_size = DV1394_PAL_FRAME_SIZE;
-	}
-
-	video->syt_offset = init->syt_offset;
-
 	if(video->user_buf == NULL) {
 		unsigned int i;
 		
@@ -1224,11 +1216,11 @@
 
  err_ctx:
 	if(video->ohci_it_ctx != -1) {
-		clear_bit(video->ohci_it_ctx, &video->ohci->it_ctx_usage);
+		ohci1394_unregister_iso_tasklet(video->ohci, &video->it_tasklet);
 		video->ohci_it_ctx = -1;
 	}
 	if(video->ohci_ir_ctx != -1) {
-		clear_bit(video->ohci_ir_ctx, &video->ohci->ir_ctx_usage);
+		ohci1394_unregister_iso_tasklet(video->ohci, &video->ir_tasklet);
 		video->ohci_ir_ctx = -1;
 	}
 	
@@ -1313,25 +1305,14 @@
 static int do_dv1394_shutdown(struct video_card *video, int free_user_buf)
 {
 	int i;
-
+	unsigned long flags;
+	
 	debug_printk("dv1394: shutdown...\n");
 
 	/* stop DMA if in progress */
 	stop_dma(video);
 	
-	/* release the ISO channel */
-	if(video->channel != -1) {
-		u64 chan_mask;
-		unsigned long flags;
-		
-		chan_mask = (u64)1 << video->channel;
-		
-		spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
-		video->ohci->ISO_channel_usage &= ~(chan_mask);
-		spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
-		
-		video->channel = -1;
-	}
+	spin_lock_irqsave(&video->spinlock, flags);
 
 	/* release the DMA contexts */
 	if(video->ohci_it_ctx != -1) {
@@ -1361,6 +1342,22 @@
 		video->ohci_ir_ctx = -1;
 	}
 
+	spin_unlock_irqrestore(&video->spinlock, flags);
+	
+	/* release the ISO channel */
+	if(video->channel != -1) {
+		u64 chan_mask;
+		unsigned long flags;
+		
+		chan_mask = (u64)1 << video->channel;
+		
+		spin_lock_irqsave(&video->ohci->IR_channel_lock, flags);
+		video->ohci->ISO_channel_usage &= ~(chan_mask);
+		spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags);
+		
+		video->channel = -1;
+	}
+	
 	/* free the frame structs */
 	for(i = 0; i < DV1394_MAX_FRAMES; i++) {
 		if(video->frames[i])
@@ -2315,12 +2312,13 @@
 
 /*** DEVICE DRIVER HANDLERS ************************************************/
 
-static void irq_handler(int card, quadlet_t isoRecvIntEvent, 
-			quadlet_t isoXmitIntEvent, void *data)
+static void it_tasklet_func(unsigned long data)
 {
 	int wake = 0;
 	struct video_card *video = (struct video_card*) data;
 
+	spin_lock(&video->spinlock);
+	
 	irq_printk("INTERRUPT! Video = %08lx Iso event Recv: %08x Xmit: %08x\n",
 		   (unsigned long) video, isoRecvIntEvent, isoXmitIntEvent);
 	irq_printk("ContextControl = %08x, CommandPtr = %08x\n", 
@@ -2330,13 +2328,12 @@
 
 	
 	if( (video->ohci_it_ctx != -1) &&
-	    (isoXmitIntEvent & (1 << video->ohci_it_ctx)) &&
 	    (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) {
 
 		struct frame *f;
 		unsigned int frame, i;
 
-		spin_lock(&video->spinlock);
+		
 		if(video->active_frame == -1)
 			frame = 0;
 		else
@@ -2392,13 +2389,15 @@
 			/* see if we need to set the timestamp for the next frame */
 			if( *(f->mid_frame_timestamp) ) {
 				struct frame *next_frame;
-				u32 ts_cyc, ts_off;
+				u32 begin_ts, ts_cyc, ts_off;
 
 				*(f->mid_frame_timestamp) = 0;
 
+				begin_ts = le32_to_cpu(*(f->frame_begin_timestamp));
+
 				irq_printk("  MIDDLE - first packet was sent at cycle %4u (%2u), assigned timestamp was (%2u) %4u\n",
-				       *(f->frame_begin_timestamp) & 0x1FFF, *(f->frame_begin_timestamp) & 0xF,
-				       f->assigned_timestamp >> 12,       f->assigned_timestamp & 0xFFF);
+					   begin_ts & 0x1FFF, begin_ts & 0xF,
+					   f->assigned_timestamp >> 12, f->assigned_timestamp & 0xFFF);
 
 				/* prepare next frame and assign timestamp */
 				next_frame = video->frames[ (frame+1) % video->n_frames ];
@@ -2412,7 +2411,7 @@
 
 				/* set the timestamp to the timestamp of the last frame sent,
 				   plus the length of the last frame sent, plus the syt latency */
-				ts_cyc = *(f->frame_begin_timestamp) & 0xF;
+				ts_cyc = begin_ts & 0xF;
 				/* advance one frame, plus syt latency (typically 2-3) */
 				ts_cyc += f->n_packets + video->syt_offset ; 
 
@@ -2446,30 +2445,41 @@
 
 		
 		} /* for(each frame) */
+	}
+
+	spin_unlock(&video->spinlock);
 
-		spin_unlock(&video->spinlock);
+	if(wake) {
+		kill_fasync(&video->fasync, SIGIO, POLL_OUT);
 		
-	} /* end XMIT portion */
+		/* wake readers/writers/ioctl'ers */
+		wake_up_interruptible(&video->waitq);
+	}
+}
 
-	/***** RECEIVE INTERRUPT and DMA ACTIVE *****/
+static void ir_tasklet_func(unsigned long data)
+{
+	int wake = 0;
+	struct video_card *video = (struct video_card*) data;
 
-	else if( (video->ohci_ir_ctx != -1) &&
-		 (isoRecvIntEvent & (1 << video->ohci_ir_ctx)) &&
-		 (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) { 
+	if( (video->ohci_ir_ctx != -1) &&
+	    (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) { 
 
 		int sof=0; /* start-of-frame flag */
 		struct frame *f;
+		u16 packet_length, packet_time;
 
-		spin_lock(&video->spinlock);
+		packet_length = le16_to_cpu(video->packet_buffer[video->current_packet].data_length);
+		packet_time   = le16_to_cpu(video->packet_buffer[video->current_packet].timestamp);
 
 		irq_printk("received packet %02d, timestamp=%04x, length=%04x, sof=%02x%02x\n", video->current_packet,
-			   video->packet_buffer[video->current_packet].timestamp, video->packet_buffer[video->current_packet].data_length, 
+			   packet_time, packet_length, 
 			   video->packet_buffer[video->current_packet].data[0], video->packet_buffer[video->current_packet].data[1]);
 		
 		f = video->frames[video->active_frame];
 
 		/* exclude empty packet */
-		if (video->packet_buffer[video->current_packet].data_length > 8) {
+		if (packet_length > 8) {
 		
 			/* check for start of frame */
 			sof = (video->packet_buffer[video->current_packet].data[0] == 0x1f &&
@@ -2524,22 +2534,15 @@
 		/* advance packet_buffer cursor */
 		video->current_packet = (video->current_packet + 1) % MAX_PACKET_BUFFER;
  
- 		spin_unlock(&video->spinlock);
-
 		wake = 1; /* why the hell not? */
 
 	} /* receive interrupt */
 
+	spin_unlock(&video->spinlock);
+	
 	if(wake) {
-		
-		/* send SIGIO */
-		
-		if(isoRecvIntEvent & (1))
-			kill_fasync(&video->fasync, SIGIO, POLL_IN);
-		
-		if(isoXmitIntEvent & (1))
-			kill_fasync(&video->fasync, SIGIO, POLL_OUT);
-		
+		kill_fasync(&video->fasync, SIGIO, POLL_IN);
+
 		/* wake readers/writers/ioctl'ers */
 		wake_up_interruptible(&video->waitq);
 	}
@@ -2572,12 +2575,15 @@
 		list_for_each(lh, &dv1394_devfs) {
 			p = list_entry(lh, struct dv1394_devfs_entry, list);
 			if(!strncmp(p->name, name, sizeof(p->name))) {
-				spin_unlock( &dv1394_devfs_lock);
-				return p;
+				goto found;
 			}
 		}
 	}
-	return NULL;
+	p = NULL;
+	
+found:
+	spin_unlock( &dv1394_devfs_lock);
+	return p;
 }
 
 static int dv1394_devfs_add_entry(struct video_card *video)
@@ -2704,12 +2710,6 @@
 	
 	memset(video, 0, sizeof(struct video_card));
 	
-	if (ohci1394_hook_irq(ohci, irq_handler, (void*) video) != 0) {
-		printk(KERN_ERR "dv1394: ohci1394_hook_irq() failed\n");
-		goto err_free;
-	}
-
-	
 	video->ohci = ohci;
 	/* lower 2 bits of id indicate which of four "plugs"
 	   per host */
@@ -2763,7 +2763,7 @@
 	if (format == DV1394_NTSC)
 		video->id |= mode;
 	else video->id |= 2 + mode;
-	
+
 #ifdef CONFIG_DEVFS_FS
 	if (dv1394_devfs_add_entry(video) < 0)
 			goto err_free;
@@ -2785,7 +2785,6 @@
 	
 	/* obviously nobody has the driver open at this point */
 	do_dv1394_shutdown(video, 1);
-	ohci1394_unhook_irq(video->ohci, irq_handler, (void*) video);
 	snprintf(buf, sizeof(buf), "dv/host%d/%s/%s", (video->id >> 2),
 		(video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),
 		(video->mode == MODE_RECEIVE ? "in" : "out")
@@ -2923,12 +2922,13 @@
 	if(!video)
 		return;
 
+	
+	spin_lock_irqsave(&video->spinlock, flags);
+
 	/* check IT context */
 	if(video->ohci_it_ctx != -1) {
 		u32 ctx;
 		
-		spin_lock_irqsave(&video->spinlock, flags);
-		
 		ctx = reg_read(video->ohci, video->ohci_IsoXmitContextControlSet);
 
 		/* if(RUN but not ACTIVE) */
@@ -2959,16 +2959,12 @@
 				   reg_read(video->ohci, video->ohci_IsoXmitContextControlSet),
 				   reg_read(video->ohci, video->ohci_IsoXmitCommandPtr));
 		}
-
-		spin_unlock_irqrestore(&video->spinlock, flags);
 	}
 	
 	/* check IR context */
 	if(video->ohci_ir_ctx != -1) {
 		u32 ctx;
 		
-		spin_lock_irqsave(&video->spinlock, flags);
-		
 		ctx = reg_read(video->ohci, video->ohci_IsoRcvContextControlSet);
 
 		/* if(RUN but not ACTIVE) */
@@ -3000,10 +2996,10 @@
 				   reg_read(video->ohci, video->ohci_IsoRcvContextControlSet),
 				   reg_read(video->ohci, video->ohci_IsoRcvCommandPtr));
 		}
-
-		spin_unlock_irqrestore(&video->spinlock, flags);
 	}
-
+	
+	spin_unlock_irqrestore(&video->spinlock, flags);
+	
 	/* wake readers/writers/ioctl'ers */
 	wake_up_interruptible(&video->waitq);
 }
diff -urN linux-2.4.20-pre7/drivers/ieee1394/eth1394.c linux-2.4.20-pre8/drivers/ieee1394/eth1394.c
--- linux-2.4.20-pre7/drivers/ieee1394/eth1394.c	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/eth1394.c	Wed Sep 25 18:21:41 2002
@@ -77,7 +77,7 @@
 	printk(KERN_ERR fmt, ## args)
 
 static char version[] __devinitdata =
-	"eth1394.c:v0.50 15/Jul/01 Ben Collins <bcollins@debian.org>";
+	"$Rev: 546 $ Ben Collins <bcollins@debian.org>";
 
 /* Our ieee1394 highlevel driver */
 #define ETHER1394_DRIVER_NAME "ether1394"
@@ -99,6 +99,7 @@
 
 MODULE_AUTHOR("Ben Collins (bcollins@debian.org)");
 MODULE_DESCRIPTION("IEEE 1394 IPv4 Driver (IPv4-over-1394 as per RFC 2734)");
+MODULE_LICENSE("GPL");
 
 /* Find our host_info struct for a given host pointer. Must be called
  * under spinlock.  */
diff -urN linux-2.4.20-pre7/drivers/ieee1394/highlevel.c linux-2.4.20-pre8/drivers/ieee1394/highlevel.c
--- linux-2.4.20-pre7/drivers/ieee1394/highlevel.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/highlevel.c	Wed Sep 25 18:21:41 2002
@@ -139,7 +139,7 @@
         }
 
         if (host->iso_listen_count[channel]++ == 0) {
-                host->ops->devctl(host, ISO_LISTEN_CHANNEL, channel);
+                host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel);
         }
 }
 
@@ -152,7 +152,7 @@
         }
 
         if (--host->iso_listen_count[channel] == 0) {
-                host->ops->devctl(host, ISO_UNLISTEN_CHANNEL, channel);
+                host->driver->devctl(host, ISO_UNLISTEN_CHANNEL, channel);
         }
 }
 
diff -urN linux-2.4.20-pre7/drivers/ieee1394/hosts.c linux-2.4.20-pre8/drivers/ieee1394/hosts.c
--- linux-2.4.20-pre7/drivers/ieee1394/hosts.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/hosts.c	Wed Sep 25 18:21:41 2002
@@ -38,7 +38,7 @@
         return -1;
 }
 
-static struct hpsb_host_operations dummy_ops = {
+static struct hpsb_host_driver dummy_driver = {
         .transmit_packet = dummy_transmit_packet,
         .devctl =          dummy_devctl
 };
@@ -63,7 +63,7 @@
         spin_lock_irqsave(&hosts_lock, flags);
         list_for_each(lh, &hosts) {
                 if (host == list_entry(lh, struct hpsb_host, host_list)) {
-                        host->ops->devctl(host, MODIFY_USAGE, 1);
+                        host->driver->devctl(host, MODIFY_USAGE, 1);
 			host->refcount++;
                         retval = 1;
 			break;
@@ -87,7 +87,7 @@
 {
         unsigned long flags;
 
-        host->ops->devctl(host, MODIFY_USAGE, 0);
+        host->driver->devctl(host, MODIFY_USAGE, 0);
 
         spin_lock_irqsave(&hosts_lock, flags);
         host->refcount--;
@@ -128,7 +128,6 @@
 
 	h->hostdata = h + 1;
         h->driver = drv;
-        h->ops = drv->ops;
 	h->refcount = 1;
 
         INIT_LIST_HEAD(&h->pending_packets);
@@ -152,63 +151,26 @@
         unsigned long flags;
 
         spin_lock_irqsave(&hosts_lock, flags);
-        host->driver->number_of_hosts++;
-        list_add_tail(&host->driver_list, &host->driver->hosts);
         list_add_tail(&host->host_list, &hosts);
         spin_unlock_irqrestore(&hosts_lock, flags);
 
         highlevel_add_host(host);
-        host->ops->devctl(host, RESET_BUS, 0);
+        host->driver->devctl(host, RESET_BUS, 0);
 }
 
 void hpsb_remove_host(struct hpsb_host *host)
 {
-        struct hpsb_host_driver *drv = host->driver;
         unsigned long flags;
 
         host->is_shutdown = 1;
-        host->ops = &dummy_ops;
+        host->driver = &dummy_driver;
         highlevel_remove_host(host);
 
         spin_lock_irqsave(&hosts_lock, flags);
-        list_del(&host->driver_list);
         list_del(&host->host_list);
-        drv->number_of_hosts--;
         spin_unlock_irqrestore(&hosts_lock, flags);
 }
 
-
-struct hpsb_host_driver *hpsb_register_lowlevel(struct hpsb_host_operations *op,
-                                                const char *name)
-{
-        struct hpsb_host_driver *drv;
-
-        drv = kmalloc(sizeof(struct hpsb_host_driver), SLAB_KERNEL);
-        if (!drv) return NULL;
-
-        INIT_LIST_HEAD(&drv->list);
-        INIT_LIST_HEAD(&drv->hosts);
-        drv->number_of_hosts = 0;
-        drv->name = name;
-        drv->ops = op;
-
-        spin_lock(&host_drivers_lock);
-        list_add_tail(&drv->list, &host_drivers);
-        spin_unlock(&host_drivers_lock);
-
-        return drv;
-}
-
-void hpsb_unregister_lowlevel(struct hpsb_host_driver *drv)
-{
-        spin_lock(&host_drivers_lock);
-        list_del(&drv->list);
-        spin_unlock(&host_drivers_lock);
-
-        kfree(drv);
-}
-
-
 /*
  * This function calls the given function for every host currently registered.
  */
diff -urN linux-2.4.20-pre7/drivers/ieee1394/hosts.h linux-2.4.20-pre8/drivers/ieee1394/hosts.h
--- linux-2.4.20-pre7/drivers/ieee1394/hosts.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/hosts.h	Wed Sep 25 18:21:41 2002
@@ -15,7 +15,6 @@
 struct hpsb_host {
         struct list_head host_list;
 
-        struct hpsb_host_operations *ops;
         void *hostdata;
 
         atomic_t generation;
@@ -59,7 +58,6 @@
         struct csr_control csr;
 
         struct hpsb_host_driver *driver;
-        struct list_head driver_list;
 
 	struct pci_dev *pdev;
 };
@@ -113,7 +111,9 @@
         SHORT_RESET
 };
 
-struct hpsb_host_operations {
+struct hpsb_host_driver {
+	const char *name;
+
         /* This function must store a pointer to the configuration ROM into the
          * location referenced to by pointer and return the size of the ROM. It
          * may not fail.  If any allocation is required, it must be done
@@ -149,18 +149,6 @@
                                  quadlet_t data, quadlet_t compare);
 };
 
-struct hpsb_host_driver {
-        struct list_head list;
-
-        struct list_head hosts;
-
-        int number_of_hosts;
-        const char *name;
-
-        struct hpsb_host_operations *ops;
-};
-
-
 /* core internal use */
 void register_builtin_lowlevels(void);
 
@@ -184,8 +172,4 @@
 void hpsb_add_host(struct hpsb_host *host);
 void hpsb_remove_host(struct hpsb_host *h);
 
-struct hpsb_host_driver *hpsb_register_lowlevel(struct hpsb_host_operations *op,
-                                                const char *name);
-void hpsb_unregister_lowlevel(struct hpsb_host_driver *drv);
-
 #endif /* _IEEE1394_HOSTS_H */
diff -urN linux-2.4.20-pre7/drivers/ieee1394/ieee1394_core.c linux-2.4.20-pre8/drivers/ieee1394/ieee1394_core.c
--- linux-2.4.20-pre7/drivers/ieee1394/ieee1394_core.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/ieee1394_core.c	Wed Sep 25 18:21:41 2002
@@ -22,7 +22,6 @@
 #include <asm/bitops.h>
 #include <asm/byteorder.h>
 #include <asm/semaphore.h>
-#include <asm/smplock.h>
 
 #include "ieee1394_types.h"
 #include "ieee1394.h"
@@ -142,7 +141,7 @@
 int hpsb_reset_bus(struct hpsb_host *host, int type)
 {
         if (!host->in_bus_reset) {
-                host->ops->devctl(host, RESET_BUS, type);
+                host->driver->devctl(host, RESET_BUS, type);
                 return 0;
         } else {
                 return 1;
@@ -355,7 +354,7 @@
         }
 
         host->reset_retries = 0;
-        if (isroot) host->ops->devctl(host, ACT_CYCLE_MASTER, 1);
+        if (isroot) host->driver->devctl(host, ACT_CYCLE_MASTER, 1);
 	atomic_inc(&host->generation);
 	host->in_bus_reset = 0;
         highlevel_host_reset(host);
@@ -441,7 +440,7 @@
         }
 #endif
 
-        return host->ops->transmit_packet(host, packet);
+        return host->driver->transmit_packet(host, packet);
 }
 
 static void send_packet_nocare(struct hpsb_packet *packet)
@@ -737,7 +736,7 @@
         struct list_head *lh;
         LIST_HEAD(llist);
 
-        host->ops->devctl(host, CANCEL_REQUESTS, 0);
+        host->driver->devctl(host, CANCEL_REQUESTS, 0);
 
         spin_lock_irqsave(&host->pending_pkt_lock, flags);
         list_splice(&host->pending_packets, &llist);
@@ -862,19 +861,57 @@
 	write_unlock(&ieee1394_chardevs_lock);
 }
 
+/*
+  ieee1394_get_chardev() - look up and acquire a character device
+  driver that has previously registered using ieee1394_register_chardev()
+  
+  On success, returns 1 and sets module and file_ops to the driver.
+  The module will have an incremented reference count.
+   
+  On failure, returns 0.
+  The module will NOT have an incremented reference count.
+*/
+
+static int ieee1394_get_chardev(int blocknum,
+				struct module **module,
+				struct file_operations **file_ops)
+{
+	int ret = 0;
+       
+	if( (blocknum < 0) || (blocknum > 15) )
+		return ret;
+
+	read_lock(&ieee1394_chardevs_lock);
+
+	*module = ieee1394_chardevs[blocknum].module;
+	*file_ops = ieee1394_chardevs[blocknum].file_ops;
+
+	if(*file_ops == NULL)
+		goto out;
+
+	/* don't need try_inc_mod_count if the driver is non-modular */
+	if(*module && (try_inc_mod_count(*module) == 0))
+		goto out;
+
+	/* success! */
+	ret = 1;
+	
+out:
+	read_unlock(&ieee1394_chardevs_lock);
+	return ret;
+}
+
 /* the point of entry for open() on any ieee1394 character device */
 static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
 {
 	struct file_operations *file_ops;
 	struct module *module;
 	int blocknum;
-	int retval = -ENODEV;
+	int retval;
 
 	/*
 	  Maintaining correct module reference counts is tricky here!
 
-	  For Linux v2.4 and later:
-	  
 	  The key thing to remember is that the VFS increments the
 	  reference count of ieee1394 before it calls
 	  ieee1394_dispatch_open().
@@ -887,16 +924,7 @@
 	  If the open() fails, then the VFS will drop the
 	  reference count of whatever module file->f_op->owner points
 	  to, immediately after this function returns.
-
-	  The comments below refer to the 2.4 case, since the 2.2
-	  case is trivial.
-	  
 	*/
-
-#define INCREF(mod_) do { struct module *mod = (struct module*) mod_; \
-                          if(mod != NULL) __MOD_INC_USE_COUNT(mod); } while(0)
-#define DECREF(mod_) do { struct module *mod = (struct module*) mod_; \
-                          if(mod != NULL) __MOD_DEC_USE_COUNT(mod); } while(0)
 	
         /* shift away lower four bits of the minor
 	   to get the index of the ieee1394_driver
@@ -904,20 +932,10 @@
 	
 	blocknum = (minor(inode->i_rdev) >> 4) & 0xF;
 
-	/* printk("ieee1394_dispatch_open(%d)", blocknum); */
+	/* look up the driver */
 
-	read_lock(&ieee1394_chardevs_lock);
-	module = ieee1394_chardevs[blocknum].module;
-	/* bump the reference count of the driver that
-	   will receive the open() */
-	INCREF(module);
-	file_ops = ieee1394_chardevs[blocknum].file_ops;
-	read_unlock(&ieee1394_chardevs_lock);
-
-	if(file_ops == NULL) {
-		DECREF(module);
-		goto out_fail;
-	}
+	if(ieee1394_get_chardev(blocknum, &module, &file_ops) == 0)
+		return -ENODEV;
 
 	/* redirect all subsequent requests to the driver's
 	   own file_operations */
@@ -929,42 +947,42 @@
 	/* follow through with the open() */
 	retval = file_ops->open(inode, file);
 
-	if(retval) {
+	if(retval == 0) {
 		
-		/* if the open() failed, then we need to drop the
-                   extra reference we gave to the task-specific
-                   driver */
+		/* If the open() succeeded, then ieee1394 will be left
+		   with an extra module reference, so we discard it here.
 
-		DECREF(module);
-		goto out_fail;
+		   The task-specific driver still has the extra
+		   reference given to it by ieee1394_get_chardev().
+		   This extra reference prevents the module from
+		   unloading while the file is open, and will be
+		   dropped by the VFS when the file is released.
+		*/
 		
-	} else {
-
-		/* if the open() succeeded, then ieee1394 will be left
-		   with an extra module reference, so we discard it here.*/
+		if(THIS_MODULE)
+			__MOD_DEC_USE_COUNT((struct module*) THIS_MODULE);
+		
+		/* note that if ieee1394 is compiled into the kernel,
+		   THIS_MODULE will be (void*) NULL, hence the if and
+		   the cast are necessary */
 
-		DECREF(THIS_MODULE);
+	} else {
 
-		/* the task-specific driver still has the extra
-		   reference we gave it. This extra reference prevents
-		   the module from unloading while the file is open,
-		   and will be dropped by the VFS when the file is
-		   released. */
+		/* if the open() failed, then we need to drop the
+		   extra reference we gave to the task-specific
+		   driver */
 		
-		return 0;
-	}
-	       
-out_fail:
-	/* point the file's f_ops back to ieee1394. The VFS will then
-	   decrement ieee1394's reference count immediately after this
-	   function returns. */
+		if(module)
+			__MOD_DEC_USE_COUNT(module);
 	
-	file->f_op = &ieee1394_chardev_ops;
-	return retval;
+		/* point the file's f_ops back to ieee1394. The VFS will then
+		   decrement ieee1394's reference count immediately after this
+		   function returns. */
+		
+		file->f_op = &ieee1394_chardev_ops;
+	}
 
-#undef INCREF
-#undef DECREF
-	     
+	return retval;
 }
 
 struct proc_dir_entry *ieee1394_procfs_entry;
@@ -1025,8 +1043,6 @@
 module_exit(ieee1394_cleanup);
 
 /* Exported symbols */
-EXPORT_SYMBOL(hpsb_register_lowlevel);
-EXPORT_SYMBOL(hpsb_unregister_lowlevel);
 EXPORT_SYMBOL(hpsb_alloc_host);
 EXPORT_SYMBOL(hpsb_add_host);
 EXPORT_SYMBOL(hpsb_remove_host);
diff -urN linux-2.4.20-pre7/drivers/ieee1394/ieee1394_core.h linux-2.4.20-pre8/drivers/ieee1394/ieee1394_core.h
--- linux-2.4.20-pre7/drivers/ieee1394/ieee1394_core.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/ieee1394_core.h	Wed Sep 25 18:21:41 2002
@@ -16,7 +16,7 @@
         struct list_head list;
 
         /* This can be used for host driver internal linking. */
-        struct hpsb_packet *xnext;
+	struct list_head driver_list;
 
         nodeid_t node_id;
 
@@ -77,6 +77,10 @@
         quadlet_t embedded_header[5];
 };
 
+static inline struct hpsb_packet *driver_packet(struct list_head *l)
+{
+	return list_entry(l, struct hpsb_packet, driver_list);
+}
 
 void abort_timedouts(struct hpsb_host *host);
 void abort_requests(struct hpsb_host *host);
diff -urN linux-2.4.20-pre7/drivers/ieee1394/nodemgr.c linux-2.4.20-pre8/drivers/ieee1394/nodemgr.c
--- linux-2.4.20-pre7/drivers/ieee1394/nodemgr.c	Wed Sep 25 18:20:50 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/nodemgr.c	Wed Sep 25 18:21:41 2002
@@ -133,16 +133,24 @@
 		/* Now the unit directories */
 		list_for_each (l, &ne->unit_directories) {
 			struct unit_directory *ud = list_entry (l, struct unit_directory, node_list);
+			int printed = 0; // small hack
+
 			PUTF("  Unit Directory %d:\n", ud_count++);
-			if (ud->flags & UNIT_DIRECTORY_VENDOR_ID)
+			if (ud->flags & UNIT_DIRECTORY_VENDOR_ID) {
 				PUTF("    Vendor/Model ID: %s [%06x]",
 				     ud->vendor_name ?: "Unknown", ud->vendor_id);
-			else if (ud->flags & UNIT_DIRECTORY_MODEL_ID) /* Have to put something */
-				PUTF("    Vendor/Model ID: %s [%06x]",
-				      ne->vendor_name ?: "Unknown", ne->vendor_id);
-			if (ud->flags & UNIT_DIRECTORY_MODEL_ID)
+				printed = 1;
+			}
+			if (ud->flags & UNIT_DIRECTORY_MODEL_ID) {
+				if (!printed)
+					PUTF("    Vendor/Model ID: %s [%06x]",
+					     ne->vendor_name ?: "Unknown", ne->vendor_id);
 				PUTF(" / %s [%06x]", ud->model_name ?: "Unknown", ud->model_id);
-			PUTF("\n");
+				printed = 1;
+			}
+			if (printed)
+				PUTF("\n");
+
 			if (ud->flags & UNIT_DIRECTORY_SPECIFIER_ID)
 				PUTF("    Software Specifier ID: %06x\n", ud->specifier_id);
 			if (ud->flags & UNIT_DIRECTORY_VERSION)
@@ -1299,14 +1307,12 @@
 		}
 	}
 
-	if (hi != NULL)
-	{
+	if (hi != NULL) {
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 		HPSB_DEBUG ("NodeMgr: Processing host reset for %s", host->driver->name);
 #endif
 		up(&hi->reset_sem);
-	}
-	else
+	} else
 		HPSB_ERR ("NodeMgr: could not process reset of non-existent host");
 
 	spin_unlock_irqrestore (&host_info_lock, flags);
diff -urN linux-2.4.20-pre7/drivers/ieee1394/ohci1394.c linux-2.4.20-pre8/drivers/ieee1394/ohci1394.c
--- linux-2.4.20-pre7/drivers/ieee1394/ohci1394.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/ohci1394.c	Wed Sep 25 18:21:41 2002
@@ -154,7 +154,7 @@
 printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
 
 static char version[] __devinitdata =
-	"$Rev: 530 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 555 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 MODULE_PARM(attempt_root,"i");
@@ -170,10 +170,6 @@
 
 static void ohci1394_pci_remove(struct pci_dev *pdev);
 
-static inline void ohci1394_run_irq_hooks(struct ti_ohci *ohci,
-					  quadlet_t isoRecvEvent, 
-					  quadlet_t isoXmitEvent);
-
 #ifndef __LITTLE_ENDIAN
 /* Swap a series of quads inplace. */
 static __inline__ void block_swab32(quadlet_t *data, size_t size) {
@@ -443,10 +439,8 @@
 	d->sent_ind = 0;
 	d->free_prgs = d->num_desc;
         d->branchAddrPtr = NULL;
-	d->fifo_first = NULL;
-	d->fifo_last = NULL;
-	d->pending_first = NULL;
-	d->pending_last = NULL;
+	INIT_LIST_HEAD(&d->fifo_list);
+	INIT_LIST_HEAD(&d->pending_list);
 
 	DBGMSG(ohci->id, "Transmit DMA ctx=%d initialized", d->ctx);
 }
@@ -477,34 +471,6 @@
 {
 	quadlet_t buf;
 
-	/* Start off with a soft reset, to clear everything to a sane
-	 * state. */
-	ohci_soft_reset(ohci);
-
-	/* Now enable LPS, which we need in order to start accessing
-	 * most of the registers.  In fact, on some cards (ALI M5251),
-	 * accessing registers in the SClk domain without LPS enabled
-	 * will lock up the machine.  Wait 50msec to make sure we have
-	 * full link enabled.  */
-	reg_write(ohci, OHCI1394_HCControlSet, 0x00080000);
-	mdelay(50);
-
-	/* Determine the number of available IR and IT contexts. */
-	ohci->nb_iso_rcv_ctx =
-		get_nb_iso_ctx(ohci, OHCI1394_IsoRecvIntMaskSet);
-	DBGMSG(ohci->id, "%d iso receive contexts available",
-	       ohci->nb_iso_rcv_ctx);
-
-	ohci->nb_iso_xmit_ctx = 
-		get_nb_iso_ctx(ohci, OHCI1394_IsoXmitIntMaskSet);
-	DBGMSG(ohci->id, "%d iso transmit contexts available",
-	       ohci->nb_iso_xmit_ctx);
-
-	/* Set the usage bits for non-existent contexts so they can't
-	 * be allocated */
-	ohci->ir_ctx_usage |= ~0 << ohci->nb_iso_rcv_ctx;
-	ohci->it_ctx_usage |= ~0 << ohci->nb_iso_xmit_ctx;
-	
 	spin_lock_init(&ohci->phy_reg_lock);
 	spin_lock_init(&ohci->event_lock);
   
@@ -571,18 +537,18 @@
 	reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear, 0xffffffff);
 
 	/* Initialize AR dma */
-	initialize_dma_rcv_ctx(ohci->ar_req_context, 0);
-	initialize_dma_rcv_ctx(ohci->ar_resp_context, 0);
+	initialize_dma_rcv_ctx(&ohci->ar_req_context, 0);
+	initialize_dma_rcv_ctx(&ohci->ar_resp_context, 0);
 
 	/* Initialize AT dma */
-	initialize_dma_trm_ctx(ohci->at_req_context);
-	initialize_dma_trm_ctx(ohci->at_resp_context);
+	initialize_dma_trm_ctx(&ohci->at_req_context);
+	initialize_dma_trm_ctx(&ohci->at_resp_context);
 
 	/* Initialize IR dma */
-	initialize_dma_rcv_ctx(ohci->ir_context, 1);
+	initialize_dma_rcv_ctx(&ohci->ir_context, 1);
 
         /* Initialize IT dma */
-        initialize_dma_trm_ctx(ohci->it_context);
+        initialize_dma_trm_ctx(&ohci->it_context);
 
 	/* Set up isoRecvIntMask to generate interrupts for context 0
 	   (thanks to Michael Greger for seeing that I forgot this) */
@@ -789,13 +755,7 @@
 	d->free_prgs--;
 
 	/* queue the packet in the appropriate context queue */
-	if (d->fifo_last) {
-		d->fifo_last->xnext = packet;
-		d->fifo_last = packet;
-	} else {
-		d->fifo_first = packet;
-		d->fifo_last = packet;
-	}
+	list_add_tail(&packet->driver_list, &d->fifo_list);
 	d->prg_ind = (d->prg_ind+1)%d->num_desc;
 }
 
@@ -807,22 +767,24 @@
  */ 
 static int dma_trm_flush(struct ti_ohci *ohci, struct dma_trm_ctx *d)
 {
+	struct hpsb_packet *p;
 	int idx,z;
 
-	if (d->pending_first == NULL || d->free_prgs == 0) 
+	if (list_empty(&d->pending_list) || d->free_prgs == 0)
 		return 0;
 
+	p = driver_packet(d->pending_list.next);
 	idx = d->prg_ind;
-	z = (d->pending_first->data_size) ? 3 : 2;
+	z = (p->data_size) ? 3 : 2;
 
 	/* insert the packets into the at dma fifo */
-	while (d->free_prgs>0 && d->pending_first) {
-		insert_packet(ohci, d, d->pending_first);
-		d->pending_first = d->pending_first->xnext;
+	while (d->free_prgs > 0 && !list_empty(&d->pending_list)) {
+		struct hpsb_packet *p = driver_packet(d->pending_list.next);
+		list_del(&p->driver_list);
+		insert_packet(ohci, d, p);
 	}
-	if (d->pending_first == NULL) 
-		d->pending_last = NULL;
-	else
+
+	if (d->free_prgs == 0)
 		PRINT(KERN_INFO, ohci->id, 
 		      "Transmit DMA FIFO ctx=%d is full... waiting",d->ctx);
 
@@ -857,25 +819,16 @@
 		      packet->data_size);
 		return 0;
 	}
-	packet->xnext = NULL;
 
 	/* Decide wether we have an iso, a request, or a response packet */
 	tcode = (packet->header[0]>>4)&0xf;
-	if (tcode == TCODE_ISO_DATA) d = ohci->it_context;
-	else if (tcode & 0x02) d = ohci->at_resp_context;
-	else d = ohci->at_req_context;
+	if (tcode == TCODE_ISO_DATA) d = &ohci->it_context;
+	else if (tcode & 0x02) d = &ohci->at_resp_context;
+	else d = &ohci->at_req_context;
 
 	spin_lock_irqsave(&d->lock,flags);
 
-	/* queue the packet for later insertion into the dma fifo */
-	if (d->pending_last) {
-		d->pending_last->xnext = packet;
-		d->pending_last = packet;
-	}
-	else {
-		d->pending_first = packet;
-		d->pending_last = packet;
-	}
+	list_add_tail(&packet->driver_list, &d->pending_list);
 	
 	dma_trm_flush(ohci, d);
 
@@ -929,8 +882,8 @@
 
 	case CANCEL_REQUESTS:
 		DBGMSG(ohci->id, "Cancel request received");
-		dma_trm_reset(ohci->at_req_context);
-		dma_trm_reset(ohci->at_resp_context);
+		dma_trm_reset(&ohci->at_req_context);
+		dma_trm_reset(&ohci->at_resp_context);
 		break;
 
 	case MODIFY_USAGE:
@@ -1033,46 +986,62 @@
 
 static void dma_trm_reset(struct dma_trm_ctx *d)
 {
-	struct ti_ohci *ohci;
 	unsigned long flags;
-        struct hpsb_packet *nextpacket;
+	LIST_HEAD(packet_list);
 
-	if (d==NULL) {
-		PRINT_G(KERN_ERR, "dma_trm_reset called with NULL arg");
-		return;
-	}
-	ohci = (struct ti_ohci *)(d->ohci);
-	ohci1394_stop_context(ohci, d->ctrlClear, NULL);
+	ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
 
-	spin_lock_irqsave(&d->lock,flags);
+	/* Lock the context, reset it and release it. Move the packets
+	 * that were pending in the context to packet_list and free
+	 * them after releasing the lock. */
 
-	/* Is there still any packet pending in the fifo ? */
-	while(d->fifo_first) {
-		PRINT(KERN_INFO, ohci->id, 
-		      "AT dma reset ctx=%d, aborting transmission", 
-		      d->ctx);
-                nextpacket = d->fifo_first->xnext;
-		hpsb_packet_sent(ohci->host, d->fifo_first, ACKX_ABORTED);
-		d->fifo_first = nextpacket;
-	}
-	d->fifo_first = d->fifo_last = NULL;
+	spin_lock_irqsave(&d->lock, flags);
 
-	/* is there still any packet pending ? */
-	while(d->pending_first) {
-		PRINT(KERN_INFO, ohci->id, 
-		      "AT dma reset ctx=%d, aborting transmission", 
-		      d->ctx);
-                nextpacket = d->pending_first->xnext;
-		hpsb_packet_sent(ohci->host, d->pending_first, 
-				 ACKX_ABORTED);
-		d->pending_first = nextpacket;
-	}
-	d->pending_first = d->pending_last = NULL;
-	
-	d->branchAddrPtr=NULL;
+	list_splice(&d->fifo_list, &packet_list);
+	list_splice(&d->pending_list, &packet_list);
+	INIT_LIST_HEAD(&d->fifo_list);
+	INIT_LIST_HEAD(&d->pending_list);
+
+	d->branchAddrPtr = NULL;
 	d->sent_ind = d->prg_ind;
 	d->free_prgs = d->num_desc;
-	spin_unlock_irqrestore(&d->lock,flags);
+
+	spin_unlock_irqrestore(&d->lock, flags);
+
+	/* Now process subsystem callbacks for the packets from the
+	 * context. */
+
+	while (!list_empty(&packet_list)) {
+		struct hpsb_packet *p = driver_packet(packet_list.next);
+		PRINT(KERN_INFO, d->ohci->id, 
+		      "AT dma reset ctx=%d, aborting transmission", d->ctx);
+		list_del(&p->driver_list);
+		hpsb_packet_sent(d->ohci->host, p, ACKX_ABORTED);
+	}
+}
+
+static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci, 
+				       quadlet_t rx_event,
+				       quadlet_t tx_event)
+{
+	struct list_head *lh;
+	struct ohci1394_iso_tasklet *t;
+	unsigned long mask;
+
+	spin_lock(&ohci->iso_tasklet_list_lock);
+
+	list_for_each(lh, &ohci->iso_tasklet_list) {
+		t = list_entry(lh, struct ohci1394_iso_tasklet, link);
+		mask = 1 << t->context;
+
+		if (t->type == OHCI_ISO_TRANSMIT && tx_event & mask)
+			tasklet_schedule(&t->tasklet);
+		if (t->type == OHCI_ISO_RECEIVE && rx_event & mask)
+			tasklet_schedule(&t->tasklet);
+	}
+
+	spin_unlock(&ohci->iso_tasklet_list_lock);
+
 }
 
 static void ohci_irq_handler(int irq, void *dev_id,
@@ -1143,7 +1112,7 @@
 	 * we get sent acks before response packets. This sucks mainly
 	 * because it halts the interrupt handler.  */
 	if (event & OHCI1394_reqTxComplete) {
-		struct dma_trm_ctx *d = ohci->at_req_context;
+		struct dma_trm_ctx *d = &ohci->at_req_context;
 		DBGMSG(ohci->id, "Got reqTxComplete interrupt "
 		       "status=0x%08X", reg_read(ohci, d->ctrlSet));
 		if (reg_read(ohci, d->ctrlSet) & 0x800)
@@ -1154,7 +1123,7 @@
 		event &= ~OHCI1394_reqTxComplete;
 	}
 	if (event & OHCI1394_respTxComplete) {
-		struct dma_trm_ctx *d = ohci->at_resp_context;
+		struct dma_trm_ctx *d = &ohci->at_resp_context;
 		DBGMSG(ohci->id, "Got respTxComplete interrupt "
 		       "status=0x%08X", reg_read(ohci, d->ctrlSet));
 		if (reg_read(ohci, d->ctrlSet) & 0x800)
@@ -1165,7 +1134,7 @@
 		event &= ~OHCI1394_respTxComplete;
 	}
 	if (event & OHCI1394_RQPkt) {
-		struct dma_rcv_ctx *d = ohci->ar_req_context;
+		struct dma_rcv_ctx *d = &ohci->ar_req_context;
 		DBGMSG(ohci->id, "Got RQPkt interrupt status=0x%08X",
 		       reg_read(ohci, d->ctrlSet));
 		if (reg_read(ohci, d->ctrlSet) & 0x800)
@@ -1175,7 +1144,7 @@
 		event &= ~OHCI1394_RQPkt;
 	}
 	if (event & OHCI1394_RSPkt) {
-		struct dma_rcv_ctx *d = ohci->ar_resp_context;
+		struct dma_rcv_ctx *d = &ohci->ar_resp_context;
 		DBGMSG(ohci->id, "Got RSPkt interrupt status=0x%08X",
 		       reg_read(ohci, d->ctrlSet));
 		if (reg_read(ohci, d->ctrlSet) & 0x800)
@@ -1185,46 +1154,19 @@
 		event &= ~OHCI1394_RSPkt;
 	}
 	if (event & OHCI1394_isochRx) {
-		quadlet_t isoRecvIntEvent;
-		struct dma_rcv_ctx *d = ohci->ir_context;
-		isoRecvIntEvent = 
-			reg_read(ohci, OHCI1394_IsoRecvIntEventSet);
-		reg_write(ohci, OHCI1394_IsoRecvIntEventClear,
-			  isoRecvIntEvent);
-		DBGMSG(ohci->id, "Got isochRx interrupt "
-		       "status=0x%08X isoRecvIntEvent=%08x", 
-		       reg_read(ohci, d->ctrlSet), isoRecvIntEvent);
-		if (isoRecvIntEvent & 0x1) {
-			if (reg_read(ohci, d->ctrlSet) & 0x800)
-				ohci1394_stop_context(ohci, d->ctrlClear, 
-					     "isochRx");
-			else
-				tasklet_schedule(&d->task);
-		}
-
-		ohci1394_run_irq_hooks(ohci, isoRecvIntEvent, 0);
+		quadlet_t rx_event;
 
+		rx_event = reg_read(ohci, OHCI1394_IsoRecvIntEventSet);
+		reg_write(ohci, OHCI1394_IsoRecvIntEventClear, rx_event);
+		ohci_schedule_iso_tasklets(ohci, rx_event, 0);
 		event &= ~OHCI1394_isochRx;
 	}
 	if (event & OHCI1394_isochTx) {
-		quadlet_t isoXmitIntEvent;
-		struct dma_trm_ctx *d = ohci->it_context;
-		isoXmitIntEvent = 
-			reg_read(ohci, OHCI1394_IsoXmitIntEventSet);
-		reg_write(ohci, OHCI1394_IsoXmitIntEventClear,
-			  isoXmitIntEvent);
-                       DBGMSG(ohci->id, "Got isochTx interrupt "
-                               "status=0x%08x isoXmitIntEvent=%08x",
-                              reg_read(ohci, d->ctrlSet), isoXmitIntEvent);
+		quadlet_t tx_event;		
 
-		ohci1394_run_irq_hooks(ohci, 0, isoXmitIntEvent);
-		
-		if (isoXmitIntEvent & 0x1) {
-			if (reg_read(ohci, d->ctrlSet) & 0x800)
-				ohci1394_stop_context(ohci, d->ctrlClear, "isochTx");
-			else
-				tasklet_schedule(&d->task);
-		}
+		tx_event = reg_read(ohci, OHCI1394_IsoXmitIntEventSet);
+		reg_write(ohci, OHCI1394_IsoXmitIntEventClear, tx_event);
+		ohci_schedule_iso_tasklets(ohci, 0, tx_event);
 		event &= ~OHCI1394_isochTx;
 	}
 	if (event & OHCI1394_selfIDComplete) {
@@ -1507,25 +1449,16 @@
 {
 	struct dma_trm_ctx *d = (struct dma_trm_ctx*)data;
 	struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
-	struct hpsb_packet *packet, *nextpacket;
+	struct hpsb_packet *packet;
 	unsigned long flags;
 	u32 ack;
         size_t datasize;
 
 	spin_lock_irqsave(&d->lock, flags);
 
-	if (d->fifo_first == NULL) {
-#if 0
-		ohci1394_stop_context(ohci, d->ctrlClear, 
-			     "Packet sent ack received but queue is empty");
-#endif
-		spin_unlock_irqrestore(&d->lock, flags);
-		return;
-	}
-
-	while (d->fifo_first) {
-		packet = d->fifo_first;
-                datasize = d->fifo_first->data_size;
+	while (!list_empty(&d->fifo_list)) {
+		packet = driver_packet(d->fifo_list.next);
+                datasize = packet->data_size;
 		if (datasize && packet->type != hpsb_raw)
 			ack = le32_to_cpu(
 				d->prg_cpu[d->sent_ind]->end.status) >> 16;
@@ -1576,7 +1509,7 @@
                                 d->ctx);
 #endif		
 
-                nextpacket = packet->xnext;
+                list_del(&packet->driver_list);
 		hpsb_packet_sent(ohci->host, packet, ack & 0xf);
 
 		if (datasize) {
@@ -1588,90 +1521,64 @@
 
 		d->sent_ind = (d->sent_ind+1)%d->num_desc;
 		d->free_prgs++;
-		d->fifo_first = nextpacket;
 	}
-	if (d->fifo_first == NULL)
-		d->fifo_last = NULL;
 
 	dma_trm_flush(ohci, d);
 
 	spin_unlock_irqrestore(&d->lock, flags);
 }
 
-static int free_dma_rcv_ctx(struct dma_rcv_ctx **d)
+static void free_dma_rcv_ctx(struct dma_rcv_ctx *d)
 {
 	int i;
-	struct ti_ohci *ohci;
 
-	if (*d==NULL) return -1;
-
-	ohci = (struct ti_ohci *)(*d)->ohci;
+	if (d->ohci == NULL)
+		return;
 
-	DBGMSG(ohci->id, "Freeing dma_rcv_ctx %d",(*d)->ctx);
+	DBGMSG(d->ohci->id, "Freeing dma_rcv_ctx %d", d->ctx);
 	
-	ohci1394_stop_context(ohci, (*d)->ctrlClear, NULL);
+	ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
 
-	tasklet_kill(&(*d)->task);
+	if (d->type == DMA_CTX_ISO)
+		ohci1394_unregister_iso_tasklet(d->ohci, &d->ohci->ir_tasklet);
+	else
+		tasklet_kill(&d->task);
 
-	if ((*d)->buf_cpu) {
-		for (i=0; i<(*d)->num_desc; i++)
-			if ((*d)->buf_cpu[i] && (*d)->buf_bus[i]) {
+	if (d->buf_cpu) {
+		for (i=0; i<d->num_desc; i++)
+			if (d->buf_cpu[i] && d->buf_bus[i]) {
 				pci_free_consistent(
-					ohci->dev, (*d)->buf_size, 
-					(*d)->buf_cpu[i], (*d)->buf_bus[i]);
+					d->ohci->dev, d->buf_size, 
+					d->buf_cpu[i], d->buf_bus[i]);
 				OHCI_DMA_FREE("consistent dma_rcv buf[%d]", i);
 			}
-		kfree((*d)->buf_cpu);
-		kfree((*d)->buf_bus);
+		kfree(d->buf_cpu);
+		kfree(d->buf_bus);
 	}
-	if ((*d)->prg_cpu) {
-		for (i=0; i<(*d)->num_desc; i++) 
-			if ((*d)->prg_cpu[i] && (*d)->prg_bus[i]) {
+	if (d->prg_cpu) {
+		for (i=0; i<d->num_desc; i++) 
+			if (d->prg_cpu[i] && d->prg_bus[i]) {
 				pci_free_consistent(
-					ohci->dev, sizeof(struct dma_cmd), 
-					(*d)->prg_cpu[i], (*d)->prg_bus[i]);
+					d->ohci->dev, sizeof(struct dma_cmd), 
+					d->prg_cpu[i], d->prg_bus[i]);
 				OHCI_DMA_FREE("consistent dma_rcv prg[%d]", i);
 			}
-		kfree((*d)->prg_cpu);
-		kfree((*d)->prg_bus);
+		kfree(d->prg_cpu);
+		kfree(d->prg_bus);
 	}
-	if ((*d)->spb) kfree((*d)->spb);
+	if (d->spb) kfree(d->spb);
 
-	/* clear ISO context usage bit */
-	if ((*d)->type == DMA_CTX_ISO) {
-		clear_bit((*d)->ctx, &ohci->ir_ctx_usage);
-	}
-	       
-	kfree(*d);
-	*d = NULL;
-
-	return 0;
+	/* Mark this context as freed. */
+	d->ohci = NULL;
 }
 
-static struct dma_rcv_ctx *
-alloc_dma_rcv_ctx(struct ti_ohci *ohci, enum context_type type, int ctx, int num_desc,
+static int
+alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d,
+		  enum context_type type, int ctx, int num_desc,
 		  int buf_size, int split_buf_size, int context_base)
 {
-	struct dma_rcv_ctx *d;
 	int i;
 
-	if (type == DMA_CTX_ISO) {
-		/* try to claim the ISO context usage bit */
-		if (test_and_set_bit(ctx, &ohci->ir_ctx_usage)) {
-			PRINT(KERN_ERR, ohci->id, "IR DMA context %d is not available", ctx);
-			return NULL;
-		}
-	}
-	
-	d = kmalloc(sizeof(struct dma_rcv_ctx), GFP_KERNEL);
-
-	if (d == NULL) {
-		PRINT(KERN_ERR, ohci->id, "Failed to allocate dma_rcv_ctx");
-		return NULL;
-	}
-
-	memset (d, 0, sizeof (struct dma_rcv_ctx));
-
 	d->ohci = ohci;
 	d->type = type;
 	d->ctx = ctx;
@@ -1689,8 +1596,8 @@
 
 	if (d->buf_cpu == NULL || d->buf_bus == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate dma buffer");
-		free_dma_rcv_ctx(&d);
-		return NULL;
+		free_dma_rcv_ctx(d);
+		return -ENOMEM;
 	}
 	memset(d->buf_cpu, 0, d->num_desc * sizeof(quadlet_t*));
 	memset(d->buf_bus, 0, d->num_desc * sizeof(dma_addr_t));
@@ -1701,8 +1608,8 @@
 
 	if (d->prg_cpu == NULL || d->prg_bus == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate dma prg");
-		free_dma_rcv_ctx(&d);
-		return NULL;
+		free_dma_rcv_ctx(d);
+		return -ENOMEM;
 	}
 	memset(d->prg_cpu, 0, d->num_desc * sizeof(struct dma_cmd*));
 	memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));
@@ -1711,8 +1618,8 @@
 
 	if (d->spb == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate split buffer");
-		free_dma_rcv_ctx(&d);
-		return NULL;
+		free_dma_rcv_ctx(d);
+		return -ENOMEM;
 	}
 
 	for (i=0; i<d->num_desc; i++) {
@@ -1726,8 +1633,8 @@
 		} else {
 			PRINT(KERN_ERR, ohci->id, 
 			      "Failed to allocate dma buffer");
-			free_dma_rcv_ctx(&d);
-			return NULL;
+			free_dma_rcv_ctx(d);
+			return -ENOMEM;
 		}
 
 		
@@ -1741,80 +1648,68 @@
 		} else {
 			PRINT(KERN_ERR, ohci->id, 
 			      "Failed to allocate dma prg");
-			free_dma_rcv_ctx(&d);
-			return NULL;
+			free_dma_rcv_ctx(d);
+			return -ENOMEM;
 		}
 	}
 
         spin_lock_init(&d->lock);
 
-	/* initialize tasklet */
-	tasklet_init (&d->task, dma_rcv_tasklet, (unsigned long)d);
+	if (type == DMA_CTX_ISO) {
+		ohci1394_init_iso_tasklet(&ohci->ir_tasklet, OHCI_ISO_RECEIVE,
+					  dma_rcv_tasklet, (unsigned long) d);
+		if (ohci1394_register_iso_tasklet(ohci,
+						  &ohci->ir_tasklet) < 0) {
+			PRINT(KERN_ERR, ohci->id, "No IR DMA context available");
+			free_dma_rcv_ctx(d);
+			return -EBUSY;
+		}
+	}
+	else
+		tasklet_init (&d->task, dma_rcv_tasklet, (unsigned long) d);
 
-	return d;
+	return 0;
 }
 
-static int free_dma_trm_ctx(struct dma_trm_ctx **d)
+static void free_dma_trm_ctx(struct dma_trm_ctx *d)
 {
-	struct ti_ohci *ohci;
 	int i;
 
-	if (*d==NULL) return -1;
-
-	ohci = (struct ti_ohci *)(*d)->ohci;
+	if (d->ohci == NULL)
+		return;
 
-	DBGMSG(ohci->id, "Freeing dma_trm_ctx %d",(*d)->ctx);
+	DBGMSG(d->ohci->id, "Freeing dma_trm_ctx %d", d->ctx);
 
-	ohci1394_stop_context(ohci, (*d)->ctrlClear, NULL);
+	ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
 
-	tasklet_kill(&(*d)->task);
+	if (d->type == DMA_CTX_ISO)
+		ohci1394_unregister_iso_tasklet(d->ohci, &d->ohci->it_tasklet);
+	else
+		tasklet_kill(&d->task);
 
-	if ((*d)->prg_cpu) {
-		for (i=0; i<(*d)->num_desc; i++) 
-			if ((*d)->prg_cpu[i] && (*d)->prg_bus[i]) {
+	if (d->prg_cpu) {
+		for (i=0; i<d->num_desc; i++) 
+			if (d->prg_cpu[i] && d->prg_bus[i]) {
 				pci_free_consistent(
-					ohci->dev, sizeof(struct at_dma_prg), 
-					(*d)->prg_cpu[i], (*d)->prg_bus[i]);
+					d->ohci->dev, sizeof(struct at_dma_prg), 
+					d->prg_cpu[i], d->prg_bus[i]);
 				OHCI_DMA_FREE("consistent dma_trm prg[%d]", i);
 			}
-		kfree((*d)->prg_cpu);
-		kfree((*d)->prg_bus);
+		kfree(d->prg_cpu);
+		kfree(d->prg_bus);
 	}
 
-	/* clear the ISO context usage bit */
-	if ((*d)->type == DMA_CTX_ISO) {
-		clear_bit((*d)->ctx, &ohci->it_ctx_usage);
-	}
-
-	kfree(*d);
-	*d = NULL;
-	return 0;
+	/* Mark this context as freed. */
+	d->ohci = NULL;
 }
 
-static struct dma_trm_ctx *
-alloc_dma_trm_ctx(struct ti_ohci *ohci, enum context_type type, int ctx, int num_desc,
+static int
+alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d,
+		  enum context_type type, int ctx, int num_desc,
 		  int context_base)
 {
-	struct dma_trm_ctx *d;
 	int i;
 
-	if (type == DMA_CTX_ISO) {
-		/* try to claim the ISO context usage bit */
-		if (test_and_set_bit(ctx, &ohci->it_ctx_usage)) {
-			PRINT(KERN_ERR, ohci->id, "IT DMA context %d is not available", ctx);
-			return NULL;
-		}
-	}
-	
-	d = kmalloc(sizeof(struct dma_trm_ctx), GFP_KERNEL);
-
-	if (d == NULL) {
-		PRINT(KERN_ERR, ohci->id, "Failed to allocate dma_trm_ctx");
-		return NULL;
-	}
-
-	memset (d, 0, sizeof (struct dma_trm_ctx));
-
 	d->ohci = ohci;
 	d->type = type;
 	d->ctx = ctx;
@@ -1829,8 +1724,8 @@
 
 	if (d->prg_cpu == NULL || d->prg_bus == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate at dma prg");
-		free_dma_trm_ctx(&d);
-		return NULL;
+		free_dma_trm_ctx(d);
+		return -ENOMEM;
 	}
 	memset(d->prg_cpu, 0, d->num_desc * sizeof(struct at_dma_prg*));
 	memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));
@@ -1846,17 +1741,28 @@
 		} else {
 			PRINT(KERN_ERR, ohci->id, 
 			      "Failed to allocate at dma prg");
-			free_dma_trm_ctx(&d);
-			return NULL;
+			free_dma_trm_ctx(d);
+			return -ENOMEM;
 		}
 	}
 
         spin_lock_init(&d->lock);
 
-        /* initialize bottom handler */
-	tasklet_init (&d->task, dma_trm_tasklet, (unsigned long)d);
+	/* initialize tasklet */
+	if (type == DMA_CTX_ISO) {
+		ohci1394_init_iso_tasklet(&ohci->it_tasklet, OHCI_ISO_TRANSMIT,
+					  dma_rcv_tasklet, (unsigned long) d);
+		if (ohci1394_register_iso_tasklet(ohci,
+						  &ohci->it_tasklet) < 0) {
+			PRINT(KERN_ERR, ohci->id, "No IT DMA context available");
+			free_dma_trm_ctx(d);
+			return -EBUSY;
+		}
+	}
+	else
+		tasklet_init (&d->task, dma_trm_tasklet, (unsigned long)d);
 
-	return d;
+	return 0;
 }
 
 static u16 ohci_crc16 (u32 *ptr, int length)
@@ -2028,15 +1934,14 @@
 	return reg_read(ohci, OHCI1394_CSRData);
 }
 
-static struct hpsb_host_operations ohci1394_ops = {
+static struct hpsb_host_driver ohci1394_driver = {
+	.name =			OHCI1394_DRIVER_NAME,
 	.get_rom =		ohci_get_rom,
 	.transmit_packet =	ohci_transmit,
 	.devctl =		ohci_devctl,
 	.hw_csr_reg =		ohci_hw_csr_reg,
 };
 
-static struct hpsb_host_driver *ohci1394_driver;
-
 
 
 /***********************************
@@ -2059,7 +1964,6 @@
 	struct hpsb_host *host;
 	struct ti_ohci *ohci;	/* shortcut to currently handled device */
 	unsigned long ohci_base;
-	int i;
 	
 	if (version_printed++ == 0)
 		PRINT_G(KERN_INFO, "%s", version);
@@ -2069,7 +1973,7 @@
 		        card_id_counter++);
         pci_set_master(dev);
 
-	host = hpsb_alloc_host(ohci1394_driver, sizeof(struct ti_ohci));
+	host = hpsb_alloc_host(&ohci1394_driver, sizeof(struct ti_ohci));
 	if (!host) FAIL(-ENOMEM, "Failed to allocate host structure");
 
 	ohci = host->hostdata;
@@ -2151,68 +2055,78 @@
 
 	ohci->init_state = OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE;
 	/* AR DMA request context allocation */
-	ohci->ar_req_context = 
-		alloc_dma_rcv_ctx(ohci, DMA_CTX_ASYNC_REQ, 0, AR_REQ_NUM_DESC,
-				  AR_REQ_BUF_SIZE, AR_REQ_SPLIT_BUF_SIZE,
-				  OHCI1394_AsReqRcvContextBase);
-
-	if (ohci->ar_req_context == NULL)
+	if (alloc_dma_rcv_ctx(ohci, &ohci->ar_req_context,
+			      DMA_CTX_ASYNC_REQ, 0, AR_REQ_NUM_DESC,
+			      AR_REQ_BUF_SIZE, AR_REQ_SPLIT_BUF_SIZE,
+			      OHCI1394_AsReqRcvContextBase) < 0)
 		FAIL(-ENOMEM, "Failed to allocate AR Req context");
 
 	/* AR DMA response context allocation */
-	ohci->ar_resp_context = 
-		alloc_dma_rcv_ctx(ohci, DMA_CTX_ASYNC_RESP, 0, AR_RESP_NUM_DESC,
-				  AR_RESP_BUF_SIZE, AR_RESP_SPLIT_BUF_SIZE,
-				  OHCI1394_AsRspRcvContextBase);
-	
-	if (ohci->ar_resp_context == NULL)
+	if (alloc_dma_rcv_ctx(ohci, &ohci->ar_resp_context,
+			      DMA_CTX_ASYNC_RESP, 0, AR_RESP_NUM_DESC,
+			      AR_RESP_BUF_SIZE, AR_RESP_SPLIT_BUF_SIZE,
+			      OHCI1394_AsRspRcvContextBase) < 0)
 		FAIL(-ENOMEM, "Failed to allocate AR Resp context");
 
 	/* AT DMA request context */
-	ohci->at_req_context = 
-		alloc_dma_trm_ctx(ohci, DMA_CTX_ASYNC_REQ, 0, AT_REQ_NUM_DESC,
-				  OHCI1394_AsReqTrContextBase);
-	
-	if (ohci->at_req_context == NULL)
+	if (alloc_dma_trm_ctx(ohci, &ohci->at_req_context,
+			      DMA_CTX_ASYNC_REQ, 0, AT_REQ_NUM_DESC,
+			      OHCI1394_AsReqTrContextBase) < 0)
 		FAIL(-ENOMEM, "Failed to allocate AT Req context");
 
 	/* AT DMA response context */
-	ohci->at_resp_context = 
-		alloc_dma_trm_ctx(ohci, DMA_CTX_ASYNC_RESP, 1, AT_RESP_NUM_DESC,
-				  OHCI1394_AsRspTrContextBase);
-	
-	if (ohci->at_resp_context == NULL)
+	if (alloc_dma_trm_ctx(ohci, &ohci->at_resp_context,
+			      DMA_CTX_ASYNC_RESP, 1, AT_RESP_NUM_DESC,
+			      OHCI1394_AsRspTrContextBase) < 0)
 		FAIL(-ENOMEM, "Failed to allocate AT Resp context");
 
-	ohci->ir_ctx_usage = 0;
-	ohci->it_ctx_usage = 0;
-	
-	/* IR DMA context */
-	ohci->ir_context =
-		alloc_dma_rcv_ctx(ohci, DMA_CTX_ISO, 0, IR_NUM_DESC,
-				  IR_BUF_SIZE, IR_SPLIT_BUF_SIZE,
-				  OHCI1394_IsoRcvContextBase);
+	/* Start off with a soft reset, to clear everything to a sane
+	 * state. */
+	ohci_soft_reset(ohci);
 
-	if (ohci->ir_context == NULL)
-		FAIL(-ENOMEM, "Failed to allocate IR context");
+	/* Now enable LPS, which we need in order to start accessing
+	 * most of the registers.  In fact, on some cards (ALI M5251),
+	 * accessing registers in the SClk domain without LPS enabled
+	 * will lock up the machine.  Wait 50msec to make sure we have
+	 * full link enabled.  */
+	reg_write(ohci, OHCI1394_HCControlSet, 0x00080000);
+	mdelay(50);
 
-	
-	/* IT DMA context allocation */
-	ohci->it_context =
-		alloc_dma_trm_ctx(ohci, DMA_CTX_ISO, 0, IT_NUM_DESC,
-				  OHCI1394_IsoXmitContextBase);
+	/* Determine the number of available IR and IT contexts. */
+	ohci->nb_iso_rcv_ctx =
+		get_nb_iso_ctx(ohci, OHCI1394_IsoRecvIntMaskSet);
+	DBGMSG(ohci->id, "%d iso receive contexts available",
+	       ohci->nb_iso_rcv_ctx);
 
-	if (ohci->it_context == NULL)
-		FAIL(-ENOMEM, "Failed to allocate IT context");
+	ohci->nb_iso_xmit_ctx =
+		get_nb_iso_ctx(ohci, OHCI1394_IsoXmitIntMaskSet);
+	DBGMSG(ohci->id, "%d iso transmit contexts available",
+	       ohci->nb_iso_xmit_ctx);
+
+	/* Set the usage bits for non-existent contexts so they can't
+	 * be allocated */
+	ohci->ir_ctx_usage = ~0 << ohci->nb_iso_rcv_ctx;
+	ohci->it_ctx_usage = ~0 << ohci->nb_iso_xmit_ctx;
 
+	INIT_LIST_HEAD(&ohci->iso_tasklet_list);
+	spin_lock_init(&ohci->iso_tasklet_list_lock);
 	ohci->ISO_channel_usage = 0;
         spin_lock_init(&ohci->IR_channel_lock);
 
-	for(i = 0; i < OHCI1394_MAX_IRQ_HOOKS; i++) {
-		ohci->irq_hooks[i].irq_handler = NULL;
-		ohci->irq_hooks[i].data = NULL;
-	}
+	/* IR DMA context */
+	if (alloc_dma_rcv_ctx(ohci, &ohci->ir_context,
+			      DMA_CTX_ISO, 0, IR_NUM_DESC,
+			      IR_BUF_SIZE, IR_SPLIT_BUF_SIZE,
+			      OHCI1394_IsoRcvContextBase) < 0)
+		FAIL(-ENOMEM, "Failed to allocate IR context");
+
 	
+	/* IT DMA context allocation */
+	if (alloc_dma_trm_ctx(ohci, &ohci->it_context,
+			      DMA_CTX_ISO, 0, IT_NUM_DESC,
+			      OHCI1394_IsoXmitContextBase) < 0)
+		FAIL(-ENOMEM, "Failed to allocate IT context");
+
 	if (request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ,
 			 OHCI1394_DRIVER_NAME, ohci))
 		FAIL(-ENOMEM, "Failed to allocate shared interrupt %d", dev->irq);
@@ -2355,65 +2269,69 @@
 	if (msg) PRINT(KERN_ERR, ohci->id, "%s: dma prg stopped", msg);
 }
 
-static inline void ohci1394_run_irq_hooks(struct ti_ohci *ohci,
-					  quadlet_t isoRecvEvent, 
-					  quadlet_t isoXmitEvent)
+void ohci1394_init_iso_tasklet(struct ohci1394_iso_tasklet *tasklet, int type,
+			       void (*func)(unsigned long), unsigned long data)
 {
-	int i;
-	for(i = 0; i < OHCI1394_MAX_IRQ_HOOKS; i++) {
-		if(ohci->irq_hooks[i].irq_handler != NULL) {
-			ohci->irq_hooks[i].irq_handler(ohci->id, isoRecvEvent, isoXmitEvent,
-						       ohci->irq_hooks[i].data);
-		}
-	}
+	tasklet_init(&tasklet->tasklet, func, data);
+	tasklet->type = type;
+	/* We init the tasklet->link field, so we can list_del() it
+	 * without worrying wether it was added to the list or not. */
+	INIT_LIST_HEAD(&tasklet->link);
 }
 
-int ohci1394_hook_irq(struct ti_ohci *ohci,
-		      void (*irq_handler) (int, quadlet_t, quadlet_t, void *),
-		      void *data)
+int ohci1394_register_iso_tasklet(struct ti_ohci *ohci,
+				  struct ohci1394_iso_tasklet *tasklet)
 {
-	int i;
-	
-	/* find a free slot */
-	for(i = 0; i < OHCI1394_MAX_IRQ_HOOKS; i++) {
-		if(ohci->irq_hooks[i].irq_handler == NULL)
-			break;
+	unsigned long flags, *usage;
+	int n, i, r = -EBUSY;
+
+	if (tasklet->type == OHCI_ISO_TRANSMIT) {
+		n = ohci->nb_iso_xmit_ctx;
+		usage = &ohci->it_ctx_usage;
+	}
+	else {
+		n = ohci->nb_iso_rcv_ctx;
+		usage = &ohci->ir_ctx_usage;
 	}
 
-	if(i >= OHCI1394_MAX_IRQ_HOOKS)
-		return -EBUSY;
+	spin_lock_irqsave(&ohci->iso_tasklet_list_lock, flags);
 
-	ohci->irq_hooks[i].irq_handler = irq_handler;
-	ohci->irq_hooks[i].data = data;
+	for (i = 0; i < n; i++)
+		if (!test_and_set_bit(i, usage)) {
+			tasklet->context = i;
+			list_add_tail(&tasklet->link, &ohci->iso_tasklet_list);
+			r = 0;
+			break;
+		}
 
-	/* ohci1394 will never be unloaded while an IRQ hook is
-	   in use, because the user must reference this symbol */
+	spin_unlock_irqrestore(&ohci->iso_tasklet_list_lock, flags);
 	
-	return 0;
+	return r;
 }
 
-void ohci1394_unhook_irq(struct ti_ohci *ohci,
-			 void (*irq_handler) (int, quadlet_t, quadlet_t, void *),
-			 void *data)
+void ohci1394_unregister_iso_tasklet(struct ti_ohci *ohci,
+				     struct ohci1394_iso_tasklet *tasklet)
 {
-	int i;
-	
-	for(i = 0; i < OHCI1394_MAX_IRQ_HOOKS; i++) {
-		if( (ohci->irq_hooks[i].irq_handler == irq_handler) &&
-		    (ohci->irq_hooks[i].data == data) )
-			break;
-	}
-	
-	if(i < OHCI1394_MAX_IRQ_HOOKS) {
-		ohci->irq_hooks[i].irq_handler = NULL;
-		ohci->irq_hooks[i].data = NULL;
-	}
+	unsigned long flags;
+
+	tasklet_kill(&tasklet->tasklet);
+
+	spin_lock_irqsave(&ohci->iso_tasklet_list_lock, flags);
+
+	if (tasklet->type == OHCI_ISO_TRANSMIT)
+		clear_bit(tasklet->context, &ohci->it_ctx_usage);
+	else
+		clear_bit(tasklet->context, &ohci->ir_ctx_usage);
+
+	list_del(&tasklet->link);
+
+	spin_unlock_irqrestore(&ohci->iso_tasklet_list_lock, flags);
 }
 
 EXPORT_SYMBOL(ohci1394_stop_context);
-EXPORT_SYMBOL(ohci1394_hook_irq);
-EXPORT_SYMBOL(ohci1394_unhook_irq);
-
+EXPORT_SYMBOL(ohci1394_init_iso_tasklet);
+EXPORT_SYMBOL(ohci1394_register_iso_tasklet);
+EXPORT_SYMBOL(ohci1394_unregister_iso_tasklet);
 
 
 /***********************************
@@ -2427,27 +2345,11 @@
 static void __exit ohci1394_cleanup (void)
 {
 	pci_unregister_driver(&ohci1394_pci_driver);
-	hpsb_unregister_lowlevel(ohci1394_driver);
 }
 
 static int __init ohci1394_init(void)
 {
-	int ret;
-
-	ohci1394_driver = hpsb_register_lowlevel(&ohci1394_ops,
-						 OHCI1394_DRIVER_NAME);
-	if (!ohci1394_driver) {
-		PRINT_G(KERN_ERR, "hpsb_register_lowlevel failed");
-		return -ENOMEM;
-	}
-
-	ret = pci_module_init(&ohci1394_pci_driver);
-	if (ret < 0) {
-		PRINT_G(KERN_ERR, "pci_module_init failed");
-		hpsb_unregister_lowlevel(ohci1394_driver);
-		return ret;
-	}
-	return ret;
+	return pci_module_init(&ohci1394_pci_driver);
 }
 
 module_init(ohci1394_init);
diff -urN linux-2.4.20-pre7/drivers/ieee1394/ohci1394.h linux-2.4.20-pre8/drivers/ieee1394/ohci1394.h
--- linux-2.4.20-pre7/drivers/ieee1394/ohci1394.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/ohci1394.h	Wed Sep 25 18:21:41 2002
@@ -127,12 +127,10 @@
         quadlet_t *branchAddrPtr;
 
 	/* list of packets inserted in the AT FIFO */
-        struct hpsb_packet *fifo_first;
-        struct hpsb_packet *fifo_last;
+	struct list_head fifo_list;
 
 	/* list of pending packets to be inserted in the AT FIFO */
-        struct hpsb_packet *pending_first;
-        struct hpsb_packet *pending_last;
+	struct list_head pending_list;
 
         spinlock_t lock;
         struct tasklet_struct task;
@@ -141,6 +139,13 @@
 	int cmdPtr;
 };
 
+struct ohci1394_iso_tasklet {
+	struct tasklet_struct tasklet;
+	struct list_head link;
+	int context;
+	enum { OHCI_ISO_TRANSMIT, OHCI_ISO_RECEIVE } type;
+};
+
 struct ti_ohci {
         int id; /* sequential card number */
 
@@ -172,21 +177,23 @@
 	unsigned int max_packet_size;
 
         /* async receive */
-	struct dma_rcv_ctx *ar_resp_context;
-	struct dma_rcv_ctx *ar_req_context;
+	struct dma_rcv_ctx ar_resp_context;
+	struct dma_rcv_ctx ar_req_context;
 
 	/* async transmit */
-	struct dma_trm_ctx *at_resp_context;
-	struct dma_trm_ctx *at_req_context;
+	struct dma_trm_ctx at_resp_context;
+	struct dma_trm_ctx at_req_context;
 
         /* iso receive */
-	struct dma_rcv_ctx *ir_context;
+	struct dma_rcv_ctx ir_context;
+	struct ohci1394_iso_tasklet ir_tasklet;
         spinlock_t IR_channel_lock;
 	int nb_iso_rcv_ctx;
 	unsigned long ir_ctx_usage; /* use test_and_set_bit() for atomicity */
 	
         /* iso transmit */
-	struct dma_trm_ctx *it_context;
+	struct dma_trm_ctx it_context;
+	struct ohci1394_iso_tasklet it_tasklet;
 	int nb_iso_xmit_ctx;
 	unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */
 	
@@ -202,16 +209,12 @@
 
 	int self_id_errors;
 
-	/* IRQ hooks, for video1394 and dv1394 */
+	/* Tasklets for iso receive and transmit, used by video1394,
+	 * amdtp and dv1394 */
 	
-#define OHCI1394_MAX_IRQ_HOOKS 16
+	struct list_head iso_tasklet_list;
+	spinlock_t iso_tasklet_list_lock;
 	
-	struct ohci1394_irq_hook {
-		void (*irq_handler) (int card, quadlet_t isoRecvEvent, 
-				     quadlet_t isoXmitEvent, void *data);
-		void *data;
-	} irq_hooks[OHCI1394_MAX_IRQ_HOOKS];
-
 	/* Swap the selfid buffer? */
 	unsigned int selfid_swap:1;
 	/* Some Apple chipset seem to swap incoming headers for us */
@@ -399,15 +402,17 @@
 
 #define OHCI1394_TCODE_PHY               0xE
 
-void ohci1394_stop_context(struct ti_ohci *ohci, int reg, char *msg);
+void ohci1394_init_iso_tasklet(struct ohci1394_iso_tasklet *tasklet, 
+			       int type,
+			       void (*func)(unsigned long), 
+			       unsigned long data);
+int ohci1394_register_iso_tasklet(struct ti_ohci *ohci,
+				  struct ohci1394_iso_tasklet *tasklet);
+void ohci1394_unregister_iso_tasklet(struct ti_ohci *ohci,
+				     struct ohci1394_iso_tasklet *tasklet);
+
+void ohci1394_stop_context      (struct ti_ohci *ohci, int reg, char *msg);
 struct ti_ohci *ohci1394_get_struct(int card_num);
 
-int ohci1394_hook_irq(struct ti_ohci *ohci,
-		      void (*irq_handler) (int, quadlet_t, quadlet_t, void *),
-		      void *data);
-
-void ohci1394_unhook_irq(struct ti_ohci *ohci,
-			 void (*irq_handler) (int, quadlet_t, quadlet_t, void *),
-			 void *data);
 #endif
 
diff -urN linux-2.4.20-pre7/drivers/ieee1394/pcilynx.c linux-2.4.20-pre8/drivers/ieee1394/pcilynx.c
--- linux-2.4.20-pre7/drivers/ieee1394/pcilynx.c	Wed Sep 25 18:20:51 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/pcilynx.c	Wed Sep 25 18:21:41 2002
@@ -65,7 +65,7 @@
 static int skip_eeprom = 0;
 
 
-static struct hpsb_host_driver *lynx_driver;
+static struct hpsb_host_driver lynx_driver;
 static unsigned int card_id;
 
 
@@ -466,7 +466,7 @@
         struct hpsb_packet *packet;
 
         d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async);
-        packet = d->queue;
+        packet = driver_packet(d->queue.next);
 
         d->header_dma = pci_map_single(lynx->dev, packet->header,
                                        packet->header_size, PCI_DMA_TODEVICE);
@@ -538,7 +538,6 @@
                 return 0;
         }
 
-        packet->xnext = NULL;
         if (packet->tcode == TCODE_WRITEQ
             || packet->tcode == TCODE_READQ_RESPONSE) {
                 cpu_to_be32s(&packet->header[3]);
@@ -546,14 +545,9 @@
 
         spin_lock_irqsave(&d->queue_lock, flags);
 
-        if (d->queue == NULL) {
-                d->queue = packet;
-                d->queue_last = packet;
+	list_add_tail(&packet->driver_list, &d->queue);
+	if (d->queue.next == &packet->driver_list)
                 send_next(lynx, packet->type);
-        } else {
-                d->queue_last->xnext = packet;
-                d->queue_last = packet;
-        }
 
         spin_unlock_irqrestore(&d->queue_lock, flags);
 
@@ -566,7 +560,8 @@
 {
         struct ti_lynx *lynx = host->hostdata;
         int retval = 0;
-        struct hpsb_packet *packet, *lastpacket;
+        struct hpsb_packet *packet;
+	LIST_HEAD(packet_list);
         unsigned long flags;
 
         switch (cmd) {
@@ -620,16 +615,16 @@
                 spin_lock_irqsave(&lynx->async.queue_lock, flags);
 
                 reg_write(lynx, DMA_CHAN_CTRL(CHANNEL_ASYNC_SEND), 0);
-                packet = lynx->async.queue;
-                lynx->async.queue = NULL;
+		list_splice(&lynx->async.queue, &packet_list);
+		INIT_LIST_HEAD(&lynx->async.queue);
 
                 spin_unlock_irqrestore(&lynx->async.queue_lock, flags);
 
-                while (packet != NULL) {
-                        lastpacket = packet;
-                        packet = packet->xnext;
-                        hpsb_packet_sent(host, lastpacket, ACKX_ABORTED);
-                }
+		while (!list_empty(&packet_list)) {
+			packet = driver_packet(packet_list.next);
+			list_del(&packet->driver_list);
+			hpsb_packet_sent(host, packet, ACKX_ABORTED);
+		}
 
                 break;
 
@@ -1128,8 +1123,9 @@
                 spin_lock(&lynx->async.queue_lock);
 
                 ack = reg_read(lynx, DMA_CHAN_STAT(CHANNEL_ASYNC_SEND));
-                packet = lynx->async.queue;
-                lynx->async.queue = packet->xnext;
+
+		packet = driver_packet(lynx->async.queue.next);
+		list_del(&packet->driver_list);
 
                 pci_unmap_single(lynx->dev, lynx->async.header_dma,
                                  packet->header_size, PCI_DMA_TODEVICE);
@@ -1138,7 +1134,7 @@
                                          packet->data_size, PCI_DMA_TODEVICE);
                 }
 
-                if (lynx->async.queue != NULL) {
+                if (!list_empty(&lynx->async.queue)) {
                         send_next(lynx, hpsb_async);
                 }
 
@@ -1160,8 +1156,8 @@
 
                 spin_lock(&lynx->iso_send.queue_lock);
 
-                packet = lynx->iso_send.queue;
-                lynx->iso_send.queue = packet->xnext;
+		packet = driver_packet(lynx->iso_send.queue.next);
+		list_del(&packet->driver_list);
 
                 pci_unmap_single(lynx->dev, lynx->iso_send.header_dma,
                                  packet->header_size, PCI_DMA_TODEVICE);
@@ -1170,7 +1166,7 @@
                                          packet->data_size, PCI_DMA_TODEVICE);
                 }
 
-                if (lynx->iso_send.queue != NULL) {
+                if (!list_empty(&lynx->iso_send.queue)) {
                         send_next(lynx, hpsb_iso);
                 }
 
@@ -1333,7 +1329,7 @@
 
         error = -ENOMEM;
 
-	host = hpsb_alloc_host(lynx_driver, sizeof(struct ti_lynx));
+	host = hpsb_alloc_host(&lynx_driver, sizeof(struct ti_lynx));
         if (!host) FAIL("failed to allocate control structure memory");
 
         lynx = host->hostdata;
@@ -1477,7 +1473,8 @@
         lynx->selfid_size = -1;
         lynx->phy_reg0 = -1;
 
-        lynx->async.queue = NULL;
+	INIT_LIST_HEAD(&lynx->async.queue);
+	INIT_LIST_HEAD(&lynx->iso_send.queue);
 
         pcl.next = pcl_bus(lynx, lynx->rcv_pcl);
         put_pcl(lynx, lynx->rcv_pcl_start, &pcl);
@@ -1703,7 +1700,8 @@
         .remove =   __devexit_p(remove_card),
 };
 
-static struct hpsb_host_operations lynx_ops = {
+static struct hpsb_host_driver lynx_driver = {
+	.name =		   PCILYNX_DRIVER_NAME,
         .get_rom =         get_lynx_rom,
         .transmit_packet = lynx_transmit,
         .devctl =          lynx_devctl,
@@ -1727,22 +1725,14 @@
         }
 #endif
 
-        lynx_driver = hpsb_register_lowlevel(&lynx_ops, PCILYNX_DRIVER_NAME);
-        if (!lynx_driver) {
-                ret = -ENOMEM;
-                goto free_char_dev;
-        }
-
         ret = pci_module_init(&lynx_pci_driver);
         if (ret < 0) {
                 PRINT_G(KERN_ERR, "PCI module init failed");
-                goto unregister_lowlevel;
+                goto free_char_dev;
         }
 
         return 0;
 
- unregister_lowlevel:
-        hpsb_unregister_lowlevel(lynx_driver);
  free_char_dev:
 #ifdef CONFIG_IEEE1394_PCILYNX_PORTS
         unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME);
@@ -1754,7 +1744,6 @@
 static void __exit pcilynx_cleanup(void)
 {
         pci_unregister_driver(&lynx_pci_driver);
-        hpsb_unregister_lowlevel(lynx_driver);
 
 #ifdef CONFIG_IEEE1394_PCILYNX_PORTS
         unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME);
diff -urN linux-2.4.20-pre7/drivers/ieee1394/pcilynx.h linux-2.4.20-pre8/drivers/ieee1394/pcilynx.h
--- linux-2.4.20-pre7/drivers/ieee1394/pcilynx.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/pcilynx.h	Wed Sep 25 18:21:41 2002
@@ -94,7 +94,7 @@
 
         struct lynx_send_data {
                 pcl_t pcl_start, pcl;
-                struct hpsb_packet *queue, *queue_last;
+                struct list_head queue;
                 spinlock_t queue_lock;
                 dma_addr_t header_dma, data_dma;
                 int channel;
diff -urN linux-2.4.20-pre7/drivers/ieee1394/sbp2.c linux-2.4.20-pre8/drivers/ieee1394/sbp2.c
--- linux-2.4.20-pre7/drivers/ieee1394/sbp2.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/sbp2.c	Wed Sep 25 18:21:41 2002
@@ -351,7 +351,7 @@
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-	"$Rev: 530 $ James Goodwin <jamesg@filanet.com>";
+	"$Rev: 545 $ James Goodwin <jamesg@filanet.com>";
 
 /*
  * Module load parameter definitions
@@ -3135,7 +3135,11 @@
 /*
  * Called by scsi stack to get bios parameters (used by fdisk, and at boot).
  */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28)
 static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[]) 
+#else
+static int sbp2scsi_biosparam (Scsi_Disk *disk, struct block_device *dev, int geom[]) 
+#endif
 {
 	int heads, sectors, cylinders;
 
diff -urN linux-2.4.20-pre7/drivers/ieee1394/sbp2.h linux-2.4.20-pre8/drivers/ieee1394/sbp2.h
--- linux-2.4.20-pre7/drivers/ieee1394/sbp2.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/sbp2.h	Wed Sep 25 18:21:41 2002
@@ -549,7 +549,11 @@
 static int sbp2scsi_detect (Scsi_Host_Template *tpnt);
 static const char *sbp2scsi_info (struct Scsi_Host *host);
 void sbp2scsi_setup(char *str, int *ints);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28)
 static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[]);
+#else
+static int sbp2scsi_biosparam (Scsi_Disk *disk, struct block_device *dev, int geom[]);
+#endif
 static int sbp2scsi_abort (Scsi_Cmnd *SCpnt); 
 static int sbp2scsi_reset (Scsi_Cmnd *SCpnt); 
 static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
diff -urN linux-2.4.20-pre7/drivers/ieee1394/video1394.c linux-2.4.20-pre8/drivers/ieee1394/video1394.c
--- linux-2.4.20-pre7/drivers/ieee1394/video1394.c	Wed Sep 25 18:20:51 2002
+++ linux-2.4.20-pre8/drivers/ieee1394/video1394.c	Wed Sep 25 18:21:41 2002
@@ -56,8 +56,6 @@
 #include "ohci1394.h"
 
 #define ISO_CHANNELS 64
-#define ISO_RECEIVE 0
-#define ISO_TRANSMIT 1
 
 #ifndef virt_to_page
 #define virt_to_page(x) MAP_NR(x)
@@ -84,9 +82,10 @@
 
 struct dma_iso_ctx {
 	struct ti_ohci *ohci;
-	int type; /* ISO_TRANSMIT or ISO_RECEIVE */
-	int ctx;
+	int type; /* OHCI_ISO_TRANSMIT or OHCI_ISO_RECEIVE */
+	struct ohci1394_iso_tasklet iso_tasklet;
 	int channel;
+	int ctx;
 	int last_buffer;
 	int * next_buffer;  /* For ISO Transmit of video packets
 			       to write the correct SYT field
@@ -153,8 +152,8 @@
 #define PRINT(level, card, fmt, args...) \
 printk(level "video1394_%d: " fmt "\n" , card , ## args)
 
-static void irq_handler(int card, quadlet_t isoRecvIntEvent, 
-			quadlet_t isoXmitIntEvent, void *data);
+void wakeup_dma_ir_ctx(unsigned long l);
+void wakeup_dma_it_ctx(unsigned long l);
 
 static LIST_HEAD(video1394_cards);
 static spinlock_t video1394_cards_lock = SPIN_LOCK_UNLOCKED;
@@ -234,12 +233,12 @@
 static int free_dma_iso_ctx(struct dma_iso_ctx *d)
 {
 	int i;
-	unsigned long *usage;
 	
 	DBGMSG(d->ohci->id, "Freeing dma_iso_ctx %d", d->ctx);
 
 	ohci1394_stop_context(d->ohci, d->ctrlClear, NULL);
-	ohci1394_unhook_irq(d->ohci, irq_handler, d);
+	if (d->iso_tasklet.link.next != NULL)
+		ohci1394_unregister_iso_tasklet(d->ohci, &d->iso_tasklet);
 
 	if (d->buf)
 		rvfree((void *)d->buf, d->num_desc * d->buf_size);
@@ -265,11 +264,6 @@
 	if (d->next_buffer)
 		kfree(d->next_buffer);
 
-	usage = (d->type == ISO_RECEIVE) ? &d->ohci->ir_ctx_usage :
-		&d->ohci->it_ctx_usage;
-       
-	/* clear the ISO context usage bit */
-	clear_bit(d->ctx, usage);
 	list_del(&d->link);
 
 	kfree(d);
@@ -281,55 +275,28 @@
 alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc,
 		  int buf_size, int channel, unsigned int packet_size)
 {
-	struct dma_iso_ctx *d=NULL;
+	struct dma_iso_ctx *d;
 	int i;
 
-	unsigned long *usage = (type == ISO_RECEIVE) ? &ohci->ir_ctx_usage :
-		                                       &ohci->it_ctx_usage;
-
-	/* try to claim the ISO context usage bit */
-	for (i = 0; i < ohci->nb_iso_rcv_ctx; i++) {
-		if (!test_and_set_bit(i, usage)) {
-			PRINT(KERN_ERR, ohci->id, "Free iso ctx %d found", i);
-			break;
-		}
-	}
-
-	if (i == ohci->nb_iso_rcv_ctx) {
-		PRINT(KERN_ERR, ohci->id, "No DMA contexts available");
-		return NULL;
-	}
-	
-	d = (struct dma_iso_ctx *)kmalloc(sizeof(struct dma_iso_ctx), 
-					  GFP_KERNEL);
-	if (d==NULL) {
+	d = kmalloc(sizeof(struct dma_iso_ctx), GFP_KERNEL);
+	if (d == NULL) {
 		PRINT(KERN_ERR, ohci->id, "Failed to allocate dma_iso_ctx");
 		return NULL;
 	}
 
-	memset(d, 0, sizeof(struct dma_iso_ctx));
+	memset(d, 0, sizeof *d);
 
-	d->ohci = (void *)ohci;
+	d->ohci = ohci;
 	d->type = type;
-	d->ctx = i;
 	d->channel = channel;
 	d->num_desc = num_desc;
 	d->frame_size = buf_size;
-	if (buf_size%PAGE_SIZE) 
-		d->buf_size = buf_size + PAGE_SIZE - (buf_size%PAGE_SIZE);
-	else
-		d->buf_size = buf_size;
+	d->buf_size = PAGE_ALIGN(buf_size);
 	d->last_buffer = -1;
 	d->buf = NULL;
 	d->ir_prg = NULL;
 	init_waitqueue_head(&d->waitq);
 
-	if (ohci1394_hook_irq(ohci, irq_handler, d) != 0) {
-		PRINT(KERN_ERR, ohci->id, "ohci1394_hook_irq() failed");
-		free_dma_iso_ctx(d);
-		return NULL;
-	}
-
 	d->buf = rvmalloc(d->num_desc * d->buf_size);
 
 	if (d->buf == NULL) {
@@ -339,7 +306,24 @@
 	}
 	memset(d->buf, 0, d->num_desc * d->buf_size);
 
-	if (type == ISO_RECEIVE) {
+	if (type == OHCI_ISO_RECEIVE)
+		ohci1394_init_iso_tasklet(&d->iso_tasklet, type,
+					  wakeup_dma_ir_ctx,
+					  (unsigned long) d);
+	else
+		ohci1394_init_iso_tasklet(&d->iso_tasklet, type,
+					  wakeup_dma_it_ctx,
+					  (unsigned long) d);
+
+	if (ohci1394_register_iso_tasklet(ohci, &d->iso_tasklet) < 0) {
+		PRINT(KERN_ERR, ohci->id, "no free iso %s contexts",
+		      type == OHCI_ISO_RECEIVE ? "receive" : "transmit");
+		free_dma_iso_ctx(d);
+		return NULL;
+	}
+	d->ctx = d->iso_tasklet.context;
+
+	if (type == OHCI_ISO_RECEIVE) {
 		d->ctrlSet = OHCI1394_IsoRcvContextControlSet+32*d->ctx;
 		d->ctrlClear = OHCI1394_IsoRcvContextControlClear+32*d->ctx;
 		d->cmdPtr = OHCI1394_IsoRcvCommandPtr+32*d->ctx;
@@ -359,7 +343,7 @@
 		d->nb_cmd = d->buf_size / PAGE_SIZE + 1;
 		d->left_size = (d->frame_size % PAGE_SIZE) ?
 			d->frame_size % PAGE_SIZE : PAGE_SIZE;
-
+ 
 		for (i=0;i<d->num_desc;i++) {
 			d->ir_prg[i] = kmalloc(d->nb_cmd * 
 					       sizeof(struct dma_cmd), 
@@ -371,8 +355,9 @@
 				return NULL;
 			}
 		}
+
 	}
-	else {  /* ISO_TRANSMIT */
+	else {  /* OHCI_ISO_TRANSMIT */
 		d->ctrlSet = OHCI1394_IsoXmitContextControlSet+16*d->ctx;
 		d->ctrlClear = OHCI1394_IsoXmitContextControlClear+16*d->ctx;
 		d->cmdPtr = OHCI1394_IsoXmitCommandPtr+16*d->ctx;
@@ -458,7 +443,7 @@
 
 	PRINT(KERN_INFO, ohci->id, "Iso %s DMA: %d buffers "
 	      "of size %d allocated for a frame size %d, each with %d prgs",
-	      (type==ISO_RECEIVE) ? "receive" : "transmit",
+	      (type == OHCI_ISO_RECEIVE) ? "receive" : "transmit",
 	      d->num_desc, d->buf_size, d->frame_size, d->nb_cmd);
 
 	return d;
@@ -563,18 +548,14 @@
 	return NULL;
 }
 
-int wakeup_dma_ir_ctx(struct ti_ohci *ohci, struct dma_iso_ctx *d) 
+void wakeup_dma_ir_ctx(unsigned long l)
 {
+	struct dma_iso_ctx *d = (struct dma_iso_ctx *) l;
 	int i;
 
-	if (d==NULL) {
-		PRINT(KERN_ERR, ohci->id, "Iso receive event received but "
-		      "context not allocated");
-		return -EFAULT;
-	}
-
 	spin_lock(&d->lock);
-	for (i=0;i<d->num_desc;i++) {
+
+	for (i = 0; i < d->num_desc; i++) {
 		if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) {
 			reset_ir_status(d, i);
 			d->buffer_status[i] = VIDEO1394_BUFFER_READY;
@@ -585,9 +566,11 @@
 #endif
 		}
 	}
+
 	spin_unlock(&d->lock);
-	if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq);
-	return 0;
+
+	if (waitqueue_active(&d->waitq))
+		wake_up_interruptible(&d->waitq);
 }
 
 static inline void put_timestamp(struct ti_ohci *ohci, struct dma_iso_ctx * d,
@@ -642,29 +625,28 @@
 #endif	
 }
 
-int wakeup_dma_it_ctx(struct ti_ohci *ohci, struct dma_iso_ctx *d) 
+void wakeup_dma_it_ctx(unsigned long l)
 {
+	struct dma_iso_ctx *d = (struct dma_iso_ctx *) l;
+	struct ti_ohci *ohci = d->ohci;
 	int i;
 
-	if (d==NULL) {
-		PRINT(KERN_ERR, ohci->id, "Iso transmit event received but "
-		      "context not allocated");
-		return -EFAULT;
-	}
-
 	spin_lock(&d->lock);
-	for (i=0;i<d->num_desc;i++) {
-		if (d->it_prg[i][d->last_used_cmd[i]].end.status& 
-			cpu_to_le32(0xFFFF0000)) {
+
+	for (i = 0; i < d->num_desc; i++) {
+		if (d->it_prg[i][d->last_used_cmd[i]].end.status & 
+		    cpu_to_le32(0xFFFF0000)) {
 			int next = d->next_buffer[i];
 			put_timestamp(ohci, d, next);
 			d->it_prg[i][d->last_used_cmd[i]].end.status = 0;
 			d->buffer_status[i] = VIDEO1394_BUFFER_READY;
 		}
 	}
+
 	spin_unlock(&d->lock);
-	if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq);
-	return 0;
+
+	if (waitqueue_active(&d->waitq))
+		wake_up_interruptible(&d->waitq);
 }
 
 static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag)
@@ -891,7 +873,7 @@
 		}
 
 		if (cmd == VIDEO1394_LISTEN_CHANNEL) {
-			d = alloc_dma_iso_ctx(ohci, ISO_RECEIVE,
+			d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE,
 					      v.nb_buffers, v.buf_size, 
 					      v.channel, 0);
 
@@ -912,7 +894,7 @@
 			      d->ctx, v.channel);
 		}
 		else {
-			d = alloc_dma_iso_ctx(ohci, ISO_TRANSMIT,
+			d = alloc_dma_iso_ctx(ohci, OHCI_ISO_TRANSMIT,
 					      v.nb_buffers, v.buf_size, 
 					      v.channel, v.packet_size);
 
@@ -966,9 +948,9 @@
 		ohci->ISO_channel_usage &= ~mask;
 
 		if (cmd == VIDEO1394_UNLISTEN_CHANNEL)
-			d = find_ctx(&ctx->context_list, ISO_RECEIVE, channel);
+			d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, channel);
 		else
-			d = find_ctx(&ctx->context_list, ISO_TRANSMIT, channel);
+			d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, channel);
 
 		if (d == NULL) return -EFAULT;
 		PRINT(KERN_INFO, ohci->id, "Iso context %d "
@@ -985,7 +967,7 @@
 		if(copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
-		d = find_ctx(&ctx->context_list, ISO_RECEIVE, v.channel);
+		d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
 
 		if ((v.buffer<0) || (v.buffer>d->num_desc)) {
 			PRINT(KERN_ERR, ohci->id, 
@@ -1047,7 +1029,7 @@
 		if(copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
-		d = find_ctx(&ctx->context_list, ISO_RECEIVE, v.channel);
+		d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
 
 		if ((v.buffer<0) || (v.buffer>d->num_desc)) {
 			PRINT(KERN_ERR, ohci->id, 
@@ -1128,7 +1110,7 @@
 		if(copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
-		d = find_ctx(&ctx->context_list, ISO_TRANSMIT, v.channel);
+		d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
 
 		if ((v.buffer<0) || (v.buffer>d->num_desc)) {
 			PRINT(KERN_ERR, ohci->id, 
@@ -1217,7 +1199,7 @@
 		if(copy_from_user(&v, (void *)arg, sizeof(v)))
 			return -EFAULT;
 
-		d = find_ctx(&ctx->context_list, ISO_TRANSMIT, v.channel);
+		d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
 
 		if ((v.buffer<0) || (v.buffer>d->num_desc)) {
 			PRINT(KERN_ERR, ohci->id, 
@@ -1340,7 +1322,7 @@
 			ohci->ISO_channel_usage &= ~mask;
 		PRINT(KERN_INFO, ohci->id, "On release: Iso %s context "
 		      "%d stop listening on channel %d",
-		      d->type == ISO_RECEIVE ? "receive" : "transmit",
+		      d->type == OHCI_ISO_RECEIVE ? "receive" : "transmit",
 		      d->ctx, d->channel);
 		free_dma_iso_ctx(d);
 	}
@@ -1352,20 +1334,6 @@
 	return 0;
 }
 
-static void irq_handler(int card, quadlet_t isoRecvIntEvent, 
-			quadlet_t isoXmitIntEvent, void *data)
-{
-	struct dma_iso_ctx *d = (struct dma_iso_ctx *) data;
-
-	DBGMSG(card, "Iso event Recv: %08x Xmit: %08x",
-	       isoRecvIntEvent, isoXmitIntEvent);
-
-	if (d->type == ISO_RECEIVE && isoRecvIntEvent & (1 << d->ctx))
-		wakeup_dma_ir_ctx(d->ohci, d);
-	if (d->type == ISO_TRANSMIT && isoXmitIntEvent & (1 << d->ctx))
-		wakeup_dma_it_ctx(d->ohci, d);
-}
-
 static struct file_operations video1394_fops=
 {
 	.owner =	THIS_MODULE,
diff -urN linux-2.4.20-pre7/drivers/isdn/hisax/config.c linux-2.4.20-pre8/drivers/isdn/hisax/config.c
--- linux-2.4.20-pre7/drivers/isdn/hisax/config.c	Wed Sep 25 18:20:51 2002
+++ linux-2.4.20-pre8/drivers/isdn/hisax/config.c	Wed Sep 25 18:21:43 2002
@@ -1261,9 +1261,12 @@
 			foundcards++;
 			i++;
 		} else {
-			printk(KERN_WARNING
-			       "HiSax: Card %s not installed !\n",
-			       CardType[cards[i].typ]);
+			/* make sure we don't oops the module */
+			if (cards[i].typ > 0 && cards[i].typ <= ISDN_CTYPE_COUNT) {
+				printk(KERN_WARNING
+			       		"HiSax: Card %s not installed !\n",
+			       		CardType[cards[i].typ]);
+			}
 			HiSax_shiftcards(i);
 			nrcards--;
 		}
diff -urN linux-2.4.20-pre7/drivers/media/video/zoran_procfs.c linux-2.4.20-pre8/drivers/media/video/zoran_procfs.c
--- linux-2.4.20-pre7/drivers/media/video/zoran_procfs.c	Wed Jul  4 14:41:33 2001
+++ linux-2.4.20-pre8/drivers/media/video/zoran_procfs.c	Wed Sep 25 18:21:45 2002
@@ -110,6 +110,9 @@
 	struct zoran *zr;
 
 	zr = (struct zoran *) data;
+	
+	if(count > 32768)		/* Stupidity filter */
+		count = 32768;
 
 	string = sp = vmalloc(count + 1);
 	if (!string) {
diff -urN linux-2.4.20-pre7/drivers/media/video/zr36067.c linux-2.4.20-pre8/drivers/media/video/zr36067.c
--- linux-2.4.20-pre7/drivers/media/video/zr36067.c	Wed Sep 25 18:20:52 2002
+++ linux-2.4.20-pre8/drivers/media/video/zr36067.c	Wed Sep 25 18:21:46 2002
@@ -3763,7 +3763,7 @@
 			 *   Write the overlay mask if clips are wanted.
 			 */
 			 
-			if (vw.clipcount > 2048)
+			if (vw.clipcount < 0 || vw.clipcount > 2048)
 				return -EINVAL;
 			if (vw.clipcount) {
 				vcp =
diff -urN linux-2.4.20-pre7/drivers/net/3c509.c linux-2.4.20-pre8/drivers/net/3c509.c
--- linux-2.4.20-pre7/drivers/net/3c509.c	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/3c509.c	Wed Sep 25 18:21:47 2002
@@ -694,7 +694,7 @@
 	outw(0x00, ioaddr + TX_FIFO);
 	/* ... and the packet rounded to a doubleword. */
 #ifdef  __powerpc__
-	outsl_unswapped(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+	outsl_ns(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 #else
 	outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 #endif
@@ -905,7 +905,7 @@
 
 				/* 'skb->data' points to the start of sk_buff data area. */
 #ifdef  __powerpc__
-				insl_unswapped(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
+				insl_ns(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
 							   (pkt_len + 3) >> 2);
 #else
 				insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len),
diff -urN linux-2.4.20-pre7/drivers/net/3c59x.c linux-2.4.20-pre8/drivers/net/3c59x.c
--- linux-2.4.20-pre7/drivers/net/3c59x.c	Fri Dec 21 09:41:54 2001
+++ linux-2.4.20-pre8/drivers/net/3c59x.c	Wed Sep 25 18:21:47 2002
@@ -1444,11 +1444,14 @@
 		/* Read BMSR (reg1) only to clear old status. */
 		mii_reg1 = mdio_read(dev, vp->phys[0], 1);
 		mii_reg5 = mdio_read(dev, vp->phys[0], 5);
-		if (mii_reg5 == 0xffff  ||  mii_reg5 == 0x0000)
-			;					/* No MII device or no link partner report */
-		else if ((mii_reg5 & 0x0100) != 0	/* 100baseTx-FD */
+		if (mii_reg5 == 0xffff  ||  mii_reg5 == 0x0000) {
+			netif_carrier_off(dev); /* No MII device or no link partner report */
+		} else {
+			if ((mii_reg5 & 0x0100) != 0	/* 100baseTx-FD */
 				 || (mii_reg5 & 0x00C0) == 0x0040) /* 10T-FD, but not 100-HD */
-			vp->full_duplex = 1;
+				vp->full_duplex = 1;
+			netif_carrier_on(dev);
+		}
 		vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
 		if (vortex_debug > 1)
 			printk(KERN_INFO "%s: MII #%d status %4.4x, link partner capability %4.4x,"
@@ -1651,13 +1654,16 @@
 	switch (dev->if_port) {
 	case XCVR_10baseT:  case XCVR_100baseTx:  case XCVR_100baseFx:
 		if (media_status & Media_LnkBeat) {
+			netif_carrier_on(dev);
 			ok = 1;
 			if (vortex_debug > 1)
 				printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n",
 					   dev->name, media_tbl[dev->if_port].name, media_status);
-		} else if (vortex_debug > 1)
+		} else if (vortex_debug > 1) {
+			netif_carrier_off(dev);
 			printk(KERN_DEBUG "%s: Media %s has no link beat, %x.\n",
 				   dev->name, media_tbl[dev->if_port].name, media_status);
+		}
 		break;
 	case XCVR_MII: case XCVR_NWAY:
 		{
@@ -1666,7 +1672,7 @@
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n",
 					dev->name, mii_status);
-			if (mii_status & 0x0004) {
+			if (mii_status & BMSR_LSTATUS) {
 				int mii_reg5 = mdio_read(dev, vp->phys[0], 5);
 				if (! vp->force_fd  &&  mii_reg5 != 0xffff) {
 					int duplex = (mii_reg5&0x0100) ||
@@ -1688,6 +1694,9 @@
 						/* AKPM: bug: should reset Tx and Rx after setting Duplex.  Page 180 */
 					}
 				}
+				netif_carrier_on(dev);
+			} else {
+				netif_carrier_off(dev);
 			}
 		}
 		break;
diff -urN linux-2.4.20-pre7/drivers/net/8139cp.c linux-2.4.20-pre8/drivers/net/8139cp.c
--- linux-2.4.20-pre7/drivers/net/8139cp.c	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/8139cp.c	Wed Sep 25 18:21:47 2002
@@ -639,13 +639,13 @@
 		cp_rx_skb(cp, skb, desc);
 
 rx_next:
+		cp->rx_ring[rx_tail].opts2 = 0;
+		cp->rx_ring[rx_tail].addr = cpu_to_le64(mapping);
 		if (rx_tail == (CP_RX_RING_SIZE - 1))
 			desc->opts1 = cpu_to_le32(DescOwn | RingEnd |
 						  cp->rx_buf_sz);
 		else
 			desc->opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz);
-		cp->rx_ring[rx_tail].opts2 = 0;
-		cp->rx_ring[rx_tail].addr = cpu_to_le64(mapping);
 		rx_tail = NEXT_RX(rx_tail);
 	}
 
@@ -669,6 +669,8 @@
 		printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n",
 		        dev->name, status, cpr8(Cmd), cpr16(CpCmd));
 
+	cpw16_f(IntrStatus, status);
+
 	spin_lock(&cp->lock);
 
 	if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
@@ -676,8 +678,6 @@
 	if (status & (TxOK | TxErr | TxEmpty | SWInt))
 		cp_tx(cp);
 
-	cpw16_f(IntrStatus, status);
-
 	if (status & PciErr) {
 		u16 pci_status;
 
@@ -781,7 +781,6 @@
 
 		len = skb->len;
 		mapping = pci_map_single(cp->pdev, skb->data, len, PCI_DMA_TODEVICE);
-		eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
 		CP_VLAN_TX_TAG(txd, vlan_tag);
 		txd->addr = cpu_to_le64(mapping);
 		wmb();
@@ -811,7 +810,7 @@
 		entry = NEXT_TX(entry);
 	} else {
 		struct cp_desc *txd;
-		u32 first_len;
+		u32 first_len, first_eor;
 		dma_addr_t first_mapping;
 		int frag, first_entry = entry;
 #ifdef CP_TX_CHECKSUM
@@ -821,6 +820,7 @@
 		/* We must give this initial chunk to the device last.
 		 * Otherwise we could race with the device.
 		 */
+		first_eor = eor;
 		first_len = skb->len - skb->data_len;
 		first_mapping = pci_map_single(cp->pdev, skb->data,
 					       first_len, PCI_DMA_TODEVICE);
@@ -879,17 +879,19 @@
 #ifdef CP_TX_CHECKSUM
 		if (skb->ip_summed == CHECKSUM_HW) {
 			if (ip->protocol == IPPROTO_TCP)
-				txd->opts1 = cpu_to_le32(first_len | FirstFrag |
-							DescOwn | IPCS | TCPCS);
+				txd->opts1 = cpu_to_le32(first_eor | first_len |
+							 FirstFrag | DescOwn |
+							 IPCS | TCPCS);
 			else if (ip->protocol == IPPROTO_UDP)
-				txd->opts1 = cpu_to_le32(first_len | FirstFrag |
-							DescOwn | IPCS | UDPCS);
+				txd->opts1 = cpu_to_le32(first_eor | first_len |
+							 FirstFrag | DescOwn |
+							 IPCS | UDPCS);
 			else
 				BUG();
 		} else
 #endif
-			txd->opts1 = cpu_to_le32(first_len | FirstFrag |
-						 DescOwn);
+			txd->opts1 = cpu_to_le32(first_eor | first_len |
+						 FirstFrag | DescOwn);
 		wmb();
 	}
 	cp->tx_head = entry;
@@ -1086,14 +1088,14 @@
 		cp->rx_skb[i].skb = skb;
 		cp->rx_skb[i].frag = 0;
 
+		cp->rx_ring[i].opts2 = 0;
+		cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping);
 		if (i == (CP_RX_RING_SIZE - 1))
 			cp->rx_ring[i].opts1 =
 				cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz);
 		else
 			cp->rx_ring[i].opts1 =
 				cpu_to_le32(DescOwn | cp->rx_buf_sz);
-		cp->rx_ring[i].opts2 = 0;
-		cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping);
 	}
 
 	return 0;
@@ -1206,7 +1208,11 @@
 		printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
 
 	netif_stop_queue(dev);
+
+	spin_lock_irq(&cp->lock);
 	cp_stop_hw(cp);
+	spin_unlock_irq(&cp->lock);
+
 	free_irq(dev->irq, dev);
 	cp_free_rings(cp);
 	return 0;
diff -urN linux-2.4.20-pre7/drivers/net/8139too.c linux-2.4.20-pre8/drivers/net/8139too.c
--- linux-2.4.20-pre7/drivers/net/8139too.c	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/8139too.c	Wed Sep 25 18:21:47 2002
@@ -1747,10 +1747,6 @@
 				tp->stats.tx_carrier_errors++;
 			if (txstatus & TxOutOfWindow)
 				tp->stats.tx_window_errors++;
-#ifdef ETHER_STATS
-			if ((txstatus & 0x0f000000) == 0x0f000000)
-				tp->stats.collisions16++;
-#endif
 		} else {
 			if (txstatus & TxUnderrun) {
 				/* Add 64 to the Tx FIFO threshold. */
diff -urN linux-2.4.20-pre7/drivers/net/Config.in linux-2.4.20-pre8/drivers/net/Config.in
--- linux-2.4.20-pre7/drivers/net/Config.in	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/Config.in	Wed Sep 25 18:21:47 2002
@@ -192,6 +192,7 @@
       dep_tristate '    SiS 900/7016 PCI Fast Ethernet Adapter support' CONFIG_SIS900 $CONFIG_PCI
       dep_tristate '    SMC EtherPower II' CONFIG_EPIC100 $CONFIG_PCI
       dep_tristate '    Sundance Alta support' CONFIG_SUNDANCE $CONFIG_PCI
+      dep_mbool '      Use MMIO instead of PIO' CONFIG_SUNDANCE_MMIO $CONFIG_SUNDANCE
       if [ "$CONFIG_PCI" = "y" -o "$CONFIG_EISA" = "y" ]; then
          tristate '    TI ThunderLAN support' CONFIG_TLAN
       fi
diff -urN linux-2.4.20-pre7/drivers/net/Makefile linux-2.4.20-pre8/drivers/net/Makefile
--- linux-2.4.20-pre7/drivers/net/Makefile	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/Makefile	Wed Sep 25 18:21:47 2002
@@ -113,7 +113,7 @@
 obj-$(CONFIG_AIRONET4500_CS)	+= aironet4500_proc.o
 
 obj-$(CONFIG_WINBOND_840) += winbond-840.o mii.o
-obj-$(CONFIG_SUNDANCE) += sundance.o
+obj-$(CONFIG_SUNDANCE) += sundance.o mii.o
 obj-$(CONFIG_HAMACHI) += hamachi.o
 obj-$(CONFIG_NET) += Space.o setup.o net_init.o loopback.o
 obj-$(CONFIG_SEEQ8005) += seeq8005.o
diff -urN linux-2.4.20-pre7/drivers/net/acenic.c linux-2.4.20-pre8/drivers/net/acenic.c
--- linux-2.4.20-pre7/drivers/net/acenic.c	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/acenic.c	Wed Sep 25 18:21:47 2002
@@ -47,6 +47,7 @@
  *                                       flushing the Jumbo ring.
  *   Hans Grobler <grobh@sun.ac.za>:     Memory leak fixes in the
  *                                       driver init path.
+ *   Grant Grundler <grundler@cup.hp.com>: PCI write posting fixes.
  */
 
 #include <linux/config.h>
@@ -123,7 +124,6 @@
 #ifndef PCI_DEVICE_ID_FARALLON_PN9100T
 #define PCI_DEVICE_ID_FARALLON_PN9100T  0xfa
 #endif
-
 #ifndef PCI_VENDOR_ID_SGI
 #define PCI_VENDOR_ID_SGI		0x10a9
 #endif
@@ -144,13 +144,13 @@
 	{ PCI_VENDOR_ID_NETGEAR, PCI_DEVICE_ID_NETGEAR_GA620T,
 	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
 	/*
-	 * Farallon used the DEC vendor ID on their cards incorrectly.
+	 * Farallon used the DEC vendor ID on their cards incorrectly,
+	 * then later Alteon's ID.
 	 */
 	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_FARALLON_PN9000SX,
 	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
 	{ PCI_VENDOR_ID_ALTEON, PCI_DEVICE_ID_FARALLON_PN9100T,
 	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
-
 	{ PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_ACENIC,
 	  PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, },
 	{ }
@@ -180,15 +180,21 @@
 #endif
 
 #ifndef SET_MODULE_OWNER
-#define SET_MODULE_OWNER(dev)		{do{} while(0);}
+#define SET_MODULE_OWNER(dev)		do{} while(0)
 #define ACE_MOD_INC_USE_COUNT		MOD_INC_USE_COUNT
 #define ACE_MOD_DEC_USE_COUNT		MOD_DEC_USE_COUNT
 #else
-#define ACE_MOD_INC_USE_COUNT		{do{} while(0);}
-#define ACE_MOD_DEC_USE_COUNT		{do{} while(0);}
+#define ACE_MOD_INC_USE_COUNT		do{} while(0)
+#define ACE_MOD_DEC_USE_COUNT		do{} while(0)
 #endif
 
 
+#if LINUX_VERSION_CODE >= 0x2051c
+#define ace_sync_irq(irq)	synchronize_irq(irq)
+#else
+#define ace_sync_irq(irq)	synchronize_irq()
+#endif
+
 #if (LINUX_VERSION_CODE < 0x02030d)
 #define pci_resource_start(dev, bar)	dev->base_address[bar]
 #elif (LINUX_VERSION_CODE < 0x02032c)
@@ -199,6 +205,7 @@
 #define net_device device
 #endif
 
+
 #if (LINUX_VERSION_CODE < 0x02032a)
 typedef u32 dma_addr_t;
 
@@ -222,8 +229,6 @@
 	(((u64)(mask) & 0xffffffff00000000) == 0 ? 0 : -EIO)
 #define pci_dma_supported(dev, mask)		\
 	(((u64)(mask) & 0xffffffff00000000) == 0 ? 1 : 0)
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
 
 #elif (LINUX_VERSION_CODE < 0x02040d)
 
@@ -247,8 +252,15 @@
 }
 #define pci_unmap_page(cookie, dma_addr, size, dir)	\
 	pci_unmap_single(cookie, dma_addr, size, dir)
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020412)
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)		0
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	do{} while(0)
+#define pci_unmap_len(PTR, LEN_NAME)		0
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do{} while(0)
 #endif
 
 
@@ -266,7 +278,7 @@
 #define dev_kfree_skb_irq(a)			dev_kfree_skb(a)
 #define netif_wake_queue(dev)			clear_bit(0, &dev->tbusy)
 #define netif_stop_queue(dev)			set_bit(0, &dev->tbusy)
-#define late_stop_netif_stop_queue(dev)		{do{} while(0);}
+#define late_stop_netif_stop_queue(dev)		do{} while(0)
 #define early_stop_netif_stop_queue(dev)	test_and_set_bit(0,&dev->tbusy)
 #define early_stop_netif_wake_queue(dev)	netif_wake_queue(dev)
 
@@ -280,7 +292,7 @@
 #define ace_mark_net_bh()			mark_bh(NET_BH)
 #define netif_queue_stopped(dev)		dev->tbusy
 #define netif_running(dev)			dev->start
-#define ace_if_down(dev)			{do{dev->start = 0;} while(0);}
+#define ace_if_down(dev)			do{dev->start = 0;} while(0)
 
 #define tasklet_struct				tq_struct
 static inline void tasklet_schedule(struct tasklet_struct *tasklet)
@@ -298,13 +310,13 @@
 	tasklet->routine = (void (*)(void *))func;
 	tasklet->data = (void *)data;
 }
-#define tasklet_kill(tasklet)			{do{} while(0);}
+#define tasklet_kill(tasklet)			do{} while(0)
 #else
 #define late_stop_netif_stop_queue(dev)		netif_stop_queue(dev)
 #define early_stop_netif_stop_queue(dev)	0
-#define early_stop_netif_wake_queue(dev)	{do{} while(0);}
-#define ace_mark_net_bh()			{do{} while(0);}
-#define ace_if_down(dev)			{do{} while(0);}
+#define early_stop_netif_wake_queue(dev)	do{} while(0)
+#define ace_mark_net_bh()			do{} while(0)
+#define ace_if_down(dev)			do{} while(0)
 #endif
 
 #if (LINUX_VERSION_CODE >= 0x02031b)
@@ -320,7 +332,7 @@
 
 #ifndef ARCH_HAS_PREFETCHW
 #ifndef prefetchw
-#define prefetchw(x)				{do{} while(0);}
+#define prefetchw(x)				do{} while(0)
 #endif
 #endif
 
@@ -575,7 +587,7 @@
 static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
 
 static char version[] __initdata = 
-  "acenic.c: v0.89 03/15/2002  Jes Sorensen, linux-acenic@SunSITE.dk\n"
+  "acenic.c: v0.92 08/05/2002  Jes Sorensen, linux-acenic@SunSITE.dk\n"
   "                            http://home.cern.ch/~jes/gige/acenic.html\n";
 
 static struct net_device *root_dev;
@@ -673,6 +685,11 @@
 			printk(version);
 		}
 
+		if (pci_enable_device(pdev)) {
+			kfree(dev);
+			continue;
+		}
+
 		/*
 		 * Enable master mode before we start playing with the
 		 * pci_command word since pci_set_master() will modify
@@ -722,11 +739,12 @@
 					"Gigabit Ethernet", sizeof (ap->name));
 				printk(KERN_INFO "%s: Farallon PN9100-T ",
 				       dev->name);
-				break;
+			} else {
+				strncpy(ap->name, "AceNIC Gigabit Ethernet",
+					sizeof (ap->name));
+				printk(KERN_INFO "%s: Alteon AceNIC ",
+				       dev->name);
 			}
-			strncpy(ap->name, "AceNIC Gigabit Ethernet",
-				sizeof (ap->name));
-			printk(KERN_INFO "%s: Alteon AceNIC ", dev->name);
 			break;
 		case PCI_VENDOR_ID_3COM:
 			strncpy(ap->name, "3Com 3C985 Gigabit Ethernet",
@@ -862,6 +880,7 @@
 		 * This clears any pending interrupts
 		 */
 		writel(1, &regs->Mb0Lo);
+		readl(&regs->CpuCtrl);	/* flush */
 
 		/*
 		 * Make sure no other CPUs are processing interrupts
@@ -872,7 +891,7 @@
 		 * Then release the RX buffers - jumbo buffers were
 		 * already released in ace_close().
 		 */
-		synchronize_irq();
+		ace_sync_irq(root_dev->irq);
 
 		for (i = 0; i < RX_STD_RING_ENTRIES; i++) {
 			struct sk_buff *skb = ap->skb->rx_std_skbuff[i].skb;
@@ -1154,10 +1173,11 @@
 	 * to any crashes involving the NIC
 	 */
 	writel(HW_RESET | (HW_RESET << 24), &regs->HostCtrl);
-	wmb();
+	readl(&regs->HostCtrl);		/* PCI write posting */
+	udelay(5);
 
 	/*
-	 * Don't access any other registes before this point!
+	 * Don't access any other registers before this point!
 	 */
 #ifdef __BIG_ENDIAN
 	/*
@@ -1170,12 +1190,13 @@
 	writel((CLR_INT | WORD_SWAP | ((CLR_INT | WORD_SWAP) << 24)),
 	       &regs->HostCtrl);
 #endif
-	mb();
+	readl(&regs->HostCtrl);		/* PCI write posting */
 
 	/*
 	 * Stop the NIC CPU and clear pending interrupts
 	 */
 	writel(readl(&regs->CpuCtrl) | CPU_HALT, &regs->CpuCtrl);
+	readl(&regs->CpuCtrl);		/* PCI write posting */
 	writel(0, &regs->Mb0Lo);
 
 	tig_ver = readl(&regs->HostCtrl) >> 28;
@@ -1196,6 +1217,7 @@
 		       tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor,
 		       tigon2FwReleaseFix);
 		writel(readl(&regs->CpuBCtrl) | CPU_HALT, &regs->CpuBCtrl);
+		readl(&regs->CpuBCtrl);		/* PCI write posting */
 		/*
 		 * The SRAM bank size does _not_ indicate the amount
 		 * of memory on the card, it controls the _bank_ size!
@@ -1227,7 +1249,7 @@
 	writel(ACE_BYTE_SWAP_DMA | ACE_WARN | ACE_FATAL |
 	       ACE_WORD_SWAP_BD | ACE_NO_JUMBO_FRAG, &regs->ModeStat);
 #endif
-	mb();
+	readl(&regs->ModeStat);		/* PCI write posting */
 
 	mac1 = 0;
 	for(i = 0; i < 4; i++) {
@@ -1365,7 +1387,7 @@
 	tmp &= ~DMA_READ_WRITE_MASK;
 	tmp |= DMA_READ_MAX_128;
 	/*
-	 * All the docs sy MUST NOT. Well, I did.
+	 * All the docs say MUST NOT. Well, I did.
 	 * Nothing terrible happens, if we load wrong size.
 	 * Bit w&i still works better!
 	 */
@@ -1375,6 +1397,13 @@
 
 #if 0
 	/*
+	 * The Host PCI bus controller driver has to set FBB.
+	 * If all devices on that PCI bus support FBB, then the controller
+	 * can enable FBB support in the Host PCI Bus controller (or on
+	 * the PCI-PCI bridge if that applies).
+	 * -ggg
+	 */
+	/*
 	 * I have received reports from people having problems when this
 	 * bit is enabled.
 	 */
@@ -1455,9 +1484,9 @@
 	set_aceaddr(&info->evt_ctrl.rngptr, ap->evt_ring_dma);
 	info->evt_ctrl.flags = 0;
 
-	set_aceaddr(&info->evt_prd_ptr, ap->evt_prd_dma);
 	*(ap->evt_prd) = 0;
 	wmb();
+	set_aceaddr(&info->evt_prd_ptr, ap->evt_prd_dma);
 	writel(0, &regs->EvtCsm);
 
 	set_aceaddr(&info->cmd_ctrl.rngptr, 0x100);
@@ -1589,7 +1618,13 @@
 
 	writel(0, &regs->MaskInt);
 	writel(1, &regs->IfIdx);
+#if 0
+	/*
+	 * McKinley boxes do not like us fiddling with AssistState
+	 * this early
+	 */
 	writel(1, &regs->AssistState);
+#endif
 
 	writel(DEF_STAT, &regs->TuneStatTicks);
 	writel(DEF_TRACE, &regs->TuneTrace);
@@ -1699,10 +1734,19 @@
 	 */
 	memset(&ap->stats, 0, sizeof(ap->stats));
 
+       /*
+	* Enable DMA engine now.
+	* If we do this sooner, Mckinley box pukes.
+	* I assume it's because Tigon II DMA engine wants to check
+	* *something* even before the CPU is started.
+	*/
+       writel(1, &regs->AssistState);  /* enable DMA */
+
 	/*
 	 * Start the NIC CPU
 	 */
 	writel(readl(&regs->CpuCtrl) & ~(CPU_HALT|CPU_TRACE), &regs->CpuCtrl);
+	readl(&regs->CpuCtrl);
 
 	/*
 	 * Wait for the firmware to spin up - max 3 seconds.
@@ -1715,6 +1759,7 @@
 
 		ace_dump_trace(ap);
 		writel(readl(&regs->CpuCtrl) | CPU_HALT, &regs->CpuCtrl);
+		readl(&regs->CpuCtrl);
 
 		/* aman@sgi.com - account for badly behaving firmware/NIC:
 		 * - have observed that the NIC may continue to generate
@@ -1729,6 +1774,7 @@
 			writel(readl(&regs->CpuBCtrl) | CPU_HALT,
 			       &regs->CpuBCtrl);
 		writel(0, &regs->Mb0Lo);
+		readl(&regs->Mb0Lo);
 
 		ecode = -EBUSY;
 		goto init_error;
@@ -2403,6 +2449,7 @@
 	 * threads and it is wrong even for that case.
 	 */
 	writel(0, &regs->Mb0Lo);
+	readl(&regs->Mb0Lo);
 
 	/*
 	 * There is no conflict between transmit handling in
@@ -2506,12 +2553,13 @@
 	struct ace_private *ap = dev->priv;
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	local_irq_save(flags);
+	ace_mask_irq(dev);
 
 	ap->vlgrp = grp;
 
-	restore_flags(flags);
+	ace_unmask_irq(dev);
+	local_irq_restore(flags);
 }
 
 
@@ -2520,13 +2568,14 @@
 	struct ace_private *ap = dev->priv;
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	local_irq_save(flags);
+	ace_mask_irq(dev);
 
 	if (ap->vlgrp)
 		ap->vlgrp->vlan_devices[vid] = NULL;
 
-	restore_flags(flags);
+	ace_unmask_irq(dev);
+	local_irq_restore(flags);
 }
 #endif /* ACENIC_DO_VLAN */
 
@@ -2630,8 +2679,9 @@
 	 * Make sure one CPU is not processing packets while
 	 * buffers are being released by another.
 	 */
-	save_flags(flags);
-	cli();
+
+	local_irq_save(flags);
+	ace_mask_irq(dev);
 
 	for (i = 0; i < ACE_TX_RING_ENTRIES(ap); i++) {
 		struct sk_buff *skb;
@@ -2668,7 +2718,8 @@
 		ace_issue_cmd(regs, &cmd);
 	}
 
-	restore_flags(flags);
+	ace_unmask_irq(dev);
+	local_irq_restore(flags);
 
 	ACE_MOD_DEC_USE_COUNT;
 	return 0;
@@ -2887,7 +2938,7 @@
 		}
 	} else {
 		while (test_and_set_bit(0, &ap->jumbo_refill_busy));
-		synchronize_irq();
+		ace_sync_irq(dev->irq);
 		ace_set_rxtx_parms(dev, 0);
 		if (ap->jumbo) {
 			struct cmd cmd;
@@ -3269,22 +3320,27 @@
 {
 	u32 local;
 
+	readl(&regs->LocalCtrl);
 	udelay(ACE_SHORT_DELAY);
 	local = readl(&regs->LocalCtrl);
 	local |= EEPROM_DATA_OUT | EEPROM_WRITE_ENABLE;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_SHORT_DELAY);
 	local |= EEPROM_CLK_OUT;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_SHORT_DELAY);
 	local &= ~EEPROM_DATA_OUT;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_SHORT_DELAY);
 	local &= ~EEPROM_CLK_OUT;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 }
 
@@ -3299,6 +3355,7 @@
 	local &= ~EEPROM_DATA_OUT;
 	local |= EEPROM_WRITE_ENABLE;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 
 	for (i = 0; i < 8; i++, magic <<= 1) {
@@ -3308,15 +3365,18 @@
 		else
 			local &= ~EEPROM_DATA_OUT;
 		writel(local, &regs->LocalCtrl);
+		readl(&regs->LocalCtrl);
 		mb();
 
 		udelay(ACE_SHORT_DELAY);
 		local |= EEPROM_CLK_OUT;
 		writel(local, &regs->LocalCtrl);
+		readl(&regs->LocalCtrl);
 		mb();
 		udelay(ACE_SHORT_DELAY);
 		local &= ~(EEPROM_CLK_OUT | EEPROM_DATA_OUT);
 		writel(local, &regs->LocalCtrl);
+		readl(&regs->LocalCtrl);
 		mb();
 	}
 }
@@ -3330,10 +3390,12 @@
 	local = readl(&regs->LocalCtrl);
 	local &= ~EEPROM_WRITE_ENABLE;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_LONG_DELAY);
 	local |= EEPROM_CLK_OUT;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_SHORT_DELAY);
 	/* sample data in middle of high clk */
@@ -3341,6 +3403,7 @@
 	udelay(ACE_SHORT_DELAY);
 	mb();
 	writel(readl(&regs->LocalCtrl) & ~EEPROM_CLK_OUT, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 
 	return state;
@@ -3355,18 +3418,22 @@
 	local = readl(&regs->LocalCtrl);
 	local |= EEPROM_WRITE_ENABLE;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_SHORT_DELAY);
 	local &= ~EEPROM_DATA_OUT;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_SHORT_DELAY);
 	local |= EEPROM_CLK_OUT;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_SHORT_DELAY);
 	local |= EEPROM_DATA_OUT;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_LONG_DELAY);
 	local &= ~EEPROM_CLK_OUT;
@@ -3399,14 +3466,13 @@
 	 * Don't take interrupts on this CPU will bit banging
 	 * the %#%#@$ I2C device
 	 */
-	__save_flags(flags);
-	__cli();
+	local_irq_save(flags);
 
 	eeprom_start(regs);
 
 	eeprom_prep(regs, EEPROM_WRITE_SELECT);
 	if (eeprom_check_ack(regs)) {
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		printk(KERN_ERR "%s: Unable to sync eeprom\n", dev->name);
 		result = -EIO;
 		goto eeprom_read_error;
@@ -3414,7 +3480,7 @@
 
 	eeprom_prep(regs, (offset >> 8) & 0xff);
 	if (eeprom_check_ack(regs)) {
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		printk(KERN_ERR "%s: Unable to set address byte 0\n",
 		       dev->name);
 		result = -EIO;
@@ -3423,7 +3489,7 @@
 
 	eeprom_prep(regs, offset & 0xff);
 	if (eeprom_check_ack(regs)) {
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		printk(KERN_ERR "%s: Unable to set address byte 1\n",
 		       dev->name);
 		result = -EIO;
@@ -3433,7 +3499,7 @@
 	eeprom_start(regs);
 	eeprom_prep(regs, EEPROM_READ_SELECT);
 	if (eeprom_check_ack(regs)) {
-		__restore_flags(flags);
+		local_irq_restore(flags);
 		printk(KERN_ERR "%s: Unable to set READ_SELECT\n",
 		       dev->name);
 		result = -EIO;
@@ -3444,10 +3510,12 @@
 		local = readl(&regs->LocalCtrl);
 		local &= ~EEPROM_WRITE_ENABLE;
 		writel(local, &regs->LocalCtrl);
+		readl(&regs->LocalCtrl);
 		udelay(ACE_LONG_DELAY);
 		mb();
 		local |= EEPROM_CLK_OUT;
 		writel(local, &regs->LocalCtrl);
+		readl(&regs->LocalCtrl);
 		mb();
 		udelay(ACE_SHORT_DELAY);
 		/* sample data mid high clk */
@@ -3458,11 +3526,13 @@
 		local = readl(&regs->LocalCtrl);
 		local &= ~EEPROM_CLK_OUT;
 		writel(local, &regs->LocalCtrl);
+		readl(&regs->LocalCtrl);
 		udelay(ACE_SHORT_DELAY);
 		mb();
 		if (i == 7) {
 			local |= EEPROM_WRITE_ENABLE;
 			writel(local, &regs->LocalCtrl);
+			readl(&regs->LocalCtrl);
 			mb();
 			udelay(ACE_SHORT_DELAY);
 		}
@@ -3470,16 +3540,19 @@
 
 	local |= EEPROM_DATA_OUT;
 	writel(local, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_SHORT_DELAY);
 	writel(readl(&regs->LocalCtrl) | EEPROM_CLK_OUT, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	udelay(ACE_LONG_DELAY);
 	writel(readl(&regs->LocalCtrl) & ~EEPROM_CLK_OUT, &regs->LocalCtrl);
+	readl(&regs->LocalCtrl);
 	mb();
 	udelay(ACE_SHORT_DELAY);
 	eeprom_stop(regs);
 
-	__restore_flags(flags);
+	local_irq_restore(flags);
  out:
 	return result;
 
diff -urN linux-2.4.20-pre7/drivers/net/acenic.h linux-2.4.20-pre8/drivers/net/acenic.h
--- linux-2.4.20-pre7/drivers/net/acenic.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/net/acenic.h	Wed Sep 25 18:21:47 2002
@@ -748,6 +748,32 @@
 }
 
 
+static inline void ace_mask_irq(struct net_device *dev)
+{
+	struct ace_private *ap = dev->priv;
+	struct ace_regs *regs = ap->regs;
+
+	if (ACE_IS_TIGON_I(ap))
+		writel(1, &regs->MaskInt);
+	else
+		writel(readl(&regs->HostCtrl) | MASK_INTS, &regs->HostCtrl);
+
+	ace_sync_irq(dev->irq);
+}
+
+
+static inline void ace_unmask_irq(struct net_device *dev)
+{
+	struct ace_private *ap = dev->priv;
+	struct ace_regs *regs = ap->regs;
+ 
+	if (ACE_IS_TIGON_I(ap))
+		writel(0, &regs->MaskInt);
+	else
+		writel(readl(&regs->HostCtrl) &= ~MASK_INTS, &regs->HostCtrl);
+}
+
+
 /*
  * Prototypes
  */
diff -urN linux-2.4.20-pre7/drivers/net/dl2k.c linux-2.4.20-pre8/drivers/net/dl2k.c
--- linux-2.4.20-pre7/drivers/net/dl2k.c	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/dl2k.c	Wed Sep 25 18:21:49 2002
@@ -809,13 +809,8 @@
 		/* Let TxStartThresh stay default value */
 	}
 	/* Maximum Collisions */
-#ifdef ETHER_STATS	
-	if (tx_status & 0x08) 
-		np->stats.collisions16++;
-#else
 	if (tx_status & 0x08) 
 		np->stats.collisions++;
-#endif
 	/* Restart the Tx */
 	writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl);
 }
diff -urN linux-2.4.20-pre7/drivers/net/e100/e100_main.c linux-2.4.20-pre8/drivers/net/e100/e100_main.c
--- linux-2.4.20-pre7/drivers/net/e100/e100_main.c	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/e100/e100_main.c	Wed Sep 25 18:21:49 2002
@@ -114,8 +114,10 @@
 static int e100_ethtool_gregs(struct net_device *, struct ifreq *);
 static int e100_ethtool_nway_rst(struct net_device *, struct ifreq *);
 static int e100_ethtool_wol(struct net_device *, struct ifreq *);
+#ifdef CONFIG_PM
 static unsigned char e100_setup_filter(struct e100_private *bdp);
 static void e100_do_wol(struct pci_dev *pcid, struct e100_private *bdp);
+#endif
 static u16 e100_get_ip_lbytes(struct net_device *dev);
 extern void e100_config_wol(struct e100_private *bdp);
 extern u32 e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags);
@@ -3740,8 +3742,8 @@
 
 	set_current_state(TASK_INTERRUPTIBLE);
 
-	if ((!ecmd.data) || (ecmd.data > MAX_SCHEDULE_TIMEOUT / HZ))
-		ecmd.data = MAX_SCHEDULE_TIMEOUT / HZ;
+	if ((!ecmd.data) || (ecmd.data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)))
+		ecmd.data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
 
 	schedule_timeout(ecmd.data * HZ);
 
@@ -3799,6 +3801,7 @@
 
 }
 
+#ifdef CONFIG_PM
 static unsigned char
 e100_setup_filter(struct e100_private *bdp)
 {
@@ -3853,6 +3856,7 @@
 		printk(KERN_ERR "e100: config WOL failed\n");
 	}
 }
+#endif
 
 static u16
 e100_get_ip_lbytes(struct net_device *dev)
diff -urN linux-2.4.20-pre7/drivers/net/eepro100.c linux-2.4.20-pre8/drivers/net/eepro100.c
--- linux-2.4.20-pre7/drivers/net/eepro100.c	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/eepro100.c	Wed Sep 25 18:21:49 2002
@@ -657,6 +657,8 @@
 		return -1;
 	}
 
+	SET_MODULE_OWNER(dev);
+
 	if (dev->mem_start > 0)
 		option = dev->mem_start;
 	else if (card_idx >= 0  &&  options[card_idx] >= 0)
@@ -847,7 +849,30 @@
 
 	return 0;
 }
-
+
+static void do_slow_command(struct net_device *dev, int cmd)
+{
+	long cmd_ioaddr = dev->base_addr + SCBCmd;
+	int wait = 0;
+	do
+		if (inb(cmd_ioaddr) == 0) break;
+	while(++wait <= 200);
+	if (wait > 100)
+		printk(KERN_ERR "Command %4.4x never accepted (%d polls)!\n",
+		       inb(cmd_ioaddr), wait);
+
+	outb(cmd, cmd_ioaddr);
+
+	for (wait = 0; wait <= 100; wait++)
+		if (inb(cmd_ioaddr) == 0) return;
+	for (; wait <= 20000; wait++)
+		if (inb(cmd_ioaddr) == 0) return;
+		else udelay(1);
+	printk(KERN_ERR "Command %4.4x was not accepted after %d polls!"
+	       "  Current status %8.8x.\n",
+	       cmd, wait, inl(dev->base_addr + SCBStatus));
+}
+
 /* Serial EEPROM section.
    A "bit" grungy, but we work our way through bit-by-bit :->. */
 /*  EEPROM_Ctrl bits. */
@@ -918,7 +943,6 @@
 	return val & 0xffff;
 }
 
-
 static int
 speedo_open(struct net_device *dev)
 {
@@ -929,8 +953,6 @@
 	if (speedo_debug > 1)
 		printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
 
-	MOD_INC_USE_COUNT;
-
 	pci_set_power_state(sp->pdev, 0);
 
 	/* Set up the Tx queue early.. */
@@ -944,7 +966,6 @@
 	/* .. we can safely take handler calls during init. */
 	retval = request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev);
 	if (retval) {
-		MOD_DEC_USE_COUNT;
 		return retval;
 	}
 
@@ -1016,7 +1037,7 @@
 /* Start the chip hardware after a full reset. */
 static void speedo_resume(struct net_device *dev)
 {
-	struct speedo_private *sp = (struct speedo_private *)dev->priv;
+	struct speedo_private *sp = dev->priv;
 	long ioaddr = dev->base_addr;
 
 	/* Start with a Tx threshold of 256 (0x..20.... 8 byte units). */
@@ -1024,34 +1045,40 @@
 
 	/* Set the segment registers to '0'. */
 	wait_for_cmd_done(ioaddr + SCBCmd);
-	outl(0, ioaddr + SCBPointer);
-	/* impose a delay to avoid a bug */
-	inl(ioaddr + SCBPointer);
-	udelay(10);
-	outb(RxAddrLoad, ioaddr + SCBCmd);
-	wait_for_cmd_done(ioaddr + SCBCmd);
-	outb(CUCmdBase, ioaddr + SCBCmd);
+	if (inb(ioaddr + SCBCmd)) {
+		outl(PortPartialReset, ioaddr + SCBPort);
+		udelay(10);
+	}
+
+        outl(0, ioaddr + SCBPointer);
+        inl(ioaddr + SCBPointer);			/* Flush to PCI. */
+        udelay(10);			/* Bogus, but it avoids the bug. */
+
+        /* Note: these next two operations can take a while. */
+        do_slow_command(dev, RxAddrLoad);
+        do_slow_command(dev, CUCmdBase);
 
 	/* Load the statistics block and rx ring addresses. */
-	wait_for_cmd_done(ioaddr + SCBCmd);
 	outl(sp->lstats_dma, ioaddr + SCBPointer);
+	inl(ioaddr + SCBPointer);			/* Flush to PCI */
+
 	outb(CUStatsAddr, ioaddr + SCBCmd);
 	sp->lstats->done_marker = 0;
+	wait_for_cmd_done(ioaddr + SCBCmd);
 
 	if (sp->rx_ringp[sp->cur_rx % RX_RING_SIZE] == NULL) {
 		if (speedo_debug > 2)
 			printk(KERN_DEBUG "%s: NULL cur_rx in speedo_resume().\n",
 					dev->name);
 	} else {
-		wait_for_cmd_done(ioaddr + SCBCmd);
 		outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
 			 ioaddr + SCBPointer);
-		outb(RxStart, ioaddr + SCBCmd);
+		inl(ioaddr + SCBPointer);		/* Flush to PCI */
 	}
 
-	wait_for_cmd_done(ioaddr + SCBCmd);
-	outb(CUDumpStats, ioaddr + SCBCmd);
-	udelay(30);
+	/* Note: RxStart should complete instantly. */
+	do_slow_command(dev, RxStart);
+	do_slow_command(dev, CUDumpStats);
 
 	/* Fill the first command with our physical address. */
 	{
@@ -1064,11 +1091,12 @@
 		ias_cmd->link =
 			cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE));
 		memcpy(ias_cmd->params, dev->dev_addr, 6);
+		if (sp->last_cmd)
+			clear_suspend(sp->last_cmd);
 		sp->last_cmd = ias_cmd;
 	}
 
 	/* Start the chip's Tx process and unmask interrupts. */
-	wait_for_cmd_done(ioaddr + SCBCmd);
 	outl(TX_RING_ELEM_DMA(sp, sp->dirty_tx % TX_RING_SIZE),
 		 ioaddr + SCBPointer);
 	/* We are not ACK-ing FCP and ER in the interrupt handler yet so they should
@@ -1884,8 +1912,6 @@
 
 	pci_set_power_state(sp->pdev, 2);
 
-	MOD_DEC_USE_COUNT;
-
 	return 0;
 }
 
diff -urN linux-2.4.20-pre7/drivers/net/epic100.c linux-2.4.20-pre8/drivers/net/epic100.c
--- linux-2.4.20-pre7/drivers/net/epic100.c	Wed Sep 25 18:20:58 2002
+++ linux-2.4.20-pre8/drivers/net/epic100.c	Wed Sep 25 18:21:49 2002
@@ -1073,13 +1073,7 @@
 					if (txstatus & 0x0008) ep->stats.tx_carrier_errors++;
 					if (txstatus & 0x0040) ep->stats.tx_window_errors++;
 					if (txstatus & 0x0010) ep->stats.tx_fifo_errors++;
-#ifdef ETHER_STATS
-					if (txstatus & 0x1000) ep->stats.collisions16++;
-#endif
 				} else {
-#ifdef ETHER_STATS
-					if ((txstatus & 0x0002) != 0) ep->stats.tx_deferred++;
-#endif
 					ep->stats.collisions += (txstatus >> 8) & 15;
 					ep->stats.tx_packets++;
 					ep->stats.tx_bytes += ep->tx_skbuff[entry]->len;
diff -urN linux-2.4.20-pre7/drivers/net/fealnx.c linux-2.4.20-pre8/drivers/net/fealnx.c
--- linux-2.4.20-pre7/drivers/net/fealnx.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/net/fealnx.c	Wed Sep 25 18:21:49 2002
@@ -1493,16 +1493,7 @@
 					if ((tx_status & HF) && np->mii.full_duplex == 0)
 						np->stats.tx_heartbeat_errors++;
 
-#ifdef ETHER_STATS
-					if (tx_status & EC)
-						np->stats.collisions16++;
-#endif
 				} else {
-#ifdef ETHER_STATS
-					if (tx_status & DFR)
-						np->stats.tx_deferred++;
-#endif
-
 					np->stats.tx_bytes +=
 					    ((tx_control & PKTSMask) >> PKTSShift);
 
@@ -1544,9 +1535,6 @@
 			np->stats.tx_errors += (data & 0xff000000) >> 24;
 			np->stats.tx_aborted_errors += (data & 0xff000000) >> 24;
 			np->stats.tx_window_errors += (data & 0x00ff0000) >> 16;
-#ifdef ETHER_STATS
-			np->stats.collisions16 += (data & 0xff000000) >> 24;
-#endif
 			np->stats.collisions += (data & 0x0000ffff);
 		}
 
diff -urN linux-2.4.20-pre7/drivers/net/gmac.c linux-2.4.20-pre8/drivers/net/gmac.c
--- linux-2.4.20-pre7/drivers/net/gmac.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/net/gmac.c	Wed Sep 25 18:21:49 2002
@@ -246,6 +246,7 @@
 #endif
 		    	full_duplex = ((aux_stat & MII_BCM5201_AUXCTLSTATUS_DUPLEX) != 0);
 		    	link_100 = ((aux_stat & MII_BCM5201_AUXCTLSTATUS_SPEED) != 0);
+			netif_carrier_on(gm->dev);
 		        break;
 		      case PHY_B5400:
 		      case PHY_B5401:
@@ -260,6 +261,7 @@
 		    	full_duplex = phy_BCM5400_link_table[link][0];
 		    	link_100 = phy_BCM5400_link_table[link][1];
 		    	gigabit = phy_BCM5400_link_table[link][2];
+			netif_carrier_on(gm->dev);
 		    	break;
 		      case PHY_LXT971:
 		    	aux_stat = mii_read(gm, gm->phy_addr, MII_LXT971_STATUS2);
@@ -269,6 +271,7 @@
 #endif
 		    	full_duplex = ((aux_stat & MII_LXT971_STATUS2_FULLDUPLEX) != 0);
 		    	link_100 = ((aux_stat & MII_LXT971_STATUS2_SPEED) != 0);
+			netif_carrier_on(gm->dev);
 		    	break;
 		      default:
 		    	full_duplex = (lpar_ability & MII_ANLPA_FDAM) != 0;
@@ -296,6 +299,7 @@
 #ifdef DEBUG_PHY
 		    printk(KERN_INFO "%s:    Link down !\n", gm->dev->name);
 #endif
+			netif_carrier_off(gm->dev);
 		}
 	}
 }
@@ -1101,7 +1105,10 @@
 	
 	/* Initialize the multicast tables & promisc mode if any */
 	gmac_set_multicast(dev);
-	
+
+	/* Initialize the carrier status */
+	netif_carrier_off(dev);
+
 	/*
 	 * Check out PHY status and start auto-poll
 	 * 
diff -urN linux-2.4.20-pre7/drivers/net/irda/smc-ircc.c linux-2.4.20-pre8/drivers/net/irda/smc-ircc.c
--- linux-2.4.20-pre7/drivers/net/irda/smc-ircc.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/irda/smc-ircc.c	Wed Sep 25 18:21:50 2002
@@ -1204,7 +1204,7 @@
 }
 #endif /* MODULE */
 
-int __init smc_init(void)
+static int __init smc_init(void)
 {
 	return ircc_init();
 }
diff -urN linux-2.4.20-pre7/drivers/net/ns83820.c linux-2.4.20-pre8/drivers/net/ns83820.c
--- linux-2.4.20-pre7/drivers/net/ns83820.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/net/ns83820.c	Wed Sep 25 18:21:50 2002
@@ -1,9 +1,9 @@
-#define _VERSION "0.18"
+#define _VERSION "0.20"
 /* ns83820.c by Benjamin LaHaise with contributions.
  *
  * Questions/comments/discussion to linux-ns83820@kvack.org.
  *
- * $Revision: 1.34.2.16 $
+ * $Revision: 1.34.2.23 $
  *
  * Copyright 2001 Benjamin LaHaise.
  * Copyright 2001, 2002 Red Hat.
@@ -57,6 +57,12 @@
  *	20020310	0.17	speedups
  *	20020610	0.18 -	actually use the pci dma api for highmem
  *			     -	remove pci latency register fiddling
+ *			0.19 -	better bist support
+ *			     -	add ihr and reset_phy parameters
+ *			     -	gmii bus probing
+ *			     -	fix missed txok introduced during performance
+ *				tuning
+ *			0.20 -	fix stupid RFEN thinko.  i am such a smurf.
  *
  * Driver Overview
  * ===============
@@ -101,10 +107,16 @@
 #include <linux/compiler.h>
 #include <linux/prefetch.h>
 #include <linux/ethtool.h>
+#include <linux/timer.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
+/* Global parameters.  See MODULE_PARM near the bottom. */
+static int ihr = 2;
+static int reset_phy = 0;
+static int lnksts = 0;		/* CFG_LNKSTS bit polarity */
+
 /* Dprintk is used for more interesting debug events */
 #undef Dprintk
 #define	Dprintk			dprintk
@@ -126,7 +138,7 @@
 
 /* Must not exceed ~65000. */
 #define NR_RX_DESC	64
-#define NR_TX_DESC	64
+#define NR_TX_DESC	128
 
 /* not tunable */
 #define REAL_RX_BUF_SIZE (RX_BUF_SIZE + 14)	/* rx/tx mac addr + type */
@@ -138,6 +150,9 @@
 
 #define CR_TXE		0x00000001
 #define CR_TXD		0x00000002
+/* Ramit : Here's a tip, don't do a RXD immediately followed by an RXE
+ * The Receive engine skips one descriptor and moves
+ * onto the next one!! */
 #define CR_RXE		0x00000004
 #define CR_RXD		0x00000008
 #define CR_TXR		0x00000010
@@ -145,8 +160,21 @@
 #define CR_SWI		0x00000080
 #define CR_RST		0x00000100
 
-#define PTSCR_EEBIST_EN	0x00000002
-#define PTSCR_EELOAD_EN	0x00000004
+#define PTSCR_EEBIST_FAIL       0x00000001
+#define PTSCR_EEBIST_EN         0x00000002
+#define PTSCR_EELOAD_EN         0x00000004
+#define PTSCR_RBIST_FAIL        0x000001b8
+#define PTSCR_RBIST_DONE        0x00000200
+#define PTSCR_RBIST_EN          0x00000400
+#define PTSCR_RBIST_RST         0x00002000
+
+#define MEAR_EEDI		0x00000001
+#define MEAR_EEDO		0x00000002
+#define MEAR_EECLK		0x00000004
+#define MEAR_EESEL		0x00000008
+#define MEAR_MDIO		0x00000010
+#define MEAR_MDDIR		0x00000020
+#define MEAR_MDC		0x00000040
 
 #define ISR_TXDESC3	0x40000000
 #define ISR_TXDESC2	0x20000000
@@ -202,6 +230,8 @@
 #define CFG_DUPSTS	0x10000000
 #define CFG_TBI_EN	0x01000000
 #define CFG_MODE_1000	0x00400000
+/* Ramit : Dont' ever use AUTO_1000, it never works and is buggy.
+ * Read the Phy response and then configure the MAC accordingly */
 #define CFG_AUTO_1000	0x00200000
 #define CFG_PINT_CTL	0x001c0000
 #define CFG_PINT_DUPSTS	0x00100000
@@ -230,22 +260,29 @@
 #define EXTSTS_TCPPKT	0x00080000
 #define EXTSTS_IPPKT	0x00020000
 
-#define SPDSTS_POLARITY	(CFG_SPDSTS1 | CFG_SPDSTS0 | CFG_DUPSTS)
+#define SPDSTS_POLARITY	(CFG_SPDSTS1 | CFG_SPDSTS0 | CFG_DUPSTS | (lnksts ? CFG_LNKSTS : 0))
 
 #define MIBC_MIBS	0x00000008
 #define MIBC_ACLR	0x00000004
 #define MIBC_FRZ	0x00000002
 #define MIBC_WRN	0x00000001
 
+#define PCR_PSEN	(1 << 31)
+#define PCR_PS_MCAST	(1 << 30)
+#define PCR_PS_DA	(1 << 29)
+#define PCR_STHI_8	(3 << 23)
+#define PCR_STLO_4	(1 << 23)
+#define PCR_FFHI_8K	(3 << 21)
+#define PCR_FFLO_4K	(1 << 21)
+#define PCR_PAUSE_CNT	0xFFFE
+
 #define RXCFG_AEP	0x80000000
 #define RXCFG_ARP	0x40000000
 #define RXCFG_STRIPCRC	0x20000000
 #define RXCFG_RX_FD	0x10000000
 #define RXCFG_ALP	0x08000000
 #define RXCFG_AIRL	0x04000000
-#define RXCFG_MXDMA	0x00700000
-#define RXCFG_MXDMA0	0x00100000
-#define RXCFG_MXDMA64	0x00600000
+#define RXCFG_MXDMA512	0x00700000
 #define RXCFG_DRTH	0x0000003e
 #define RXCFG_DRTH0	0x00000002
 
@@ -354,23 +391,22 @@
 #define desc_addr_set(desc, addr)				\
 	do {							\
 		u64 __addr = (addr);				\
-		desc[BUFPTR] = cpu_to_le32(__addr);		\
-		desc[BUFPTR+1] = cpu_to_le32(__addr >> 32);	\
+		(desc)[0] = cpu_to_le32(__addr);		\
+		(desc)[1] = cpu_to_le32(__addr >> 32);		\
 	} while(0)
 #define desc_addr_get(desc)					\
-		(((u64)le32_to_cpu(desc[BUFPTR+1]) << 32)	\
-		     | le32_to_cpu(desc[BUFPTR]))
+		(((u64)le32_to_cpu((desc)[1]) << 32)		\
+		     | le32_to_cpu((desc)[0]))
 #else
 #define HW_ADDR_LEN	4
-#define desc_addr_set(desc, addr)	(desc[BUFPTR] = cpu_to_le32(addr))
-#define desc_addr_get(desc)		(le32_to_cpu(desc[BUFPTR]))
+#define desc_addr_set(desc, addr)	((desc)[0] = cpu_to_le32(addr))
+#define desc_addr_get(desc)		(le32_to_cpu((desc)[0]))
 #endif
 
-#define LINK		0
-#define BUFPTR		(LINK + HW_ADDR_LEN/4)
-#define CMDSTS		(BUFPTR + HW_ADDR_LEN/4)
-#define EXTSTS		(CMDSTS + 4/4)
-#define DRV_NEXT	(EXTSTS + 4/4)
+#define DESC_LINK		0
+#define DESC_BUFPTR		(DESC_LINK + HW_ADDR_LEN/4)
+#define DESC_CMDSTS		(DESC_BUFPTR + HW_ADDR_LEN/4)
+#define DESC_EXTSTS		(DESC_CMDSTS + 4/4)
 
 #define CMDSTS_OWN	0x80000000
 #define CMDSTS_MORE	0x40000000
@@ -426,18 +462,19 @@
 
 	spinlock_t	tx_lock;
 
-	long		tx_idle;
-
 	u16		tx_done_idx;
 	u16		tx_idx;
 	volatile u16	tx_free_idx;	/* idx of free desc chain */
 	u16		tx_intr_idx;
 
+	atomic_t	nr_tx_skbs;
 	struct sk_buff	*tx_skbs[NR_TX_DESC];
 
 	char		pad[16] __attribute__((aligned(16)));
 	u32		*tx_descs;
 	dma_addr_t	tx_phy_descs;
+
+	struct timer_list	tx_watchdog;
 };
 
 //free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC
@@ -458,33 +495,15 @@
  * conditions, still route realtime traffic with as low jitter as
  * possible.
  */
-#ifdef USE_64BIT_ADDR
-static inline void build_rx_desc64(struct ns83820 *dev, u32 *desc, u64 link, u64 buf, u32 cmdsts, u32 extsts)
-{
-	desc[0] = link;
-	desc[1] = link >> 32;
-	desc[2] = buf;
-	desc[3] = buf >> 32;
-	desc[5] = extsts;
-	mb();
-	desc[4] = cmdsts;
-}
-
-#define build_rx_desc	build_rx_desc64
-#else
-
-static inline void build_rx_desc32(struct ns83820 *dev, u32 *desc, u32 link, u32 buf, u32 cmdsts, u32 extsts)
+static inline void build_rx_desc(struct ns83820 *dev, u32 *desc, dma_addr_t link, dma_addr_t buf, u32 cmdsts, u32 extsts)
 {
-	desc[0] = cpu_to_le32(link);
-	desc[1] = cpu_to_le32(buf);
-	desc[3] = cpu_to_le32(extsts);
+	desc_addr_set(desc + DESC_LINK, link);
+	desc_addr_set(desc + DESC_BUFPTR, buf);
+	desc[DESC_EXTSTS] = extsts;
 	mb();
-	desc[2] = cpu_to_le32(cmdsts);
+	desc[DESC_CMDSTS] = cmdsts;
 }
 
-#define build_rx_desc	build_rx_desc32
-#endif
-
 #define nr_rx_empty(dev) ((NR_RX_DESC-2 + dev->rx_info.next_rx - dev->rx_info.next_empty) % NR_RX_DESC)
 static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb)
 {
@@ -717,7 +736,7 @@
 		phy_intr(dev);
 
 		/* Okay, let it rip */
-		spin_lock(&dev->misc_lock);
+		spin_lock_irq(&dev->misc_lock);
 		dev->IMR_cache |= ISR_PHY;
 		dev->IMR_cache |= ISR_RXRCMP;
 		//dev->IMR_cache |= ISR_RXERR;
@@ -731,7 +750,7 @@
 
 		writel(dev->IMR_cache, dev->base + IMR);
 		writel(1, dev->base + IER);
-		spin_unlock(&dev->misc_lock);
+		spin_unlock_irq(&dev->misc_lock);
 
 		kick_rx(dev);
 
@@ -788,7 +807,7 @@
 	else
 		kick_rx(dev);
 	if (dev->rx_info.idle)
-		Dprintk("BAD\n");
+		printk(KERN_DEBUG "%s: BAD\n", dev->net_dev.name);
 }
 
 /* rx_irq
@@ -820,14 +839,14 @@
 	dprintk("walking descs\n");
 	next_rx = info->next_rx;
 	desc = info->next_rx_desc;
-	while ((CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[CMDSTS]))) &&
+	while ((CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[DESC_CMDSTS]))) &&
 	       (cmdsts != CMDSTS_OWN)) {
 		struct sk_buff *skb;
-		u32 extsts = le32_to_cpu(desc[EXTSTS]);
-		dma_addr_t bufptr = desc_addr_get(desc);
+		u32 extsts = le32_to_cpu(desc[DESC_EXTSTS]);
+		dma_addr_t bufptr = desc_addr_get(desc + DESC_BUFPTR);
 
 		dprintk("cmdsts: %08x\n", cmdsts);
-		dprintk("link: %08x\n", cpu_to_le32(desc[LINK]));
+		dprintk("link: %08x\n", cpu_to_le32(desc[DESC_LINK]));
 		dprintk("extsts: %08x\n", extsts);
 
 		skb = info->skbs[next_rx];
@@ -881,8 +900,13 @@
 {
 	struct ns83820 *dev = (void *)_dev;
 	rx_irq(dev);
-	writel(0x002, dev->base + IHR);
-	writel(dev->IMR_cache | ISR_RXDESC, dev->base + IMR);
+	writel(ihr, dev->base + IHR);
+
+	spin_lock_irq(&dev->misc_lock);
+	dev->IMR_cache |= ISR_RXDESC;
+	writel(dev->IMR_cache, dev->base + IMR);
+	spin_unlock_irq(&dev->misc_lock);
+
 	rx_irq(dev);
 	ns83820_rx_kick(dev);
 }
@@ -891,8 +915,8 @@
  */
 static inline void kick_tx(struct ns83820 *dev)
 {
-	dprintk("kick_tx(%p): tx_idle=%ld, tx_idx=%d free_idx=%d\n",
-		dev, dev->tx_idle, dev->tx_idx, dev->tx_free_idx);
+	dprintk("kick_tx(%p): tx_idx=%d free_idx=%d\n",
+		dev, dev->tx_idx, dev->tx_free_idx);
 	writel(CR_TXE, dev->base + CR);
 }
 
@@ -903,14 +927,16 @@
 {
 	u32 cmdsts, tx_done_idx, *desc;
 
+	spin_lock_irq(&dev->tx_lock);
+
 	dprintk("do_tx_done(%p)\n", dev);
 	tx_done_idx = dev->tx_done_idx;
 	desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
 
 	dprintk("tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
-		tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[CMDSTS]));
+		tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS]));
 	while ((tx_done_idx != dev->tx_free_idx) &&
-	       !(CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[CMDSTS]))) ) {
+	       !(CMDSTS_OWN & (cmdsts = le32_to_cpu(desc[DESC_CMDSTS]))) ) {
 		struct sk_buff *skb;
 		unsigned len;
 		dma_addr_t addr;
@@ -929,13 +955,14 @@
 		dprintk("done(%p)\n", skb);
 
 		len = cmdsts & CMDSTS_LEN_MASK;
-		addr = desc_addr_get(desc);
+		addr = desc_addr_get(desc + DESC_BUFPTR);
 		if (skb) {
 			pci_unmap_single(dev->pci_dev,
 					addr,
 					len,
 					PCI_DMA_TODEVICE);
 			dev_kfree_skb_irq(skb);
+			atomic_dec(&dev->nr_tx_skbs);
 		} else
 			pci_unmap_page(dev->pci_dev, 
 					addr,
@@ -944,7 +971,7 @@
 
 		tx_done_idx = (tx_done_idx + 1) % NR_TX_DESC;
 		dev->tx_done_idx = tx_done_idx;
-		desc[CMDSTS] = cpu_to_le32(0);
+		desc[DESC_CMDSTS] = cpu_to_le32(0);
 		mb();
 		desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
 	}
@@ -957,6 +984,7 @@
 		netif_start_queue(&dev->net_dev);
 		netif_wake_queue(&dev->net_dev);
 	}
+	spin_unlock_irq(&dev->tx_lock);
 }
 
 static void ns83820_cleanup_tx(struct ns83820 *dev)
@@ -966,12 +994,18 @@
 	for (i=0; i<NR_TX_DESC; i++) {
 		struct sk_buff *skb = dev->tx_skbs[i];
 		dev->tx_skbs[i] = NULL;
-		if (skb)
-			dev_kfree_skb(skb);
+		if (skb) {
+			u32 *desc = dev->tx_descs + (i * DESC_SIZE);
+			pci_unmap_single(dev->pci_dev,
+					desc_addr_get(desc + DESC_BUFPTR),
+					le32_to_cpu(desc[DESC_CMDSTS]) & CMDSTS_LEN_MASK,
+					PCI_DMA_TODEVICE);
+			dev_kfree_skb_irq(skb);
+			atomic_dec(&dev->nr_tx_skbs);
+		}
 	}
 
 	memset(dev->tx_descs, 0, NR_TX_DESC * DESC_SIZE * 4);
-	set_bit(0, &dev->tx_idle);
 }
 
 /* transmit routine.  This code relies on the network layer serializing
@@ -985,7 +1019,7 @@
 	struct ns83820 *dev = (struct ns83820 *)_dev;
 	u32 free_idx, cmdsts, extsts;
 	int nr_free, nr_frags;
-	unsigned tx_done_idx;
+	unsigned tx_done_idx, last_idx;
 	dma_addr_t buf;
 	unsigned len;
 	skb_frag_t *frag;
@@ -1004,7 +1038,7 @@
 		netif_start_queue(&dev->net_dev);
 	}
 
-	free_idx = dev->tx_free_idx;
+	last_idx = free_idx = dev->tx_free_idx;
 	tx_done_idx = dev->tx_done_idx;
 	nr_free = (tx_done_idx + NR_TX_DESC-2 - free_idx) % NR_TX_DESC;
 	nr_free -= 1;
@@ -1058,15 +1092,16 @@
 
 		dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len,
 			(unsigned long long)buf);
+		last_idx = free_idx;
 		free_idx = (free_idx + 1) % NR_TX_DESC;
-		desc[LINK] = cpu_to_le32(dev->tx_phy_descs + (free_idx * DESC_SIZE * 4));
-		desc_addr_set(desc, buf);
-		desc[EXTSTS] = cpu_to_le32(extsts);
+		desc[DESC_LINK] = cpu_to_le32(dev->tx_phy_descs + (free_idx * DESC_SIZE * 4));
+		desc_addr_set(desc + DESC_BUFPTR, buf);
+		desc[DESC_EXTSTS] = cpu_to_le32(extsts);
 
 		cmdsts = ((nr_frags|residue) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0);
 		cmdsts |= (desc == first_desc) ? 0 : CMDSTS_OWN;
 		cmdsts |= len;
-		desc[CMDSTS] = cpu_to_le32(cmdsts);
+		desc[DESC_CMDSTS] = cpu_to_le32(cmdsts);
 
 		if (residue) {
 			buf += len;
@@ -1088,15 +1123,22 @@
 		nr_frags--;
 	}
 	dprintk("done pkt\n");
-	dev->tx_skbs[free_idx] = skb;
-	first_desc[CMDSTS] |= cpu_to_le32(CMDSTS_OWN);
+
+	spin_lock_irq(&dev->tx_lock);
+	dev->tx_skbs[last_idx] = skb;
+	first_desc[DESC_CMDSTS] |= cpu_to_le32(CMDSTS_OWN);
 	dev->tx_free_idx = free_idx;
+	atomic_inc(&dev->nr_tx_skbs);
+	spin_unlock_irq(&dev->tx_lock);
+
 	kick_tx(dev);
 
 	/* Check again: we may have raced with a tx done irq */
 	if (stopped && (dev->tx_done_idx != tx_done_idx) && start_tx_okay(dev))
 		netif_start_queue(&dev->net_dev);
 
+	/* set the transmit start time to catch transmit timeouts */
+	dev->net_dev.trans_start = jiffies;
 	return 0;
 }
 
@@ -1190,6 +1232,7 @@
 	spin_unlock(&dev->misc_lock);
 }
 
+static void ns83820_do_isr(struct ns83820 *dev, u32 isr);
 static void ns83820_irq(int foo, void *data, struct pt_regs *regs)
 {
 	struct ns83820 *dev = data;
@@ -1200,7 +1243,11 @@
 
 	isr = readl(dev->base + ISR);
 	dprintk("irq: %08x\n", isr);
+	ns83820_do_isr(dev, isr);
+}
 
+static void ns83820_do_isr(struct ns83820 *dev, u32 isr)
+{
 #ifdef DEBUG
 	if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC))
 		Dprintk("odd isr? 0x%08x\n", isr);
@@ -1214,7 +1261,12 @@
 
 	if ((ISR_RXDESC | ISR_RXOK) & isr) {
 		prefetch(dev->rx_info.next_rx_desc);
-		writel(dev->IMR_cache & ~(ISR_RXDESC | ISR_RXOK), dev->base + IMR);
+
+		spin_lock_irq(&dev->misc_lock);
+		dev->IMR_cache &= ~(ISR_RXDESC | ISR_RXOK);
+		writel(dev->IMR_cache, dev->base + IMR);
+		spin_unlock_irq(&dev->misc_lock);
+
 		tasklet_schedule(&dev->rx_tasklet);
 		//rx_irq(dev);
 		//writel(4, dev->base + IHR);
@@ -1246,12 +1298,11 @@
 			printk(KERN_ALERT "%s: BUG -- txdp out of range\n", dev->net_dev.name);
 			dev->tx_idx = 0;
 		}
-		if (dev->tx_idx != dev->tx_free_idx)
-			writel(CR_TXE, dev->base + CR);
-			//kick_tx(dev);
-		else
-			dev->tx_idle = 1;
-		mb();
+		/* The may have been a race between a pci originated read
+		 * and the descriptor update from the cpu.  Just in case, 
+		 * kick the transmitter if the hardware thinks it is on a 
+		 * different descriptor than we are.
+		 */
 		if (dev->tx_idx != dev->tx_free_idx)
 			kick_tx(dev);
 	}
@@ -1259,12 +1310,38 @@
 	/* Defer tx ring processing until more than a minimum amount of
 	 * work has accumulated
 	 */
-	if ((ISR_TXDESC | ISR_TXIDLE) & isr)
+	if ((ISR_TXDESC | ISR_TXIDLE | ISR_TXOK | ISR_TXERR) & isr) {
 		do_tx_done(dev);
 
+		/* Disable TxOk if there are no outstanding tx packets.
+		 */
+		if ((dev->tx_done_idx == dev->tx_free_idx) &&
+		    (dev->IMR_cache & ISR_TXOK)) {
+			spin_lock_irq(&dev->misc_lock);
+			dev->IMR_cache &= ~ISR_TXOK;
+			writel(dev->IMR_cache, dev->base + IMR);
+			spin_unlock_irq(&dev->misc_lock);
+		}
+	}
+
+	/* The TxIdle interrupt can come in before the transmit has
+	 * completed.  Normally we reap packets off of the combination
+	 * of TxDesc and TxIdle and leave TxOk disabled (since it 
+	 * occurs on every packet), but when no further irqs of this 
+	 * nature are expected, we must enable TxOk.
+	 */
+	if ((ISR_TXIDLE & isr) && (dev->tx_done_idx != dev->tx_free_idx)) {
+		spin_lock_irq(&dev->misc_lock);
+		dev->IMR_cache |= ISR_TXOK;
+		writel(dev->IMR_cache, dev->base + IMR);
+		spin_unlock_irq(&dev->misc_lock);
+	}
+
+	/* MIB interrupt: one of the statistics counters is about to overflow */
 	if (unlikely(ISR_MIB & isr))
 		ns83820_mib_isr(dev);
 
+	/* PHY: Link up/down/negotiation state change */
 	if (unlikely(ISR_PHY & isr))
 		phy_intr(dev);
 
@@ -1289,6 +1366,7 @@
 	struct ns83820 *dev = (struct ns83820 *)_dev;
 
 	/* FIXME: protect against interrupt handler? */
+	del_timer_sync(&dev->tx_watchdog);
 
 	/* disable interrupts */
 	writel(0, dev->base + IMR);
@@ -1302,13 +1380,76 @@
 
 	synchronize_irq();
 
+	spin_lock_irq(&dev->misc_lock);
 	dev->IMR_cache &= ~(ISR_TXURN | ISR_TXIDLE | ISR_TXERR | ISR_TXDESC | ISR_TXOK);
+	spin_unlock_irq(&dev->misc_lock);
+
 	ns83820_cleanup_rx(dev);
 	ns83820_cleanup_tx(dev);
 
 	return 0;
 }
 
+static void ns83820_do_isr(struct ns83820 *dev, u32 isr);
+static void ns83820_tx_timeout(struct net_device *_dev)
+{
+	struct ns83820 *dev = (struct ns83820 *)_dev;
+        u32 tx_done_idx, *desc;
+	long flags;
+
+	__save_flags(flags);
+	__cli();
+
+	tx_done_idx = dev->tx_done_idx;
+	desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
+
+	printk(KERN_INFO "%s: tx_timeout: tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
+		dev->net_dev.name,
+		tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS]));
+
+#if defined(DEBUG)
+	{
+		u32 isr;
+		isr = readl(dev->base + ISR);
+		printk("irq: %08x imr: %08x\n", isr, dev->IMR_cache);
+		ns83820_do_isr(dev, isr);
+	}
+#endif
+
+	do_tx_done(dev);
+
+	tx_done_idx = dev->tx_done_idx;
+	desc = dev->tx_descs + (tx_done_idx * DESC_SIZE);
+
+	printk(KERN_INFO "%s: after: tx_done_idx=%d free_idx=%d cmdsts=%08x\n",
+		dev->net_dev.name,
+		tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS]));
+
+	__restore_flags(flags);
+}
+
+static void ns83820_tx_watch(unsigned long data)
+{
+	struct ns83820 *dev = (void *)data;
+
+#if defined(DEBUG)
+	printk("ns83820_tx_watch: %u %u %d\n",
+		dev->tx_done_idx, dev->tx_free_idx, atomic_read(&dev->nr_tx_skbs)
+		);
+#endif
+
+	if (time_after(jiffies, dev->net_dev.trans_start + 1*HZ) &&
+	    dev->tx_done_idx != dev->tx_free_idx) {
+		printk(KERN_DEBUG "%s: ns83820_tx_watch: %u %u %d\n",
+			dev->net_dev.name,
+			dev->tx_done_idx, dev->tx_free_idx,
+			atomic_read(&dev->nr_tx_skbs));
+		ns83820_tx_timeout(&dev->net_dev);
+	}
+
+	mod_timer(&dev->tx_watchdog, jiffies + 2*HZ);
+}
+
 static int ns83820_open(struct net_device *_dev)
 {
 	struct ns83820 *dev = (struct ns83820 *)_dev;
@@ -1326,7 +1467,7 @@
 
 	memset(dev->tx_descs, 0, 4 * NR_TX_DESC * DESC_SIZE);
 	for (i=0; i<NR_TX_DESC; i++) {
-		dev->tx_descs[(i * DESC_SIZE) + LINK]
+		dev->tx_descs[(i * DESC_SIZE) + DESC_LINK]
 				= cpu_to_le32(
 				  dev->tx_phy_descs
 				  + ((i+1) % NR_TX_DESC) * DESC_SIZE * 4);
@@ -1338,9 +1479,11 @@
 	writel(0, dev->base + TXDP_HI);
 	writel(desc, dev->base + TXDP);
 
-//printk("IMR: %08x / %08x\n", readl(dev->base + IMR), dev->IMR_cache);
+	init_timer(&dev->tx_watchdog);
+	dev->tx_watchdog.data = (unsigned long)dev;
+	dev->tx_watchdog.function = ns83820_tx_watch;
+	mod_timer(&dev->tx_watchdog, jiffies + 2*HZ);
 
-	set_bit(0, &dev->tx_idle);
 	netif_start_queue(&dev->net_dev);	/* FIXME: wait for phy to come up */
 
 	return 0;
@@ -1350,15 +1493,6 @@
 	return ret;
 }
 
-#if 0	/* FIXME: implement this! */
-static void ns83820_tx_timeout(struct net_device *_dev)
-{
-	struct ns83820 *dev = (struct ns83820 *)_dev;
-
-	printk("ns83820_tx_timeout\n");
-}
-#endif
-
 static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
 {
 	unsigned i;
@@ -1392,6 +1526,7 @@
 	u8 *rfcr = dev->base + RFCR;
 	u32 and_mask = 0xffffffff;
 	u32 or_mask = 0;
+	u32 val;
 
 	if (dev->net_dev.flags & IFF_PROMISC)
 		or_mask |= RFCR_AAU | RFCR_AAM;
@@ -1404,10 +1539,225 @@
 		and_mask &= ~RFCR_AAM;
 
 	spin_lock_irq(&dev->misc_lock);
-	writel((readl(rfcr) & and_mask) | or_mask, rfcr);
+	val = (readl(rfcr) & and_mask) | or_mask;
+	/* Ramit : RFCR Write Fix doc says RFEN must be 0 modify other bits */
+	writel(val & ~RFCR_RFEN, rfcr);
+	writel(val, rfcr);
 	spin_unlock_irq(&dev->misc_lock);
 }
 
+static void ns83820_run_bist(struct ns83820 *dev, const char *name, u32 enable, u32 done, u32 fail)
+{
+	int timed_out = 0;
+	long start;
+	u32 status;
+	int loops = 0;
+
+	dprintk("%s: start %s\n", dev->net_dev.name, name);
+
+	start = jiffies;
+
+	writel(enable, dev->base + PTSCR);
+	for (;;) {
+		loops++;
+		status = readl(dev->base + PTSCR);
+		if (!(status & enable))
+			break;
+		if (status & done)
+			break;
+		if (status & fail)
+			break;
+		if ((jiffies - start) >= HZ) {
+			timed_out = 1;
+			break;
+		}
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+
+	if (status & fail)
+		printk(KERN_INFO "%s: %s failed! (0x%08x & 0x%08x)\n",
+			dev->net_dev.name, name, status, fail);
+	else if (timed_out)
+		printk(KERN_INFO "%s: run_bist %s timed out! (%08x)\n",
+			dev->net_dev.name, name, status);
+
+	dprintk("%s: done %s in %d loops\n", dev->net_dev.name, name, loops);
+}
+
+static void ns83820_mii_write_bit(struct ns83820 *dev, int bit)
+{
+	/* drive MDC low */
+	dev->MEAR_cache &= ~MEAR_MDC;
+	writel(dev->MEAR_cache, dev->base + MEAR);
+	readl(dev->base + MEAR);
+
+	/* enable output, set bit */
+	dev->MEAR_cache |= MEAR_MDDIR;
+	if (bit)
+		dev->MEAR_cache |= MEAR_MDIO;
+	else
+		dev->MEAR_cache &= ~MEAR_MDIO;
+
+	/* set the output bit */
+	writel(dev->MEAR_cache, dev->base + MEAR);
+	readl(dev->base + MEAR);
+
+	/* Wait.  Max clock rate is 2.5MHz, this way we come in under 1MHz */
+	udelay(1);
+
+	/* drive MDC high causing the data bit to be latched */
+	dev->MEAR_cache |= MEAR_MDC;
+	writel(dev->MEAR_cache, dev->base + MEAR);
+	readl(dev->base + MEAR);
+
+	/* Wait again... */
+	udelay(1);
+}
+
+static int ns83820_mii_read_bit(struct ns83820 *dev)
+{
+	int bit;
+
+	/* drive MDC low, disable output */
+	dev->MEAR_cache &= ~MEAR_MDC;
+	dev->MEAR_cache &= ~MEAR_MDDIR;
+	writel(dev->MEAR_cache, dev->base + MEAR);
+	readl(dev->base + MEAR);
+
+	/* Wait.  Max clock rate is 2.5MHz, this way we come in under 1MHz */
+	udelay(1);
+
+	/* drive MDC high causing the data bit to be latched */
+	bit = (readl(dev->base + MEAR) & MEAR_MDIO) ? 1 : 0;
+	dev->MEAR_cache |= MEAR_MDC;
+	writel(dev->MEAR_cache, dev->base + MEAR);
+
+	/* Wait again... */
+	udelay(1);
+
+	return bit;
+}
+
+static unsigned ns83820_mii_read_reg(struct ns83820 *dev, unsigned phy, unsigned reg)
+{
+	unsigned data = 0;
+	int i;
+
+	/* read some garbage so that we eventually sync up */
+	for (i=0; i<64; i++)
+		ns83820_mii_read_bit(dev);
+
+	ns83820_mii_write_bit(dev, 0);	/* start */
+	ns83820_mii_write_bit(dev, 1);
+	ns83820_mii_write_bit(dev, 1);	/* opcode read */
+	ns83820_mii_write_bit(dev, 0);
+
+	/* write out the phy address: 5 bits, msb first */
+	for (i=0; i<5; i++)
+		ns83820_mii_write_bit(dev, phy & (0x10 >> i));
+
+	/* write out the register address, 5 bits, msb first */
+	for (i=0; i<5; i++)
+		ns83820_mii_write_bit(dev, reg & (0x10 >> i));
+
+	ns83820_mii_read_bit(dev);	/* turn around cycles */
+	ns83820_mii_read_bit(dev);
+
+	/* read in the register data, 16 bits msb first */
+	for (i=0; i<16; i++) {
+		data <<= 1;
+		data |= ns83820_mii_read_bit(dev);
+	}
+
+	return data;
+}
+
+static unsigned ns83820_mii_write_reg(struct ns83820 *dev, unsigned phy, unsigned reg, unsigned data)
+{
+	int i;
+
+	/* read some garbage so that we eventually sync up */
+	for (i=0; i<64; i++)
+		ns83820_mii_read_bit(dev);
+
+	ns83820_mii_write_bit(dev, 0);	/* start */
+	ns83820_mii_write_bit(dev, 1);
+	ns83820_mii_write_bit(dev, 0);	/* opcode read */
+	ns83820_mii_write_bit(dev, 1);
+
+	/* write out the phy address: 5 bits, msb first */
+	for (i=0; i<5; i++)
+		ns83820_mii_write_bit(dev, phy & (0x10 >> i));
+
+	/* write out the register address, 5 bits, msb first */
+	for (i=0; i<5; i++)
+		ns83820_mii_write_bit(dev, reg & (0x10 >> i));
+
+	ns83820_mii_read_bit(dev);	/* turn around cycles */
+	ns83820_mii_read_bit(dev);
+
+	/* read in the register data, 16 bits msb first */
+	for (i=0; i<16; i++)
+		ns83820_mii_write_bit(dev, (data >> (15 - i)) & 1);
+
+	return data;
+}
+
+static void ns83820_probe_phy(struct ns83820 *dev)
+{
+	static int first;
+	int i;
+#define MII_PHYIDR1	0x02
+#define MII_PHYIDR2	0x03
+
+#if 0
+	if (!first) {
+		unsigned tmp;
+		ns83820_mii_read_reg(dev, 1, 0x09);
+		ns83820_mii_write_reg(dev, 1, 0x10, 0x0d3e);
+
+		tmp = ns83820_mii_read_reg(dev, 1, 0x00);
+		ns83820_mii_write_reg(dev, 1, 0x00, tmp | 0x8000);
+		udelay(1300);
+		ns83820_mii_read_reg(dev, 1, 0x09);
+	}
+#endif
+	first = 1;
+
+	for (i=1; i<2; i++) {
+		int j;
+		unsigned a, b;
+		a = ns83820_mii_read_reg(dev, i, MII_PHYIDR1);
+		b = ns83820_mii_read_reg(dev, i, MII_PHYIDR2);
+
+		//printk("%s: phy %d: 0x%04x 0x%04x\n",
+		//	dev->net_dev.name, i, a, b);
+
+		for (j=0; j<0x16; j+=4) {
+			dprintk("%s: [0x%02x] %04x %04x %04x %04x\n",
+				dev->net_dev.name, j,
+				ns83820_mii_read_reg(dev, i, 0 + j),
+				ns83820_mii_read_reg(dev, i, 1 + j),
+				ns83820_mii_read_reg(dev, i, 2 + j),
+				ns83820_mii_read_reg(dev, i, 3 + j)
+				);
+		}
+	}
+	{
+		unsigned a, b;
+		/* read firmware version: memory addr is 0x8402 and 0x8403 */
+		ns83820_mii_write_reg(dev, 1, 0x16, 0x000d);
+		ns83820_mii_write_reg(dev, 1, 0x1e, 0x810e);
+		a = ns83820_mii_read_reg(dev, 1, 0x1d);
+
+		ns83820_mii_write_reg(dev, 1, 0x16, 0x000d);
+		ns83820_mii_write_reg(dev, 1, 0x1e, 0x810e);
+		b = ns83820_mii_read_reg(dev, 1, 0x1d);
+		dprintk("version: 0x%04x 0x%04x\n", a, b);
+	}
+}
+
 static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_device_id *id)
 {
 	struct ns83820 *dev;
@@ -1415,6 +1765,7 @@
 	int err;
 	int using_dac = 0;
 
+	/* See if we can set the dma mask early on; failure is fatal. */
 	if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffff)) {
 		using_dac = 1;
 	} else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) {
@@ -1443,7 +1794,7 @@
 
 	err = pci_enable_device(pci_dev);
 	if (err) {
-		printk(KERN_INFO "ns83820: pci_enable_dev: %d\n", err);
+		printk(KERN_INFO "ns83820: pci_enable_dev failed: %d\n", err);
 		goto out_free;
 	}
 
@@ -1461,6 +1812,7 @@
 	dprintk("%p: %08lx  %p: %08lx\n",
 		dev->tx_descs, (long)dev->tx_phy_descs,
 		dev->rx_info.descs, (long)dev->rx_info.phy_descs);
+
 	/* disable interrupts */
 	writel(0, dev->base + IMR);
 	writel(0, dev->base + IER);
@@ -1479,45 +1831,47 @@
 		goto out_unmap;
 	}
 
-	if(register_netdev(&dev->net_dev)) goto out_unmap;
+	err = register_netdev(&dev->net_dev);
+	if (err) {
+		printk(KERN_INFO "ns83820: unable to register netdev: %d\n", err);
+		goto out_unmap;
+	}
+
+	printk("%s: ns83820.c: 0x22c: %08x, subsystem: %04x:%04x\n",
+		dev->net_dev.name, le32_to_cpu(readl(dev->base + 0x22c)),
+		pci_dev->subsystem_vendor, pci_dev->subsystem_device);
 
 	dev->net_dev.open = ns83820_open;
 	dev->net_dev.stop = ns83820_stop;
 	dev->net_dev.hard_start_xmit = ns83820_hard_start_xmit;
-	dev->net_dev.change_mtu = ns83820_change_mtu;
 	dev->net_dev.get_stats = ns83820_get_stats;
 	dev->net_dev.change_mtu = ns83820_change_mtu;
 	dev->net_dev.set_multicast_list = ns83820_set_multicast;
 	dev->net_dev.do_ioctl = ns83820_ioctl;
-	//FIXME: dev->net_dev.tx_timeout = ns83820_tx_timeout;
+	dev->net_dev.tx_timeout = ns83820_tx_timeout;
+	dev->net_dev.watchdog_timeo = 5 * HZ;
 
 	pci_set_drvdata(pci_dev, dev);
 
 	ns83820_do_reset(dev, CR_RST);
 
-	dprintk("start bist\n");
-	writel(PTSCR_EEBIST_EN, dev->base + PTSCR);
-	do {
-		schedule();
-	} while (readl(dev->base + PTSCR) & PTSCR_EEBIST_EN);
-	dprintk("done bist\n");
-
-	dprintk("start eeload\n");
-	writel(PTSCR_EELOAD_EN, dev->base + PTSCR);
-	do {
-		schedule();
-	} while (readl(dev->base + PTSCR) & PTSCR_EELOAD_EN);
-	dprintk("done eeload\n");
+	/* Must reset the ram bist before running it */
+	writel(PTSCR_RBIST_RST, dev->base + PTSCR);
+	ns83820_run_bist(dev, "sram bist",   PTSCR_RBIST_EN,
+			 PTSCR_RBIST_DONE, PTSCR_RBIST_FAIL);
+	ns83820_run_bist(dev, "eeprom bist", PTSCR_EEBIST_EN, 0,
+			 PTSCR_EEBIST_FAIL);
+	ns83820_run_bist(dev, "eeprom load", PTSCR_EELOAD_EN, 0, 0);
 
 	/* I love config registers */
 	dev->CFG_cache = readl(dev->base + CFG);
 
 	if ((dev->CFG_cache & CFG_PCI64_DET)) {
-		printk("%s: detected 64 bit PCI data bus.\n",
+		printk(KERN_INFO "%s: detected 64 bit PCI data bus.\n",
 			dev->net_dev.name);
 		/*dev->CFG_cache |= CFG_DATA64_EN;*/
 		if (!(dev->CFG_cache & CFG_DATA64_EN))
-			printk("%s: EEPROM did not enable 64 bit bus.  Disabled.\n",
+			printk(KERN_INFO "%s: EEPROM did not enable 64 bit bus.  Disabled.\n",
 				dev->net_dev.name);
 	} else
 		dev->CFG_cache &= ~(CFG_DATA64_EN);
@@ -1529,6 +1883,11 @@
 			  CFG_EXTSTS_EN   | CFG_EXD         | CFG_PESEL;
 	dev->CFG_cache |= CFG_REQALG;
 	dev->CFG_cache |= CFG_POW;
+	dev->CFG_cache |= CFG_TMRTEST;
+
+	/* When compiled with 64 bit addressing, we must always enable
+	 * the 64 bit descriptor format.
+	 */
 #ifdef USE_64BIT_ADDR
 	dev->CFG_cache |= CFG_M64ADDR;
 #endif
@@ -1540,7 +1899,8 @@
 
 	/* setup optical transceiver if we have one */
 	if (dev->CFG_cache & CFG_TBI_EN) {
-		printk("%s: enabling optical transceiver\n", dev->net_dev.name);
+		printk(KERN_INFO "%s: enabling optical transceiver\n",
+			dev->net_dev.name);
 		writel(readl(dev->base + GPIOR) | 0x3e8, dev->base + GPIOR);
 
 		/* setup auto negotiation feature advertisement */
@@ -1560,6 +1920,14 @@
 	writel(dev->CFG_cache, dev->base + CFG);
 	dprintk("CFG: %08x\n", dev->CFG_cache);
 
+	if (reset_phy) {
+		printk(KERN_INFO "%s: resetting phy\n", dev->net_dev.name);
+		writel(dev->CFG_cache | CFG_PHY_RST, dev->base + CFG);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout((HZ+99)/100);
+		writel(dev->CFG_cache, dev->base + CFG);
+	}
+
 #if 0	/* Huh?  This sets the PCI latency register.  Should be done via 
 	 * the PCI layer.  FIXME.
 	 */
@@ -1572,7 +1940,9 @@
 	 * can be transmitted is 8192 - FLTH - burst size.
 	 * If only the transmit fifo was larger...
 	 */
-	writel(TXCFG_CSI | TXCFG_HBI | TXCFG_ATP | TXCFG_MXDMA1024
+	/* Ramit : 1024 DMA is not a good idea, it ends up banging 
+	 * some DELL and COMPAQ SMP systems */
+	writel(TXCFG_CSI | TXCFG_HBI | TXCFG_ATP | TXCFG_MXDMA512
 		| ((1600 / 32) * 0x100),
 		dev->base + TXCFG);
 
@@ -1582,12 +1952,15 @@
 	writel(0x000, dev->base + IHR);
 
 	/* Set Rx to full duplex, don't accept runt, errored, long or length
-	 * range errored packets.  Set MXDMA to 0 => 1024 word burst
+	 * range errored packets.  Use 512 byte DMA.
 	 */
+	/* Ramit : 1024 DMA is not a good idea, it ends up banging 
+	 * some DELL and COMPAQ SMP systems 
+	 * Turn on ALP, only we are accpeting Jumbo Packets */
 	writel(RXCFG_AEP | RXCFG_ARP | RXCFG_AIRL | RXCFG_RX_FD
 		| RXCFG_STRIPCRC
-		| RXCFG_ALP
-		| (RXCFG_MXDMA0 * 0) | 0, dev->base + RXCFG);
+		//| RXCFG_ALP
+		| (RXCFG_MXDMA512) | 0, dev->base + RXCFG);
 
 	/* Disable priority queueing */
 	writel(0, dev->base + PQCR);
@@ -1597,13 +1970,23 @@
 	 * revision of the chip does not properly accept IP fragments
 	 * at least for UDP.
 	 */
+	/* Ramit : Be sure to turn on RXCFG_ARP if VLAN's are enabled, since
+	 * the MAC it calculates the packetsize AFTER stripping the VLAN
+	 * header, and if a VLAN Tagged packet of 64 bytes is received (like
+	 * a ping with a VLAN header) then the card, strips the 4 byte VLAN
+	 * tag and then checks the packet size, so if RXCFG_ARP is not enabled,
+	 * it discrards it!.  These guys......
+	 */
 	writel(VRCR_IPEN | VRCR_VTDEN, dev->base + VRCR);
 
 	/* Enable per-packet TCP/UDP/IP checksumming */
 	writel(VTCR_PPCHK, dev->base + VTCR);
 
-	/* Disable Pause frames */
-	writel(0, dev->base + PCR);
+	/* Ramit : Enable async and sync pause frames */
+	/* writel(0, dev->base + PCR); */
+	writel((PCR_PS_MCAST | PCR_PS_DA | PCR_PSEN | PCR_FFLO_4K |
+		PCR_FFHI_8K | PCR_STLO_4 | PCR_STHI_8 | PCR_PAUSE_CNT),
+		dev->base + PCR);
 
 	/* Disable Wake On Lan */
 	writel(0, dev->base + WCSR);
@@ -1631,6 +2014,10 @@
 		(dev->net_dev.features & NETIF_F_HIGHDMA) ? "h,sg" : "sg"
 		);
 
+#ifdef PHY_CODE_IS_FINISHED
+	ns83820_probe_phy(dev);
+#endif
+
 	return 0;
 
 out_unmap:
@@ -1670,7 +2057,7 @@
 }
 
 static struct pci_device_id ns83820_pci_tbl[] __devinitdata = {
-	{ 0x100b, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
+	{ 0x100b, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, .driver_data = 0, },
 	{ 0, },
 };
 
@@ -1703,5 +2090,14 @@
 
 MODULE_DEVICE_TABLE(pci, ns83820_pci_tbl);
 
+MODULE_PARM(lnksts, "i");
+MODULE_PARM_DESC(lnksts, "Polarity of LNKSTS bit");
+
+MODULE_PARM(ihr, "i");
+MODULE_PARM_DESC(ihr, "Time in 100 us increments to delay interrupts (range 0-127)");
+
+MODULE_PARM(reset_phy, "i");
+MODULE_PARM_DESC(reset_phy, "Set to 1 to reset the PHY on startup");
+
 module_init(ns83820_init);
 module_exit(ns83820_exit);
diff -urN linux-2.4.20-pre7/drivers/net/pci-skeleton.c linux-2.4.20-pre8/drivers/net/pci-skeleton.c
--- linux-2.4.20-pre7/drivers/net/pci-skeleton.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/net/pci-skeleton.c	Wed Sep 25 18:21:50 2002
@@ -1411,10 +1411,6 @@
 				tp->stats.tx_carrier_errors++;
 			if (txstatus & TxOutOfWindow)
 				tp->stats.tx_window_errors++;
-#ifdef ETHER_STATS
-			if ((txstatus & 0x0f000000) == 0x0f000000)
-				tp->stats.collisions16++;
-#endif
 		} else {
 			if (txstatus & TxUnderrun) {
 				/* Add 64 to the Tx FIFO threshold. */
diff -urN linux-2.4.20-pre7/drivers/net/pcmcia/pcnet_cs.c linux-2.4.20-pre8/drivers/net/pcmcia/pcnet_cs.c
--- linux-2.4.20-pre7/drivers/net/pcmcia/pcnet_cs.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/pcmcia/pcnet_cs.c	Wed Sep 25 18:21:50 2002
@@ -66,7 +66,7 @@
 #define SOCKET_START_PG	0x01
 #define SOCKET_STOP_PG	0xff
 
-#define PCNET_RDC_TIMEOUT 0x02	/* Max wait in jiffies for Tx RDC */
+#define PCNET_RDC_TIMEOUT (2*HZ/100)	/* Max wait in jiffies for Tx RDC */
 
 static char *if_names[] = { "auto", "10baseT", "10base2"};
 
@@ -1188,7 +1188,7 @@
 	}
 	info->link_status = link;
     }
-    if (info->pna_phy && (jiffies - info->mii_reset > 6*HZ)) {
+    if (info->pna_phy && time_after(jiffies, info->mii_reset + 6*HZ)) {
 	link = mdio_read(mii_addr, info->eth_phy, 1) & 0x0004;
 	if (((info->phy_id == info->pna_phy) && link) ||
 	    ((info->phy_id != info->pna_phy) && !link)) {
@@ -1426,7 +1426,7 @@
 #endif
 
     while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
-	if (jiffies - dma_start > PCNET_RDC_TIMEOUT) {
+	if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) {
 	    printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n",
 		   dev->name);
 	    pcnet_reset_8390(dev);
diff -urN linux-2.4.20-pre7/drivers/net/pcmcia/xircom_tulip_cb.c linux-2.4.20-pre8/drivers/net/pcmcia/xircom_tulip_cb.c
--- linux-2.4.20-pre7/drivers/net/pcmcia/xircom_tulip_cb.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/pcmcia/xircom_tulip_cb.c	Wed Sep 25 18:21:51 2002
@@ -1105,9 +1105,6 @@
 					tp->stats.tx_errors++;
 					if (status & Tx0ManyColl) {
 						tp->stats.tx_aborted_errors++;
-#ifdef ETHER_STATS
-						tp->stats.collisions16++;
-#endif
 					}
 					if (status & Tx0NoCarrier) tp->stats.tx_carrier_errors++;
 					if (status & Tx0LateColl) tp->stats.tx_window_errors++;
diff -urN linux-2.4.20-pre7/drivers/net/sundance.c linux-2.4.20-pre8/drivers/net/sundance.c
--- linux-2.4.20-pre7/drivers/net/sundance.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/net/sundance.c	Wed Sep 25 18:21:51 2002
@@ -18,26 +18,62 @@
 	http://www.scyld.com/network/sundance.html
 
 
-	Version 1.01a (jgarzik):
+	Version LK1.01a (jgarzik):
 	- Replace some MII-related magic numbers with constants
 
-	Version 1.01b (D-Link):
+	Version LK1.02 (D-Link):
 	- Add new board to PCI ID list
-	
+	- Fix multicast bug
+
+	Version LK1.03 (D-Link):
+	- New Rx scheme, reduce Rx congestion
+	- Option to disable flow control
+
+	Version LK1.04 (D-Link):
+	- Tx timeout recovery
+	- More support for ethtool.
+
+	Version LK1.04a:
+	- Remove unused/constant members from struct pci_id_info
+	(which then allows removal of 'drv_flags' from private struct)
+	(jgarzik)
+	- If no phy is found, fail to load that board (jgarzik)
+	- Always start phy id scan at id 1 to avoid problems (Donald Becker)
+	- Autodetect where mii_preable_required is needed,
+	default to not needed.  (Donald Becker)
+
+	Version LK1.04b:
+	- Remove mii_preamble_required module parameter (Donald Becker)
+	- Add per-interface mii_preamble_required (setting is autodetected)
+	  (Donald Becker)
+	- Remove unnecessary cast from void pointer (jgarzik)
+	- Re-align comments in private struct (jgarzik)
+
+	Version LK1.04c (jgarzik):
+	- Support bitmapped message levels (NETIF_MSG_xxx), and the
+	  two ethtool ioctls that get/set them
+	- Don't hand-code MII ethtool support, use standard API/lib
+
+	Version LK1.04d:
+	- Merge from Donald Becker's sundance.c: (Jason Lunz)
+		* proper support for variably-sized MTUs
+		* default to PIO, to fix chip bugs
+	- Add missing unregister_netdev (Jason Lunz)
+	- Add CONFIG_SUNDANCE_MMIO config option (jgarzik)
+	- Better rx buf size calculation (Donald Becker)
 
 */
 
 #define DRV_NAME	"sundance"
-#define DRV_VERSION	"1.01b"
-#define DRV_RELDATE	"17-Jan-2002"
+#define DRV_VERSION	"1.01+LK1.04d"
+#define DRV_RELDATE	"19-Sep-2002"
 
 
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 30;
-static int mtu;
+static int max_interrupt_work = 0;
 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
    Typical is a 64 element hash table based on the Ethernet CRC.  */
 static int multicast_filter_limit = 32;
@@ -47,6 +83,8 @@
    This chip can receive into offset buffers, so the Alpha does not
    need a copy-align. */
 static int rx_copybreak;
+static int tx_coalesce=1;
+static int flowctrl=1;
 
 /* media[] specifies the media type the NIC operates at.
 		 autosense	Autosensing active media.
@@ -60,8 +98,10 @@
 		 3	 	100Mbps half duplex.
 		 4	 	100Mbps full duplex.
 */
-#define MAX_UNITS 8	
+#define MAX_UNITS 8
 static char *media[MAX_UNITS];
+
+
 /* Operational parameters that are set at compile time. */
 
 /* Keep the ring sizes a power of two for compile efficiency.
@@ -70,9 +110,10 @@
    bonding and packet priority, and more than 128 requires modifying the
    Tx error recovery.
    Large receive rings merely waste memory. */
-#define TX_RING_SIZE	16
-#define TX_QUEUE_LEN	10		/* Limit ring entries actually used.  */
-#define RX_RING_SIZE	32
+#define TX_RING_SIZE	64
+#define TX_QUEUE_LEN	(TX_RING_SIZE - 1) /* Limit ring entries actually used.  */
+#define RX_RING_SIZE	64
+#define RX_BUDGET	32
 #define TX_TOTAL_SIZE	TX_RING_SIZE*sizeof(struct netdev_desc)
 #define RX_TOTAL_SIZE	RX_RING_SIZE*sizeof(struct netdev_desc)
 
@@ -107,13 +148,17 @@
 #include <linux/init.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
-#include <linux/crc32.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#ifndef _LOCAL_CRC32
+#include <linux/crc32.h>
+#else
+#include "crc32.h"
+#endif
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
@@ -125,14 +170,15 @@
 MODULE_LICENSE("GPL");
 
 MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(mtu, "i");
 MODULE_PARM(debug, "i");
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(media, "1-" __MODULE_STRING(MAX_UNITS) "s");
+MODULE_PARM(flowctrl, "i");
 MODULE_PARM_DESC(max_interrupt_work, "Sundance Alta maximum events handled per interrupt");
-MODULE_PARM_DESC(mtu, "Sundance Alta MTU (all boards)");
 MODULE_PARM_DESC(debug, "Sundance Alta debug level (0-5)");
 MODULE_PARM_DESC(rx_copybreak, "Sundance Alta copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(flowctrl, "Sundance Alta flow control [0|1]");
+
 /*
 				Theory of Operation
 
@@ -207,20 +253,9 @@
 
 */
 
-
-
-enum pci_id_flags_bits {
-        /* Set PCI command register bits before calling probe1(). */
-        PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
-        /* Read and map the single following PCI BAR. */
-        PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
-        PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
-};
-enum chip_capability_flags {CanHaveMII=1, };
-#ifdef USE_IO_OPS
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO  | PCI_ADDR0)
-#else
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
+/* Work-around for Kendin chip bugs. */
+#ifndef CONFIG_SUNDANCE_MMIO
+#define USE_IO_OPS 1
 #endif
 
 static struct pci_device_id sundance_pci_tbl[] __devinitdata = {
@@ -234,31 +269,20 @@
 };
 MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
 
+enum {
+	netdev_io_size = 128
+};
+
 struct pci_id_info {
         const char *name;
-        struct match_info {
-                int     pci, pci_mask, subsystem, subsystem_mask;
-                int revision, revision_mask;                            /* Only 8 bits. */
-        } id;
-        enum pci_id_flags_bits pci_flags;
-        int io_size;                            /* Needed for I/O region check or ioremap(). */
-        int drv_flags;                          /* Driver use, intended as capability flags. */
 };
 static struct pci_id_info pci_id_tbl[] = {
-	{"D-Link DFE-550TX FAST Ethernet Adapter", {0x10021186, 0xffffffff,},
-	 PCI_IOTYPE, 128, CanHaveMII},
-	{"D-Link DFE-550FX 100Mbps Fiber-optics Adapter",
-	 {0x10031186, 0xffffffff,},
-	 PCI_IOTYPE, 128, CanHaveMII},
-	{"D-Link DFE-580TX 4 port Server Adapter", {0x10121186, 0xffffffff,},
-	 PCI_IOTYPE, 128, CanHaveMII},
-	{"D-Link DFE-530TXS FAST Ethernet Adapter", {0x10021186, 0xffffffff,},
-	 PCI_IOTYPE, 128, CanHaveMII},
-	{"D-Link DL10050-based FAST Ethernet Adapter",
-	 {0x10021186, 0xffffffff,},
-	 PCI_IOTYPE, 128, CanHaveMII},
-	{"Sundance Technology Alta", {0x020113F0, 0xffffffff,},
-	 PCI_IOTYPE, 128, CanHaveMII},
+	{"D-Link DFE-550TX FAST Ethernet Adapter"},
+	{"D-Link DFE-550FX 100Mbps Fiber-optics Adapter"},
+	{"D-Link DFE-580TX 4 port Server Adapter"},
+	{"D-Link DFE-530TXS FAST Ethernet Adapter"},
+	{"D-Link DL10050-based FAST Ethernet Adapter"},
+	{"Sundance Technology Alta"},
 	{0,},			/* 0 terminated list. */
 };
 
@@ -290,20 +314,24 @@
 enum alta_offsets {
 	DMACtrl = 0x00,
 	TxListPtr = 0x04,
-	TxDMACtrl = 0x08,
-	TxDescPoll = 0x0a,
+	TxDMABurstThresh = 0x08,
+	TxDMAUrgentThresh = 0x09,
+	TxDMAPollPeriod = 0x0a,
 	RxDMAStatus = 0x0c,
 	RxListPtr = 0x10,
-	RxDMACtrl = 0x14,
-	RxDescPoll = 0x16,
+	RxDMABurstThresh = 0x14,
+	RxDMAUrgentThresh = 0x15,
+	RxDMAPollPeriod = 0x16,
 	LEDCtrl = 0x1a,
 	ASICCtrl = 0x30,
 	EEData = 0x34,
 	EECtrl = 0x36,
-	TxThreshold = 0x3c,
+	TxStartThresh = 0x3c,
+	RxEarlyThresh = 0x3e,
 	FlashAddr = 0x40,
 	FlashData = 0x44,
 	TxStatus = 0x46,
+	TxFrameId = 0x47,
 	DownCounter = 0x18,
 	IntrClear = 0x4a,
 	IntrEnable = 0x4c,
@@ -311,7 +339,7 @@
 	MACCtrl0 = 0x50,
 	MACCtrl1 = 0x52,
 	StationAddr = 0x54,
-	MaxTxSize = 0x5A,
+	MaxFrameSize = 0x5A,
 	RxMode = 0x5c,
 	MIICtrl = 0x5e,
 	MulticastFilter0 = 0x60,
@@ -337,6 +365,16 @@
 	/* Aliased and bogus values! */
 	RxStatus = 0x0c,
 };
+enum ASICCtrl_HiWord_bit {
+	GlobalReset = 0x0001,
+	RxReset = 0x0002,
+	TxReset = 0x0004,
+	DMAReset = 0x0008,
+	FIFOReset = 0x0010,
+	NetworkReset = 0x0020,
+	HostReset = 0x0040,
+	ResetBusy = 0x0400,
+};
 
 /* Bits in the interrupt status/mask registers. */
 enum intr_status_bits {
@@ -396,35 +434,40 @@
         dma_addr_t tx_ring_dma;
         dma_addr_t rx_ring_dma;
 	struct net_device_stats stats;
-	struct timer_list timer;	/* Media monitoring timer. */
+	struct timer_list timer;		/* Media monitoring timer. */
 	/* Frequently used values: keep some adjacent for cache effect. */
 	spinlock_t lock;
-	int chip_id, drv_flags;
+	spinlock_t rx_lock;			/* Group with Tx control cache line. */
+	int msg_enable;
+	int chip_id;
 	unsigned int cur_rx, dirty_rx;		/* Producer/consumer ring indices */
-	unsigned int rx_buf_sz;				/* Based on MTU+slack. */
-	spinlock_t txlock;					/* Group with Tx control cache line. */
+	unsigned int rx_buf_sz;			/* Based on MTU+slack. */
 	struct netdev_desc *last_tx;		/* Last Tx descriptor used. */
 	unsigned int cur_tx, dirty_tx;
-	unsigned int tx_full:1;				/* The Tx queue is full. */
 	/* These values are keep track of the transceiver/media in use. */
-	unsigned int full_duplex:1;			/* Full-duplex operation requested. */
-	unsigned int medialock:1;			/* Do not sense media. */
+	unsigned int flowctrl:1;
 	unsigned int default_port:4;		/* Last dev->if_port value. */
 	unsigned int an_enable:1;
 	unsigned int speed;
+	struct tasklet_struct rx_tasklet;
+	int budget;
 	/* Multicast and receive mode. */
-	spinlock_t mcastlock;				/* SMP lock multicast updates. */
+	spinlock_t mcastlock;			/* SMP lock multicast updates. */
 	u16 mcast_filter[4];
 	/* MII transceiver section. */
-	int mii_cnt;						/* MII device addresses. */
-	u16 advertising;					/* NWay media advertisement */
+	struct mii_if_info mii_if;
+	int mii_preamble_required;
 	unsigned char phys[MII_CNT];		/* MII device addresses, only first one used. */
 	struct pci_dev *pci_dev;
 };
 
 /* The station address location in the EEPROM. */
 #define EEPROM_SA_OFFSET	0x10
+#define DEFAULT_INTR (IntrRxDMADone | IntrPCIErr | \
+			IntrDrvRqst | IntrTxDone | StatsMax | \
+			LinkChange)
 
+static int  change_mtu(struct net_device *dev, int new_mtu);
 static int  eeprom_read(long ioaddr, int location);
 static int  mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
@@ -434,16 +477,18 @@
 static void tx_timeout(struct net_device *dev);
 static void init_ring(struct net_device *dev);
 static int  start_tx(struct sk_buff *skb, struct net_device *dev);
+static int reset_tx (struct net_device *dev, int irq);
 static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static void rx_poll(unsigned long data);
+static void refill_rx (struct net_device *dev);
 static void netdev_error(struct net_device *dev, int intr_status);
-static int  netdev_rx(struct net_device *dev);
 static void netdev_error(struct net_device *dev, int intr_status);
 static void set_rx_mode(struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int  netdev_close(struct net_device *dev);
 
-
+
 
 static int __devinit sundance_probe1 (struct pci_dev *pdev,
 				      const struct pci_device_id *ent)
@@ -485,7 +530,7 @@
 	ioaddr = pci_resource_start(pdev, 0);
 #else
 	ioaddr = pci_resource_start(pdev, 1);
-	ioaddr = (long) ioremap (ioaddr, pci_id_tbl[chip_idx].io_size);
+	ioaddr = (long) ioremap (ioaddr, netdev_io_size);
 	if (!ioaddr)
 		goto err_out_res;
 #endif
@@ -498,10 +543,11 @@
 	dev->irq = irq;
 
 	np = dev->priv;
-	np->chip_id = chip_idx;
-	np->drv_flags = pci_id_tbl[chip_idx].drv_flags;
 	np->pci_dev = pdev;
+	np->chip_id = chip_idx;
+	np->msg_enable = (1 << debug) - 1;
 	spin_lock_init(&np->lock);
+	tasklet_init(&np->rx_tasklet, rx_poll, (unsigned long)dev);
 
 	ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
 	if (!ring_space)
@@ -515,6 +561,10 @@
 	np->rx_ring = (struct netdev_desc *)ring_space;
 	np->rx_ring_dma = ring_dma;
 
+	np->mii_if.dev = dev;
+	np->mii_if.mdio_read = mdio_read;
+	np->mii_if.mdio_write = mdio_write;
+
 	/* The chip-specific entries in the device structure. */
 	dev->open = &netdev_open;
 	dev->hard_start_xmit = &start_tx;
@@ -524,11 +574,9 @@
 	dev->do_ioctl = &netdev_ioctl;
 	dev->tx_timeout = &tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
+	dev->change_mtu = &change_mtu;
 	pci_set_drvdata(pdev, dev);
 
-	if (mtu)
-		dev->mtu = mtu;
-
 	i = register_netdev(dev);
 	if (i)
 		goto err_out_unmap_rx;
@@ -542,21 +590,30 @@
 	if (1) {
 		int phy, phy_idx = 0;
 		np->phys[0] = 1;		/* Default setting */
-		for (phy = 0; phy < 32 && phy_idx < MII_CNT; phy++) {
-			int mii_status = mdio_read(dev, phy, 1);
+		np->mii_preamble_required++;
+		for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
+			int mii_status = mdio_read(dev, phy, MII_BMSR);
 			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
 				np->phys[phy_idx++] = phy;
-				np->advertising = mdio_read(dev, phy, 4);
+				np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
+				if ((mii_status & 0x0040) == 0)
+					np->mii_preamble_required++;
 				printk(KERN_INFO "%s: MII PHY found at address %d, status "
 					   "0x%4.4x advertising %4.4x.\n",
-					   dev->name, phy, mii_status, np->advertising);
+					   dev->name, phy, mii_status, np->mii_if.advertising);
 			}
 		}
-		np->mii_cnt = phy_idx;
-		if (phy_idx == 0)
-			printk(KERN_INFO "%s: No MII transceiver found!, ASIC status %x\n",
+		np->mii_preamble_required--;
+
+		if (phy_idx == 0) {
+			printk(KERN_INFO "%s: No MII transceiver found, aborting.  ASIC status %x\n",
 				   dev->name, readl(ioaddr + ASICCtrl));
+			goto err_out_unregister;
+		}
+
+		np->mii_if.phy_id = np->phys[0];
 	}
+
 	/* Parse override configuration */
 	np->an_enable = 1;
 	if (card_idx < MAX_UNITS) {
@@ -565,23 +622,29 @@
 			if (strcmp (media[card_idx], "100mbps_fd") == 0 ||
 			    strcmp (media[card_idx], "4") == 0) {
 				np->speed = 100;
-				np->full_duplex = 1;
+				np->mii_if.full_duplex = 1;
 			} else if (strcmp (media[card_idx], "100mbps_hd") == 0
 				   || strcmp (media[card_idx], "3") == 0) {
 				np->speed = 100;
-				np->full_duplex = 0;
+				np->mii_if.full_duplex = 0;
 			} else if (strcmp (media[card_idx], "10mbps_fd") == 0 ||
 				   strcmp (media[card_idx], "2") == 0) {
 				np->speed = 10;
-				np->full_duplex = 1;
+				np->mii_if.full_duplex = 1;
 			} else if (strcmp (media[card_idx], "10mbps_hd") == 0 ||
 				   strcmp (media[card_idx], "1") == 0) {
 				np->speed = 10;
-				np->full_duplex = 0;
+				np->mii_if.full_duplex = 0;
 			} else {
 				np->an_enable = 1;
 			}
 		}
+		if (tx_coalesce < 1)
+			tx_coalesce = 1;
+		else if (tx_coalesce > TX_QUEUE_LEN - 1)
+			tx_coalesce = TX_QUEUE_LEN - 1;
+		if (flowctrl == 0)
+			np->flowctrl = 0;
 	}
 
 	/* Fibre PHY? */
@@ -589,7 +652,7 @@
 		/* Default 100Mbps Full */
 		if (np->an_enable) {
 			np->speed = 100;
-			np->full_duplex = 1;
+			np->mii_if.full_duplex = 1;
 			np->an_enable = 0;
 		}
 	}
@@ -601,24 +664,26 @@
 	if (!np->an_enable) {
 		mii_ctl = 0;
 		mii_ctl |= (np->speed == 100) ? BMCR_SPEED100 : 0;
-		mii_ctl |= (np->full_duplex) ? BMCR_FULLDPLX : 0;
+		mii_ctl |= (np->mii_if.full_duplex) ? BMCR_FULLDPLX : 0;
 		mdio_write (dev, np->phys[0], MII_BMCR, mii_ctl);
 		printk (KERN_INFO "Override speed=%d, %s duplex\n",
-			np->speed, np->full_duplex ? "Full" : "Half");
+			np->speed, np->mii_if.full_duplex ? "Full" : "Half");
 
 	}
 
 	/* Perhaps move the reset here? */
 	/* Reset the chip to erase previous misconfiguration. */
-	if (debug > 1)
+	if (netif_msg_hw(np))
 		printk("ASIC Control is %x.\n", readl(ioaddr + ASICCtrl));
 	writew(0x007f, ioaddr + ASICCtrl + 2);
-	if (debug > 1)
+	if (netif_msg_hw(np))
 		printk("ASIC Control is now %x.\n", readl(ioaddr + ASICCtrl));
 
 	card_idx++;
 	return 0;
 
+err_out_unregister:
+	unregister_netdev(dev);
 err_out_unmap_rx:
         pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
 err_out_unmap_tx:
@@ -635,7 +700,16 @@
 	return -ENODEV;
 }
 
-
+static int change_mtu(struct net_device *dev, int new_mtu)
+{
+	if ((new_mtu < 68) || (new_mtu > 8191)) /* Set by RxDMAFrameLen */
+		return -EINVAL;
+	if (netif_running(dev))
+		return -EBUSY;
+	dev->mtu = new_mtu;
+	return 0;
+}
+
 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
 static int __devinit eeprom_read(long ioaddr, int location)
 {
@@ -658,11 +732,6 @@
 	met by back-to-back 33Mhz PCI cycles. */
 #define mdio_delay() readb(mdio_addr)
 
-/* Set iff a MII transceiver on any interface requires mdio preamble.
-   This only set with older tranceivers, so the extra
-   code size of a per-interface flag is not worthwhile. */
-static const char mii_preamble_required = 1;
-
 enum mii_reg_bits {
 	MDIO_ShiftClk=0x0001, MDIO_Data=0x0002, MDIO_EnbOutput=0x0004,
 };
@@ -687,11 +756,12 @@
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
+	struct netdev_private *np = dev->priv;
 	long mdio_addr = dev->base_addr + MIICtrl;
 	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	int i, retval = 0;
 
-	if (mii_preamble_required)
+	if (np->mii_preamble_required)
 		mdio_sync(mdio_addr);
 
 	/* Shift the read command bits out. */
@@ -716,11 +786,12 @@
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
+	struct netdev_private *np = dev->priv;
 	long mdio_addr = dev->base_addr + MIICtrl;
 	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
 	int i;
 
-	if (mii_preamble_required)
+	if (np->mii_preamble_required)
 		mdio_sync(mdio_addr);
 
 	/* Shift the command bits out. */
@@ -742,7 +813,6 @@
 	return;
 }
 
-
 static int netdev_open(struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
@@ -755,7 +825,7 @@
 	if (i)
 		return i;
 
-	if (debug > 1)
+	if (netif_msg_ifup(np))
 		printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
 			   dev->name, dev->irq);
 
@@ -768,6 +838,10 @@
 		writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
 
 	/* Initialize other registers. */
+	writew(dev->mtu + 14, ioaddr + MaxFrameSize);
+	if (dev->mtu > 2047)
+		writel(readl(ioaddr + ASICCtrl) | 0x0C, ioaddr + ASICCtrl);
+
 	/* Configure the PCI bus bursts and FIFO thresholds. */
 
 	if (dev->if_port == 0)
@@ -779,17 +853,13 @@
 	writew(0, ioaddr + IntrEnable);
 	writew(0, ioaddr + DownCounter);
 	/* Set the chip to poll every N*320nsec. */
-	writeb(100, ioaddr + RxDescPoll);
-	writeb(127, ioaddr + TxDescPoll);
+	writeb(100, ioaddr + RxDMAPollPeriod);
+	writeb(127, ioaddr + TxDMAPollPeriod);
 	netif_start_queue(dev);
 
-	/* Enable interrupts by setting the interrupt mask. */
-	writew(IntrRxDone | IntrRxDMADone | IntrPCIErr | IntrDrvRqst | IntrTxDone
-		   | StatsMax | LinkChange, ioaddr + IntrEnable);
-
 	writew(StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
 
-	if (debug > 2)
+	if (netif_msg_ifup(np))
 		printk(KERN_DEBUG "%s: Done netdev_open(), status: Rx %x Tx %x "
 			   "MAC Control %x, %4.4x %4.4x.\n",
 			   dev->name, readl(ioaddr + RxStatus), readb(ioaddr + TxStatus),
@@ -803,6 +873,9 @@
 	np->timer.function = &netdev_timer;				/* timer handler */
 	add_timer(&np->timer);
 
+	/* Enable interrupts by setting the interrupt mask. */
+	writew(DEFAULT_INTR, ioaddr + IntrEnable);
+
 	return 0;
 }
 
@@ -811,21 +884,22 @@
 	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 	int mii_lpa = mdio_read(dev, np->phys[0], MII_LPA);
-	int negotiated = mii_lpa & np->advertising;
+	int negotiated = mii_lpa & np->mii_if.advertising;
 	int duplex;
-	
+
 	/* Force media */
 	if (!np->an_enable || mii_lpa == 0xffff) {
-		if (np->full_duplex)
+		if (np->mii_if.full_duplex)
 			writew (readw (ioaddr + MACCtrl0) | EnbFullDuplex,
 				ioaddr + MACCtrl0);
 		return;
 	}
+
 	/* Autonegotiation */
 	duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
-	if (np->full_duplex != duplex) {
-		np->full_duplex = duplex;
-		if (debug)
+	if (np->mii_if.full_duplex != duplex) {
+		np->mii_if.full_duplex = duplex;
+		if (netif_msg_link(np))
 			printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
 				   "negotiated capability %4.4x.\n", dev->name,
 				   duplex ? "full" : "half", np->phys[0], negotiated);
@@ -840,7 +914,7 @@
 	long ioaddr = dev->base_addr;
 	int next_tick = 10*HZ;
 
-	if (debug > 3) {
+	if (netif_msg_timer(np)) {
 		printk(KERN_DEBUG "%s: Media selection timer tick, intr status %4.4x, "
 			   "Tx %x Rx %x.\n",
 			   dev->name, readw(ioaddr + IntrEnable),
@@ -855,9 +929,12 @@
 {
 	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
+	long flag;
 
-	printk(KERN_WARNING "%s: Transmit timed out, status %2.2x,"
-		   " resetting...\n", dev->name, readb(ioaddr + TxStatus));
+	printk(KERN_WARNING "%s: Transmit timed out, TxStatus %2.2x "
+		   "TxFrameId %2.2x,"
+		   " resetting...\n", dev->name, readb(ioaddr + TxStatus),
+		   readb(ioaddr + TxFrameId));
 
 	{
 		int i;
@@ -866,22 +943,24 @@
 			printk(" %8.8x", (unsigned int)np->rx_ring[i].status);
 		printk("\n"KERN_DEBUG"  Tx ring %p: ", np->tx_ring);
 		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(" %4.4x", np->tx_ring[i].status);
+			printk(" %8.8x", np->tx_ring[i].status);
 		printk("\n");
 	}
+	spin_lock_irqsave(&np->lock, flag);
+	reset_tx(dev, 0);
+	spin_unlock_irqrestore(&np->lock, flag);
 
 	/* Perhaps we should reinitialize the hardware here. */
 	dev->if_port = 0;
 	/* Stop and restart the chip's Tx processes . */
 
 	/* Trigger an immediate transmit demand. */
-	writew(IntrRxDone | IntrRxDMADone | IntrPCIErr | IntrDrvRqst | IntrTxDone
-		   | StatsMax | LinkChange, ioaddr + IntrEnable);
+	writew(DEFAULT_INTR, ioaddr + IntrEnable);
 
 	dev->trans_start = jiffies;
 	np->stats.tx_errors++;
 
-	if (!np->tx_full)
+	if (!netif_queue_stopped(dev))
 		netif_wake_queue(dev);
 }
 
@@ -892,15 +971,14 @@
 	struct netdev_private *np = dev->priv;
 	int i;
 
-	np->tx_full = 0;
 	np->cur_rx = np->cur_tx = 0;
 	np->dirty_rx = np->dirty_tx = 0;
 
-	np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+	np->rx_buf_sz = (dev->mtu <= 1520 ? PKT_BUF_SZ : dev->mtu + 16);
 
 	/* Initialize all Rx descriptors. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		np->rx_ring[i].next_desc = cpu_to_le32(np->rx_ring_dma + 
+		np->rx_ring[i].next_desc = cpu_to_le32(np->rx_ring_dma +
 			((i+1)%RX_RING_SIZE)*sizeof(*np->rx_ring));
 		np->rx_ring[i].status = 0;
 		np->rx_ring[i].frag[0].length = 0;
@@ -916,7 +994,7 @@
 		skb->dev = dev;		/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		np->rx_ring[i].frag[0].addr = cpu_to_le32(
-			pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, 
+			pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz,
 				PCI_DMA_FROMDEVICE));
 		np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
 	}
@@ -929,15 +1007,16 @@
 	return;
 }
 
-static int start_tx(struct sk_buff *skb, struct net_device *dev)
+static int
+start_tx (struct sk_buff *skb, struct net_device *dev)
 {
 	struct netdev_private *np = dev->priv;
 	struct netdev_desc *txdesc;
 	unsigned entry;
+	long ioaddr = dev->base_addr;
 
 	/* Note: Ordering is important here, set the field with the
 	   "ownership" bit last, and only then increment cur_tx. */
-
 	/* Calculate the next Tx descriptor entry. */
 	entry = np->cur_tx % TX_RING_SIZE;
 	np->tx_skbuff[entry] = skb;
@@ -945,11 +1024,17 @@
 
 	txdesc->next_desc = 0;
 	/* Note: disable the interrupt generation here before releasing. */
-	txdesc->status =
-		cpu_to_le32((entry<<2) | DescIntrOnDMADone | DescIntrOnTx | DisableAlign);
-	txdesc->frag[0].addr = cpu_to_le32(pci_map_single(np->pci_dev, 
-		skb->data, skb->len, PCI_DMA_TODEVICE));
-	txdesc->frag[0].length = cpu_to_le32(skb->len | LastFrag);
+	if (entry % tx_coalesce == 0) {
+		txdesc->status = cpu_to_le32 ((entry << 2) |
+				 DescIntrOnTx | DisableAlign);
+
+	} else {
+		txdesc->status = cpu_to_le32 ((entry << 2) | DisableAlign);
+	}
+	txdesc->frag[0].addr = cpu_to_le32 (pci_map_single (np->pci_dev, skb->data,
+							skb->len,
+							PCI_DMA_TODEVICE));
+	txdesc->frag[0].length = cpu_to_le32 (skb->len | LastFrag);
 	if (np->last_tx)
 		np->last_tx->next_desc = cpu_to_le32(np->tx_ring_dma +
 			entry*sizeof(struct netdev_desc));
@@ -957,24 +1042,63 @@
 	np->cur_tx++;
 
 	/* On some architectures: explicitly flush cache lines here. */
-
-	if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 1) {
+	if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 1
+			&& !netif_queue_stopped(dev)) {
 		/* do nothing */
 	} else {
-		np->tx_full = 1;
-		netif_stop_queue(dev);
+		netif_stop_queue (dev);
 	}
 	/* Side effect: The read wakes the potentially-idle transmit channel. */
-	if (readl(dev->base_addr + TxListPtr) == 0)
-		writel(np->tx_ring_dma + entry*sizeof(*np->tx_ring),
+	if (readl (dev->base_addr + TxListPtr) == 0)
+		writel (np->tx_ring_dma + entry*sizeof(*np->tx_ring),
 			dev->base_addr + TxListPtr);
 
 	dev->trans_start = jiffies;
 
-	if (debug > 4) {
-		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
-			   dev->name, np->cur_tx, entry);
+	if (netif_msg_tx_queued(np)) {
+		printk (KERN_DEBUG
+			"%s: Transmit frame #%d queued in slot %d.\n",
+			dev->name, np->cur_tx, entry);
+	}
+	if (tx_coalesce > 1)
+		writel (1000, ioaddr + DownCounter);
+	return 0;
+}
+static int
+reset_tx (struct net_device *dev, int irq)
+{
+	struct netdev_private *np = (struct netdev_private*) dev->priv;
+	long ioaddr = dev->base_addr;
+	int i;
+	int frame_id;
+
+	frame_id = readb(ioaddr + TxFrameId);
+	writew (TxReset | DMAReset | FIFOReset | NetworkReset,
+			ioaddr + ASICCtrl + 2);
+	for (i=50; i > 0; i--) {
+		if ((readw(ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
+			break;
+		mdelay(1);
+	}
+	for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
+		int entry = np->dirty_tx % TX_RING_SIZE;
+		struct sk_buff *skb;
+		if (!(np->tx_ring[entry].status & 0x00010000))
+			break;
+		skb = np->tx_skbuff[entry];
+		/* Free the original skb. */
+		pci_unmap_single(np->pci_dev,
+			np->tx_ring[entry].frag[0].addr,
+			skb->len, PCI_DMA_TODEVICE);
+		if (irq)
+			dev_kfree_skb_irq (np->tx_skbuff[entry]);
+		else
+			dev_kfree_skb (np->tx_skbuff[entry]);
+
+		np->tx_skbuff[entry] = 0;
 	}
+	writel (np->tx_ring_dma + frame_id * sizeof(*np->tx_ring),
+			dev->base_addr + TxListPtr);
 	return 0;
 }
 
@@ -989,139 +1113,131 @@
 
 	ioaddr = dev->base_addr;
 	np = dev->priv;
-	spin_lock(&np->lock);
 
 	do {
 		int intr_status = readw(ioaddr + IntrStatus);
-		writew(intr_status & (IntrRxDone | IntrRxDMADone | IntrPCIErr |
-			IntrDrvRqst | IntrTxDone | IntrTxDMADone | StatsMax | 
-			LinkChange), ioaddr + IntrStatus);
+		writew(intr_status, ioaddr + IntrStatus);
 
-		if (debug > 4)
+		if (netif_msg_intr(np))
 			printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
 				   dev->name, intr_status);
 
-		if (intr_status == 0)
+		if (!(intr_status & DEFAULT_INTR))
 			break;
 
-		if (intr_status & (IntrRxDone|IntrRxDMADone))
-			netdev_rx(dev);
+		if (intr_status & (IntrRxDMADone)) {
+			writew(DEFAULT_INTR & ~(IntrRxDone|IntrRxDMADone),
+					ioaddr + IntrEnable);
+			if (np->budget < 0)
+				np->budget = RX_BUDGET;
+			tasklet_schedule(&np->rx_tasklet);
+		}
 
-		if (intr_status & IntrTxDone) {
+		if (intr_status & (IntrTxDone | IntrDrvRqst)) {
 			int boguscnt = 32;
-			int tx_status = readw(ioaddr + TxStatus);
+			int tx_status = readw (ioaddr + TxStatus);
 			while (tx_status & 0x80) {
-				if (debug > 4)
-					printk("%s: Transmit status is %2.2x.\n",
-						   dev->name, tx_status);
+				if (netif_msg_tx_done(np))
+					printk
+					    ("%s: Transmit status is %2.2x.\n",
+					     dev->name, tx_status);
 				if (tx_status & 0x1e) {
 					np->stats.tx_errors++;
-					if (tx_status & 0x10)  np->stats.tx_fifo_errors++;
-#ifdef ETHER_STATS
-					if (tx_status & 0x08)  np->stats.collisions16++;
-#else
-					if (tx_status & 0x08)  np->stats.collisions++;
-#endif
-					if (tx_status & 0x04)  np->stats.tx_fifo_errors++;
-					if (tx_status & 0x02)  np->stats.tx_window_errors++;
+					if (tx_status & 0x10)
+						np->stats.tx_fifo_errors++;
+					if (tx_status & 0x08)
+						np->stats.collisions++;
+					if (tx_status & 0x02)
+						np->stats.tx_window_errors++;
 					/* This reset has not been verified!. */
-					if (tx_status & 0x10) {			/* Reset the Tx. */
-						writew(0x001c, ioaddr + ASICCtrl + 2);
-#if 0					/* Do we need to reset the Tx pointer here? */
-						writel(np->tx_ring_dma
-							+ np->dirty_tx*sizeof(*np->tx_ring),
-							dev->base_addr + TxListPtr);
-#endif
+					if (tx_status & 0x10) {	/* Reset the Tx. */
+						np->stats.tx_fifo_errors++;
+						spin_lock(&np->lock);
+						reset_tx(dev, 1);
+						spin_unlock(&np->lock);
 					}
-					if (tx_status & 0x1e) 		/* Restart the Tx. */
-						writew(TxEnable, ioaddr + MACCtrl1);
+					if (tx_status & 0x1e)	/* Restart the Tx. */
+						writew (TxEnable,
+							ioaddr + MACCtrl1);
 				}
 				/* Yup, this is a documentation bug.  It cost me *hours*. */
-				writew(0, ioaddr + TxStatus);
-				tx_status = readb(ioaddr + TxStatus);
+				writew (0, ioaddr + TxStatus);
+				tx_status = readw (ioaddr + TxStatus);
 				if (--boguscnt < 0)
 					break;
 			}
 		}
+		spin_lock(&np->lock);
 		for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
 			int entry = np->dirty_tx % TX_RING_SIZE;
 			struct sk_buff *skb;
-
-			if ( ! (np->tx_ring[entry].status & 0x00010000))
+			if (!(np->tx_ring[entry].status & 0x00010000))
 				break;
 			skb = np->tx_skbuff[entry];
 			/* Free the original skb. */
-			pci_unmap_single(np->pci_dev, 
-				np->tx_ring[entry].frag[0].addr, 
+			pci_unmap_single(np->pci_dev,
+				np->tx_ring[entry].frag[0].addr,
 				skb->len, PCI_DMA_TODEVICE);
-			dev_kfree_skb_irq(skb);
+			dev_kfree_skb_irq (np->tx_skbuff[entry]);
 			np->tx_skbuff[entry] = 0;
 		}
-		if (np->tx_full
-			&& np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
+		spin_unlock(&np->lock);
+		if (netif_queue_stopped(dev) &&
+			np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
 			/* The ring is no longer full, clear tbusy. */
-			np->tx_full = 0;
-			netif_wake_queue(dev);
+			netif_wake_queue (dev);
 		}
 
 		/* Abnormal error summary/uncommon events handlers. */
-		if (intr_status & (IntrDrvRqst | IntrPCIErr | LinkChange | StatsMax))
+		if (intr_status & (IntrPCIErr | LinkChange | StatsMax))
 			netdev_error(dev, intr_status);
 		if (--boguscnt < 0) {
 			get_stats(dev);
-			if (debug > 1) 
+			if (netif_msg_hw(np))
 				printk(KERN_WARNING "%s: Too much work at interrupt, "
 				   "status=0x%4.4x / 0x%4.4x.\n",
 				   dev->name, intr_status, readw(ioaddr + IntrClear));
-			/* Re-enable us in 3.2msec. */
-			writew(0, ioaddr + IntrEnable);
-			writew(1000, ioaddr + DownCounter);
-			writew(IntrDrvRqst, ioaddr + IntrEnable);
 			break;
 		}
 	} while (1);
-
-	if (debug > 3)
+	if (netif_msg_intr(np))
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
 			   dev->name, readw(ioaddr + IntrStatus));
+	if (np->cur_tx - np->dirty_tx > 0 && tx_coalesce > 1)
+		writel(100, ioaddr + DownCounter);
 
-	spin_unlock(&np->lock);
 }
 
-/* This routine is logically part of the interrupt handler, but separated
-   for clarity and better register allocation. */
-static int netdev_rx(struct net_device *dev)
+static void rx_poll(unsigned long data)
 {
+	struct net_device *dev = (struct net_device *)data;
 	struct netdev_private *np = dev->priv;
 	int entry = np->cur_rx % RX_RING_SIZE;
-	int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx;
-
-	if (debug > 4) {
-		printk(KERN_DEBUG " In netdev_rx(), entry %d status %4.4x.\n",
-			   entry, np->rx_ring[entry].status);
-	}
+	int boguscnt = np->budget;
+	long ioaddr = dev->base_addr;
+	int received = 0;
 
 	/* If EOP is set on the next entry, it's a new packet. Send it up. */
 	while (1) {
 		struct netdev_desc *desc = &(np->rx_ring[entry]);
-		u32 frame_status;
+		u32 frame_status = le32_to_cpu(desc->status);
 		int pkt_len;
 
+		if (--boguscnt < 0) {
+			goto not_done;
+		}
 		if (!(desc->status & DescOwn))
 			break;
-		frame_status = le32_to_cpu(desc->status);
 		pkt_len = frame_status & 0x1fff;	/* Chip omits the CRC. */
-		if (debug > 4)
+		if (netif_msg_rx_status(np))
 			printk(KERN_DEBUG "  netdev_rx() status was %8.8x.\n",
 				   frame_status);
-		if (--boguscnt < 0)
-			break;
 		pci_dma_sync_single(np->pci_dev, desc->frag[0].addr,
 			np->rx_buf_sz, PCI_DMA_FROMDEVICE);
-		
+
 		if (frame_status & 0x001f4000) {
 			/* There was a error. */
-			if (debug > 2)
+			if (netif_msg_rx_err(np))
 				printk(KERN_DEBUG "  netdev_rx() Rx error was %8.8x.\n",
 					   frame_status);
 			np->stats.rx_errors++;
@@ -1136,9 +1252,8 @@
 			}
 		} else {
 			struct sk_buff *skb;
-
 #ifndef final_version
-			if (debug > 4)
+			if (netif_msg_rx_status(np))
 				printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d"
 					   ", bogus_cnt %d.\n",
 					   pkt_len, boguscnt);
@@ -1152,9 +1267,9 @@
 				eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
 				skb_put(skb, pkt_len);
 			} else {
-				pci_unmap_single(np->pci_dev, 
+				pci_unmap_single(np->pci_dev,
 					desc->frag[0].addr,
-					np->rx_buf_sz, 
+					np->rx_buf_sz,
 					PCI_DMA_FROMDEVICE);
 				skb_put(skb = np->rx_skbuff[entry], pkt_len);
 				np->rx_skbuff[entry] = NULL;
@@ -1164,11 +1279,36 @@
 			netif_rx(skb);
 			dev->last_rx = jiffies;
 		}
-		entry = (++np->cur_rx) % RX_RING_SIZE;
+		entry = (entry + 1) % RX_RING_SIZE;
+		received++;
 	}
+	np->cur_rx = entry;
+	refill_rx (dev);
+	np->budget -= received;
+	writew(DEFAULT_INTR, ioaddr + IntrEnable);
+	return;
+
+not_done:
+	np->cur_rx = entry;
+	refill_rx (dev);
+	if (!received)
+		received = 1;
+	np->budget -= received;
+	if (np->budget <= 0)
+		np->budget = RX_BUDGET;
+	tasklet_schedule(&np->rx_tasklet);
+	return;
+}
+
+static void refill_rx (struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	int entry;
+	int cnt = 0;
 
 	/* Refill the Rx ring buffers. */
-	for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {
+	for (;(np->cur_rx - np->dirty_rx + RX_RING_SIZE) % RX_RING_SIZE > 0;
+		np->dirty_rx = (np->dirty_rx + 1) % RX_RING_SIZE) {
 		struct sk_buff *skb;
 		entry = np->dirty_rx % RX_RING_SIZE;
 		if (np->rx_skbuff[entry] == NULL) {
@@ -1179,19 +1319,17 @@
 			skb->dev = dev;		/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			np->rx_ring[entry].frag[0].addr = cpu_to_le32(
-				pci_map_single(np->pci_dev, skb->tail, 
+				pci_map_single(np->pci_dev, skb->tail,
 					np->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		}
 		/* Perhaps we need not reset this field. */
 		np->rx_ring[entry].frag[0].length =
 			cpu_to_le32(np->rx_buf_sz | LastFrag);
 		np->rx_ring[entry].status = 0;
+		cnt++;
 	}
-
-	/* No need to restart Rx engine, it will poll. */
-	return 0;
+	return;
 }
-
 static void netdev_error(struct net_device *dev, int intr_status)
 {
 	long ioaddr = dev->base_addr;
@@ -1199,43 +1337,40 @@
 	u16 mii_ctl, mii_advertise, mii_lpa;
 	int speed;
 
-	if (intr_status & IntrDrvRqst) {
-		/* Stop the down counter and turn interrupts back on. */
-		if (debug > 1)
-			printk("%s: Turning interrupts back on.\n", dev->name);
-		writew(0, ioaddr + IntrEnable);
-		writew(0, ioaddr + DownCounter);
-		writew(IntrRxDone | IntrRxDMADone | IntrPCIErr | IntrDrvRqst |
-			   IntrTxDone | StatsMax | LinkChange, ioaddr + IntrEnable);
-		/* Ack buggy InRequest */
-		writew (IntrDrvRqst, ioaddr + IntrStatus);
-	}
 	if (intr_status & LinkChange) {
 		if (np->an_enable) {
 			mii_advertise = mdio_read (dev, np->phys[0], MII_ADVERTISE);
 			mii_lpa= mdio_read (dev, np->phys[0], MII_LPA);
 			mii_advertise &= mii_lpa;
 			printk (KERN_INFO "%s: Link changed: ", dev->name);
-			if (mii_advertise & ADVERTISE_100FULL)
+			if (mii_advertise & ADVERTISE_100FULL) {
+				np->speed = 100;
 				printk ("100Mbps, full duplex\n");
-			else if (mii_advertise & ADVERTISE_100HALF)
+			} else if (mii_advertise & ADVERTISE_100HALF) {
+				np->speed = 100;
 				printk ("100Mbps, half duplex\n");
-			else if (mii_advertise & ADVERTISE_10FULL)
+			} else if (mii_advertise & ADVERTISE_10FULL) {
+				np->speed = 10;
 				printk ("10Mbps, full duplex\n");
-			else if (mii_advertise & ADVERTISE_10HALF)
+			} else if (mii_advertise & ADVERTISE_10HALF) {
+				np->speed = 10;
 				printk ("10Mbps, half duplex\n");
-			else
+			} else
 				printk ("\n");
 
 		} else {
 			mii_ctl = mdio_read (dev, np->phys[0], MII_BMCR);
 			speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
+			np->speed = speed;
 			printk (KERN_INFO "%s: Link changed: %dMbps ,",
 				dev->name, speed);
 			printk ("%s duplex.\n", (mii_ctl & BMCR_FULLDPLX) ?
 				"full" : "half");
 		}
 		check_duplex (dev);
+		if (np->flowctrl == 0)
+			writew(readw(ioaddr + MACCtrl0) & ~EnbFlowCtrl,
+				ioaddr + MACCtrl0);
 	}
 	if (intr_status & StatsMax) {
 		get_stats(dev);
@@ -1294,11 +1429,16 @@
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 	} else if (dev->mc_count) {
 		struct dev_mc_list *mclist;
-		memset(mc_filter, 0, sizeof(mc_filter));
+		int bit;
+		int index;
+		int crc;
+		memset (mc_filter, 0, sizeof (mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next) {
-			set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f,
-					mc_filter);
+		     i++, mclist = mclist->next) {
+			crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
+			for (index=0, bit=0; bit < 6; bit++, crc <<= 1)
+				if (crc & 0x80000000) index |= 1 << bit;
+			mc_filter[index/16] |= (1 << (index % 16));
 		}
 		rx_mode = AcceptBroadcast | AcceptMultiHash | AcceptMyPhys;
 	} else {
@@ -1314,24 +1454,80 @@
 {
 	struct netdev_private *np = dev->priv;
 	u32 ethcmd;
-		
+
 	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
 		return -EFAULT;
 
         switch (ethcmd) {
-        case ETHTOOL_GDRVINFO: {
-		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-		strcpy(info.driver, DRV_NAME);
-		strcpy(info.version, DRV_VERSION);
-		strcpy(info.bus_info, np->pci_dev->slot_name);
-		if (copy_to_user(useraddr, &info, sizeof(info)))
-			return -EFAULT;
-		return 0;
-	}
+		/* get constant driver settings/info */
+        	case ETHTOOL_GDRVINFO: {
+			struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+			strcpy(info.driver, DRV_NAME);
+			strcpy(info.version, DRV_VERSION);
+			strcpy(info.bus_info, np->pci_dev->slot_name);
+			memset(&info.fw_version, 0, sizeof(info.fw_version));
+			if (copy_to_user(useraddr, &info, sizeof(info)))
+				return -EFAULT;
+			return 0;
+		}
+
+		/* get media settings */
+		case ETHTOOL_GSET: {
+			struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+			spin_lock_irq(&np->lock);
+			mii_ethtool_gset(&np->mii_if, &ecmd);
+			spin_unlock_irq(&np->lock);
+			if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+				return -EFAULT;
+			return 0;
+		}
+		/* set media settings */
+		case ETHTOOL_SSET: {
+			int r;
+			struct ethtool_cmd ecmd;
+			if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+				return -EFAULT;
+			spin_lock_irq(&np->lock);
+			r = mii_ethtool_sset(&np->mii_if, &ecmd);
+			spin_unlock_irq(&np->lock);
+			return r;
+		}
+
+		/* restart autonegotiation */
+		case ETHTOOL_NWAY_RST: {
+			return mii_nway_restart(&np->mii_if);
+		}
+
+		/* get link status */
+		case ETHTOOL_GLINK: {
+			struct ethtool_value edata = {ETHTOOL_GLINK};
+			edata.data = mii_link_ok(&np->mii_if);
+			if (copy_to_user(useraddr, &edata, sizeof(edata)))
+				return -EFAULT;
+			return 0;
+		}
+
+		/* get message-level */
+		case ETHTOOL_GMSGLVL: {
+			struct ethtool_value edata = {ETHTOOL_GMSGLVL};
+			edata.data = np->msg_enable;
+			if (copy_to_user(useraddr, &edata, sizeof(edata)))
+				return -EFAULT;
+			return 0;
+		}
+		/* set message-level */
+		case ETHTOOL_SMSGLVL: {
+			struct ethtool_value edata;
+			if (copy_from_user(&edata, useraddr, sizeof(edata)))
+				return -EFAULT;
+			np->msg_enable = edata.data;
+			return 0;
+		}
+
+		default:
+		return -EOPNOTSUPP;
 
         }
-	
-	return -EOPNOTSUPP;
 }
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1342,17 +1538,14 @@
 	case SIOCETHTOOL:
 		return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
 	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
-	case SIOCDEVPRIVATE:		/* for binary compat, remove in 2.5 */
 		data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f;
 		/* Fall Through */
 
 	case SIOCGMIIREG:		/* Read MII PHY register. */
-	case SIOCDEVPRIVATE+1:		/* for binary compat, remove in 2.5 */
 		data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
 		return 0;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-	case SIOCDEVPRIVATE+2:		/* for binary compat, remove in 2.5 */
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 		mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
@@ -1371,7 +1564,7 @@
 
 	netif_stop_queue(dev);
 
-	if (debug > 1) {
+	if (netif_msg_ifdown(np)) {
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %2.2x "
 			   "Rx %4.4x Int %2.2x.\n",
 			   dev->name, readb(ioaddr + TxStatus),
@@ -1387,7 +1580,7 @@
 	writew(TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl1);
 
 #ifdef __i386__
-	if (debug > 2) {
+	if (netif_msg_hw(np)) {
 		printk("\n"KERN_DEBUG"  Tx ring at %8.8x:\n",
 			   (int)(np->tx_ring_dma));
 		for (i = 0; i < TX_RING_SIZE; i++)
@@ -1414,8 +1607,8 @@
 		np->rx_ring[i].frag[0].addr = 0xBADF00D0; /* An invalid address. */
 		skb = np->rx_skbuff[i];
 		if (skb) {
-			pci_unmap_single(np->pci_dev, 
-				np->rx_ring[i].frag[0].addr, np->rx_buf_sz, 
+			pci_unmap_single(np->pci_dev,
+				np->rx_ring[i].frag[0].addr, np->rx_buf_sz,
 				PCI_DMA_FROMDEVICE);
 			dev_kfree_skb(skb);
 			np->rx_skbuff[i] = 0;
@@ -1424,7 +1617,7 @@
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		skb = np->tx_skbuff[i];
 		if (skb) {
-			pci_unmap_single(np->pci_dev, 
+			pci_unmap_single(np->pci_dev,
 				np->tx_ring[i].frag[0].addr, skb->len,
 				PCI_DMA_TODEVICE);
 			dev_kfree_skb(skb);
@@ -1438,15 +1631,15 @@
 static void __devexit sundance_remove1 (struct pci_dev *pdev)
 {
 	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;
 
 		unregister_netdev(dev);
-        	pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, 
+        	pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring,
 			np->rx_ring_dma);
-	        pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, 
+	        pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring,
 			np->tx_ring_dma);
 		pci_release_regions(pdev);
 #ifndef USE_IO_OPS
@@ -1480,3 +1673,5 @@
 
 module_init(sundance_init);
 module_exit(sundance_exit);
+
+
diff -urN linux-2.4.20-pre7/drivers/net/tg3.c linux-2.4.20-pre8/drivers/net/tg3.c
--- linux-2.4.20-pre7/drivers/net/tg3.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/tg3.c	Wed Sep 25 18:21:51 2002
@@ -149,6 +149,8 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5703,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5704,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702FE,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5702X,
@@ -235,6 +237,39 @@
 	tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
 }
 
+static inline void tg3_mask_ints(struct tg3 *tp)
+{
+	tw32(TG3PCI_MISC_HOST_CTRL,
+	     (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
+}
+
+static inline void tg3_unmask_ints(struct tg3 *tp)
+{
+	tw32(TG3PCI_MISC_HOST_CTRL,
+	     (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
+	if (tp->hw_status->status & SD_STATUS_UPDATED) {
+		tw32(GRC_LOCAL_CTRL,
+		     tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+	}
+}
+
+static void tg3_switch_clocks(struct tg3 *tp)
+{
+	if (tr32(TG3PCI_CLOCK_CTRL) & CLOCK_CTRL_44MHZ_CORE) {
+		tw32(TG3PCI_CLOCK_CTRL,
+		     (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK));
+		tr32(TG3PCI_CLOCK_CTRL);
+		udelay(40);
+		tw32(TG3PCI_CLOCK_CTRL,
+		     (CLOCK_CTRL_ALTCLK));
+		tr32(TG3PCI_CLOCK_CTRL);
+		udelay(40);
+	}
+	tw32(TG3PCI_CLOCK_CTRL, 0);
+	tr32(TG3PCI_CLOCK_CTRL);
+	udelay(40);
+}
+
 #define PHY_BUSY_LOOPS	5000
 
 static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
@@ -407,7 +442,6 @@
 		tr32(GRC_LOCAL_CTRL);
 		udelay(100);
 
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
 		return 0;
 
 	case 1:
@@ -442,10 +476,12 @@
 		tp->link_config.orig_autoneg = tp->link_config.autoneg;
 	}
 
-	tp->link_config.speed = SPEED_10;
-	tp->link_config.duplex = DUPLEX_HALF;
-	tp->link_config.autoneg = AUTONEG_ENABLE;
-	tg3_setup_phy(tp);
+	if (tp->phy_id != PHY_ID_SERDES) {
+		tp->link_config.speed = SPEED_10;
+		tp->link_config.duplex = DUPLEX_HALF;
+		tp->link_config.autoneg = AUTONEG_ENABLE;
+		tg3_setup_phy(tp);
+	}
 
 	tg3_halt(tp);
 
@@ -454,14 +490,19 @@
 	if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
 		u32 mac_mode;
 
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
-		udelay(40);
+		if (tp->phy_id != PHY_ID_SERDES) {
+			tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
+			udelay(40);
 
-		mac_mode = MAC_MODE_PORT_MODE_MII;
+			mac_mode = MAC_MODE_PORT_MODE_MII;
+
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 ||
+			    !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB))
+				mac_mode |= MAC_MODE_LINK_POLARITY;
+		} else {
+			mac_mode = MAC_MODE_PORT_MODE_TBI;
+		}
 
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 ||
-		    !(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB))
-			mac_mode |= MAC_MODE_LINK_POLARITY;
 
 		if (((power_caps & PCI_PM_CAP_PME_D3cold) &&
 		     (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)))
@@ -469,7 +510,7 @@
 
 		tw32(MAC_MODE, mac_mode);
 		tr32(MAC_MODE);
-		udelay(40);
+		udelay(100);
 
 		tw32(MAC_RX_MODE, RX_MODE_ENABLE);
 		tr32(MAC_RX_MODE);
@@ -873,6 +914,8 @@
 	tr32(MAC_MI_MODE);
 	udelay(40);
 
+	tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
+
 	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
 		tg3_readphy(tp, MII_BMSR, &bmsr);
 		tg3_readphy(tp, MII_BMSR, &bmsr);
@@ -1030,16 +1073,15 @@
 		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
 
 	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
-		if (current_link_up == 1)
-			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
-		tw32(MAC_LED_CTRL, LED_CTRL_PHY_MODE_1);
-	} else {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
 		if ((tp->led_mode == led_mode_link10) ||
 		    (current_link_up == 1 &&
 		     tp->link_config.active_speed == SPEED_10))
 			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+	} else {
+		if (current_link_up == 1)
+			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+		tw32(MAC_LED_CTRL, LED_CTRL_PHY_MODE_1);
 	}
 
 	/* ??? Without this setting Netgear GA302T PHY does not
@@ -1661,7 +1703,7 @@
 	u32 sw_idx = tp->tx_cons;
 
 	while (sw_idx != hw_idx) {
-		struct ring_info *ri = &tp->tx_buffers[sw_idx];
+		struct tx_ring_info *ri = &tp->tx_buffers[sw_idx];
 		struct sk_buff *skb = ri->skb;
 		int i;
 
@@ -2065,7 +2107,7 @@
 
 	if (done) {
 		netif_rx_complete(netdev);
-		tg3_enable_ints(tp);
+		tg3_unmask_ints(tp);
 	}
 
 	spin_unlock_irq(&tp->lock);
@@ -2092,11 +2134,10 @@
 		return;
 
 	if (netif_rx_schedule_prep(dev)) {
-		/* NOTE: This write is posted by the readback of
+		/* NOTE: These writes are posted by the readback of
 		 *       the mailbox register done by our caller.
 		 */
-		tw32(TG3PCI_MISC_HOST_CTRL,
-		     (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
+		tg3_mask_ints(tp);
 		__netif_rx_schedule(dev);
 	} else {
 		printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
@@ -2109,8 +2150,9 @@
 	struct net_device *dev = dev_id;
 	struct tg3 *tp = dev->priv;
 	struct tg3_hw_status *sblk = tp->hw_status;
+	unsigned long flags;
 
-	spin_lock(&tp->lock);
+	spin_lock_irqsave(&tp->lock, flags);
 
 	if (sblk->status & SD_STATUS_UPDATED) {
 		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
@@ -2124,7 +2166,7 @@
 		tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
 	}
 
-	spin_unlock(&tp->lock);
+	spin_unlock_irqrestore(&tp->lock, flags);
 }
 
 static void tg3_init_rings(struct tg3 *);
@@ -2286,6 +2328,7 @@
 		txd->len_flags = (len << TXD_LEN_SHIFT) | flags;
 		txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
 	} else {
+		struct tx_ring_info *txr = &tp->tx_buffers[entry];
 		unsigned long txd;
 
 		txd = (tp->regs +
@@ -2301,7 +2344,10 @@
 		writel(((u64) mapping & 0xffffffff),
 		       txd + TXD_ADDR + TG3_64BIT_REG_LOW);
 		writel(len << TXD_LEN_SHIFT | flags, txd + TXD_LEN_FLAGS);
-		writel(vlan_tag << TXD_VLAN_TAG_SHIFT, txd + TXD_VLAN_TAG);
+		if (txr->prev_vlan_tag != vlan_tag) {
+			writel(vlan_tag << TXD_VLAN_TAG_SHIFT, txd + TXD_VLAN_TAG);
+			txr->prev_vlan_tag = vlan_tag;
+		}
 	}
 }
 
@@ -2684,7 +2730,7 @@
 	}
 
 	for (i = 0; i < TG3_TX_RING_SIZE; ) {
-		struct ring_info *txp;
+		struct tx_ring_info *txp;
 		struct sk_buff *skb;
 		int j;
 
@@ -2751,6 +2797,8 @@
 			writel(0, start);
 			start += 4;
 		}
+		for (i = 0; i < TG3_TX_RING_SIZE; i++)
+			tp->tx_buffers[i].prev_vlan_tag = 0;
 	}
 
 	/* Initialize invariants of the rings, we only set this
@@ -2873,12 +2921,13 @@
  */
 static int tg3_alloc_consistent(struct tg3 *tp)
 {
-	tp->rx_std_buffers = kmalloc(sizeof(struct ring_info) *
-				     (TG3_RX_RING_SIZE +
+	tp->rx_std_buffers = kmalloc((sizeof(struct ring_info) *
+				      (TG3_RX_RING_SIZE +
 #if TG3_MINI_RING_WORKS
-				      TG3_RX_MINI_RING_SIZE +
+				       TG3_RX_MINI_RING_SIZE +
 #endif
-				      TG3_RX_JUMBO_RING_SIZE +
+				       TG3_RX_JUMBO_RING_SIZE)) +
+				     (sizeof(struct tx_ring_info) *
 				      TG3_TX_RING_SIZE),
 				     GFP_KERNEL);
 	if (!tp->rx_std_buffers)
@@ -2889,14 +2938,16 @@
 	       (sizeof(struct ring_info) *
 		(TG3_RX_RING_SIZE +
 		 TG3_RX_MINI_RING_SIZE +
-		 TG3_RX_JUMBO_RING_SIZE +
-		 TG3_TX_RING_SIZE)));
+		 TG3_RX_JUMBO_RING_SIZE)) +
+	       (sizeof(struct tx_ring_info) *
+		TG3_TX_RING_SIZE));
 #else
 	memset(tp->rx_std_buffers, 0,
 	       (sizeof(struct ring_info) *
 		(TG3_RX_RING_SIZE +
-		 TG3_RX_JUMBO_RING_SIZE +
-		 TG3_TX_RING_SIZE)));
+		 TG3_RX_JUMBO_RING_SIZE)) +
+	       (sizeof(struct tx_ring_info) *
+		TG3_TX_RING_SIZE));
 #endif
 
 #if TG3_MINI_RING_WORKS
@@ -2905,7 +2956,8 @@
 #else
 	tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE];
 #endif
-	tp->tx_buffers = &tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE];
+	tp->tx_buffers = (struct tx_ring_info *)
+		&tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE];
 
 	tp->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
 					  &tp->rx_std_mapping);
@@ -3065,7 +3117,6 @@
 /* tp->lock is held. */
 static void tg3_chip_reset(struct tg3 *tp)
 {
-	unsigned long flags;
 	u32 val;
 
 	/* Force NVRAM to settle.
@@ -3083,15 +3134,14 @@
 		}
 	}
 
-	/* Use indirect register writes for this so that there are
-	 * no PCI write posting issues.
+	tw32(GRC_MISC_CFG, GRC_MISC_CFG_CORECLK_RESET);
+
+	/* Flush PCI posted writes.  The normal MMIO registers
+	 * are inaccessible at this time so this is the only
+	 * way to make this reliably.  I tried to use indirect
+	 * register read/write but this upset some 5701 variants.
 	 */
-	spin_lock_irqsave(&tp->indirect_lock, flags);
-	pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR,
-			       GRC_MISC_CFG);
-	pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA,
-			       GRC_MISC_CFG_CORECLK_RESET);
-	spin_unlock_irqrestore(&tp->indirect_lock, flags);
+	pci_read_config_dword(tp->pdev, PCI_COMMAND, &val);
 
 	udelay(40);
 	udelay(40);
@@ -3102,9 +3152,11 @@
 			       tp->misc_host_ctrl);
 
 	/* Set MAX PCI retry to zero. */
-	pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE,
-			       (PCISTATE_ROM_ENABLE |
-				PCISTATE_ROM_RETRY_ENABLE));
+	val = (PCISTATE_ROM_ENABLE | PCISTATE_ROM_RETRY_ENABLE);
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
+	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE))
+		val |= PCISTATE_RETRY_SAME_DMA;
+	pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);
 
 	pci_restore_state(tp->pdev, tp->pci_cfg_state);
 
@@ -3119,11 +3171,33 @@
 }
 
 /* tp->lock is held. */
+static void tg3_stop_fw(struct tg3 *tp)
+{
+	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+		u32 val;
+		int i;
+
+		tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
+		val = tr32(GRC_RX_CPU_EVENT);
+		val |= (1 << 14);
+		tw32(GRC_RX_CPU_EVENT, val);
+
+		/* Wait for RX cpu to ACK the event.  */
+		for (i = 0; i < 100; i++) {
+			if (!(tr32(GRC_RX_CPU_EVENT) & (1 << 14)))
+				break;
+			udelay(1);
+		}
+	}
+}
+
+/* tp->lock is held. */
 static int tg3_halt(struct tg3 *tp)
 {
 	u32 val;
 	int i;
 
+	tg3_stop_fw(tp);
 	tg3_abort_hw(tp);
 	tg3_chip_reset(tp);
 	tg3_write_mem(tp,
@@ -3143,6 +3217,17 @@
 		return -ENODEV;
 	}
 
+	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+		if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)
+			tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+				      DRV_STATE_WOL);
+		else
+			tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+				      DRV_STATE_UNLOAD);
+	} else
+		tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+			      DRV_STATE_SUSPEND);
+
 	return 0;
 }
 
@@ -3840,6 +3925,8 @@
 
 	tg3_disable_ints(tp);
 
+	tg3_stop_fw(tp);
+
 	if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) {
 		err = tg3_abort_hw(tp);
 		if (err)
@@ -3874,6 +3961,13 @@
 		return -ENODEV;
 	}
 
+	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+		tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+			      DRV_STATE_START);
+	else
+		tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
+			      DRV_STATE_SUSPEND);
+
 	/* This works around an issue with Athlon chipsets on
 	 * B3 tigon3 silicon.  This bit has no effect on any
 	 * other revision.
@@ -3883,6 +3977,13 @@
 	tw32(TG3PCI_CLOCK_CTRL, val);
 	tr32(TG3PCI_CLOCK_CTRL);
 
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
+	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
+		val = tr32(TG3PCI_PCISTATE);
+		val |= PCISTATE_RETRY_SAME_DMA;
+		tw32(TG3PCI_PCISTATE, val);
+	}
+
 	/* Clear statistics/status block in chip, and status block in ram. */
 	for (i = NIC_SRAM_STATS_BLK;
 	     i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
@@ -3920,7 +4021,10 @@
 
 	/* Initialize MBUF/DESC pool. */
 	tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);
-	tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
+		tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64);
+	else
+		tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96);
 	tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);
 	tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);
 
@@ -4186,11 +4290,25 @@
 	tr32(WDMAC_MODE);
 	udelay(40);
 
-	tw32(RDMAC_MODE, (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB |
-			  RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB |
-			  RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
-			  RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
-			  RDMAC_MODE_LNGREAD_ENAB));
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
+	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
+		val = tr32(TG3PCI_X_CAPS);
+		val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK);
+		val |= (PCIX_CAPS_MAX_BURST_5704 << PCIX_CAPS_BURST_SHIFT);
+		if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
+			val |= (tp->split_mode_max_reqs <<
+				PCIX_CAPS_SPLIT_SHIFT);
+		tw32(TG3PCI_X_CAPS, val);
+	}
+
+	val = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB |
+	       RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB |
+	       RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
+	       RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
+	       RDMAC_MODE_LNGREAD_ENAB);
+	if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
+		val |= RDMAC_MODE_SPLIT_ENABLE;
+	tw32(RDMAC_MODE, val);
 	tr32(RDMAC_MODE);
 	udelay(40);
 
@@ -4305,6 +4423,8 @@
 	if (err)
 		goto out;
 
+	tg3_switch_clocks(tp);
+
 	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
 
 	err = tg3_reset_hw(tp);
@@ -4383,6 +4503,21 @@
 		tp->timer_counter = tp->timer_multiplier;
 	}
 
+	/* Heartbeat is only sent once every 120 seconds.  */
+	if (!--tp->asf_counter) {
+		if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+			u32 val;
+
+			tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_ALIVE);
+			tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
+			tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 3);
+			val = tr32(GRC_RX_CPU_EVENT);
+			val |= (1 << 14);
+			tw32(GRC_RX_CPU_EVENT, val);
+		}
+		tp->asf_counter = tp->asf_multiplier;
+	}
+
 	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
@@ -4431,6 +4566,7 @@
 	} else {
 		tp->timer_offset = HZ / 10;
 		tp->timer_counter = tp->timer_multiplier = 10;
+		tp->asf_counter = tp->asf_multiplier = (10 * 120);
 
 		init_timer(&tp->timer);
 		tp->timer.expires = jiffies + tp->timer_offset;
@@ -4883,10 +5019,11 @@
 		rx_mode |= RX_MODE_KEEP_VLAN_TAG;
 #else
 	/* By definition, VLAN is disabled always in this
-	* case.
-	*/
+	 * case.
+	 */
 	rx_mode |= RX_MODE_KEEP_VLAN_TAG;
-#endif 
+#endif
+
 	if (dev->flags & IFF_PROMISC) {
 		/* Promiscuous mode. */
 		rx_mode |= RX_MODE_PROMISC;
@@ -5162,6 +5299,11 @@
 			return -EFAULT;
 		if (wol.wolopts & ~WAKE_MAGIC)
 			return -EINVAL;
+		if ((wol.wolopts & WAKE_MAGIC) &&
+		    tp->phy_id == PHY_ID_SERDES &&
+		    !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP))
+			return -EINVAL;
+
 		spin_lock_irq(&tp->lock);
 		if (wol.wolopts & WAKE_MAGIC)
 			tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
@@ -5693,6 +5835,11 @@
 		     tp->pci_chip_rev_id == CHIPREV_ID_5703_A2) &&
 		    (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP))
 			tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
+
+		if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE)
+			tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
+		if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)
+			tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP;
 	}
 
 	/* Now read the physical PHY_ID from the chip and verify
@@ -5760,6 +5907,11 @@
 		tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
 	}
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+		tg3_writephy(tp, 0x1c, 0x8d68);
+		tg3_writephy(tp, 0x1c, 0x8d68);
+	}
+
 	/* Enable Ethernet@WireSpeed */
 	tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007);
 	tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
@@ -6026,8 +6178,9 @@
 	/* Initialize data/descriptor byte/word swapping. */
 	tw32(GRC_MODE, tp->grc_mode);
 
-	/* Clear these out for sanity. */
-	tw32(TG3PCI_CLOCK_CTRL, 0);
+	tg3_switch_clocks(tp);
+
+	/* Clear this out for sanity. */
 	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
 
 	pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
@@ -6075,9 +6228,16 @@
 	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5702FE &&
 	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703 &&
 	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5703S &&
+	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_5704 &&
 	    grc_misc_cfg != GRC_MISC_CFG_BOARD_ID_AC91002A1)
 		return -ENODEV;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
+	    grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) {
+		tp->tg3_flags |= TG3_FLAG_SPLIT_MODE;
+		tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ;
+	}
+
 	/* ROFL, you should see Broadcom's driver code implementing
 	 * this, stuff like "if (a || b)" where a and b are always
 	 * mutually exclusive.  DaveM finds like 6 bugs today, hello!
@@ -6167,7 +6327,12 @@
 static int __devinit tg3_get_device_address(struct tg3 *tp)
 {
 	struct net_device *dev = tp->dev;
-	u32 hi, lo;
+	u32 hi, lo, mac_offset;
+
+	if (PCI_FUNC(tp->pdev->devfn) == 0)
+		mac_offset = 0x7c;
+	else
+		mac_offset = 0xcc;
 
 	/* First try to get it from MAC address mailbox. */
 	tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi);
@@ -6182,8 +6347,8 @@
 		dev->dev_addr[5] = (lo >>  0) & 0xff;
 	}
 	/* Next, try NVRAM. */
-	else if (!tg3_nvram_read(tp, 0x7c, &hi) &&
-		 !tg3_nvram_read(tp, 0x80, &lo)) {
+	else if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
+		 !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
 		dev->dev_addr[0] = ((hi >> 16) & 0xff);
 		dev->dev_addr[1] = ((hi >> 24) & 0xff);
 		dev->dev_addr[2] = ((lo >>  0) & 0xff);
@@ -6311,16 +6476,26 @@
 			(0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
 			(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
 	} else {
-		tp->dma_rwctrl =
-			(0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
-			(0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
-			(0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
-			(0x3 << DMA_RWCTRL_READ_WATER_SHIFT) |
-			(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
+			tp->dma_rwctrl =
+				(0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
+				(0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
+				(0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
+				(0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
+				(0x00 << DMA_RWCTRL_MIN_DMA_SHIFT);
+		else
+			tp->dma_rwctrl =
+				(0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
+				(0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
+				(0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
+				(0x3 << DMA_RWCTRL_READ_WATER_SHIFT) |
+				(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
 
 		/* Wheee, some more chip bugs... */
 		if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1 ||
-		    tp->pci_chip_rev_id == CHIPREV_ID_5703_A2)
+		    tp->pci_chip_rev_id == CHIPREV_ID_5703_A2 ||
+		    tp->pci_chip_rev_id == CHIPREV_ID_5703_A3 ||
+		    tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
 			tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
 	}
 
@@ -6495,6 +6670,7 @@
 	case PHY_ID_BCM5411:	return "5411";
 	case PHY_ID_BCM5701:	return "5701";
 	case PHY_ID_BCM5703:	return "5703";
+	case PHY_ID_BCM5704:	return "5704";
 	case PHY_ID_BCM8002:	return "8002";
 	case PHY_ID_SERDES:	return "serdes";
 	default:		return "unknown";
@@ -6810,12 +6986,12 @@
 }
 
 static struct pci_driver tg3_driver = {
-	name:		DRV_MODULE_NAME,
-	id_table:	tg3_pci_tbl,
-	probe:		tg3_init_one,
-	remove:		__devexit_p(tg3_remove_one),
-	suspend:	tg3_suspend,
-	resume:		tg3_resume
+	.name		= DRV_MODULE_NAME,
+	.id_table	= tg3_pci_tbl,
+	.probe		= tg3_init_one,
+	.remove		= __devexit_p(tg3_remove_one),
+	.suspend	= tg3_suspend,
+	.resume		= tg3_resume
 };
 
 static int __init tg3_init(void)
diff -urN linux-2.4.20-pre7/drivers/net/tg3.h linux-2.4.20-pre8/drivers/net/tg3.h
--- linux-2.4.20-pre7/drivers/net/tg3.h	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/tg3.h	Wed Sep 25 18:21:51 2002
@@ -58,6 +58,11 @@
 #define TG3PCI_MAX_LAT			0x0000003f
 #define TG3PCI_X_CAPS			0x00000040
 #define  PCIX_CAPS_RELAXED_ORDERING	 0x00020000
+#define  PCIX_CAPS_SPLIT_MASK		 0x00700000
+#define  PCIX_CAPS_SPLIT_SHIFT		 20
+#define  PCIX_CAPS_BURST_MASK		 0x000c0000
+#define  PCIX_CAPS_BURST_SHIFT		 18
+#define  PCIX_CAPS_MAX_BURST_5704	 2
 #define TG3PCI_PM_CAP_PTR		0x00000041
 #define TG3PCI_X_COMMAND		0x00000042
 #define TG3PCI_X_STATUS			0x00000044
@@ -109,10 +114,13 @@
 #define  CHIPREV_ID_5703_A0		 0x1000
 #define  CHIPREV_ID_5703_A1		 0x1001
 #define  CHIPREV_ID_5703_A2		 0x1002
+#define  CHIPREV_ID_5703_A3		 0x1003
+#define  CHIPREV_ID_5704_A0		 0x2000
 #define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700			 0x07
 #define   ASIC_REV_5701			 0x00
 #define   ASIC_REV_5703			 0x01
+#define   ASIC_REV_5704			 0x02
 #define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX		 0x70
 #define   CHIPREV_5700_BX		 0x71
@@ -165,6 +173,7 @@
 #define  PCISTATE_ROM_ENABLE		 0x00000020
 #define  PCISTATE_ROM_RETRY_ENABLE	 0x00000040
 #define  PCISTATE_FLAT_VIEW		 0x00000100
+#define  PCISTATE_RETRY_SAME_DMA	 0x00002000
 #define TG3PCI_CLOCK_CTRL		0x00000074
 #define  CLOCK_CTRL_CORECLK_DISABLE	 0x00000200
 #define  CLOCK_CTRL_RXCLK_DISABLE	 0x00000400
@@ -843,6 +852,8 @@
 #define  RDMAC_MODE_FIFOURUN_ENAB	 0x00000080
 #define  RDMAC_MODE_FIFOOREAD_ENAB	 0x00000100
 #define  RDMAC_MODE_LNGREAD_ENAB	 0x00000200
+#define  RDMAC_MODE_SPLIT_ENABLE	 0x00000800
+#define  RDMAC_MODE_SPLIT_RESET		 0x00001000
 #define RDMAC_STATUS			0x00004804
 #define  RDMAC_STATUS_TGTABORT		 0x00000004
 #define  RDMAC_STATUS_MSTABORT		 0x00000008
@@ -1126,6 +1137,8 @@
 #define  GRC_MISC_CFG_BOARD_ID_5702FE	0x00004000
 #define  GRC_MISC_CFG_BOARD_ID_5703	0x00000000
 #define  GRC_MISC_CFG_BOARD_ID_5703S	0x00002000
+#define  GRC_MISC_CFG_BOARD_ID_5704	0x00000000
+#define  GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000
 #define  GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
 #define GRC_LOCAL_CTRL			0x00006808
 #define  GRC_LCLCTRL_INT_ACTIVE		0x00000001
@@ -1261,6 +1274,7 @@
 #define  NIC_SRAM_DATA_CFG_WOL_ENABLE		 0x00000040
 #define  NIC_SRAM_DATA_CFG_ASF_ENABLE		 0x00000080
 #define  NIC_SRAM_DATA_CFG_EEPROM_WP		 0x00000100
+#define  NIC_SRAM_DATA_CFG_FIBER_WOL		 0x00004000
 
 #define NIC_SRAM_DATA_PHY_ID		0x00000b74
 #define  NIC_SRAM_DATA_PHY_ID1_MASK	 0xffff0000
@@ -1297,7 +1311,8 @@
 #define NIC_SRAM_RX_BUFFER_DESC		0x00006000 /* 256 entries */
 #define NIC_SRAM_RX_JUMBO_BUFFER_DESC	0x00007000 /* 256 entries */
 #define NIC_SRAM_MBUF_POOL_BASE		0x00008000
-#define  NIC_SRAM_MBUF_POOL_SIZE	 0x00018000
+#define  NIC_SRAM_MBUF_POOL_SIZE96	 0x00018000
+#define  NIC_SRAM_MBUF_POOL_SIZE64	 0x00010000
 
 /* Currently this is fixed. */
 #define PHY_ADDR		0x01
@@ -1666,6 +1681,12 @@
 	DECLARE_PCI_UNMAP_ADDR(mapping)
 };
 
+struct tx_ring_info {
+	struct sk_buff			*skb;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+	u32				prev_vlan_tag;
+};
+
 struct tg3_config_info {
 	u32				flags;
 };
@@ -1743,6 +1764,7 @@
 #define TG3_FLAG_RX_CHECKSUMS		0x00000004
 #define TG3_FLAG_USE_LINKCHG_REG	0x00000008
 #define TG3_FLAG_USE_MI_INTERRUPT	0x00000010
+#define TG3_FLAG_ENABLE_ASF		0x00000020
 #define TG3_FLAG_POLL_SERDES		0x00000080
 #define TG3_FLAG_MBOX_WRITE_REORDER	0x00000100
 #define TG3_FLAG_PCIX_TARGET_HWBUG	0x00000200
@@ -1758,7 +1780,7 @@
 #define TG3_FLAG_PCI_32BIT		0x00080000
 #define TG3_FLAG_NO_TX_PSEUDO_CSUM	0x00100000
 #define TG3_FLAG_NO_RX_PSEUDO_CSUM	0x00200000
-#define TG3_FLAG_AUTONEG_DISABLE	0x00400000
+#define TG3_FLAG_SERDES_WOL_CAP		0x00400000
 #define TG3_FLAG_JUMBO_ENABLE		0x00800000
 #define TG3_FLAG_10_100_ONLY		0x01000000
 #define TG3_FLAG_PAUSE_AUTONEG		0x02000000
@@ -1766,14 +1788,20 @@
 #define TG3_FLAG_PAUSE_TX		0x08000000
 #define TG3_FLAG_BROKEN_CHECKSUMS	0x10000000
 #define TG3_FLAG_GOT_SERDES_FLOWCTL	0x20000000
+#define TG3_FLAG_SPLIT_MODE		0x40000000
 #define TG3_FLAG_INIT_COMPLETE		0x80000000
 
 	u32				msg_enable;
 
+	u32				split_mode_max_reqs;
+#define SPLIT_MODE_5704_MAX_REQ		3
+
 	struct timer_list		timer;
 	u16				timer_counter;
 	u16				timer_multiplier;
 	u32				timer_offset;
+	u16				asf_counter;
+	u16				asf_multiplier;
 
 	struct tg3_link_config		link_config;
 	struct tg3_bufmgr_config	bufmgr_config;
@@ -1814,6 +1842,7 @@
 #define PHY_ID_BCM5411			0x60008070
 #define PHY_ID_BCM5701			0x60008110
 #define PHY_ID_BCM5703			0x60008160
+#define PHY_ID_BCM5704			0x60008190
 #define PHY_ID_BCM8002			0x60010140
 #define PHY_ID_SERDES			0xfeedbee0
 #define PHY_ID_INVALID			0xffffffff
@@ -1833,7 +1862,7 @@
 #define KNOWN_PHY_ID(X)		\
 	((X) == PHY_ID_BCM5400 || (X) == PHY_ID_BCM5401 || \
 	 (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
-	 (X) == PHY_ID_BCM5703 ||			   \
+	 (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
 	 (X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES)
 
 	unsigned long			regs;
@@ -1860,7 +1889,7 @@
 
 	/* TX descs are only used if TG3_FLAG_HOST_TXDS is set. */
 	struct tg3_tx_buffer_desc	*tx_ring;
-	struct ring_info		*tx_buffers;
+	struct tx_ring_info		*tx_buffers;
 	dma_addr_t			tx_desc_mapping;
 
 	struct tg3_hw_status		*hw_status;
diff -urN linux-2.4.20-pre7/drivers/net/tulip/ChangeLog linux-2.4.20-pre8/drivers/net/tulip/ChangeLog
--- linux-2.4.20-pre7/drivers/net/tulip/ChangeLog	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/net/tulip/ChangeLog	Wed Sep 25 18:21:51 2002
@@ -1,3 +1,14 @@
+2002-09-18  Ryan Bradetich  <rbradetich@uswest.net>
+
+	tulip hppa support:
+	* eeprom.c (tulip_build_fake_mediatable): new function
+	(tulip_parse_eeprom): call it, when no media table
+	* interrupt.c (phy_interrupt): new function
+	(tulip_interrupt): call it, before checking for no-irq-work
+	* tulip.c: add HAS_PHY_IRQ chip feature flag.
+	add csr12_shadow to tulip_private struct, only for hppa currently.
+	* tulip_core (tulip_init_one): support hppa wonky eeproms
+
 2002-05-11  Juan Quintela  <quintela@mandrakesoft.com>
 
 	* 21142.c (t21142_lnk_change): Revert earlier patch
diff -urN linux-2.4.20-pre7/drivers/net/tulip/eeprom.c linux-2.4.20-pre8/drivers/net/tulip/eeprom.c
--- linux-2.4.20-pre7/drivers/net/tulip/eeprom.c	Tue Oct  2 09:00:58 2001
+++ linux-2.4.20-pre8/drivers/net/tulip/eeprom.c	Wed Sep 25 18:21:51 2002
@@ -75,6 +75,61 @@
 };
 
 
+/**
+ * tulip_build_fake_mediatable - Build a fake mediatable entry.
+ * @tp: Ptr to the tulip private data.
+ *
+ * Some cards like the 3x5 HSC cards (J3514A) do not have a standard 
+ * srom and can not be handled under the fixup routine.  These cards
+ * still need a valid mediatable entry for correct csr12 setup and 
+ * mii handling.
+ * 
+ * Since this is currently a parisc-linux specific function, the
+ * #ifdef __hppa__ should completely optimize this function away for
+ * non-parisc hardware.
+ */
+static void __devinit tulip_build_fake_mediatable(struct tulip_private *tp)
+{
+#ifdef __hppa__
+	unsigned char *ee_data = tp->eeprom;
+
+	if (ee_data[0] == 0x3c && ee_data[1] == 0x10 && 
+		(ee_data[2] == 0x63 || ee_data[2] == 0x61) && ee_data[3] == 0x10) {
+
+		static unsigned char leafdata[] =
+			{ 0x01,       /* phy number */
+			  0x02,       /* gpr setup sequence length */
+			  0x02, 0x00, /* gpr setup sequence */
+			  0x02,       /* phy reset sequence length */
+			  0x01, 0x00, /* phy reset sequence */
+			  0x00, 0x78, /* media capabilities */
+			  0x00, 0xe0, /* nway advertisment */
+			  0x00, 0x05, /* fdx bit map */
+			  0x00, 0x06  /* ttm bit map */
+			};
+
+		tp->mtable = (struct mediatable *)
+			kmalloc(sizeof(struct mediatable) + sizeof(struct medialeaf), GFP_KERNEL);
+
+		if (tp->mtable == NULL)
+			return; /* Horrible, impossible failure. */
+
+		tp->mtable->defaultmedia = 0x800;
+		tp->mtable->leafcount = 1;
+		tp->mtable->csr12dir = 0x3f; /* inputs on bit7 for hsc-pci, bit6 for pci-fx */
+		tp->mtable->has_nonmii = 0;
+		tp->mtable->has_reset = 0;
+		tp->mtable->has_mii = 1;
+		tp->mtable->csr15dir = tp->mtable->csr15val = 0;
+		tp->mtable->mleaf[0].type = 1;
+		tp->mtable->mleaf[0].media = 11;
+		tp->mtable->mleaf[0].leafdata = &leafdata[0];
+		tp->flags |= HAS_PHY_IRQ;
+		tp->csr12_shadow = -1;
+	}
+#endif 
+}
+
 void __devinit tulip_parse_eeprom(struct net_device *dev)
 {
 	/* The last media info list parsed, for multiport boards.  */
@@ -136,6 +191,7 @@
 subsequent_board:
 
 	if (ee_data[27] == 0) {		/* No valid media table. */
+		tulip_build_fake_mediatable(tp);
 	} else if (tp->chip_id == DC21041) {
 		unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3];
 		int media = get_u16(p);
diff -urN linux-2.4.20-pre7/drivers/net/tulip/interrupt.c linux-2.4.20-pre8/drivers/net/tulip/interrupt.c
--- linux-2.4.20-pre7/drivers/net/tulip/interrupt.c	Fri Nov  9 13:45:35 2001
+++ linux-2.4.20-pre8/drivers/net/tulip/interrupt.c	Wed Sep 25 18:21:51 2002
@@ -291,6 +291,25 @@
 #endif
 }
 
+static inline void phy_interrupt (struct net_device *dev)
+{
+#ifdef __hppa__
+	int csr12 = inl(dev->base_addr + CSR12) & 0xff;
+	struct tulip_private *tp = (struct tulip_private *)dev->priv;
+
+	if (csr12 != tp->csr12_shadow) {
+		/* ack interrupt */
+		outl(csr12 | 0x02, dev->base_addr + CSR12);
+		tp->csr12_shadow = csr12;
+		/* do link change stuff */
+		spin_lock(&tp->lock);
+		tulip_check_duplex(dev);
+		spin_unlock(&tp->lock);
+		/* clear irq ack bit */
+		outl(csr12 & ~0x02, dev->base_addr + CSR12);
+	}
+#endif
+}
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
@@ -313,6 +332,9 @@
 	/* Let's see whether the interrupt really is for us */
 	csr5 = inl(ioaddr + CSR5);
 
+        if (tp->flags & HAS_PHY_IRQ)
+	        phy_interrupt (dev);
+    
 	if ((csr5 & (NormalIntr|AbnormalIntr)) == 0)
 		return;
 
diff -urN linux-2.4.20-pre7/drivers/net/tulip/tulip.h linux-2.4.20-pre8/drivers/net/tulip/tulip.h
--- linux-2.4.20-pre7/drivers/net/tulip/tulip.h	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/tulip/tulip.h	Wed Sep 25 18:21:51 2002
@@ -63,6 +63,7 @@
 	HAS_8023X		= 0x0400,
 	COMET_MAC_ADDR		= 0x0800,
 	HAS_PCI_MWI		= 0x1000,
+	HAS_PHY_IRQ		= 0x2000,
 };
 
 
@@ -388,7 +389,8 @@
 	int susp_rx;
 	unsigned long nir;
 	unsigned long base_addr;
-	int pad0, pad1;		/* Used for 8-byte alignment */
+	int csr12_shadow;
+	int pad0;		/* Used for 8-byte alignment */
 };
 
 
diff -urN linux-2.4.20-pre7/drivers/net/tulip/tulip_core.c linux-2.4.20-pre8/drivers/net/tulip/tulip_core.c
--- linux-2.4.20-pre7/drivers/net/tulip/tulip_core.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/tulip/tulip_core.c	Wed Sep 25 18:21:51 2002
@@ -1592,6 +1592,25 @@
                        tp->flags &= ~HAS_MEDIA_TABLE;
                }
 #endif
+#ifdef __hppa__
+		/* 3x5 HSC (J3514A) has a broken srom */
+		if(ee_data[0] == 0x61 && ee_data[1] == 0x10) {
+			/* pci_vendor_id and subsystem_id are swapped */
+			ee_data[0] = ee_data[2];
+			ee_data[1] = ee_data[3];
+			ee_data[2] = 0x61;
+			ee_data[3] = 0x10;
+
+			/* srom need to be byte-swaped and shifted up 1 word.  
+			 * This shift needs to happen at the end of the MAC
+			 * first because of the 2 byte overlap.
+			 */
+			for(i = 4; i >= 0; i -= 2) {
+				ee_data[17 + i + 3] = ee_data[17 + i];
+				ee_data[16 + i + 5] = ee_data[16 + i];
+			}
+		}
+#endif
 		for (i = 0; i < 6; i ++) {
 			dev->dev_addr[i] = ee_data[i + sa_offset];
 			sum += ee_data[i + sa_offset];
diff -urN linux-2.4.20-pre7/drivers/net/wan/comx-hw-munich.c linux-2.4.20-pre8/drivers/net/wan/comx-hw-munich.c
--- linux-2.4.20-pre7/drivers/net/wan/comx-hw-munich.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/wan/comx-hw-munich.c	Wed Sep 25 18:21:52 2002
@@ -55,11 +55,9 @@
 #include "falc-lh.h"
 #endif
 
-MODULE_AUTHOR
-    ("Bartok Istvan <bartoki@itc.hu>, Gergely Madarasz <gorgo@itc.hu>, Szilard Pasztor <don@itc.hu>");
-MODULE_DESCRIPTION
-    ("Hardware-level driver for the SliceCOM and PciCOM (WelCOM) adapters");
-
+MODULE_AUTHOR("Bartok Istvan <bartoki@itc.hu>, Gergely Madarasz <gorgo@itc.hu>, Szilard Pasztor <don@itc.hu>");
+MODULE_DESCRIPTION("Hardware-level driver for the SliceCOM and PciCOM (WelCOM) adapters");
+MODULE_LICENSE("GPL");
 /*
  *	TODO: az ilyenek a comxhw.h -ban szoktak lenni, idovel menjenek majd oda:
  */
@@ -1253,8 +1251,6 @@
 	/* jon interrupt, de nincs mit feldolgozni, akkor torlom a STAT-ot.     */
 	/* 'needs a rewrite', de elso megoldasnak jo lesz                       */
 //              {
-
-udelay(10000);
 	int_info = board->tiq[board->tiq_ptr];
 	if (int_info.all & 0xF0000000)	/* ha ez nem 0, akkor itt interrupt_info van    */
 	{
@@ -2009,7 +2005,8 @@
 	if (board->tiq) kfree((void *)board->tiq);
 	if (board->riq) kfree((void *)board->riq);
 	if (board->piq) kfree((void *)board->piq);
-	board->ccb = board->tiq = board->riq = board->piq = NULL;
+	board->ccb = NULL;
+	board->tiq = board->riq = board->piq = NULL;
     }
 
     /* Enable setting of hw parameters */
@@ -2778,8 +2775,6 @@
 static int BOARD_exit(struct net_device *dev)
 {
     struct comx_channel *ch = (struct comx_channel *)dev->priv;
-    struct slicecom_privdata *hw = ch->HW_privdata;
-//    munich_board_t *board;
 
     /* Free private data area */
 //    board = hw->boardnum + (ch->hardware == &pcicomhw ? pcicom_boards : slicecom_boards);
diff -urN linux-2.4.20-pre7/drivers/net/winbond-840.c linux-2.4.20-pre8/drivers/net/winbond-840.c
--- linux-2.4.20-pre7/drivers/net/winbond-840.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/winbond-840.c	Wed Sep 25 18:21:54 2002
@@ -1136,13 +1136,7 @@
 			if (tx_status & 0x0002) np->stats.tx_fifo_errors++;
 			if ((tx_status & 0x0080) && np->mii_if.full_duplex == 0)
 				np->stats.tx_heartbeat_errors++;
-#ifdef ETHER_STATS
-			if (tx_status & 0x0100) np->stats.collisions16++;
-#endif
 		} else {
-#ifdef ETHER_STATS
-			if (tx_status & 0x0001) np->stats.tx_deferred++;
-#endif
 #ifndef final_version
 			if (debug > 3)
 				printk(KERN_DEBUG "%s: Transmit slot %d ok, Tx status %8.8x.\n",
diff -urN linux-2.4.20-pre7/drivers/net/wireless/airo.c linux-2.4.20-pre8/drivers/net/wireless/airo.c
--- linux-2.4.20-pre7/drivers/net/wireless/airo.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/net/wireless/airo.c	Wed Sep 25 18:21:54 2002
@@ -278,26 +278,76 @@
 #define NO_PACKET -2
 
 /* Commands */
-#define NOP 0x0010
-#define MAC_ENABLE 0x0001
-#define MAC_DISABLE 0x0002
-#define CMD_LOSE_SYNC 0x0003 /* Not sure what this does... */
-#define CMD_MAGIC_PKT 0x0006
-#define CMD_ACCESS 0x0021
-#define CMD_ALLOCATETX 0x000a
-#define CMD_TRANSMIT 0x000b
-#define CMD_DEALLOCATETX 0x000c
-#define HOSTSLEEP 0x85
-#define CMD_SETMODE 0x0009
-#define CMD_ENABLEAUX 0x0111
-#define CMD_SOFTRESET 0x0004
-#define CMD_ALLOCBUF 0x0028
-#define CMD_PSPNODES 0x0030
-#define CMD_SETPHYREG 0x003e
-#define CMD_TXTEST 0x003f
-#define CMD_READCFG 0x0008
-#define CMD_SAVECFG 0x0108
-#define CMD_LISTBSS 0x0103
+#define NOP2 0x00    
+#define MAC_ENABLE 0x01
+#define MAC_ENABLETX 0x101
+#define CMD_ENABLEAUX 0x111
+#define MAC_ENABLERX 0x201   
+#define MAC_DISABLE 0x02    
+#define CMD_LOSE_SYNC 0x03    
+#define CMD_LOSE_SYNC_BSS 0x103
+#define CMD_SOFTRESET 0x04    
+#define HOSTSLEEP 0x05    
+#define CMD_MAGICPACKET 0x06
+#define CMD_SETWAKEMASK 0x07
+#define CMD_SAVECONFIG 0x108   
+#define CMD_READCONFIG 0x08
+#define CMD_SETMODE 0x09    
+#define CMD_ALLOCATETX 0x0A
+#define CMD_TRANSMIT 0x0B    
+#define CMD_DEALLOC 0x0C
+#define CMD_LISTBSS 0x103
+#define NOP 0x10    
+#define CMD_WORKAROUND 0x11
+#define CMD_ACCESS 0x21
+#define CMD_WRITERID 0x121
+#define CMD_PCIBAP 0x22
+#define CMD_PCIAUX 0x23
+#define CMD_ALLOCTLV 0x28
+#define CMD_GETTLV 0x29
+#define CMD_PUTTLV 0x2A
+#define CMD_DELTLV 0x2B    
+#define CMD_FINDNEXTTLV 0x2C    
+#define CMD_SETPHYREG 0x3E
+#define CMD_TXTEST 0x3F    
+#define CMD_NOPSPNODES 0x30    
+#define CMD_USEPSPNODES 0x130
+#define CMD_SETCW 0x31    
+#define CMD_SETPCF 0x32    
+
+/* Command errors */
+#define ERROR_QUALIF 0x00
+#define ERROR_ILLCMD 0x01
+#define ERROR_ILLFMT 0x02
+#define ERROR_INVFID 0x03
+#define ERROR_INVRID 0x04
+#define ERROR_LARGE 0x05
+#define ERROR_NDISABL 0x06
+#define ERROR_ALLOCBSY 0x07
+#define ERROR_NORD 0x0B
+#define ERROR_NOWR 0x0C
+#define ERROR_INVFIDTX 0x0D
+#define ERROR_TESTACT 0x0E
+#define ERROR_TAGNFND 0x12
+#define ERROR_DECODE 0x20
+#define ERROR_DESCUNAV 0x21
+#define ERROR_BADLEN 0x22
+#define ERROR_MODE 0x80
+#define ERROR_HOP 0x81
+#define ERROR_BINTER 0x82
+#define ERROR_RXMODE 0x83
+#define ERROR_MACADDR 0x84
+#define ERROR_RATES 0x85
+#define ERROR_ORDER 0x86
+#define ERROR_SCAN 0x87
+#define ERROR_AUTH 0x88
+#define ERROR_PSMODE 0x89
+#define ERROR_RTYPE 0x8A
+#define ERROR_DIVER 0x8B
+#define ERROR_SSID 0x8C
+#define ERROR_APLIST 0x8D
+#define ERROR_AUTOWAKE 0x8E
+#define ERROR_LEAP 0x8F
 
 /* Registers */
 #define COMMAND 0x00
@@ -391,8 +441,8 @@
 #define RID_STATS      0xFF68
 #define RID_STATSDELTA 0xFF69
 #define RID_STATSDELTACLEAR 0xFF6A
-#define RID_UNKNOWN70  0xFF70
-#define RID_UNKNOWN71  0xFF71
+#define RID_ECHOTEST_RID 0xFF70
+#define RID_ECHOTEST_RESULTS 0xFF71
 #define RID_BSSLISTFIRST 0xFF72
 #define RID_BSSLISTNEXT  0xFF73
 
diff -urN linux-2.4.20-pre7/drivers/net/yellowfin.c linux-2.4.20-pre8/drivers/net/yellowfin.c
--- linux-2.4.20-pre7/drivers/net/yellowfin.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/net/yellowfin.c	Wed Sep 25 18:21:54 2002
@@ -1020,18 +1020,12 @@
 					if (tx_errs & 0x0800) yp->stats.tx_carrier_errors++;
 					if (tx_errs & 0x2000) yp->stats.tx_window_errors++;
 					if (tx_errs & 0x8000) yp->stats.tx_fifo_errors++;
-#ifdef ETHER_STATS
-					if (tx_errs & 0x1000) yp->stats.collisions16++;
-#endif
 				} else {
 #ifndef final_version
 					if (yellowfin_debug > 4)
 						printk(KERN_DEBUG "%s: Normal transmit, Tx status %4.4x.\n",
 							   dev->name, tx_errs);
 #endif
-#ifdef ETHER_STATS
-					if (tx_errs & 0x0400) yp->stats.tx_deferred++;
-#endif
 					yp->stats.tx_bytes += skb->len;
 					yp->stats.collisions += tx_errs & 15;
 					yp->stats.tx_packets++;
diff -urN linux-2.4.20-pre7/drivers/pci/pci.c linux-2.4.20-pre8/drivers/pci/pci.c
--- linux-2.4.20-pre7/drivers/pci/pci.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/pci/pci.c	Wed Sep 25 18:21:55 2002
@@ -586,7 +586,7 @@
 		i + 1, /* PCI BAR # */
 		pci_resource_len(pdev, i), pci_resource_start(pdev, i),
 		pdev->slot_name);
-	while(--i <= 0)
+	while(--i >= 0)
 		pci_release_region(pdev, i);
 		
 	return -EBUSY;
@@ -1159,7 +1159,6 @@
 		res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
 		res->start = base;
 		res->end = limit + 0xfff;
-		res->name = child->name;
 	}
 
 	res = child->resource[1];
@@ -1171,7 +1170,6 @@
 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
 		res->start = base;
 		res->end = limit + 0xfffff;
-		res->name = child->name;
 	}
 
 	res = child->resource[2];
@@ -1198,7 +1196,6 @@
 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
 		res->start = base;
 		res->end = limit + 0xfffff;
-		res->name = child->name;
 	}
 }
 
@@ -1240,9 +1237,11 @@
 	child->primary = parent->secondary;
 	child->subordinate = 0xff;
 
-	/* Set up default resource pointers.. */
-	for (i = 0; i < 4; i++)
+	/* Set up default resource pointers and names.. */
+	for (i = 0; i < 4; i++) {
 		child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+		child->resource[i]->name = child->name;
+	}
 
 	return child;
 }
@@ -2153,11 +2152,13 @@
 EXPORT_SYMBOL(pci_add_new_bus);
 EXPORT_SYMBOL(pci_do_scan_bus);
 EXPORT_SYMBOL(pci_scan_slot);
+EXPORT_SYMBOL(pci_scan_bus);
 #ifdef CONFIG_PROC_FS
 EXPORT_SYMBOL(pci_proc_attach_device);
 EXPORT_SYMBOL(pci_proc_detach_device);
 EXPORT_SYMBOL(pci_proc_attach_bus);
 EXPORT_SYMBOL(pci_proc_detach_bus);
+EXPORT_SYMBOL(proc_bus_pci_dir);
 #endif
 #endif
 
diff -urN linux-2.4.20-pre7/drivers/pci/pci.ids linux-2.4.20-pre8/drivers/pci/pci.ids
--- linux-2.4.20-pre7/drivers/pci/pci.ids	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/pci/pci.ids	Wed Sep 25 18:21:55 2002
@@ -5059,6 +5059,7 @@
 		14e4 000b  BCM5703 1000BaseTX
 		14e4 8009  BCM5703 1000BaseTX
 		14e4 800a  BCM5703 1000BaseTX
+	1648  NetXtreme BCM5704 Gigabit Ethernet
 	164d  NetXtreme BCM5702FE Gigabit Ethernet
 	16a6  NetXtreme BCM5702X Gigabit Ethernet
 	16a7  NetXtreme BCM5703X Gigabit Ethernet
diff -urN linux-2.4.20-pre7/drivers/pci/proc.c linux-2.4.20-pre8/drivers/pci/proc.c
--- linux-2.4.20-pre7/drivers/pci/proc.c	Fri Nov 16 18:38:39 2001
+++ linux-2.4.20-pre8/drivers/pci/proc.c	Wed Sep 25 18:21:55 2002
@@ -369,7 +369,7 @@
 	show:	show_device
 };
 
-static struct proc_dir_entry *proc_bus_pci_dir;
+struct proc_dir_entry *proc_bus_pci_dir;
 
 int pci_proc_attach_device(struct pci_dev *dev)
 {
diff -urN linux-2.4.20-pre7/drivers/pci/setup-bus.c linux-2.4.20-pre8/drivers/pci/setup-bus.c
--- linux-2.4.20-pre7/drivers/pci/setup-bus.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/pci/setup-bus.c	Wed Sep 25 18:21:55 2002
@@ -11,7 +11,10 @@
 
 /*
  * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
- *	     PCI-PCI bridges cleanup, sorted resource allocation
+ *	     PCI-PCI bridges cleanup, sorted resource allocation.
+ * Feb 2002, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+ *	     Converted to allocation in 3 passes, which gives
+ *	     tighter packing. Prefetchable range support.
  */
 
 #include <linux/init.h>
@@ -23,7 +26,7 @@
 #include <linux/slab.h>
 
 
-#define DEBUG_CONFIG 0
+#define DEBUG_CONFIG 1
 #if DEBUG_CONFIG
 # define DBGC(args)     printk args
 #else
@@ -33,16 +36,14 @@
 #define ROUND_UP(x, a)		(((x) + (a) - 1) & ~((a) - 1))
 
 static int __init
-pbus_assign_resources_sorted(struct pci_bus *bus,
-			     struct pbus_set_ranges_data *ranges)
+pbus_assign_resources_sorted(struct pci_bus *bus)
 {
 	struct list_head *ln;
 	struct resource *res;
-	struct resource_list head_io, head_mem, *list, *tmp;
-	unsigned long io_reserved = 0, mem_reserved = 0;
+	struct resource_list head, *list, *tmp;
 	int idx, found_vga = 0;
 
-	head_io.next = head_mem.next = NULL;
+	head.next = NULL;
 	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
 		struct pci_dev *dev = pci_dev_b(ln);
 		u16 class = dev->class >> 8;
@@ -64,63 +65,26 @@
 			pci_write_config_word(dev, PCI_COMMAND, cmd);
 		}
 
-		/* Reserve some resources for CardBus.
-		   Are these values reasonable? */
-		if (class == PCI_CLASS_BRIDGE_CARDBUS) {
-			io_reserved += 8*1024;
-			mem_reserved += 32*1024*1024;
-			continue;
-		}
-
-		pdev_sort_resources(dev, &head_io, IORESOURCE_IO);
-		pdev_sort_resources(dev, &head_mem, IORESOURCE_MEM);
+		pdev_sort_resources(dev, &head);
 	}
 
-	for (list = head_io.next; list;) {
+	for (list = head.next; list;) {
 		res = list->res;
 		idx = res - &list->dev->resource[0];
-		if (pci_assign_resource(list->dev, idx) == 0
-		    && ranges->io_end < res->end)
-			ranges->io_end = res->end;
+		pci_assign_resource(list->dev, idx);
 		tmp = list;
 		list = list->next;
 		kfree(tmp);
 	}
-	for (list = head_mem.next; list;) {
-		res = list->res;
-		idx = res - &list->dev->resource[0];
-		if (pci_assign_resource(list->dev, idx) == 0
-		    && ranges->mem_end < res->end)
-			ranges->mem_end = res->end;
-		tmp = list;
-		list = list->next;
-		kfree(tmp);
-	}
-
-	ranges->io_end += io_reserved;
-	ranges->mem_end += mem_reserved;
-
-	/* PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
-	   requires that if there is no I/O ports or memory behind the
-	   bridge, corresponding range must be turned off by writing base
-	   value greater than limit to the bridge's base/limit registers.  */
-#if 1
-	/* But assuming that some hardware designed before 1998 might
-	   not support this (very unlikely - at least all DEC bridges
-	   are ok and I believe that was standard de-facto. -ink), we
-	   must allow for at least one unit.  */
-	if (ranges->io_end == ranges->io_start)
-		ranges->io_end += 1;
-	if (ranges->mem_end == ranges->mem_start)
-		ranges->mem_end += 1;
-#endif
-	ranges->io_end = ROUND_UP(ranges->io_end, 4*1024);
-	ranges->mem_end = ROUND_UP(ranges->mem_end, 1024*1024);
 
 	return found_vga;
 }
 
-/* Initialize bridges with base/limit values we have collected */
+/* Initialize bridges with base/limit values we have collected.
+   PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998)
+   requires that if there is no I/O ports or memory behind the
+   bridge, corresponding range must be turned off by writing base
+   value greater than limit to the bridge's base/limit registers.  */
 static void __init
 pci_setup_bridge(struct pci_bus *bus)
 {
@@ -130,130 +94,307 @@
 
 	if (!bridge || (bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI)
 		return;
+
 	ranges.io_start = bus->resource[0]->start;
 	ranges.io_end = bus->resource[0]->end;
 	ranges.mem_start = bus->resource[1]->start;
 	ranges.mem_end = bus->resource[1]->end;
+	ranges.prefetch_start = bus->resource[2]->start;
+	ranges.prefetch_end = bus->resource[2]->end;
 	pcibios_fixup_pbus_ranges(bus, &ranges);
 
-	DBGC((KERN_ERR "PCI: Bus %d, bridge: %s\n", bus->number, bridge->name));
-	DBGC((KERN_ERR "  IO window: %04lx-%04lx\n", ranges.io_start, ranges.io_end));
-	DBGC((KERN_ERR "  MEM window: %08lx-%08lx\n", ranges.mem_start, ranges.mem_end));
+	DBGC((KERN_INFO "PCI: Bus %d, bridge: %s\n",
+			bus->number, bridge->name));
 
 	/* Set up the top and bottom of the PCI I/O segment for this bus. */
-	pci_read_config_dword(bridge, PCI_IO_BASE, &l);
-	l &= 0xffff0000;
-	l |= (ranges.io_start >> 8) & 0x00f0;
-	l |= ranges.io_end & 0xf000;
+	if (bus->resource[0]->flags & IORESOURCE_IO) {
+		pci_read_config_dword(bridge, PCI_IO_BASE, &l);
+		l &= 0xffff0000;
+		l |= (ranges.io_start >> 8) & 0x00f0;
+		l |= ranges.io_end & 0xf000;
+		/* Set up upper 16 bits of I/O base/limit. */
+		pci_write_config_word(bridge, PCI_IO_BASE_UPPER16,
+				      ranges.io_start >> 16);
+		pci_write_config_word(bridge, PCI_IO_LIMIT_UPPER16,
+				      ranges.io_end >> 16);
+		DBGC((KERN_INFO "  IO window: %04lx-%04lx\n",
+				ranges.io_start, ranges.io_end));
+	}
+	else {
+		/* Clear upper 16 bits of I/O base/limit. */
+		pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0);
+		l = 0x00f0;
+		DBGC((KERN_INFO "  IO window: disabled.\n"));
+	}
 	pci_write_config_dword(bridge, PCI_IO_BASE, l);
 
-	/* Clear upper 16 bits of I/O base/limit. */
-	pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0);
+	/* Set up the top and bottom of the PCI Memory segment
+	   for this bus. */
+	if (bus->resource[1]->flags & IORESOURCE_MEM) {
+		l = (ranges.mem_start >> 16) & 0xfff0;
+		l |= ranges.mem_end & 0xfff00000;
+		DBGC((KERN_INFO "  MEM window: %08lx-%08lx\n",
+				ranges.mem_start, ranges.mem_end));
+	}
+	else {
+		l = 0x0000fff0;
+		DBGC((KERN_INFO "  MEM window: disabled.\n"));
+	}
+	pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
 
 	/* Clear out the upper 32 bits of PREF base/limit. */
 	pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0);
 	pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0);
 
-	/* Set up the top and bottom of the PCI Memory segment
-	   for this bus. */
-	l = (ranges.mem_start >> 16) & 0xfff0;
-	l |= ranges.mem_end & 0xfff00000;
-	pci_write_config_dword(bridge, PCI_MEMORY_BASE, l);
-
 	/* Set up PREF base/limit. */
-	l = (bus->resource[2]->start >> 16) & 0xfff0;
-	l |= bus->resource[2]->end & 0xfff00000;
+	if (bus->resource[2]->flags & IORESOURCE_PREFETCH) {
+		l = (ranges.prefetch_start >> 16) & 0xfff0;
+		l |= ranges.prefetch_end & 0xfff00000;
+		DBGC((KERN_INFO "  PREFETCH window: %08lx-%08lx\n",
+				ranges.prefetch_start, ranges.prefetch_end));
+	}
+	else {
+		l = 0x0000fff0;
+		DBGC((KERN_INFO "  PREFETCH window: disabled.\n"));
+	}
 	pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
 
 	/* Check if we have VGA behind the bridge.
-	   Enable ISA in either case. */
+	   Enable ISA in either case (FIXME!). */
 	l = (bus->resource[0]->flags & IORESOURCE_BUS_HAS_VGA) ? 0x0c : 0x04;
 	pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, l);
 }
 
+/* Check whether the bridge supports optional I/O and
+   prefetchable memory ranges. If not, the respective
+   base/limit registers must be read-only and read as 0. */
 static void __init
-pbus_assign_resources(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+pci_bridge_check_ranges(struct pci_bus *bus)
+{
+	u16 io;
+	u32 pmem;
+	struct pci_dev *bridge = bus->self;
+	struct resource *b_res;
+
+	if (!bridge || (bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+		return;
+
+	b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
+	b_res[1].flags |= IORESOURCE_MEM;
+
+	pci_read_config_word(bridge, PCI_IO_BASE, &io);
+	if (!io) {
+		pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
+		pci_read_config_word(bridge, PCI_IO_BASE, &io);
+ 		pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
+ 	}
+ 	if (io)
+		b_res[0].flags |= IORESOURCE_IO;
+	/*  DECchip 21050 pass 2 errata: the bridge may miss an address
+	    disconnect boundary by one PCI data phase.
+	    Workaround: do not use prefetching on this device. */
+	if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001)
+		return;
+	pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
+	if (!pmem) {
+		pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE,
+					       0xfff0fff0);
+		pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
+		pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
+	}
+	if (pmem)
+		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
+}
+
+/* Sizing the IO windows of the PCI-PCI bridge is trivial,
+   since these windows have 4K granularity and the IO ranges
+   of non-bridge PCI devices are limited to 256 bytes.
+   We must be careful with the ISA aliasing though. */
+static void __init
+pbus_size_io(struct pci_bus *bus)
 {
 	struct list_head *ln;
-	int found_vga = pbus_assign_resources_sorted(bus, ranges);
+	struct resource *b_res = bus->resource[0];
+	unsigned long size = 0, size1 = 0;
 
-	if (!ranges->found_vga && found_vga) {
-		struct pci_bus *b;
+	if (!(b_res->flags & IORESOURCE_IO))
+		return;
 
-		ranges->found_vga = 1;
-		/* Propogate presence of the VGA to upstream bridges */
-		for (b = bus; b->parent; b = b->parent) {
-#if 0
-			/* ? Do we actually need to enable PF memory? */
-			b->resource[2]->start = 0;
+	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
+		struct pci_dev *dev = pci_dev_b(ln);
+		int i;
+		
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource *r = &dev->resource[i];
+			unsigned long r_size;
+
+			if (r->parent || !(r->flags & IORESOURCE_IO))
+				continue;
+			r_size = r->end - r->start + 1;
+
+			if (r_size < 0x400)
+				/* Might be re-aligned for ISA */
+				size += r_size;
+			else
+				size1 += r_size;
+		}
+		/* ??? Reserve some resources for CardBus. */
+		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS)
+			size1 += 4*1024;
+	}
+/* To be fixed in 2.5: we should have sort of HAVE_ISA
+   flag in the struct pci_bus. */
+#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
+	size = (size & 0xff) + ((size & ~0xffUL) << 2);
 #endif
-			b->resource[0]->flags |= IORESOURCE_BUS_HAS_VGA;
+	size = ROUND_UP(size + size1, 4096);
+	if (!size) {
+		b_res->flags = 0;
+		return;
+	}
+	/* Alignment of the IO window is always 4K */
+	b_res->start = 4096;
+	b_res->end = b_res->start + size - 1;
+}
+
+/* Calculate the size of the bus and minimal alignment which
+   guarantees that all child resources fit in this size. */
+static void __init
+pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
+{
+	struct list_head *ln;
+	unsigned long min_align, align, size;
+	unsigned long aligns[12];	/* Alignments from 1Mb to 2Gb */
+	int order, max_order;
+	struct resource *b_res = (type & IORESOURCE_PREFETCH) ?
+				 bus->resource[2] : bus->resource[1];
+
+	memset(aligns, 0, sizeof(aligns));
+	max_order = 0;
+	size = 0;
+
+	for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
+		struct pci_dev *dev = pci_dev_b(ln);
+		int i;
+		
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource *r = &dev->resource[i];
+			unsigned long r_size;
+
+			if (r->parent || (r->flags & mask) != type)
+				continue;
+			r_size = r->end - r->start + 1;
+			/* For bridges size != alignment */
+			align = (i < PCI_BRIDGE_RESOURCES) ? r_size : r->start;
+			order = ffz(~align) - 20;
+			if (order > 11) {
+				printk(KERN_WARNING "PCI: region %s/%d "
+				       "too large: %lx-%lx\n",
+				       dev->slot_name, i, r->start, r->end);
+				r->flags = 0;
+				continue;
+			}
+			size += r_size;
+			if (order < 0)
+				order = 0;
+			/* Exclude ranges with size > align from
+			   calculation of the alignment. */
+			if (size == align)
+				aligns[order] += align;
+			if (order > max_order)
+				max_order = order;
+		}
+		/* ??? Reserve some resources for CardBus. */
+		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
+			size += 1UL << 24;		/* 16 Mb */
+			aligns[24 - 20] += 1UL << 24;
 		}
 	}
-	for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
-		struct pci_bus *b = pci_bus_b(ln);
 
-		b->resource[0]->start = ranges->io_start = ranges->io_end;
-		b->resource[1]->start = ranges->mem_start = ranges->mem_end;
+	align = 0;
+	min_align = 0;
+	for (order = 0; order <= max_order; order++) {
+		unsigned long align1 = 1UL << (order + 20);
+
+		if (!align)
+			min_align = align1;
+		else if (ROUND_UP(align + min_align, min_align) < align1)
+			min_align = align1 >> 1;
+		align += aligns[order];
+	}
+	size = ROUND_UP(size, min_align);
+	if (!size) {
+		b_res->flags = 0;
+		return;
+	}
+	b_res->start = min_align;
+	b_res->end = size + min_align - 1;
+}
+
+void __init
+pbus_size_bridges(struct pci_bus *bus)
+{
+	struct list_head *ln;
+	unsigned long mask, type;
+
+	for (ln=bus->children.next; ln != &bus->children; ln=ln->next)
+		pbus_size_bridges(pci_bus_b(ln));
 
-		pbus_assign_resources(b, ranges);
+	/* The root bus? */
+	if (!bus->self)
+		return;
 
-		b->resource[0]->end = ranges->io_end - 1;
-		b->resource[1]->end = ranges->mem_end - 1;
+	pci_bridge_check_ranges(bus);
 
-		/* Add bridge resources to the resource tree. */
-		if (b->resource[0]->end > b->resource[0]->start &&
-		    request_resource(bus->resource[0], b->resource[0]) < 0)
-			printk(KERN_ERR "PCI: failed to reserve IO "
-					"for bus %d\n",	b->number);
-		if (b->resource[1]->end > b->resource[1]->start &&
-		    request_resource(bus->resource[1], b->resource[1]) < 0)
-			printk(KERN_ERR "PCI: failed to reserve MEM "
-					"for bus %d\n", b->number);
+	pbus_size_io(bus);
 
-		pci_setup_bridge(b);
+	mask = type = IORESOURCE_MEM;
+	/* If the bridge supports prefetchable range, size it separately. */
+	if (bus->resource[2] &&
+	    bus->resource[2]->flags & IORESOURCE_PREFETCH) {
+		pbus_size_mem(bus, IORESOURCE_PREFETCH, IORESOURCE_PREFETCH);
+		mask |= IORESOURCE_PREFETCH;	/* Size non-prefetch only. */
 	}
+	pbus_size_mem(bus, mask, type);
 }
 
 void __init
-pci_assign_unassigned_resources(void)
+pbus_assign_resources(struct pci_bus *bus)
 {
-	struct pbus_set_ranges_data ranges;
 	struct list_head *ln;
-	struct pci_dev *dev;
+	int found_vga = pbus_assign_resources_sorted(bus);
 
-	for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) {
-		struct pci_bus *b = pci_bus_b(ln);
+	if (found_vga) {
+		struct pci_bus *b;
 
-		ranges.io_start = b->resource[0]->start + PCIBIOS_MIN_IO;
-		ranges.mem_start = b->resource[1]->start + PCIBIOS_MIN_MEM;
-		ranges.io_end = ranges.io_start;
-		ranges.mem_end = ranges.mem_start;
-		ranges.found_vga = 0;
-		pbus_assign_resources(b, &ranges);
+		/* Propagate presence of the VGA to upstream bridges */
+		for (b = bus; b->parent; b = b->parent) {
+			b->resource[0]->flags |= IORESOURCE_BUS_HAS_VGA;
+		}
 	}
-	pci_for_each_dev(dev) {
-		pdev_enable_device(dev);
+	for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
+		struct pci_bus *b = pci_bus_b(ln);
+
+		pbus_assign_resources(b);
+		pci_setup_bridge(b);
 	}
 }
 
-/* Check whether the bridge supports I/O forwarding.
-   If not, its I/O base/limit register must be
-   read-only and read as 0. */
-unsigned long __init
-pci_bridge_check_io(struct pci_dev *bridge)
+void __init
+pci_assign_unassigned_resources(void)
 {
-	u16 io;
+	struct list_head *ln;
+	struct pci_dev *dev;
 
-	pci_read_config_word(bridge, PCI_IO_BASE, &io);
-	if (!io) {
-		pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0);
-		pci_read_config_word(bridge, PCI_IO_BASE, &io);
-		pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
+	/* Depth first, calculate sizes and alignments of all
+	   subordinate buses. */
+	for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next)
+		pbus_size_bridges(pci_bus_b(ln));
+	/* Depth last, allocate resources and update the hardware. */
+	for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next)
+		pbus_assign_resources(pci_bus_b(ln));
+
+	pci_for_each_dev(dev) {
+		pdev_enable_device(dev);
 	}
-	if (io)
-		return IORESOURCE_IO;
-	printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n",
-				bridge->name);
-	return 0;
 }
diff -urN linux-2.4.20-pre7/drivers/pci/setup-res.c linux-2.4.20-pre8/drivers/pci/setup-res.c
--- linux-2.4.20-pre7/drivers/pci/setup-res.c	Thu Oct  4 18:47:08 2001
+++ linux-2.4.20-pre8/drivers/pci/setup-res.c	Wed Sep 25 18:21:55 2002
@@ -69,6 +69,7 @@
 	unsigned int type_mask,
 	int resno)
 {
+	unsigned long align;
 	int i;
 
 	type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
@@ -81,12 +82,20 @@
 		if ((res->flags ^ r->flags) & type_mask)
 			continue;
 
-		/* We cannot allocate a non-prefetching resource from a pre-fetching area */
-		if ((r->flags & IORESOURCE_PREFETCH) && !(res->flags & IORESOURCE_PREFETCH))
+		/* We cannot allocate a non-prefetching resource
+		   from a pre-fetching area */
+		if ((r->flags & IORESOURCE_PREFETCH) &&
+		    !(res->flags & IORESOURCE_PREFETCH))
 			continue;
 
+		/* The bridge resources are special, as their
+		   size != alignment. Sizing routines return
+		   required alignment in the "start" field. */
+		align = (resno < PCI_BRIDGE_RESOURCES) ? size : res->start;
+
 		/* Ok, try it out.. */
-		if (allocate_resource(r, res, size, min, -1, size, pcibios_align_resource, dev) < 0)
+		if (allocate_resource(r, res, size, min, -1, align,
+				      pcibios_align_resource, dev) < 0)
 			continue;
 
 		/* Update PCI config space.  */
@@ -127,47 +136,45 @@
 	return 0;
 }
 
-/* Sort resources of a given type by alignment */
+/* Sort resources by alignment */
 void __init
-pdev_sort_resources(struct pci_dev *dev,
-		    struct resource_list *head, u32 type_mask)
+pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
 {
 	int i;
 
 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 		struct resource *r;
 		struct resource_list *list, *tmp;
-		unsigned long r_size;
-
-		/* PCI-PCI bridges may have I/O ports or
-		   memory on the primary bus */
-		if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI &&
-						i >= PCI_BRIDGE_RESOURCES)
-			continue;
+		unsigned long r_align;
 
 		r = &dev->resource[i];
-		r_size = r->end - r->start;
+		r_align = r->end - r->start;
 		
-		if (!(r->flags & type_mask) || r->parent)
+		if (!(r->flags) || r->parent)
 			continue;
-		if (!r_size) {
+		if (!r_align) {
 			printk(KERN_WARNING "PCI: Ignore bogus resource %d "
-					 "[%lx:%lx] of %s\n",
-					  i, r->start, r->end, dev->name);
+					    "[%lx:%lx] of %s\n",
+					    i, r->start, r->end, dev->name);
 			continue;
 		}
+		r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start;
 		for (list = head; ; list = list->next) {
-			unsigned long size = 0;
+			unsigned long align = 0;
 			struct resource_list *ln = list->next;
+			int idx;
 
-			if (ln)
-				size = ln->res->end - ln->res->start;
-			if (r_size > size) {
+			if (ln) {
+				idx = ln->res - &ln->dev->resource[0];
+				align = (idx < PCI_BRIDGE_RESOURCES) ?
+					ln->res->end - ln->res->start + 1 :
+					ln->res->start;
+			}
+			if (r_align > align) {
 				tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
-				if (!tmp) {
-					printk(KERN_ERR "pdev_sort_resources(): kmalloc() failed!\n");
-					continue;
-				}
+				if (!tmp)
+					panic("pdev_sort_resources(): "
+					      "kmalloc() failed!\n");
 				tmp->next = ln;
 				tmp->res = r;
 				tmp->dev = dev;
diff -urN linux-2.4.20-pre7/drivers/s390/block/dasd.c linux-2.4.20-pre8/drivers/s390/block/dasd.c
--- linux-2.4.20-pre7/drivers/s390/block/dasd.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/s390/block/dasd.c	Wed Sep 25 18:21:55 2002
@@ -4055,7 +4055,12 @@
 dasd_statistics_write (struct file *file, const char *user_buf,
 		       size_t user_len, loff_t * offset)
 {
-	char *buffer = vmalloc (user_len);
+	char *buffer;
+	
+	if(user_len > 65536)
+		user_len = 65536;
+		
+	buffer = vmalloc (user_len);
 
 	if (buffer == NULL)
 		return -ENOMEM;
diff -urN linux-2.4.20-pre7/drivers/s390/char/tubfs.c linux-2.4.20-pre8/drivers/s390/char/tubfs.c
--- linux-2.4.20-pre7/drivers/s390/char/tubfs.c	Wed Sep 25 18:20:59 2002
+++ linux-2.4.20-pre8/drivers/s390/char/tubfs.c	Wed Sep 25 18:21:55 2002
@@ -381,6 +381,9 @@
 		return rc;
 	}
 
+	if(len > 8192)
+		len = 8192;
+		
 	kp = kmalloc(len, GFP_KERNEL|GFP_DMA);
 	if (kp == NULL) {
 		TUBUNLOCK(tubp->irq, flags);
@@ -412,7 +415,11 @@
 			*(int*)((long)kp + 4),
 			*(int*)((long)kp + 8),
 			*(int*)((long)kp + 12));
-	copy_to_user(dp, kp, len);
+	if(copy_to_user(dp, kp, len))
+	{
+		kfree(kp);
+		return -EFAULT;
+	}
 	kfree(kp);
 	return len;
 }
@@ -433,6 +440,12 @@
 	if ((tubp = INODE2TUB((struct inode *)fp->private_data)) == NULL)
 		return -ENODEV;
 
+	/* Buffer limit
+	   FIXME: we should probably loop through I/O's waiting as we go
+	 */
+	if(len > 8192)
+		len = 8192;
+		
 	/* Copy data to write from user address space */
 	if ((kb = kmalloc(len, GFP_KERNEL|GFP_DMA)) == NULL)
 		return -ENOMEM;
diff -urN linux-2.4.20-pre7/drivers/s390/misc/chandev.c linux-2.4.20-pre8/drivers/s390/misc/chandev.c
--- linux-2.4.20-pre7/drivers/s390/misc/chandev.c	Wed Sep 25 18:21:00 2002
+++ linux-2.4.20-pre8/drivers/s390/misc/chandev.c	Wed Sep 25 18:21:55 2002
@@ -3140,6 +3140,9 @@
 	int         rc;
 	char        *buff;
 	
+	if(count > 65536)
+		count = 65536;
+		
 	buff=vmalloc(count+1);
 	if(buff)
 	{
diff -urN linux-2.4.20-pre7/drivers/s390/net/netiucv.c linux-2.4.20-pre8/drivers/s390/net/netiucv.c
--- linux-2.4.20-pre7/drivers/s390/net/netiucv.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/s390/net/netiucv.c	Wed Sep 25 18:21:55 2002
@@ -1362,7 +1362,7 @@
 
 	privptr = (netiucv_priv *)dev->priv;
 
-	if (count >= 39)
+	if (count >= CTRL_BUFSIZE-1)
 		return -EINVAL;
 
 	if (copy_from_user(tmp, buf, count))
@@ -1459,7 +1459,7 @@
 
 	privptr = (netiucv_priv *)dev->priv;
 
-	if (count >= 39)
+	if (count >= CTRL_BUFSIZE-1)
 		return -EINVAL;
 
 	if (copy_from_user(tmp, buf, count))
diff -urN linux-2.4.20-pre7/drivers/s390/s390io.c linux-2.4.20-pre8/drivers/s390/s390io.c
--- linux-2.4.20-pre7/drivers/s390/s390io.c	Wed Sep 25 18:21:00 2002
+++ linux-2.4.20-pre8/drivers/s390/s390io.c	Wed Sep 25 18:21:55 2002
@@ -8607,8 +8607,13 @@
 cio_ignore_proc_write (struct file *file, const char *user_buf,
 		       size_t user_len, loff_t * offset)
 {
-	char *buffer = vmalloc (user_len + 1);
-
+	char *buffer
+	
+	if(user_len > 65536)
+		user_len = 65536;
+	
+	buffer = vmalloc (user_len + 1);
+	
 	if (buffer == NULL)
 		return -ENOMEM;
 	if (copy_from_user (buffer, user_buf, user_len)) {
@@ -8845,7 +8850,12 @@
 cio_chpids_proc_write (struct file *file, const char *user_buf,
 		       size_t user_len, loff_t * offset)
 {
-	char *buffer = vmalloc (user_len + 1);
+	char *buffer;
+	
+	if(user_len > 65536)
+		user_len = 65536;
+	
+	buffer = vmalloc (user_len + 1);
 
 	if (buffer == NULL)
 		return -ENOMEM;
diff -urN linux-2.4.20-pre7/drivers/scsi/3w-xxxx.c linux-2.4.20-pre8/drivers/scsi/3w-xxxx.c
--- linux-2.4.20-pre7/drivers/scsi/3w-xxxx.c	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/scsi/3w-xxxx.c	Wed Sep 25 18:21:56 2002
@@ -144,6 +144,11 @@
                  Fix bug in raw command post with data ioctl method.
                  Fix bug where rollcall sometimes failed with cable errors.
    1.02.00.025 - Print unit # on all command timeouts.
+   1.02.00.026 - Fix possible infinite retry bug with power glitch induced
+                 drive timeouts.
+                 Cleanup some AEN severity levels.
+   1.02.00.027 - Add drive not supported AEN code for SATA controllers.
+                 Remove spurious unknown ioctl error message.
 */
 
 #include <linux/module.h>
@@ -197,7 +202,7 @@
 };
 
 /* Globals */
-char *tw_driver_version="1.02.00.025";
+char *tw_driver_version="1.02.00.027";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -208,7 +213,7 @@
 {
 	TW_Param *param;
 	unsigned short aen;
-	int error = 0;
+	int error = 0, table_max = 0;
 
 	dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
 	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
@@ -223,7 +228,8 @@
 	if (aen == 0x0ff) {
 		printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
 	} else {
-		if ((aen & 0x0ff) < TW_AEN_STRING_MAX) {
+		table_max = sizeof(tw_aen_string)/sizeof(char *);
+		if ((aen & 0x0ff) < table_max) {
 			if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
 				printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
 			} else {
@@ -285,7 +291,7 @@
 	int first_reset = 0;
 	int queue = 0;
 	int imax, i;
-	int found = 0;
+	int found = 0, table_max = 0;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
 
@@ -405,7 +411,8 @@
 						if (aen == 0x0ff) {
 							printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
 						} else {
-							if ((aen & 0x0ff) < TW_AEN_STRING_MAX) {
+							table_max = sizeof(tw_aen_string)/sizeof(char *);
+							if ((aen & 0x0ff) < table_max) {
 								if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
 									printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
 								} else {
@@ -1549,7 +1556,8 @@
 
 					/* If error, command failed */
 					if (error == 1) {
-						tw_dev->srb[request_id]->result = (DID_RESET << 16);
+						/* Ask for a host reset */
+						tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
 					}
 					
 					/* Now complete the io */
@@ -1886,7 +1894,7 @@
 				return 1;
 			}
 		default:
-			printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
+			dprintk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
 			tw_dev->state[request_id] = TW_S_COMPLETED;
 			tw_state_request_finish(tw_dev, request_id);
 			tw_dev->srb[request_id]->result = (DID_OK << 16);
diff -urN linux-2.4.20-pre7/drivers/scsi/3w-xxxx.h linux-2.4.20-pre8/drivers/scsi/3w-xxxx.h
--- linux-2.4.20-pre7/drivers/scsi/3w-xxxx.h	Fri Aug  2 17:39:44 2002
+++ linux-2.4.20-pre8/drivers/scsi/3w-xxxx.h	Wed Sep 25 18:21:56 2002
@@ -91,14 +91,13 @@
 	"INFO: Verify started: Unit #",                // 0x029
 	"ERROR: Verify failed: Port #",                // 0x02A
 	"INFO: Verify complete: Unit #",               // 0x02B
-	"ERROR: Overwrote bad sector during rebuild: Port #",   //0x02C
-	"ERROR: Encountered bad sector during rebuild: Port #", //0x02D
-	"INFO: Replacement drive is too small: Port #",         //0x02E
-	"WARNING: Verify error: Unit not previously initialized: Unit #" //0x02F
+	"WARNING: Overwrote bad sector during rebuild: Port #",  //0x02C
+	"ERROR: Encountered bad sector during rebuild: Port #",  //0x02D
+	"ERROR: Replacement drive is too small: Port #",         //0x02E
+	"WARNING: Verify error: Unit not previously initialized: Unit #", //0x02F
+	"ERROR: Drive not supported: Port #"           // 0x030
 };
 
-#define TW_AEN_STRING_MAX                      0x030
-
 /* 
    Sense key lookup table 
    Format: ESDC/flags,SenseKey,AdditionalSenseCode,AdditionalSenseCodeQualifier
diff -urN linux-2.4.20-pre7/drivers/scsi/cpqioctl.c linux-2.4.20-pre8/drivers/scsi/cpqioctl.c
--- linux-2.4.20-pre7/drivers/scsi/cpqioctl.c	Tue Sep 19 08:01:35 2000
+++ linux-2.4.20-pre8/drivers/scsi/cpqioctl.c	Wed Dec 31 16:00:00 1969
@@ -1,76 +0,0 @@
-// Test program for CPQFCTS ioctl calls
-// build with:
-// gcc -o cpqioctl cpqioctl.c
-// ld -o cpqioctl /lib/crt0.o cpqioctl.o -lc
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <linux/types.h>
-#include "../../include/scsi/scsi.h"
-#include "cpqfcTSioctl.h"
-
-typedef struct scsi_fctargaddress {
-        unsigned long host_port_id;
-        unsigned char host_wwn[8];
-} Scsi_FCTargAddress;
-
-int main(int argc, char **argv) {
-
- int fd, i;
- Scsi_FCTargAddress targ;
- int uselect=0;
-
-
-
-  if ( argc < 2 ) {
-    printf("usage: cpqioctl <Devfile>\n");
-    exit(1);
-  }
-
-  if ( (fd = open(argv[1], O_RDONLY)) == -1) {
-    perror("open");
-    exit(1);
-  }
-
-  if ( ioctl(fd, SCSI_IOCTL_FC_TARGET_ADDRESS, &targ) ) {
-    perror("ioctl");
-    exit(1);
-  }
-
-
-  printf("portid: %08x. wwn: ", targ.host_port_id);
-
-  for (i=0;i<8;i++) printf(" %02x", targ.host_wwn[i]);
-  printf("\n");
-
- while( uselect != 27 ) // not ESC key
-  {
-    printf("\n IOCTL \n");
-    printf( "1. Get PCI info\n");
-    printf( "2. Send Passthru\n");
-    printf( " ==> ");
-    scanf("%c", &uselect);
-
-    switch( uselect  )
-    {
-      case '1':
-      {
-        cciss_pci_info_struct pciinfo;
-	
-  	if( ioctl( fd, CCPQFCTS_GETPCIINFO ,&pciinfo ))
-          perror("ioctl");
-	else
-          printf( "\nPCI bus %d, dev_fn %d, board_id %Xh\n",
-            pciinfo.bus, pciinfo.dev_fn, pciinfo.board_id);
-      }
-
-    }
-  }
-
-
-  close(fd);
-  return 0;
-} 
diff -urN linux-2.4.20-pre7/drivers/scsi/scsi_merge.c linux-2.4.20-pre8/drivers/scsi/scsi_merge.c
--- linux-2.4.20-pre7/drivers/scsi/scsi_merge.c	Wed Sep 25 18:21:00 2002
+++ linux-2.4.20-pre8/drivers/scsi/scsi_merge.c	Wed Sep 25 18:22:02 2002
@@ -64,6 +64,12 @@
 #include <scsi/scsi_ioctl.h>
 
 /*
+ * scsi_malloc() can only dish out items of PAGE_SIZE or less, so we cannot
+ * build a request that requires an sg table allocation of more than that.
+ */
+static const int scsi_max_sg = PAGE_SIZE / sizeof(struct scatterlist);
+
+/*
  * This means that bounce buffers cannot be allocated in chunks > PAGE_SIZE.
  * Ultimately we should get away from using a dedicated DMA bounce buffer
  * pool, and we should instead try and use kmalloc() instead.  If we can
@@ -397,11 +403,11 @@
 {
 	unsigned int count;
 	unsigned int segment_size = 0;
-	Scsi_Device *SDpnt;
-	struct Scsi_Host *SHpnt;
+	Scsi_Device *SDpnt = q->queuedata;
+	struct Scsi_Host *SHpnt = SDpnt->host;
 
-	SDpnt = (Scsi_Device *) q->queuedata;
-	SHpnt = SDpnt->host;
+	if (max_segments > scsi_max_sg)
+		max_segments = scsi_max_sg;
 
 #ifdef DMA_CHUNK_SIZE
 	if (max_segments > 64)
@@ -456,11 +462,11 @@
 {
 	unsigned int count;
 	unsigned int segment_size = 0;
-	Scsi_Device *SDpnt;
-	struct Scsi_Host *SHpnt;
+	Scsi_Device *SDpnt = q->queuedata;
+	struct Scsi_Host *SHpnt = SDpnt->host;
 
-	SDpnt = (Scsi_Device *) q->queuedata;
-	SHpnt = SDpnt->host;
+	if (max_segments > scsi_max_sg)
+		max_segments = scsi_max_sg;
 
 #ifdef DMA_CHUNK_SIZE
 	if (max_segments > 64)
@@ -592,8 +598,8 @@
 					     int use_clustering,
 					     int dma_host)
 {
-	Scsi_Device *SDpnt;
-	struct Scsi_Host *SHpnt;
+	Scsi_Device *SDpnt = q->queuedata;
+	struct Scsi_Host *SHpnt = SDpnt->host;
 
 	/*
 	 * First check if the either of the requests are re-queued
@@ -602,8 +608,8 @@
 	if (req->special || next->special)
 		return 0;
 
-	SDpnt = (Scsi_Device *) q->queuedata;
-	SHpnt = SDpnt->host;
+	if (max_segments > scsi_max_sg)
+		max_segments = scsi_max_sg;
 
 #ifdef DMA_CHUNK_SIZE
 	if (max_segments > 64)
diff -urN linux-2.4.20-pre7/drivers/sound/ac97_codec.c linux-2.4.20-pre8/drivers/sound/ac97_codec.c
--- linux-2.4.20-pre7/drivers/sound/ac97_codec.c	Wed Sep 25 18:21:00 2002
+++ linux-2.4.20-pre8/drivers/sound/ac97_codec.c	Wed Sep 25 18:22:03 2002
@@ -654,6 +654,27 @@
 }
 
 /**
+ *	codec_id	-  Turn id1/id2 into a PnP string
+ *	@id1: Vendor ID1
+ *	@id2: Vendor ID2
+ *	@buf: 10 byte buffer
+ *
+ *	Fills buf with a zero terminated PnP ident string for the id1/id2
+ *	pair. For convenience the return is the passed in buffer pointer.
+ */
+ 
+static char *codec_id(u16 id1, u16 id2, char *buf)
+{
+	if(id1&0x8080)
+		snprintf(buf, 10, "%0x4X:%0x4X", id1, id2);
+	buf[0] = (id1 >> 8);
+	buf[1] = (id1 & 0xFF);
+	buf[2] = (id2 >> 8);
+	snprintf(buf+3, 7, "%d", id2&0xFF);
+	return buf;
+}
+ 
+/**
  *	ac97_probe_codec - Initialize and setup AC97-compatible codec
  *	@codec: (in/out) Kernel info for a single AC97 codec
  *
@@ -681,6 +702,7 @@
 	u16 id1, id2;
 	u16 audio, modem;
 	int i;
+	char cidbuf[10];
 
 	/* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should 
 	 * be read zero.
@@ -705,7 +727,9 @@
 
 	/* probe for Modem Codec */
 	codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L);
-	modem = codec->codec_read(codec, AC97_EXTENDED_MODEM_ID);
+	modem = codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1;
+	modem |= (audio&2);
+	audio &= ~2;
 
 	codec->name = NULL;
 	codec->codec_ops = &null_ops;
@@ -722,9 +746,9 @@
 	}
 	if (codec->name == NULL)
 		codec->name = "Unknown";
-	printk(KERN_INFO "ac97_codec: AC97 %s codec, id: 0x%04x:"
-	       "0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""),
-	       id1, id2, codec->name);
+	printk(KERN_INFO "ac97_codec: AC97 %s codec, id: %s(%s)\n", 
+		modem ? "Modem" : (audio ? "Audio" : ""),
+	       codec_id(id1, id2, cidbuf), codec->name);
 
 	return ac97_init_mixer(codec);
 }
diff -urN linux-2.4.20-pre7/drivers/sound/forte.c linux-2.4.20-pre8/drivers/sound/forte.c
--- linux-2.4.20-pre7/drivers/sound/forte.c	Wed Sep 25 18:21:00 2002
+++ linux-2.4.20-pre8/drivers/sound/forte.c	Wed Sep 25 18:22:03 2002
@@ -830,7 +830,6 @@
 		 unsigned long arg)
 {
 	int ival, ret, rval, rd, wr, count;
-	unsigned long flags;
 	struct forte_chip *chip;
 	struct audio_buf_info abi;
 	struct count_info cinfo;
@@ -1200,7 +1199,6 @@
 forte_dsp_open (struct inode *inode, struct file *file)
 {
 	struct forte_chip *chip = forte; /* FIXME: HACK FROM HELL! */
-	struct forte_channel *channel;
 
 	if (down_interruptible (&chip->open_sem)) {
 		DPRINTK ("%s: returning -ERESTARTSYS\n", __FUNCTION__);
@@ -1252,7 +1250,6 @@
 		forte_channel_free (chip, &chip->rec);
 	}
 
- out:
 	up (&chip->open_sem);
 
 	return ret;
@@ -1484,7 +1481,7 @@
 {
 	struct forte_chip *chip;
 	struct forte_channel *channel;
-	unsigned int i = bytes, sz, ret;
+	unsigned int i = bytes, sz;
 	unsigned long flags;
 
 	if (ppos != &file->f_pos)
diff -urN linux-2.4.20-pre7/drivers/sound/trident.c linux-2.4.20-pre8/drivers/sound/trident.c
--- linux-2.4.20-pre7/drivers/sound/trident.c	Wed Sep 25 18:21:00 2002
+++ linux-2.4.20-pre8/drivers/sound/trident.c	Wed Sep 25 18:22:03 2002
@@ -36,6 +36,12 @@
  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  History
+ *  v0.14.10h
+ *	Sept 10 2002 Pascal Schmidt <der.eremit@email.de>
+ *	added support for ALi 5451 joystick port
+ *  v0.14.10g
+ *	Sept 05 2002 Alan Cox <alan@redhat.com>
+ *	adapt to new pci joystick attachment interface
  *  v0.14.10f
  *      July 24 2002 Muli Ben-Yehuda <mulix@actcom.co.il>
  *      patch from Eric Lemar (via Ian Soboroff): in suspend and resume, 
@@ -197,6 +203,8 @@
 #include <linux/proc_fs.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
+#include <linux/gameport.h>
+#include <linux/pci_gameport.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
 #include <asm/io.h>
@@ -208,7 +216,7 @@
 
 #include "trident.h"
 
-#define DRIVER_VERSION "0.14.10f"
+#define DRIVER_VERSION "0.14.10h"
 
 /* magic numbers to protect our data structures */
 #define TRIDENT_CARD_MAGIC	0x5072696E /* "Prin" */
@@ -419,6 +427,8 @@
 	/* Added for hardware volume control */
 	int hwvolctl;
 	struct timer_list timer;
+
+	struct pcigame *joystick;	/* joystick device */
 };
 
 /* table to map from CHANNELMASK to channel attribute for SiS 7018 */
@@ -4236,6 +4246,11 @@
 
 	/* Enable Address Engine Interrupts */
 	trident_enable_loop_interrupts(card);
+	
+	/* Attach joystick */
+	if((pci_dev->vendor == PCI_VENDOR_ID_TRIDENT) ||
+	   (pci_dev->vendor == PCI_VENDOR_ID_AL))
+		card->joystick = pcigame_attach(pci_dev, PCIGAME_4DWAVE);
 out:	return rc;
 out_unregister_sound_dsp:
 	unregister_sound_dsp(card->dev_audio);
@@ -4287,6 +4302,9 @@
 			kfree (card->ac97_codec[i]);
 		}
 	unregister_sound_dsp(card->dev_audio);
+	
+	if(card->joystick)
+		pcigame_detach(card->joystick);
 
 	kfree(card);
 
diff -urN linux-2.4.20-pre7/drivers/usb/hpusbscsi.c linux-2.4.20-pre8/drivers/usb/hpusbscsi.c
--- linux-2.4.20-pre7/drivers/usb/hpusbscsi.c	Wed Sep 25 18:21:02 2002
+++ linux-2.4.20-pre8/drivers/usb/hpusbscsi.c	Wed Sep 25 18:22:04 2002
@@ -396,6 +396,12 @@
 	);
 	hpusbscsi->scallback = callback;
 	hpusbscsi->srb = srb;
+	
+	if (hpusbscsi->dev == NULL) {
+		srb->result = DID_ERROR;
+		callback(srb);
+		goto out;
+	}
 
 	res = usb_submit_urb(&hpusbscsi->dataurb);
 	if (res) {
diff -urN linux-2.4.20-pre7/drivers/usb/hub.c linux-2.4.20-pre8/drivers/usb/hub.c
--- linux-2.4.20-pre7/drivers/usb/hub.c	Wed Sep 25 18:21:02 2002
+++ linux-2.4.20-pre8/drivers/usb/hub.c	Wed Sep 25 18:22:04 2002
@@ -1055,8 +1055,8 @@
 	if (!descriptor) {
 		return -ENOMEM;
 	}
-	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &descriptor,
-			sizeof(descriptor));
+	ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, descriptor,
+			sizeof(*descriptor));
 	if (ret < 0)
 		return ret;
 
@@ -1065,7 +1065,7 @@
 	le16_to_cpus(&descriptor->idProduct);
 	le16_to_cpus(&descriptor->bcdDevice);
 
-	if (memcmp(&dev->descriptor, descriptor, sizeof(descriptor))) {
+	if (memcmp(&dev->descriptor, descriptor, sizeof(*descriptor))) {
 		kfree(descriptor);
 		usb_destroy_configuration(dev);
 
diff -urN linux-2.4.20-pre7/drivers/usb/kaweth.c linux-2.4.20-pre8/drivers/usb/kaweth.c
--- linux-2.4.20-pre7/drivers/usb/kaweth.c	Wed Sep 25 18:21:02 2002
+++ linux-2.4.20-pre8/drivers/usb/kaweth.c	Wed Sep 25 18:22:04 2002
@@ -565,6 +565,8 @@
                         return;
 		}
 
+		skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
+
 		skb->dev = net;
 
 		eth_copy_and_sum(skb, kaweth->rx_buf + 2, pkt_len, 0);
diff -urN linux-2.4.20-pre7/drivers/usb/printer.c linux-2.4.20-pre8/drivers/usb/printer.c
--- linux-2.4.20-pre7/drivers/usb/printer.c	Wed Sep 25 18:21:02 2002
+++ linux-2.4.20-pre8/drivers/usb/printer.c	Wed Sep 25 18:22:04 2002
@@ -257,7 +257,7 @@
  * Get and print printer errors.
  */
 
-static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
+static char *usblp_messages[] = { "ok", "out of paper", "off-line", "unknown error" };
 
 static int usblp_check_status(struct usblp *usblp, int err)
 {
diff -urN linux-2.4.20-pre7/drivers/usb/serial/usbserial.c linux-2.4.20-pre8/drivers/usb/serial/usbserial.c
--- linux-2.4.20-pre7/drivers/usb/serial/usbserial.c	Wed Sep 25 18:21:06 2002
+++ linux-2.4.20-pre8/drivers/usb/serial/usbserial.c	Wed Sep 25 18:22:05 2002
@@ -469,7 +469,7 @@
 		return -ENOMEM;
 	}
 	memcpy (transfer_buffer, data, length);
-	result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 300);
+	result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 3*HZ);
 	kfree (transfer_buffer);
 	return result;
 }
diff -urN linux-2.4.20-pre7/drivers/usb/storage/freecom.c linux-2.4.20-pre8/drivers/usb/storage/freecom.c
--- linux-2.4.20-pre7/drivers/usb/storage/freecom.c	Mon Feb 25 11:38:07 2002
+++ linux-2.4.20-pre8/drivers/usb/storage/freecom.c	Wed Sep 25 18:22:05 2002
@@ -34,7 +34,7 @@
 #include "usb.h"
 #include "debug.h"
 #include "freecom.h"
-#include "linux/hdreg.h"
+#include <linux/hdreg.h>
 
 #ifdef CONFIG_USB_STORAGE_DEBUG
 static void pdump (void *, int);
diff -urN linux-2.4.20-pre7/drivers/usb/usblcd.c linux-2.4.20-pre8/drivers/usb/usblcd.c
--- linux-2.4.20-pre7/drivers/usb/usblcd.c	Wed Sep 25 18:21:06 2002
+++ linux-2.4.20-pre8/drivers/usb/usblcd.c	Wed Sep 25 18:22:05 2002
@@ -1,7 +1,7 @@
 /***************************************************************************** 
  *                          USBLCD Kernel Driver                             *
  *        See http://www.usblcd.de for Hardware and Documentation.           *
- *                            Version 1.01                                   *
+ *                            Version 1.03                                   *
  *             (C) 2002 Adams IT Services <info@usblcd.de>                   *
  *                                                                           *
  *     This file is licensed under the GPL. See COPYING in the package.      *
@@ -9,6 +9,7 @@
  * hp_scanner.c by David E. Nelson (dnelson@jump.net)                        *
  *                                                                           *
  * 23.7.02 RA changed minor device number to the official assigned one       *
+ * 18.9.02 RA Vendor ID change, longer timeouts                              *
  *****************************************************************************/
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -18,15 +19,15 @@
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 
-#define DRIVER_VERSION "USBLCD Driver Version 1.01"
+#define DRIVER_VERSION "USBLCD Driver Version 1.03"
 
-#define USBLCD_MINOR		128
+#define USBLCD_MINOR		144
 
 #define IOCTL_GET_HARD_VERSION	1
 #define IOCTL_GET_DRV_VERSION	2
 
 /* stall/wait timeout for USBLCD */
-#define NAK_TIMEOUT	(HZ)
+#define NAK_TIMEOUT	(10*HZ)
 
 #define IBUF_SIZE	0x1000
 #define OBUF_SIZE	0x10000
@@ -293,7 +294,7 @@
 }
 
 static struct usb_device_id id_table [] = {
-	{ .idVendor = 0x1212, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, },
+	{ .idVendor = 0x10D2, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, },
 	{},
 };
 
diff -urN linux-2.4.20-pre7/drivers/usb/usbnet.c linux-2.4.20-pre8/drivers/usb/usbnet.c
--- linux-2.4.20-pre7/drivers/usb/usbnet.c	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre8/drivers/usb/usbnet.c	Wed Sep 25 18:22:05 2002
@@ -1,6 +1,6 @@
 /*
  * USB Host-to-Host Links
- * Copyright (C) 2000-2001 by David Brownell <dbrownell@users.sourceforge.net>
+ * Copyright (C) 2000-2002 by David Brownell <dbrownell@users.sourceforge.net>
  */
 
 /*
@@ -16,6 +16,7 @@
  *
  *	- AnchorChip 2720
  *	- Belkin, eTEK (interops with Win32 drivers)
+ *	- EPSON USB clients
  *	- GeneSys GL620USB-A
  *	- "Linux Devices" (like iPaq and similar SA-1100 based PDAs)
  *	- NetChip 1080 (interoperates with NetChip Win32 drivers)
@@ -23,33 +24,41 @@
  *
  * USB devices can implement their side of this protocol at the cost
  * of two bulk endpoints; it's not restricted to "cable" applications.
- * See the LINUXDEV support.
+ * See the LINUXDEV or EPSON device/client support.
  *
  * 
- * TODO:
+ * Status:
  *
- * This needs to be retested for bulk queuing problems ... earlier versions
- * seemed to find different types of problems in each HCD.  Once they're fixed,
- * re-enable queues to get higher bandwidth utilization (without needing
- * to tweak MTU for larger packets).
- *
- * Add support for more "network cable" chips; interop with their Win32
- * drivers may be a good thing.  Test the AnchorChip 2720 support..
- * Figure out the initialization protocol used by the Prolific chips,
- * for better robustness ... there's some powerup/reset handshake that's
- * needed when only one end reboots.
- *
- * Use interrupt on PL230x to detect peer connect/disconnect, and call
- * netif_carrier_{on,off} (?) appropriately.  For Net1080, detect peer
- * connect/disconnect with async control messages.
- *
- * Find some way to report "peer connected" network hotplug events; it'll
- * likely mean updating the networking layer.  (This has been discussed
- * on the netdev list...)
+ * - AN2720 ... not widely available, but reportedly works well
  *
- * Craft smarter hotplug policy scripts ... ones that know how to arrange
+ * - Belkin/eTEK ... no known issues
+ *
+ * - Both GeneSys and PL-230x use interrupt transfers for driver-to-driver
+ *   handshaking; it'd be worth implementing those as "carrier detect".
+ *   Prefer generic hooks, not minidriver-specific hacks.
+ *
+ * - Linux devices ... the www.handhelds.org SA-1100 support works nicely,
+ *   but the Sharp Zaurus uses an incompatible protocol (extra checksums).
+ *   No reason not to merge the Zaurus protocol here too (got patch? :)
+ *
+ * - For Netchip, should use keventd to poll via control requests to detect
+ *   hardware level "carrier detect". 
+ *
+ * - PL-230x ... the initialization protocol doesn't seem to match chip data
+ *   sheets, sometimes it's not needed and sometimes it hangs.  Prolific has
+ *   not responded to repeated support/information requests.
+ *
+ * Interop with more Win32 drivers may be a good thing.
+ *
+ * Seems like reporting "peer connected" (carrier present) events may end
+ * up going through the netlink event system, not hotplug ... that may be
+ * awkward in terms of automatic configuration though.
+ *
+ * There are reports that bridging gives lower-than-usual throughput.
+ *
+ * Need smarter hotplug policy scripts ... ones that know how to arrange
  * bridging with "brctl", and can handle static and dynamic ("pump") setups.
- * Use those "peer connected" events.
+ * Use those eventual "peer connected" events, and zeroconf.
  *
  *
  * CHANGELOG:
@@ -62,6 +71,7 @@
  * 18-dec-2000	(db) tx watchdog, "net1080" renaming to "usbnet", device_info
  *		and prolific support, isolate net1080-specific bits, cleanup.
  *		fix unlink_urbs oops in D3 PM resume code path.
+ *
  * 02-feb-2001	(db) fix tx skb sharing, packet length, match_flags, ...
  * 08-feb-2001	stubbed in "linuxdev", maybe the SA-1100 folk can use it;
  *		AnchorChips 2720 support (from spec) for testing;
@@ -83,6 +93,14 @@
  *		tie mostly to (sub)driver info.  Workaround some PL-2302
  *		chips that seem to reject SET_INTERFACE requests.
  *
+ * 06-apr-2002	Added ethtool support, based on a patch from Brad Hards.
+ *		Level of diagnostics is more configurable; they use device
+ *		location (usb_device->devpath) instead of address (2.5).
+ *		For tx_fixup, memflags can't be NOIO.
+ * 07-may-2002	Generalize/cleanup keventd support, handling rx stalls (mostly
+ *		for USB 2.0 TTs) and memory shortages (potential) too. (db)
+ *		Use "locally assigned" IEEE802 address space. (Brad Hards)
+ *
  *-------------------------------------------------------------------------*/
 
 #include <linux/config.h>
@@ -93,6 +111,9 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/random.h>
+#include <linux/ethtool.h>
+#include <linux/tqueue.h>
+#include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
 // #define	DEBUG			// error path messages, extra info
@@ -104,15 +125,27 @@
 #endif
 #include <linux/usb.h>
 
+/* in 2.5 these standard usb ops take mem_flags */
+#define ALLOC_URB(n,flags)	usb_alloc_urb(n)
+#define SUBMIT_URB(u,flags)	usb_submit_urb(u)
+
+/* and these got renamed (may move to usb.h) */
+#define usb_get_dev		usb_inc_dev_use
+#define usb_put_dev		usb_dec_dev_use
 
+
+/* minidrivers _could_ be individually configured */
 #define	CONFIG_USB_AN2720
 #define	CONFIG_USB_BELKIN
+#define	CONFIG_USB_EPSON2888
 #define	CONFIG_USB_GENESYS
 #define	CONFIG_USB_LINUXDEV
 #define	CONFIG_USB_NET1080
 #define	CONFIG_USB_PL2301
 
 
+#define DRIVER_VERSION		"17-Jul-2002"
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -164,6 +197,7 @@
 	// protocol/interface state
 	struct net_device	net;
 	struct net_device_stats	stats;
+	int			msg_level;
 
 #ifdef CONFIG_USB_NET1080
 	u16			packet_id;
@@ -174,7 +208,12 @@
 	struct sk_buff_head	txq;
 	struct sk_buff_head	done;
 	struct tasklet_struct	bh;
-	struct tq_struct	ctrl_task;
+
+	struct tq_struct	kevent;
+	unsigned long		flags;
+#		define EVENT_TX_HALT	0
+#		define EVENT_RX_HALT	1
+#		define EVENT_RX_MEMORY	2
 };
 
 // device-specific info used by the driver
@@ -224,6 +263,13 @@
 	size_t			length;
 };
 
+static const char driver_name [] = "usbnet";
+
+/* use ethtool to change the level for any given device */
+static int msg_level = 1;
+MODULE_PARM (msg_level, "i");
+MODULE_PARM_DESC (msg_level, "Initial message level (default = 1)");
+
 
 #define	mutex_lock(x)	down(x)
 #define	mutex_unlock(x)	up(x)
@@ -241,7 +287,9 @@
 #endif
 
 #define devinfo(usbnet, fmt, arg...) \
-	printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net.name, ## arg)
+	do { if ((usbnet)->msg_level >= 1) \
+	printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net.name, ## arg); \
+	} while (0)
 
 
 #ifdef	CONFIG_USB_AN2720
@@ -258,12 +306,12 @@
  *-------------------------------------------------------------------------*/
 
 static const struct driver_info	an2720_info = {
-	description:	"AnchorChips/Cypress 2720",
+	.description =	"AnchorChips/Cypress 2720",
 	// no reset available!
 	// no check_connect available!
 
-	in: 2, out: 2,		// direction distinguishes these
-	epsize:	64,
+	.in = 2, .out = 2,		// direction distinguishes these
+	.epsize =64,
 };
 
 #endif	/* CONFIG_USB_AN2720 */
@@ -281,16 +329,39 @@
  *-------------------------------------------------------------------------*/
 
 static const struct driver_info	belkin_info = {
-	description:	"Belkin, eTEK, or compatible",
+	.description =	"Belkin, eTEK, or compatible",
 
-	in: 1, out: 1,		// direction distinguishes these
-	epsize:	64,
+	.in = 1, .out = 1,		// direction distinguishes these
+	.epsize =64,
 };
 
 #endif	/* CONFIG_USB_BELKIN */
 
 
 
+#ifdef	CONFIG_USB_EPSON2888
+
+/*-------------------------------------------------------------------------
+ *
+ * EPSON USB clients
+ *
+ * This is the same idea as "linuxdev" (below) except the firmware in the
+ * device might not be Tux-powered.  Epson provides reference firmware that
+ * implements this interface.  Product developers can reuse or modify that
+ * code, such as by using their own product and vendor codes.
+ *
+ *-------------------------------------------------------------------------*/
+
+static const struct driver_info	epson2888_info = {
+	.description =	"Epson USB Device",
+
+	.in = 4, .out = 3,
+	.epsize = 64,
+};
+
+#endif	/* CONFIG_USB_EPSON2888 */
+
+
 #ifdef CONFIG_USB_GENESYS
 
 /*-------------------------------------------------------------------------
@@ -300,6 +371,15 @@
  * ... should partially interop with the Win32 driver for this hardware
  * The GeneSys docs imply there's some NDIS issue motivating this framing.
  *
+ * Some info from GeneSys:
+ *  - GL620USB-A is full duplex; GL620USB is only half duplex for bulk.
+ *    (Some cables, like the BAFO-100c, use the half duplex version.)
+ *  - For the full duplex model, the low bit of the version code says
+ *    which side is which ("left/right").
+ *  - For the half duplex type, a control/interrupt handshake settles
+ *    the transfer direction.  (That's disabled here, partially coded.)
+ *    A control URB would block until other side writes an interrupt.
+ *
  *-------------------------------------------------------------------------*/
 
 // control msg write command
@@ -373,7 +453,7 @@
 	// issue usb interrupt read
 	if (priv && priv->irq_urb) {
 		// submit urb
-		if ((retval = usb_submit_urb (priv->irq_urb)) != 0)
+		if ((retval = SUBMIT_URB (priv->irq_urb, GFP_KERNEL)) != 0)
 			dbg ("gl_interrupt_read: submit fail - %X...", retval);
 		else
 			dbg ("gl_interrupt_read: submit success...");
@@ -420,7 +500,7 @@
 	}
 
 	// allocate irq urb
-	if ((priv->irq_urb = usb_alloc_urb (0)) == 0) {
+	if ((priv->irq_urb = ALLOC_URB (0, GFP_KERNEL)) == 0) {
 		dbg ("%s: cannot allocate private irq urb per device",
 			dev->net.name);
 		kfree (priv);
@@ -464,23 +544,8 @@
 	return 0;
 }
 
-#else
-
-static int genelink_check_connect (struct usbnet *dev)
-{
-	dbg ("%s: assuming peer is connected", dev->net.name);
-	return 0;
-}
-
 #endif
 
-// reset the device status
-static int genelink_reset (struct usbnet *dev)
-{
-	// we don't need to reset, just return 0
-	return 0;
-}
-
 static int genelink_rx_fixup (struct usbnet *dev, struct sk_buff *skb)
 {
 	struct gl_header	*header;
@@ -600,15 +665,17 @@
 }
 
 static const struct driver_info	genelink_info = {
-	description:	"Genesys GeneLink",
-	flags:		FLAG_FRAMING_GL | FLAG_NO_SETINT,
-	reset:		genelink_reset,
-	check_connect:	genelink_check_connect,
-	rx_fixup:	genelink_rx_fixup,
-	tx_fixup:	genelink_tx_fixup,
+	.description =	"Genesys GeneLink",
+	.flags =	FLAG_FRAMING_GL | FLAG_NO_SETINT,
+	.rx_fixup =	genelink_rx_fixup,
+	.tx_fixup =	genelink_tx_fixup,
+
+	.in = 1, .out = 2,
+	.epsize =64,
 
-	in: 1, out: 2,
-	epsize:	64,
+#ifdef	GENELINK_ACK
+	.check_connect =genelink_check_connect,
+#endif
 };
 
 #endif /* CONFIG_USB_GENESYS */
@@ -629,21 +696,19 @@
  *
  * One example is Intel's SA-1100 chip, which integrates basic USB
  * support (arch/arm/sa1100/usb-eth.c); it's used in the iPaq PDA.
+ * And others too, like the Yopy.
  *
  *-------------------------------------------------------------------------*/
 
-
 static const struct driver_info	linuxdev_info = {
-	description:	"Linux Device",
-	// no reset defined (yet?)
-	// no check_connect needed!
-	in: 2, out: 1,
-	epsize:	64,
+	.description =	"Linux Device",
+
+	.in = 2, .out = 1,
+	.epsize = 64,
 };
 
 #endif	/* CONFIG_USB_LINUXDEV */
 
-
 
 #ifdef	CONFIG_USB_NET1080
 
@@ -814,10 +879,10 @@
 static inline void nc_dump_usbctl (struct usbnet *dev, u16 usbctl)
 {
 #ifdef DEBUG
-	devdbg (dev, "net1080 %03d/%03d usbctl 0x%x:%s%s%s%s%s;"
+	devdbg (dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;"
 			" this%s%s;"
 			" other%s%s; r/o 0x%x",
-		dev->udev->bus->busnum, dev->udev->devnum,
+		dev->udev->bus->bus_name, dev->udev->devpath,
 		usbctl,
 		(usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
 		(usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
@@ -859,10 +924,10 @@
 static inline void nc_dump_status (struct usbnet *dev, u16 status)
 {
 #ifdef DEBUG
-	devdbg (dev, "net1080 %03d/%03d status 0x%x:"
+	devdbg (dev, "net1080 %s-%s status 0x%x:"
 			" this (%c) PKT=%d%s%s%s;"
 			" other PKT=%d%s%s%s; unspec 0x%x",
-		dev->udev->bus->busnum, dev->udev->devnum,
+		dev->udev->bus->bus_name, dev->udev->devpath,
 		status,
 
 		// XXX the packet counts don't seem right
@@ -897,8 +962,8 @@
 static inline void nc_dump_ttl (struct usbnet *dev, u16 ttl)
 {
 #ifdef DEBUG
-	devdbg (dev, "net1080 %03d/%03d ttl 0x%x this = %d, other = %d",
-		dev->udev->bus->busnum, dev->udev->devnum,
+	devdbg (dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d",
+		dev->udev->bus->bus_name, dev->udev->devpath,
 		ttl,
 
 		TTL_THIS (ttl),
@@ -921,7 +986,8 @@
 	// nc_dump_registers (dev);
 
 	if ((retval = nc_register_read (dev, REG_STATUS, vp)) < 0) {
-		dbg ("can't read dev %d status: %d", dev->udev->devnum, retval);
+		dbg ("can't read %s-%s status: %d",
+			dev->udev->bus->bus_name, dev->udev->devpath, retval);
 		goto done;
 	}
 	status = *vp;
@@ -948,10 +1014,11 @@
 			MK_TTL (NC_READ_TTL_MS, TTL_OTHER (ttl)) );
 	dbg ("%s: assigned TTL, %d ms", dev->net.name, NC_READ_TTL_MS);
 
-	devdbg (dev, "port %c, peer %sconnected",
-		(status & STATUS_PORT_A) ? 'A' : 'B',
-		(status & STATUS_CONN_OTHER) ? "" : "dis"
-		);
+	if (dev->msg_level >= 2)
+		devinfo (dev, "port %c, peer %sconnected",
+			(status & STATUS_PORT_A) ? 'A' : 'B',
+			(status & STATUS_CONN_OTHER) ? "" : "dis"
+			);
 	retval = 0;
 
 done:
@@ -1079,15 +1146,15 @@
 }
 
 static const struct driver_info	net1080_info = {
-	description:	"NetChip TurboCONNECT",
-	flags:		FLAG_FRAMING_NC,
-	reset:		net1080_reset,
-	check_connect:	net1080_check_connect,
-	rx_fixup:	net1080_rx_fixup,
-	tx_fixup:	net1080_tx_fixup,
+	.description =	"NetChip TurboCONNECT",
+	.flags =	FLAG_FRAMING_NC,
+	.reset =	net1080_reset,
+	.check_connect =net1080_check_connect,
+	.rx_fixup =	net1080_rx_fixup,
+	.tx_fixup =	net1080_tx_fixup,
 
-	in: 1, out: 1,		// direction distinguishes these
-	epsize:	64,
+	.in = 1, .out = 1,		// direction distinguishes these
+	.epsize =64,
 };
 
 #endif /* CONFIG_USB_NET1080 */
@@ -1147,24 +1214,14 @@
 		PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
 }
 
-static int pl_check_connect (struct usbnet *dev)
-{
-	// FIXME test interrupt data PL_PEER_E bit
-	// plus, there's some handshake done by
-	// the prolific win32 driver... 
-	dbg ("%s: assuming peer is connected", dev->net.name);
-	return 0;
-}
-
 static const struct driver_info	prolific_info = {
-	description:	"Prolific PL-2301/PL-2302",
-	flags:		FLAG_NO_SETINT,
+	.description =	"Prolific PL-2301/PL-2302",
+	.flags =	FLAG_NO_SETINT,
 		/* some PL-2302 versions seem to fail usb_set_interface() */
-	reset:		pl_reset,
-	check_connect:	pl_check_connect,
+	.reset =	pl_reset,
 
-	in: 3, out: 2,
-	epsize:	64,
+	.in = 3, .out = 2,
+	.epsize =64,
 };
 
 #endif /* CONFIG_USB_PL2301 */
@@ -1227,6 +1284,21 @@
 	spin_unlock_irqrestore (&dev->done.lock, flags);
 }
 
+/* some work can't be done in tasklets, so we use keventd
+ *
+ * NOTE:  annoying asymmetry:  if it's active, schedule_task() fails,
+ * but tasklet_schedule() doesn't.  hope the failure is rare.
+ */
+static void defer_kevent (struct usbnet *dev, int work)
+{
+	set_bit (work, &dev->flags);
+	if (!schedule_task (&dev->kevent))
+		err ("%s: kevent %d may have been dropped",
+			dev->net.name, work);
+	else
+		dbg ("%s: kevent %d scheduled", dev->net.name, work);
+}
+
 /*-------------------------------------------------------------------------*/
 
 static void rx_complete (struct urb *urb);
@@ -1253,7 +1325,7 @@
 
 	if ((skb = alloc_skb (size, flags)) == 0) {
 		dbg ("no rx skb");
-		tasklet_schedule (&dev->bh);
+		defer_kevent (dev, EVENT_RX_MEMORY);
 		usb_free_urb (urb);
 		return;
 	}
@@ -1268,9 +1340,6 @@
 		usb_rcvbulkpipe (dev->udev, dev->driver_info->in),
 		skb->data, size, rx_complete, skb);
 	urb->transfer_flags |= USB_ASYNC_UNLINK;
-#ifdef	REALLY_QUEUE
-	urb->transfer_flags |= USB_QUEUE_BULK;
-#endif
 #if 0
 	// Idle-but-posted reads with UHCI really chew up
 	// PCI bandwidth unless FSBR is disabled
@@ -1279,11 +1348,20 @@
 
 	spin_lock_irqsave (&dev->rxq.lock, lockflags);
 
-	if (netif_running (&dev->net)) {
-		if ((retval = usb_submit_urb (urb)) != 0) {
+	if (netif_running (&dev->net)
+			&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
+		switch (retval = SUBMIT_URB (urb, GFP_ATOMIC)){ 
+		case -EPIPE:
+			defer_kevent (dev, EVENT_RX_HALT);
+			break;
+		case -ENOMEM:
+			defer_kevent (dev, EVENT_RX_MEMORY);
+			break;
+		default:
 			dbg ("%s rx submit, %d", dev->net.name, retval);
 			tasklet_schedule (&dev->bh);
-		} else {
+			break;
+		case 0:
 			__skb_queue_tail (&dev->rxq, skb);
 		}
 	} else {
@@ -1357,12 +1435,20 @@
 		}
 		break;
 
+	    // stalls need manual reset. this is rare ... except that
+	    // when going through USB 2.0 TTs, unplug appears this way.
+	    // we avoid the highspeed version of the ETIMEOUT/EILSEQ
+	    // storm, recovering as needed.
+	    case -EPIPE:
+		defer_kevent (dev, EVENT_RX_HALT);
+		// FALLTHROUGH
+
 	    // software-driven interface shutdown
-	    case -ECONNRESET:		// usb-ohci, usb-uhci
-	    case -ECONNABORTED:		// uhci ... for usb-uhci, INTR
-		dbg ("%s shutdown, code %d", dev->net.name, urb_status);
+	    case -ECONNRESET:		// according to API spec
+	    case -ECONNABORTED:		// some (now fixed?) UHCI bugs
+		dbg ("%s rx shutdown, code %d", dev->net.name, urb_status);
 		entry->state = rx_cleanup;
-		// do urb frees only in the tasklet
+		// do urb frees only in the tasklet (UHCI has oopsed ...)
 		entry->urb = urb;
 		urb = 0;
 		break;
@@ -1373,8 +1459,9 @@
 		// FALLTHROUGH
 	    
 	    default:
-		// on unplug we'll get a burst of ETIMEDOUT/EILSEQ
-		// till the khubd gets and handles its interrupt.
+		// on unplug we get ETIMEDOUT (ohci) or EILSEQ (uhci)
+		// until khubd sees its interrupt and disconnects us.
+		// that can easily be hundreds of passes through here.
 		entry->state = rx_cleanup;
 		dev->stats.rx_errors++;
 		dbg ("%s rx: status %d", dev->net.name, urb_status);
@@ -1384,10 +1471,12 @@
 	defer_bh (dev, skb);
 
 	if (urb) {
-		if (netif_running (&dev->net)) {
+		if (netif_running (&dev->net)
+				&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
 			rx_submit (dev, urb, GFP_ATOMIC);
 			return;
 		}
+		usb_free_urb (urb);
 	}
 #ifdef	VERBOSE
 	dbg ("no read resubmitted");
@@ -1417,7 +1506,7 @@
 		// during some PM-driven resume scenarios,
 		// these (async) unlinks complete immediately
 		retval = usb_unlink_urb (urb);
-		if (retval < 0)
+		if (retval != -EINPROGRESS && retval != 0)
 			dbg ("unlink urb err, %d", retval);
 		else
 			count++;
@@ -1441,10 +1530,11 @@
 	mutex_lock (&dev->mutex);
 	netif_stop_queue (net);
 
-	devdbg (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld",
-		dev->stats.rx_packets, dev->stats.tx_packets, 
-		dev->stats.rx_errors, dev->stats.tx_errors
-		);
+	if (dev->msg_level >= 2)
+		devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld",
+			dev->stats.rx_packets, dev->stats.tx_packets, 
+			dev->stats.rx_errors, dev->stats.tx_errors
+			);
 
 	// ensure there are no more active urbs
 	add_wait_queue (&unlink_wakeup, &wait);
@@ -1482,9 +1572,9 @@
 
 	// put into "known safe" state
 	if (info->reset && (retval = info->reset (dev)) < 0) {
-		devinfo (dev, "open reset fail (%d) usbnet %03d/%03d, %s",
+		devinfo (dev, "open reset fail (%d) usbnet usb-%s-%s, %s",
 			retval,
-			dev->udev->bus->busnum, dev->udev->devnum,
+			dev->udev->bus->bus_name, dev->udev->devpath,
 			info->description);
 		goto done;
 	}
@@ -1496,14 +1586,16 @@
 	}
 
 	netif_start_queue (net);
-	devdbg (dev, "open: enable queueing (rx %d, tx %d) mtu %d %s framing",
-		RX_QLEN, TX_QLEN, dev->net.mtu,
-		(info->flags & (FLAG_FRAMING_NC | FLAG_FRAMING_GL))
-		    ? ((info->flags & FLAG_FRAMING_NC)
-			? "NetChip"
-			: "GeneSys")
-		    : "raw"
-		);
+	if (dev->msg_level >= 2)
+		devinfo (dev, "open: enable queueing "
+				"(rx %d, tx %d) mtu %d %s framing",
+			RX_QLEN, TX_QLEN, dev->net.mtu,
+			(info->flags & (FLAG_FRAMING_NC | FLAG_FRAMING_GL))
+			    ? ((info->flags & FLAG_FRAMING_NC)
+				? "NetChip"
+				: "GeneSys")
+			    : "raw"
+			);
 
 	// delay posting reads until we're fully open
 	tasklet_schedule (&dev->bh);
@@ -1514,16 +1606,134 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* usb_clear_halt cannot be called in interrupt context */
+static int usbnet_ethtool_ioctl (struct net_device *net, void *useraddr)
+{
+	struct usbnet	*dev = (struct usbnet *) net->priv;
+	u32		cmd;
+
+	if (get_user (cmd, (u32 *)useraddr))
+		return -EFAULT;
+	switch (cmd) {
+
+	case ETHTOOL_GDRVINFO: {	/* get driver info */
+		struct ethtool_drvinfo		info;
+
+		memset (&info, 0, sizeof info);
+		info.cmd = ETHTOOL_GDRVINFO;
+		strncpy (info.driver, driver_name, sizeof info.driver);
+		strncpy (info.version, DRIVER_VERSION, sizeof info.version);
+		strncpy (info.fw_version, dev->driver_info->description,
+			sizeof info.fw_version);
+		usb_make_path (dev->udev, info.bus_info, sizeof info.bus_info);
+		if (copy_to_user (useraddr, &info, sizeof (info)))
+			return -EFAULT;
+		return 0;
+		}
+
+	case ETHTOOL_GLINK: 		/* get link status */
+		if (dev->driver_info->check_connect) {
+			struct ethtool_value	edata = { ETHTOOL_GLINK };
+
+			edata.data = dev->driver_info->check_connect (dev) == 0;
+			if (copy_to_user (useraddr, &edata, sizeof (edata)))
+				return -EFAULT;
+			return 0;
+		}
+		break;
 
+	case ETHTOOL_GMSGLVL: {		/* get message-level */
+		struct ethtool_value	edata = {ETHTOOL_GMSGLVL};
+
+		edata.data = dev->msg_level;
+		if (copy_to_user (useraddr, &edata, sizeof (edata)))
+			return -EFAULT;
+		return 0;
+		}
+
+	case ETHTOOL_SMSGLVL: {		/* set message-level */
+		struct ethtool_value	edata;
+
+		if (copy_from_user (&edata, useraddr, sizeof (edata)))
+			return -EFAULT;
+		dev->msg_level = edata.data;
+		return 0;
+		}
+	
+	/* could also map RINGPARAM to RX/TX QLEN */
+
+	}
+        /* Note that the ethtool user space code requires EOPNOTSUPP */
+	return -EOPNOTSUPP;
+}
+
+static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
+{
+	switch (cmd) {
+	case SIOCETHTOOL:
+		return usbnet_ethtool_ioctl (net, (void *)rq->ifr_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* work that cannot be done in interrupt context uses keventd.
+ *
+ * NOTE:  "uhci" and "usb-uhci" may have trouble with this since they don't
+ * queue control transfers to individual devices, and other threads could
+ * trigger control requests concurrently.  hope that's rare.
+ */
 static void
-tx_clear_halt (void *data)
+kevent (void *data)
 {
 	struct usbnet		*dev = data;
+	int			status;
 
-	usb_clear_halt (dev->udev,
-		usb_sndbulkpipe (dev->udev, dev->driver_info->out));
-	netif_wake_queue (&dev->net);
+	/* usb_clear_halt() needs a thread context */
+	if (test_bit (EVENT_TX_HALT, &dev->flags)) {
+		unlink_urbs (&dev->txq);
+		status = usb_clear_halt (dev->udev,
+			usb_sndbulkpipe (dev->udev, dev->driver_info->out));
+		if (status < 0)
+			err ("%s: can't clear tx halt, status %d",
+				dev->net.name, status);
+		else {
+			clear_bit (EVENT_TX_HALT, &dev->flags);
+			netif_wake_queue (&dev->net);
+		}
+	}
+	if (test_bit (EVENT_RX_HALT, &dev->flags)) {
+		unlink_urbs (&dev->rxq);
+		status = usb_clear_halt (dev->udev,
+			usb_rcvbulkpipe (dev->udev, dev->driver_info->in));
+		if (status < 0)
+			err ("%s: can't clear rx halt, status %d",
+				dev->net.name, status);
+		else {
+			clear_bit (EVENT_RX_HALT, &dev->flags);
+			tasklet_schedule (&dev->bh);
+		}
+	}
+
+	/* tasklet could resubmit itself forever if memory is tight */
+	if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
+		struct urb	*urb = 0;
+
+		if (netif_running (&dev->net))
+			urb = ALLOC_URB (0, GFP_KERNEL);
+		else
+			clear_bit (EVENT_RX_MEMORY, &dev->flags);
+		if (urb != 0) {
+			clear_bit (EVENT_RX_MEMORY, &dev->flags);
+			rx_submit (dev, urb, GFP_KERNEL);
+			tasklet_schedule (&dev->bh);
+		}
+	}
+
+	if (dev->flags)
+		dbg ("%s: kevent done, flags = 0x%lx",
+			dev->net.name, dev->flags);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1534,15 +1744,8 @@
 	struct skb_data		*entry = (struct skb_data *) skb->cb;
 	struct usbnet		*dev = entry->dev;
 
-	if (urb->status == USB_ST_STALL) {
-		if (dev->ctrl_task.sync == 0) {
-			dev->ctrl_task.routine = tx_clear_halt;
-			dev->ctrl_task.data = dev;
-			schedule_task (&dev->ctrl_task);
-		} else {
-			dbg ("Cannot clear TX stall");
-		}
-	}
+	if (urb->status == -EPIPE)
+		defer_kevent (dev, EVENT_TX_HALT);
 	urb->dev = 0;
 	entry->state = tx_done;
 	defer_bh (dev, skb);
@@ -1576,19 +1779,17 @@
 	struct nc_trailer	*trailer = 0;
 #endif	/* CONFIG_USB_NET1080 */
 
-	flags = in_interrupt () ? GFP_ATOMIC : GFP_NOIO; /* might be used for nfs */
-
 	// some devices want funky USB-level framing, for
 	// win32 driver (usually) and/or hardware quirks
 	if (info->tx_fixup) {
-		skb = info->tx_fixup (dev, skb, flags);
+		skb = info->tx_fixup (dev, skb, GFP_ATOMIC);
 		if (!skb) {
 			dbg ("can't tx_fixup skb");
 			goto drop;
 		}
 	}
 
-	if (!(urb = usb_alloc_urb (0))) {
+	if (!(urb = ALLOC_URB (0, GFP_ATOMIC))) {
 		dbg ("no urb");
 		goto drop;
 	}
@@ -1621,9 +1822,6 @@
 			usb_sndbulkpipe (dev->udev, info->out),
 			skb->data, skb->len, tx_complete, skb);
 	urb->transfer_flags |= USB_ASYNC_UNLINK;
-#ifdef	REALLY_QUEUE
-	urb->transfer_flags |= USB_QUEUE_BULK;
-#endif
 	// FIXME urb->timeout = ... jiffies ... ;
 
 	spin_lock_irqsave (&dev->txq.lock, flags);
@@ -1640,15 +1838,19 @@
 	}
 #endif	/* CONFIG_USB_NET1080 */
 
-	netif_stop_queue (net);
-	if ((retval = usb_submit_urb (urb)) != 0) {
-		netif_start_queue (net);
+	switch ((retval = SUBMIT_URB (urb, GFP_ATOMIC))) {
+	case -EPIPE:
+		netif_stop_queue (net);
+		defer_kevent (dev, EVENT_TX_HALT);
+		break;
+	default:
 		dbg ("%s tx: submit urb err %d", net->name, retval);
-	} else {
+		break;
+	case 0:
 		net->trans_start = jiffies;
 		__skb_queue_tail (&dev->txq, skb);
-		if (dev->txq.qlen < TX_QLEN)
-			netif_start_queue (net);
+		if (dev->txq.qlen >= TX_QLEN)
+			netif_stop_queue (net);
 	}
 	spin_unlock_irqrestore (&dev->txq.lock, flags);
 
@@ -1715,14 +1917,15 @@
 		}
 
 	// or are we maybe short a few urbs?
-	} else if (netif_running (&dev->net)) {
+	} else if (netif_running (&dev->net)
+			&& !test_bit (EVENT_RX_HALT, &dev->flags)) {
 		int	temp = dev->rxq.qlen;
 
 		if (temp < RX_QLEN) {
 			struct urb	*urb;
 			int		i;
 			for (i = 0; i < 3 && dev->rxq.qlen < RX_QLEN; i++) {
-				if ((urb = usb_alloc_urb (0)) != 0)
+				if ((urb = ALLOC_URB (0, GFP_ATOMIC)) != 0)
 					rx_submit (dev, urb, GFP_ATOMIC);
 			}
 			if (temp != dev->rxq.qlen)
@@ -1750,8 +1953,8 @@
 {
 	struct usbnet	*dev = (struct usbnet *) ptr;
 
-	devinfo (dev, "unregister usbnet %03d/%03d, %s",
-		udev->bus->busnum, udev->devnum,
+	devinfo (dev, "unregister usbnet usb-%s-%s, %s",
+		udev->bus->bus_name, udev->devpath,
 		dev->driver_info->description);
 	
 	unregister_netdev (&dev->net);
@@ -1761,8 +1964,11 @@
 	list_del (&dev->dev_list);
 	mutex_unlock (&usbnet_mutex);
 
+	// assuming we used keventd, it must quiesce too
+	flush_scheduled_tasks ();
+
 	kfree (dev);
-	usb_dec_dev_use (udev);
+	usb_put_dev (udev);
 }
 
 
@@ -1808,15 +2014,17 @@
 	memset (dev, 0, sizeof *dev);
 
 	init_MUTEX_LOCKED (&dev->mutex);
-	usb_inc_dev_use (udev);
+	usb_get_dev (udev);
 	dev->udev = udev;
 	dev->driver_info = info;
+	dev->msg_level = msg_level;
 	INIT_LIST_HEAD (&dev->dev_list);
 	skb_queue_head_init (&dev->rxq);
 	skb_queue_head_init (&dev->txq);
 	skb_queue_head_init (&dev->done);
 	dev->bh.func = usbnet_bh;
 	dev->bh.data = (unsigned long) dev;
+	INIT_TQUEUE (&dev->kevent, kevent, dev);
 
 	// set up network interface records
 	net = &dev->net;
@@ -1836,10 +2044,11 @@
 	net->stop = usbnet_stop;
 	net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
 	net->tx_timeout = usbnet_tx_timeout;
+	net->do_ioctl = usbnet_ioctl;
 
 	register_netdev (&dev->net);
-	devinfo (dev, "register usbnet %03d/%03d, %s",
-		udev->bus->busnum, udev->devnum,
+	devinfo (dev, "register usbnet usb-%s-%s, %s",
+		udev->bus->bus_name, udev->devpath,
 		dev->driver_info->description);
 
 	// ok, it's ready to go.
@@ -1867,33 +2076,41 @@
 #ifdef	CONFIG_USB_AN2720
 {
 	USB_DEVICE (0x0547, 0x2720),	// AnchorChips defaults
-	driver_info:	(unsigned long) &an2720_info,
-},
-
-{
+	.driver_info =	(unsigned long) &an2720_info,
+}, {
 	USB_DEVICE (0x0547, 0x2727),	// Xircom PGUNET
-	driver_info:	(unsigned long) &an2720_info,
+	.driver_info =	(unsigned long) &an2720_info,
 },
 #endif
 
 #ifdef	CONFIG_USB_BELKIN
 {
 	USB_DEVICE (0x050d, 0x0004),	// Belkin
-	driver_info:	(unsigned long) &belkin_info,
+	.driver_info =	(unsigned long) &belkin_info,
 }, {
 	USB_DEVICE (0x056c, 0x8100),	// eTEK
-	driver_info:	(unsigned long) &belkin_info,
+	.driver_info =	(unsigned long) &belkin_info,
 }, {
 	USB_DEVICE (0x0525, 0x9901),	// Advance USBNET (eTEK)
-	driver_info:	(unsigned long) &belkin_info,
+	.driver_info =	(unsigned long) &belkin_info,
+},
+#endif
+
+#ifdef	CONFIG_USB_EPSON2888
+{
+	USB_DEVICE (0x0525, 0x2888),	// EPSON USB client
+	driver_info:	(unsigned long) &epson2888_info,
 },
 #endif
 
 #ifdef	CONFIG_USB_GENESYS
 {
 	USB_DEVICE (0x05e3, 0x0502),	// GL620USB-A
-	driver_info:	(unsigned long) &genelink_info,
+	.driver_info =	(unsigned long) &genelink_info,
 },
+	/* NOT: USB_DEVICE (0x05e3, 0x0501),	// GL620USB
+	 * that's half duplex, not currently supported
+	 */
 #endif
 
 #ifdef	CONFIG_USB_LINUXDEV
@@ -1904,28 +2121,32 @@
 {
 	// 1183 = 0x049F, both used as hex values?
 	USB_DEVICE (0x049F, 0x505A),	// Compaq "Itsy"
-	driver_info:	(unsigned long) &linuxdev_info,
+	.driver_info =	(unsigned long) &linuxdev_info,
+}, {
+	USB_DEVICE (0x0E7E, 0x1001),	// G.Mate "Yopy"
+	.driver_info =	(unsigned long) &linuxdev_info,
 },
+	// NOTE:  the Sharp Zaurus uses a modified version of
+	// this driver, which is not interoperable with this.
 #endif
 
 #ifdef	CONFIG_USB_NET1080
 {
 	USB_DEVICE (0x0525, 0x1080),	// NetChip ref design
-	driver_info:	(unsigned long) &net1080_info,
-},
-{
+	.driver_info =	(unsigned long) &net1080_info,
+}, {
 	USB_DEVICE (0x06D0, 0x0622),	// Laplink Gold
-	driver_info:	(unsigned long) &net1080_info,
+	.driver_info =	(unsigned long) &net1080_info,
 },
 #endif
 
 #ifdef CONFIG_USB_PL2301
 {
 	USB_DEVICE (0x067b, 0x0000),	// PL-2301
-	driver_info:	(unsigned long) &prolific_info,
+	.driver_info =	(unsigned long) &prolific_info,
 }, {
 	USB_DEVICE (0x067b, 0x0001),	// PL-2302
-	driver_info:	(unsigned long) &prolific_info,
+	.driver_info =	(unsigned long) &prolific_info,
 },
 #endif
 
@@ -1936,10 +2157,10 @@
 MODULE_DEVICE_TABLE (usb, products);
 
 static struct usb_driver usbnet_driver = {
-	name:		"usbnet",
-	id_table:	products,
-	probe:		usbnet_probe,
-	disconnect:	usbnet_disconnect,
+	.name =		driver_name,
+	.id_table =	products,
+	.probe =	usbnet_probe,
+	.disconnect =	usbnet_disconnect,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -1952,6 +2173,7 @@
 
 	get_random_bytes (node_id, sizeof node_id);
 	node_id [0] &= 0xfe;	// clear multicast bit
+	node_id [0] |= 0x02;    // set local assignment bit (IEEE802)
 
  	if (usb_register (&usbnet_driver) < 0)
  		return -1;
diff -urN linux-2.4.20-pre7/drivers/usb/vicam.c linux-2.4.20-pre8/drivers/usb/vicam.c
--- linux-2.4.20-pre7/drivers/usb/vicam.c	Wed Sep 25 18:21:07 2002
+++ linux-2.4.20-pre8/drivers/usb/vicam.c	Wed Sep 25 18:22:05 2002
@@ -475,7 +475,9 @@
 
 	if (!vdev || !buf)
 		return -EFAULT;
-
+	
+	if(buflen > 0x1e480)
+		buflen = 0x1e480;
 	if (copy_to_user(user_buf, buf2, buflen))
 		return -EFAULT;
 	return buflen;
diff -urN linux-2.4.20-pre7/drivers/video/Config.in linux-2.4.20-pre8/drivers/video/Config.in
--- linux-2.4.20-pre7/drivers/video/Config.in	Wed Sep 25 18:21:07 2002
+++ linux-2.4.20-pre8/drivers/video/Config.in	Wed Sep 25 18:22:05 2002
@@ -213,7 +213,7 @@
    if [ "$CONFIG_DECSTATION" = "y" ]; then
       dep_bool '  PMAG-BA TURBOchannel framebuffer support' CONFIG_FB_PMAG_BA $CONFIG_TC
       dep_bool '  PMAGB-B TURBOchannel framebuffer support' CONFIG_FB_PMAGB_B $CONFIG_TC
-      dep_bool '  Maxine (Personal DECstation) onboard framebuffer support' CONFIG_FB_MAXINE
+      bool '  Maxine (Personal DECstation) onboard framebuffer support' CONFIG_FB_MAXINE
    fi
    if [ "$CONFIG_NINO" = "y" ]; then
       bool '  TMPTX3912/PR31700 frame buffer support' CONFIG_FB_TX3912
diff -urN linux-2.4.20-pre7/drivers/video/clgenfb.c linux-2.4.20-pre8/drivers/video/clgenfb.c
--- linux-2.4.20-pre7/drivers/video/clgenfb.c	Wed Sep 25 18:21:07 2002
+++ linux-2.4.20-pre8/drivers/video/clgenfb.c	Wed Sep 25 18:22:05 2002
@@ -280,6 +280,7 @@
 	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_4 },
 	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5430 }, /* GD-5440 has identical id */
 	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_7543 },
+	{ BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_7548 },
 	{ BT_GD5480, NULL, PCI_DEVICE_ID_CIRRUS_5480 }, /* MacPicasso probably */
 	{ BT_PICASSO4, NULL, PCI_DEVICE_ID_CIRRUS_5446 }, /* Picasso 4 is a GD5446 */
 	{ BT_LAGUNA, "CL Laguna", PCI_DEVICE_ID_CIRRUS_5462 },
diff -urN linux-2.4.20-pre7/drivers/video/epson1356fb.c linux-2.4.20-pre8/drivers/video/epson1356fb.c
--- linux-2.4.20-pre7/drivers/video/epson1356fb.c	Wed Sep 25 18:21:09 2002
+++ linux-2.4.20-pre8/drivers/video/epson1356fb.c	Wed Sep 25 18:22:05 2002
@@ -203,7 +203,6 @@
 	fb_get_cmap:    e1356fb_get_cmap,
 	fb_set_cmap:    e1356fb_set_cmap,
 	fb_pan_display: e1356fb_pan_display,
-	fb_ioctl:	e1356fb_ioctl,
 	fb_mmap:        e1356fb_mmap,
 };
 
@@ -2032,46 +2031,6 @@
 }
 
 static int
-e1356fb_ioctl(struct inode *inode, 
-	      struct file *file, 
-	      u_int cmd,
-	      u_long arg, 
-	      int con, 
-	      struct fb_info *fb)
-{
-	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
-	blt_info_t blt;
-	u16* src = NULL;
-	int ret=0;
-    
-	switch (cmd) {
-	case FBIO_SED1356_BITBLT:
-		if (copy_from_user(&blt, (void *)arg, sizeof(blt_info_t)))
-			return -EFAULT;
-		if (blt.src) {
-			if ((ret = verify_area(VERIFY_READ,
-					       (void*)blt.src, blt.srcsize)))
-				return ret;
-			if ((src = (u16*)kmalloc(blt.srcsize,
-						 GFP_KERNEL)) == NULL)
-				return -ENOMEM;
-			if (copy_from_user(src, (void *)blt.src, blt.srcsize))
-				return -EFAULT;
-			blt.src = src;
-		}
-		ret = doBlt(&info->current_par, info, &blt);
-		if (src)
-			kfree(src);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-
-static int
 e1356fb_mmap(struct fb_info *fb,
 	     struct file *file,
 	     struct vm_area_struct *vma)
diff -urN linux-2.4.20-pre7/drivers/video/sstfb.c linux-2.4.20-pre8/drivers/video/sstfb.c
--- linux-2.4.20-pre7/drivers/video/sstfb.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/drivers/video/sstfb.c	Wed Sep 25 18:22:07 2002
@@ -11,6 +11,8 @@
  * 04/2001 Paul Mundt      <lethal@chaoticdreams.org>
  * 05/2001 Urs Ganse       <ursg@uni.de>
  *     (initial work on voodoo2 port, interlace)
+ * 09/2002 Helge Deller    <deller@gmx.de>
+ *     (enable driver on big-endian machines (hppa), ioctl fixes)
  *
  *
  * $Id: sstfb.c,v 1.26.4.1 2001/08/29 01:30:37 ghoz Exp $
@@ -30,8 +32,6 @@
 -ASK: I can choose different ordering for the color bitfields (rgba argb ...)
       wich one should i use ? is there any preferred one ? It seems ARGB is
       the one ...
--ASK: later: how to cope with endianness ? the fbi chip has builtin functions
-      to do byte swizling /swapping, maybe use that ...
 -TODO: check the error paths . if something get wrong, the error doesn't seem
       to be very well handled...if handled at all.. not good.
 -TODO: in  set_var check the validity of timings (hsync vsync)...
@@ -107,6 +107,7 @@
 
 #include <asm/io.h>
 #include <asm/ioctl.h>
+#include <asm/uaccess.h>
 
 #include <video/fbcon.h>
 #include <video/fbcon-cfb16.h>
@@ -774,13 +775,19 @@
 {
 #define sst_info	((struct sstfb_info *) info)
 
-	struct fb_var_screeninfo tmpvar;
+  	struct fb_var_screeninfo *var;
+ 	struct fb_var_screeninfo var2;
 
 	f_dprintk("sstfb_get_fix(con: %d)\n",con);
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	
 	if (con == -1)
-		sstfb_encode_var(&tmpvar, &sst_info->current_par, sst_info);
+	{
+		sstfb_encode_var(&var2, &sst_info->current_par, sst_info);
+		var = &var2;
+	}
 	else
-		tmpvar = fb_display[con].var;
+		var = &fb_display[con].var;
 
 	strcpy(fix->id, sst_info->info.modename);
 	/* lfb phys address = membase + 4Mb */
@@ -789,11 +796,12 @@
 
 	fix->type        = FB_TYPE_PACKED_PIXELS;
 	fix->visual      = FB_VISUAL_TRUECOLOR;
+	fix->accel       = FB_ACCEL_NONE;
 	/*
 	 *   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 = (tmpvar.bits_per_pixel == 16) ? 2048 : 4096 ;
+	fix->line_length = (var->bits_per_pixel == 16) ? 2048 : 4096 ;
 	return 0;
 #undef sst_info
 }
@@ -969,7 +977,7 @@
 #if (SST_DEBUG_IOCTL >0)
 	int i;
 	u_long p;
-	u32 tmp;
+	u32 tmp, val;
 	u32 fbiinit0;
 	struct pci_dev * sst_dev = sst_info->dev;
 #endif
@@ -988,20 +996,24 @@
 #  endif /* (SST_DEBUG_VAR >0) */
 /* fills the lfb up to *(u32*)arg */
 	case _IOW('F', 0xdc, u32):	/* 0x46dc */
-		if (*(u32*)arg > 0x400000 )
-			*(u32*) arg = 0x400000;
-		f_dprintk("filling %#x \n", *(u32*)arg);
-		for (p = 0 ; p < *(u32*)arg; p+=2)
+		if (copy_from_user(&val, (void *) arg, sizeof(val)))
+			return -EFAULT;
+		if (val > 0x400000 )
+			val = 0x400000;
+		f_dprintk("filling %#x \n", val);
+		for (p = 0 ; p < val; p+=2)
 			writew( p >> 6 , sst_info->video.vbase + p);
 		return 0;
 /* change VGA pass_through */
 	case _IOW('F', 0xdd, u32):	/* 0x46dd */
+		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 (* (u32*)arg) {
+		if (val) {
 			sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
 			iprintk ( "Disabling VGA pass-through\n");
 		} else {
@@ -1494,7 +1506,7 @@
 	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR);
 
 	/* set lfbmode : set mode + front buffer for reads/writes
-	   + disable pipeline + disable byte swapping */
+	   + disable pipeline */
 	switch(par->bpp) {
 	case 16:
 		lfbmode = LFB_565;
@@ -1514,6 +1526,12 @@
 		break;
 	}
 
+#if defined(__BIG_ENDIAN)
+	/* enable byte-swizzle functionality in hardware */
+	lfbmode |= ( LFB_WORD_SWIZZLE_WR | LFB_BYTE_SWIZZLE_WR |
+		     LFB_WORD_SWIZZLE_RD | LFB_BYTE_SWIZZLE_RD );
+#endif
+	
 	if (clipping) {
 		sst_write(LFBMODE, lfbmode | EN_PXL_PIPELINE);
 	/*
diff -urN linux-2.4.20-pre7/drivers/video/sstfb.h linux-2.4.20-pre8/drivers/video/sstfb.h
--- linux-2.4.20-pre7/drivers/video/sstfb.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre8/drivers/video/sstfb.h	Wed Sep 25 18:22:07 2002
@@ -114,7 +114,11 @@
 #  define RD_BUFF_FRONT		  0		/* read buff select (front) */
 #  define RD_BUFF_BACK		  (1 << 6)	/* back */
 #  define EN_PXL_PIPELINE	  BIT(8)	/* pixel pipeline (clip..)*/
+#  define LFB_WORD_SWIZZLE_WR	  BIT(11)	/* enable write-wordswap (big-endian) */
+#  define LFB_BYTE_SWIZZLE_WR	  BIT(12)	/* enable write-byteswap (big-endian) */
 #  define LFB_INVERT_Y		  BIT(13)	/* invert Y origin (LFB) */
+#  define LFB_WORD_SWIZZLE_RD	  BIT(15)	/* enable read-wordswap (big-endian) */
+#  define LFB_BYTE_SWIZZLE_RD	  BIT(16)	/* enable read-byteswap (big-endian) */
 #define CLIP_LEFT_RIGHT		0x0118
 #define CLIP_LOWY_HIGHY		0x011c
 #define NOPCMD			0x0120
diff -urN linux-2.4.20-pre7/fs/ext2/super.c linux-2.4.20-pre8/fs/ext2/super.c
--- linux-2.4.20-pre7/fs/ext2/super.c	Mon Feb 25 11:38:08 2002
+++ linux-2.4.20-pre8/fs/ext2/super.c	Wed Sep 25 18:22:07 2002
@@ -486,6 +486,9 @@
 		       bdevname(dev), i);
 		goto failed_mount;
 	}
+	if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL))
+		ext2_warning(sb, __FUNCTION__,
+			"mounting ext3 filesystem as ext2\n");
 	sb->s_blocksize_bits =
 		le32_to_cpu(EXT2_SB(sb)->s_es->s_log_block_size) + 10;
 	sb->s_blocksize = 1 << sb->s_blocksize_bits;
diff -urN linux-2.4.20-pre7/fs/jfs/file.c linux-2.4.20-pre8/fs/jfs/file.c
--- linux-2.4.20-pre7/fs/jfs/file.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/file.c	Wed Sep 25 18:22:07 2002
@@ -19,6 +19,7 @@
 
 #include <linux/fs.h>
 #include "jfs_incore.h"
+#include "jfs_dmap.h"
 #include "jfs_txnmgr.h"
 #include "jfs_xattr.h"
 #include "jfs_debug.h"
@@ -96,6 +97,47 @@
 	IWRITE_UNLOCK(ip);
 }
 
+static int jfs_open(struct inode *inode, struct file *file)
+{
+	int rc;
+
+	if ((rc = generic_file_open(inode, file)))
+		return rc;
+
+	/*
+	 * We attempt to allow only one "active" file open per aggregate
+	 * group.  Otherwise, appending to files in parallel can cause
+	 * fragmentation within the files.
+	 *
+	 * If the file is empty, it was probably just created and going
+	 * to be written to.  If it has a size, we'll hold off until the
+	 * file is actually grown.
+	 */
+	if (S_ISREG(inode->i_mode) && file->f_mode & FMODE_WRITE &&
+	    (inode->i_size == 0)) {
+		struct jfs_inode_info *ji = JFS_IP(inode);
+		if (ji->active_ag == -1) {
+			ji->active_ag = ji->agno;
+			atomic_inc(
+			    &JFS_SBI(inode->i_sb)->bmap->db_active[ji->agno]);
+		}
+	}
+
+	return 0;
+}
+static int jfs_release(struct inode *inode, struct file *file)
+{
+	struct jfs_inode_info *ji = JFS_IP(inode);
+
+	if (ji->active_ag != -1) {
+		struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap;
+		atomic_dec(&bmap->db_active[ji->active_ag]);
+		ji->active_ag = -1;
+	}
+
+	return 0;
+}
+
 struct inode_operations jfs_file_inode_operations = {
 	.truncate	= jfs_truncate,
 	.setxattr	= jfs_setxattr,
@@ -105,10 +147,11 @@
 };
 
 struct file_operations jfs_file_operations = {
-	.open		= generic_file_open,
+	.open		= jfs_open,
 	.llseek		= generic_file_llseek,
 	.write		= generic_file_write,
 	.read		= generic_file_read,
 	.mmap		= generic_file_mmap,
 	.fsync		= jfs_fsync,
+	.release	= jfs_release,
 };
diff -urN linux-2.4.20-pre7/fs/jfs/inode.c linux-2.4.20-pre8/fs/jfs/inode.c
--- linux-2.4.20-pre7/fs/jfs/inode.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/inode.c	Wed Sep 25 18:22:07 2002
@@ -41,6 +41,13 @@
 
 	jFYI(1, ("jfs_clear_inode called ip = 0x%p\n", inode));
 
+	if (ji->active_ag != -1) {
+		printk(KERN_ERR "jfs_clear_inode, active_ag = %d\n",
+		       ji->active_ag);
+		printk(KERN_ERR "i_ino = %ld, i_mode = %o\n",
+		       inode->i_ino, inode->i_mode);
+	}
+
 	ASSERT(list_empty(&ji->mp_list));
 	ASSERT(list_empty(&ji->anon_inode_list));
 
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_btree.h linux-2.4.20-pre8/fs/jfs/jfs_btree.h
--- linux-2.4.20-pre7/fs/jfs/jfs_btree.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_btree.h	Wed Sep 25 18:22:07 2002
@@ -25,18 +25,18 @@
  */
 
 /*
- *	basic btree page - btpage_t
- */
-typedef struct {
-	s64 next;		/* 8: right sibling bn */
-	s64 prev;		/* 8: left sibling bn */
-
-	u8 flag;		/* 1: */
-	u8 rsrvd[7];		/* 7: type specific */
-	s64 self;		/* 8: self address */
+ *	basic btree page - btpage
+ *
+struct btpage {
+	s64 next;		right sibling bn
+	s64 prev;		left sibling bn
+
+	u8 flag;
+	u8 rsrvd[7];		type specific
+	s64 self;		self address
 
-	u8 entry[4064];		/* 4064: */
-} btpage_t;			/* (4096) */
+	u8 entry[4064];
+};						*/
 
 /* btpaget_t flag */
 #define BT_TYPE		0x07	/* B+-tree index */
@@ -68,7 +68,7 @@
 {\
 	if ((BN) == 0)\
 	{\
-		MP = (metapage_t *)&JFS_IP(IP)->bxflag;\
+		MP = (struct metapage *)&JFS_IP(IP)->bxflag;\
 		P = (TYPE *)&JFS_IP(IP)->ROOT;\
 		RC = 0;\
 		jEVENT(0,("%d BT_GETPAGE returning root\n", __LINE__));\
@@ -112,18 +112,18 @@
  * top frame record the leaf page/entry selected.
  */
 #define	MAXTREEHEIGHT		8
-typedef struct btframe {	/* stack frame */
+struct btframe {	/* stack frame */
 	s64 bn;			/* 8: */
 	s16 index;		/* 2: */
 	s16 lastindex;		/* 2: */
 	struct metapage *mp;	/* 4: */
-} btframe_t;			/* (16) */
+};				/* (16) */
 
-typedef struct btstack {
-	btframe_t *top;		/* 4: */
-	int nsplit;		/* 4: */
-	btframe_t stack[MAXTREEHEIGHT];
-} btstack_t;
+struct btstack {
+	struct btframe *top;
+	int nsplit;
+	struct btframe stack[MAXTREEHEIGHT];
+};
 
 #define BT_CLR(btstack)\
 	(btstack)->top = (btstack)->stack
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_defragfs.h linux-2.4.20-pre8/fs/jfs/jfs_defragfs.h
--- linux-2.4.20-pre7/fs/jfs/jfs_defragfs.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_defragfs.h	Wed Sep 25 18:22:07 2002
@@ -21,7 +21,7 @@
 /*
  *	defragfs parameter list
  */
-typedef struct {
+struct defragfs {
 	uint flag;		/* 4: */
 	u8 dev;			/* 1: */
 	u8 pad[3];		/* 3: */
@@ -33,7 +33,7 @@
 	s64 old_xaddr;		/* 8: */
 	s64 new_xaddr;		/* 8: */
 	s32 xlen;		/* 4: */
-} defragfs_t;			/* (52) */
+};
 
 /* plist flag */
 #define DEFRAGFS_SYNC		0x80000000
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_dinode.h linux-2.4.20-pre8/fs/jfs/jfs_dinode.h
--- linux-2.4.20-pre7/fs/jfs/jfs_dinode.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_dinode.h	Wed Sep 25 18:22:07 2002
@@ -28,7 +28,7 @@
 
 
 /*
- *      on-disk inode (dinode_t): 512 bytes
+ *      on-disk inode : 512 bytes
  *
  * note: align 64-bit fields on 8-byte boundary.
  */
@@ -89,7 +89,7 @@
 			 * If the index is small enough, the table is inline,
 			 * otherwise, an x-tree root overlays this table
 			 */
-			dir_table_slot_t _table[12];	/* 96: inline */
+			struct dir_table_slot _table[12]; /* 96: inline */
 
 			dtroot_t _dtroot;		/* 288: dtree root */
 		} _dir;					/* (384) */
@@ -131,9 +131,6 @@
 	} u;
 };
 
-typedef struct dinode dinode_t;
-
-
 /* extended mode bits (on-disk inode di_mode) */
 #define IFJOURNAL       0x00010000	/* journalled file */
 #define ISPARSE         0x00020000	/* sparse file enabled */
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_dmap.c linux-2.4.20-pre8/fs/jfs/jfs_dmap.c
--- linux-2.4.20-pre7/fs/jfs/jfs_dmap.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_dmap.c	Wed Sep 25 18:22:07 2002
@@ -100,30 +100,37 @@
 /*
  * forward references
  */
-static void dbAllocBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
+static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+			int nblocks);
 static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval);
 static void dbBackSplit(dmtree_t * tp, int leafno);
 static void dbJoin(dmtree_t * tp, int leafno, int newval);
 static void dbAdjTree(dmtree_t * tp, int leafno, int newval);
-static int dbAdjCtl(bmap_t * bmp, s64 blkno, int newval, int alloc,
+static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc,
 		    int level);
-static int dbAllocAny(bmap_t * bmp, s64 nblocks, int l2nb, s64 * results);
-static int dbAllocNext(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
-static int dbAllocNear(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks,
+static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results);
+static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		       int nblocks);
+static int dbAllocNear(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		       int nblocks,
 		       int l2nb, s64 * results);
-static int dbAllocDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
-static int dbAllocDmapLev(bmap_t * bmp, dmap_t * dp, int nblocks, int l2nb,
+static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		       int nblocks);
+static int dbAllocDmapLev(struct bmap * bmp, struct dmap * dp, int nblocks,
+			  int l2nb,
 			  s64 * results);
-static int dbAllocAG(bmap_t * bmp, int agno, s64 nblocks, int l2nb,
+static int dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb,
 		     s64 * results);
-static int dbAllocCtl(bmap_t * bmp, s64 nblocks, int l2nb, s64 blkno,
+static int dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno,
 		      s64 * results);
 int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks);
 static int dbFindBits(u32 word, int l2nb);
-static int dbFindCtl(bmap_t * bmp, int l2nb, int level, s64 * blkno);
+static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno);
 static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx);
-static void dbFreeBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
-static int dbFreeDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
+static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		       int nblocks);
+static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		      int nblocks);
 static int dbMaxBud(u8 * cp);
 s64 dbMapFileSizeToMapSize(struct inode *ipbmap);
 int blkstol2(s64 nb);
@@ -132,12 +139,12 @@
 int cntlz(u32 value);
 int cnttz(u32 word);
 
-static int dbAllocDmapBU(bmap_t * bmp, dmap_t * dp, s64 blkno,
+static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
 			 int nblocks);
-static int dbInitDmap(dmap_t * dp, s64 blkno, int nblocks);
-static int dbInitDmapTree(dmap_t * dp);
-static int dbInitTree(dmaptree_t * dtp);
-static int dbInitDmapCtl(dmapctl_t * dcp, int level, int i);
+static int dbInitDmap(struct dmap * dp, s64 blkno, int nblocks);
+static int dbInitDmapTree(struct dmap * dp);
+static int dbInitTree(struct dmaptree * dtp);
+static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i);
 static int dbGetL2AGSize(s64 nblocks);
 
 /*
@@ -186,16 +193,16 @@
  */
 int dbMount(struct inode *ipbmap)
 {
-	bmap_t *bmp;
-	dbmap_t *dbmp_le;
-	metapage_t *mp;
+	struct bmap *bmp;
+	struct dbmap *dbmp_le;
+	struct metapage *mp;
 	int i;
 
 	/*
 	 * allocate/initialize the in-memory bmap descriptor
 	 */
 	/* allocate memory for the in-memory bmap descriptor */
-	bmp = kmalloc(sizeof(bmap_t), GFP_KERNEL);
+	bmp = kmalloc(sizeof(struct bmap), GFP_KERNEL);
 	if (bmp == NULL)
 		return (ENOMEM);
 
@@ -209,7 +216,7 @@
 	}
 
 	/* copy the on-disk bmap descriptor to its in-memory version. */
-	dbmp_le = (dbmap_t *) mp->data;
+	dbmp_le = (struct dbmap *) mp->data;
 	bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize);
 	bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);
 	bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
@@ -234,6 +241,7 @@
 	bmp->db_ipbmap = ipbmap;
 	JFS_SBI(ipbmap->i_sb)->bmap = bmp;
 
+	memset(bmp->db_active, 0, sizeof(bmp->db_active));
 	DBINITMAP(bmp->db_mapsize, ipbmap, &bmp->db_DBmap);
 
 	/*
@@ -263,7 +271,8 @@
  */
 int dbUnmount(struct inode *ipbmap, int mounterror)
 {
-	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+	struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+	int i;
 
 	if (!(mounterror || isReadOnly(ipbmap)))
 		dbSync(ipbmap);
@@ -273,6 +282,14 @@
 	 */
 	truncate_inode_pages(ipbmap->i_mapping, 0);
 
+	/*
+	 * Sanity Check
+	 */
+	for (i = 0; i < bmp->db_numag; i++)
+		if (atomic_read(&bmp->db_active[i]))
+			printk(KERN_ERR "dbUnmount: db_active[%d] = %d\n",
+			       i, atomic_read(&bmp->db_active[i]));
+
 	/* free the memory for the in-memory bmap. */
 	kfree(bmp);
 
@@ -284,9 +301,9 @@
  */
 int dbSync(struct inode *ipbmap)
 {
-	dbmap_t *dbmp_le;
-	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
-	metapage_t *mp;
+	struct dbmap *dbmp_le;
+	struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+	struct metapage *mp;
 	int i;
 
 	/*
@@ -301,7 +318,7 @@
 		return (EIO);
 	}
 	/* copy the in-memory version of the bmap to the on-disk version */
-	dbmp_le = (dbmap_t *) mp->data;
+	dbmp_le = (struct dbmap *) mp->data;
 	dbmp_le->dn_mapsize = cpu_to_le64(bmp->db_mapsize);
 	dbmp_le->dn_nfree = cpu_to_le64(bmp->db_nfree);
 	dbmp_le->dn_l2nbperpage = cpu_to_le32(bmp->db_l2nbperpage);
@@ -354,12 +371,12 @@
  */
 int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
 {
-	metapage_t *mp;
-	dmap_t *dp;
+	struct metapage *mp;
+	struct dmap *dp;
 	int nb, rc;
 	s64 lblkno, rem;
 	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
-	bmap_t *bmp = JFS_SBI(ip->i_sb)->bmap;
+	struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;
 
 	IREAD_LOCK(ipbmap);
 
@@ -383,7 +400,7 @@
 			IREAD_UNLOCK(ipbmap);
 			return (EIO);
 		}
-		dp = (dmap_t *) mp->data;
+		dp = (struct dmap *) mp->data;
 
 		/* determine the number of blocks to be freed from
 		 * this dmap.
@@ -434,16 +451,16 @@
  */
 int
 dbUpdatePMap(struct inode *ipbmap,
-	     int free, s64 blkno, s64 nblocks, tblock_t * tblk)
+	     int free, s64 blkno, s64 nblocks, struct tblock * tblk)
 {
 	int nblks, dbitno, wbitno, rbits;
 	int word, nbits, nwords;
-	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+	struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
 	s64 lblkno, rem, lastlblkno;
 	u32 mask;
-	dmap_t *dp;
-	metapage_t *mp;
-	log_t *log;
+	struct dmap *dp;
+	struct metapage *mp;
+	struct jfs_log *log;
 	int lsn, difft, diffp;
 
 	/* the blocks better be within the mapsize. */
@@ -451,7 +468,7 @@
 
 	/* compute delta of transaction lsn from log syncpt */
 	lsn = tblk->lsn;
-	log = (log_t *) JFS_SBI(tblk->sb)->log;
+	log = (struct jfs_log *) JFS_SBI(tblk->sb)->log;
 	logdiff(difft, lsn, log);
 
 	/*
@@ -472,7 +489,7 @@
 			if (mp == NULL)
 				return (EIO);
 		}
-		dp = (dmap_t *) mp->data;
+		dp = (struct dmap *) mp->data;
 
 		/* determine the bit number and word within the dmap of
 		 * the starting block.  also determine how many blocks
@@ -591,102 +608,77 @@
  *
  * FUNCTION:    find the preferred allocation group for new allocations.
  *
- *		we try to keep the trailing (rightmost) allocation groups
- *		free for large allocations.  we try to do this by targeting
- *		new inode allocations towards the leftmost or 'active'
- *		allocation groups while keeping the rightmost or 'inactive'
- *		allocation groups free. once the active allocation groups
- *		have dropped to a certain percentage of free space, we add
- *		the leftmost inactive allocation group to the active set.
- *
- *		within the active allocation groups, we maintain a preferred
+ *		Within the allocation groups, we maintain a preferred
  *		allocation group which consists of a group with at least
- *		average free space over the active set. it is the preferred
- *		group that we target new inode allocation towards.  the 
- *		tie-in between inode allocation and block allocation occurs
- *		as we allocate the first (data) block of an inode and specify
- *		the inode (block) as the allocation hint for this block.
+ *		average free space.  It is the preferred group that we target
+ *		new inode allocation towards.  The tie-in between inode
+ *		allocation and block allocation occurs as we allocate the
+ *		first (data) block of an inode and specify the inode (block)
+ *		as the allocation hint for this block.
+ *
+ *		We try to avoid having more than one open file growing in
+ *		an allocation group, as this will lead to fragmentation.
+ *		This differs from the old OS/2 method of trying to keep
+ *		empty ags around for large allocations.
  *
  * PARAMETERS:
  *      ipbmap	-  pointer to in-core inode for the block map.
  *
  * RETURN VALUES:
  *      the preferred allocation group number.
- *
- * note: only called by dbAlloc();
  */
 int dbNextAG(struct inode *ipbmap)
 {
-	s64 avgfree, inactfree, actfree, rem;
-	int actags, inactags, l2agsize;
-	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+	s64 avgfree;
+	int agpref;
+	s64 hwm = 0;
+	int i;
+	int next_best = -1;
+	struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
 
 	BMAP_LOCK(bmp);
 
-	/* determine the number of active allocation groups (i.e.
-	 * the number of allocation groups up to and including
-	 * the rightmost allocation group with blocks allocated
-	 * in it.
-	 */
-	actags = bmp->db_maxag + 1;
-	assert(actags <= bmp->db_numag);
-
-	/* get the number of inactive allocation groups (i.e. the
-	 * number of allocation group following the rightmost group
-	 * with allocation in it.
-	 */
-	inactags = bmp->db_numag - actags;
+	/* determine the average number of free blocks within the ags. */
+	avgfree = (u32)bmp->db_nfree / bmp->db_numag;
 
-	/* determine how many blocks are in the inactive allocation
-	 * groups. in doing this, we must account for the fact that
-	 * the rightmost group might be a partial group (i.e. file
-	 * system size is not a multiple of the group size).
+	/*
+	 * if the current preferred ag does not have an active allocator
+	 * and has at least average freespace, return it
 	 */
-	l2agsize = bmp->db_agl2size;
-	rem = bmp->db_mapsize & (bmp->db_agsize - 1);
-	inactfree = (inactags
-		     && rem) ? ((inactags - 1) << l2agsize) +
-	    rem : inactags << l2agsize;
+	agpref = bmp->db_agpref;
+	if ((atomic_read(&bmp->db_active[agpref]) == 0) &&
+	    (bmp->db_agfree[agpref] >= avgfree))
+		goto unlock;
 
-	/* now determine how many free blocks are in the active
-	 * allocation groups plus the average number of free blocks
-	 * within the active ags.
+	/* From the last preferred ag, find the next one with at least
+	 * average free space.
 	 */
-	actfree = bmp->db_nfree - inactfree;
-	avgfree = (u32) actfree / (u32) actags;
+	for (i = 0 ; i < bmp->db_numag; i++, agpref++) {
+		if (agpref == bmp->db_numag)
+			agpref = 0;
 
-	/* check if not all of the allocation groups are active.
-	 */
-	if (actags < bmp->db_numag) {
-		/* not all of the allocation groups are active.  determine
-		 * if we should extend the active set by 1 (i.e. add the
-		 * group following the current active set).  we do so if
-		 * the number of free blocks within the active set is less
-		 * than the allocation group set and average free within
-		 * the active set is less than 60%.  we activate a new group
-		 * by setting the allocation group preference to the new
-		 * group.
-		 */
-		if (actfree < bmp->db_agsize &&
-		    ((avgfree * 100) >> l2agsize) < 60)
-			bmp->db_agpref = actags;
-	} else {
-		/* all allocation groups are in the active set.  check if
-		 * the preferred allocation group has average free space.
-		 * if not, re-establish the preferred group as the leftmost
-		 * group with average free space.
-		 */
-		if (bmp->db_agfree[bmp->db_agpref] < avgfree) {
-			for (bmp->db_agpref = 0; bmp->db_agpref < actags;
-			     bmp->db_agpref++) {
-				if (bmp->db_agfree[bmp->db_agpref] <=
-				    avgfree)
-					break;
-			}
-			assert(bmp->db_agpref < bmp->db_numag);
+		if (atomic_read(&bmp->db_active[agpref]))
+			/* open file is currently growing in this ag */
+			continue;
+		if (bmp->db_agfree[agpref] >= avgfree) {
+			/* Return this one */
+			bmp->db_agpref = agpref;
+			goto unlock;
+		} else if (bmp->db_agfree[agpref] > hwm) {
+			/* Less than avg. freespace, but best so far */
+			hwm = bmp->db_agfree[agpref];
+			next_best = agpref;
 		}
 	}
 
+	/*
+	 * If no inactive ag was found with average freespace, use the
+	 * next best
+	 */
+	if (next_best != -1)
+		bmp->db_agpref = next_best;
+	/* else leave db_agpref unchanged */
+unlock:
 	BMAP_UNLOCK(bmp);
 
 	/* return the preferred group.
@@ -694,7 +686,6 @@
 	return (bmp->db_agpref);
 }
 
-
 /*
  * NAME:	dbAlloc()
  *
@@ -737,12 +728,13 @@
 {
 	int rc, agno;
 	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
-	bmap_t *bmp;
-	metapage_t *mp;
+	struct bmap *bmp;
+	struct metapage *mp;
 	s64 lblkno, blkno;
-	dmap_t *dp;
+	struct dmap *dp;
 	int l2nb;
 	s64 mapSize;
+	int writers;
 
 	/* assert that nblocks is valid */
 	assert(nblocks > 0);
@@ -767,11 +759,10 @@
 	/* the hint should be within the map */
 	assert(hint < mapSize);
 
-	/* if no hint was specified or the number of blocks to be
-	 * allocated is greater than the allocation group size, try
-	 * to allocate anywhere.
+	/* if the number of blocks to be allocated is greater than the
+	 * allocation group size, try to allocate anywhere.
 	 */
-	if (hint == 0 || l2nb > bmp->db_agl2size) {
+	if (l2nb > bmp->db_agl2size) {
 		IWRITE_LOCK(ipbmap);
 
 		rc = dbAllocAny(bmp, nblocks, l2nb, results);
@@ -783,39 +774,34 @@
 		goto write_unlock;
 	}
 
+	/*
+	 * If no hint, let dbNextAG recommend an allocation group
+	 */
+	if (hint == 0)
+		goto pref_ag;
+
 	/* we would like to allocate close to the hint.  adjust the
 	 * hint to the block following the hint since the allocators
 	 * will start looking for free space starting at this point.
-	 * if the hint was the last block of the file system, try to
-	 * allocate in the same allocation group as the hint.
 	 */
 	blkno = hint + 1;
-	if (blkno >= bmp->db_mapsize) {
-		blkno--;
-		goto tryag;
-	}
+
+	if (blkno >= bmp->db_mapsize)
+		goto pref_ag;
+
+	agno = blkno >> bmp->db_agl2size;
 
 	/* check if blkno crosses over into a new allocation group.
 	 * if so, check if we should allow allocations within this
-	 * allocation group.  we try to keep the trailing (rightmost)
-	 * allocation groups of the file system free for large
-	 * allocations and may want to prevent this allocation from
-	 * spilling over into this space.
-	 */
-	if ((blkno & (bmp->db_agsize - 1)) == 0) {
-		/* check if the AG is beyond the rightmost AG with
-		 * allocations in it.  if so, call dbNextAG() to
-		 * determine if the allocation should be allowed
-		 * to proceed within this AG or should be targeted
-		 * to another AG.
-		 */
-		agno = blkno >> bmp->db_agl2size;
-		if (agno > bmp->db_maxag) {
-			agno = dbNextAG(ipbmap);
-			blkno = (s64) agno << bmp->db_agl2size;
-			goto tryag;
-		}
-	}
+	 * allocation group.
+	 */
+	if ((blkno & (bmp->db_agsize - 1)) == 0)
+		/* check if the AG is currenly being written to.
+		 * if so, call dbNextAG() to find a non-busy
+		 * AG with sufficient free space.
+		 */
+		if (atomic_read(&bmp->db_active[agno]))
+			goto pref_ag;
 
 	/* check if the allocation request size can be satisfied from a
 	 * single dmap.  if so, try to allocate from the dmap containing
@@ -832,14 +818,13 @@
 		if (mp == NULL)
 			goto read_unlock;
 
-		dp = (dmap_t *) mp->data;
+		dp = (struct dmap *) mp->data;
 
 		/* first, try to satisfy the allocation request with the
 		 * blocks beginning at the hint.
 		 */
-		if ((rc =
-		     dbAllocNext(bmp, dp, blkno,
-				 (int) nblocks)) != ENOSPC) {
+		if ((rc = dbAllocNext(bmp, dp, blkno, (int) nblocks))
+		    != ENOSPC) {
 			if (rc == 0) {
 				*results = blkno;
 				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
@@ -851,12 +836,23 @@
 			goto read_unlock;
 		}
 
+		writers = atomic_read(&bmp->db_active[agno]);
+		if ((writers > 1) ||
+		    ((writers == 1) && (JFS_IP(ip)->active_ag != agno))) {
+			/*
+			 * Someone else is writing in this allocation
+			 * group.  To avoid fragmenting, try another ag
+			 */
+			release_metapage(mp);
+			IREAD_UNLOCK(ipbmap);
+			goto pref_ag;
+		}
+
 		/* next, try to satisfy the allocation request with blocks
 		 * near the hint.
 		 */
 		if ((rc =
-		     dbAllocNear(bmp, dp, blkno, (int) nblocks, l2nb,
-				 results))
+		     dbAllocNear(bmp, dp, blkno, (int) nblocks, l2nb, results))
 		    != ENOSPC) {
 			if (rc == 0) {
 				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
@@ -869,10 +865,9 @@
 		}
 
 		/* try to satisfy the allocation request with blocks within
-		 * the same allocation group as the hint.
+		 * the same dmap as the hint.
 		 */
-		if ((rc =
-		     dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results))
+		if ((rc = dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results))
 		    != ENOSPC) {
 			if (rc == 0) {
 				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
@@ -888,14 +883,30 @@
 		IREAD_UNLOCK(ipbmap);
 	}
 
-      tryag:
+	/* try to satisfy the allocation request with blocks within
+	 * the same allocation group as the hint.
+	 */
 	IWRITE_LOCK(ipbmap);
+	if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results))
+	    != ENOSPC) {
+		if (rc == 0)
+			DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
+				*results, nblocks);
+		goto write_unlock;
+	}
+	IWRITE_UNLOCK(ipbmap);
+
 
-	/* determine the allocation group number of the hint and try to
-	 * allocate within this allocation group.  if that fails, try to
+      pref_ag:
+	/*
+	 * Let dbNextAG recommend a preferred allocation group
+	 */
+	agno = dbNextAG(ipbmap);
+	IWRITE_LOCK(ipbmap);
+
+	/* Try to allocate within this allocation group.  if that fails, try to
 	 * allocate anywhere in the map.
 	 */
-	agno = blkno >> bmp->db_agl2size;
 	if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) == ENOSPC)
 		rc = dbAllocAny(bmp, nblocks, l2nb, results);
 	if (rc == 0) {
@@ -933,10 +944,10 @@
 {
 	int rc;
 	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
-	bmap_t *bmp = JFS_SBI(ip->i_sb)->bmap;
-	dmap_t *dp;
+	struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;
+	struct dmap *dp;
 	s64 lblkno;
-	metapage_t *mp;
+	struct metapage *mp;
 
 	IREAD_LOCK(ipbmap);
 
@@ -965,7 +976,7 @@
 		IREAD_UNLOCK(ipbmap);
 		return (EIO);
 	}
-	dp = (dmap_t *) mp->data;
+	dp = (struct dmap *) mp->data;
 
 	/* try to allocate the requested extent */
 	rc = dbAllocNext(bmp, dp, blkno, nblocks);
@@ -1068,11 +1079,11 @@
 	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
 	s64 lblkno, lastblkno, extblkno;
 	uint rel_block;
-	metapage_t *mp;
-	dmap_t *dp;
+	struct metapage *mp;
+	struct dmap *dp;
 	int rc;
 	struct inode *ipbmap = sbi->ipbmap;
-	bmap_t *bmp;
+	struct bmap *bmp;
 
 	/*
 	 * We don't want a non-aligned extent to cross a page boundary
@@ -1120,7 +1131,7 @@
 	}
 
 	DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks);
-	dp = (dmap_t *) mp->data;
+	dp = (struct dmap *) mp->data;
 
 	/* try to allocate the blocks immediately following the
 	 * current allocation.
@@ -1163,7 +1174,8 @@
  *
  * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
  */
-static int dbAllocNext(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		       int nblocks)
 {
 	int dbitno, word, rembits, nb, nwords, wbitno, nw;
 	int l2size;
@@ -1289,8 +1301,8 @@
  * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
  */
 static int
-dbAllocNear(bmap_t * bmp,
-	    dmap_t * dp, s64 blkno, int nblocks, int l2nb, s64 * results)
+dbAllocNear(struct bmap * bmp,
+	    struct dmap * dp, s64 blkno, int nblocks, int l2nb, s64 * results)
 {
 	int word, lword, rc;
 	s8 *leaf = dp->tree.stree + le32_to_cpu(dp->tree.leafidx);
@@ -1391,10 +1403,10 @@
  * note: IWRITE_LOCK(ipmap) held on entry/exit;
  */
 static int
-dbAllocAG(bmap_t * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
+dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
 {
-	metapage_t *mp;
-	dmapctl_t *dcp;
+	struct metapage *mp;
+	struct dmapctl *dcp;
 	int rc, ti, i, k, m, n, agperlev;
 	s64 blkno, lblkno;
 	int budmin;
@@ -1447,7 +1459,7 @@
 	mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
 	if (mp == NULL)
 		return (EIO);
-	dcp = (dmapctl_t *) mp->data;
+	dcp = (struct dmapctl *) mp->data;
 	budmin = dcp->budmin;
 
 	/* search the subtree(s) of the dmap control page that describes
@@ -1566,7 +1578,7 @@
  *
  * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
  */
-static int dbAllocAny(bmap_t * bmp, s64 nblocks, int l2nb, s64 * results)
+static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results)
 {
 	int rc;
 	s64 blkno = 0;
@@ -1616,13 +1628,13 @@
  *
  * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
  */
-static int dbFindCtl(bmap_t * bmp, int l2nb, int level, s64 * blkno)
+static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
 {
 	int rc, leafidx, lev;
 	s64 b, lblkno;
-	dmapctl_t *dcp;
+	struct dmapctl *dcp;
 	int budmin;
-	metapage_t *mp;
+	struct metapage *mp;
 
 	/* starting at the specified dmap control page level and block
 	 * number, search down the dmap control levels for the starting
@@ -1637,7 +1649,7 @@
 		mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
 		if (mp == NULL)
 			return (EIO);
-		dcp = (dmapctl_t *) mp->data;
+		dcp = (struct dmapctl *) mp->data;
 		budmin = dcp->budmin;
 
 		/* search the tree within the dmap control page for
@@ -1724,12 +1736,12 @@
  * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
  */
 static int
-dbAllocCtl(bmap_t * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
+dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
 {
 	int rc, nb;
 	s64 b, lblkno, n;
-	metapage_t *mp;
-	dmap_t *dp;
+	struct metapage *mp;
+	struct dmap *dp;
 
 	/* check if the allocation request is confined to a single dmap.
 	 */
@@ -1740,7 +1752,7 @@
 		mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
 		if (mp == NULL)
 			return (EIO);
-		dp = (dmap_t *) mp->data;
+		dp = (struct dmap *) mp->data;
 
 		/* try to allocate the blocks.
 		 */
@@ -1769,7 +1781,7 @@
 			rc = EIO;
 			goto backout;
 		}
-		dp = (dmap_t *) mp->data;
+		dp = (struct dmap *) mp->data;
 
 		/* the dmap better be all free.
 		 */
@@ -1821,7 +1833,7 @@
 			       ("dbAllocCtl: I/O Error: Block Leakage.\n"));
 			continue;
 		}
-		dp = (dmap_t *) mp->data;
+		dp = (struct dmap *) mp->data;
 
 		/* free the blocks is this dmap.
 		 */
@@ -1871,8 +1883,8 @@
  *	IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit;
  */
 static int
-dbAllocDmapLev(bmap_t * bmp,
-	       dmap_t * dp, int nblocks, int l2nb, s64 * results)
+dbAllocDmapLev(struct bmap * bmp,
+	       struct dmap * dp, int nblocks, int l2nb, s64 * results)
 {
 	s64 blkno;
 	int leafidx, rc;
@@ -1934,7 +1946,8 @@
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
-static int dbAllocDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		       int nblocks)
 {
 	s8 oldroot;
 	int rc;
@@ -1988,7 +2001,8 @@
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
-static int dbFreeDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		      int nblocks)
 {
 	s8 oldroot;
 	int rc, word;
@@ -2049,7 +2063,8 @@
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
-static void dbAllocBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+			int nblocks)
 {
 	int dbitno, word, rembits, nb, nwords, wbitno, nw, agno;
 	dmtree_t *tp = (dmtree_t *) & dp->tree;
@@ -2190,7 +2205,8 @@
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
-static void dbFreeBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		       int nblocks)
 {
 	int dbitno, word, rembits, nb, nwords, wbitno, nw, agno;
 	dmtree_t *tp = (dmtree_t *) & dp->tree;
@@ -2302,11 +2318,9 @@
 	 * if so, establish the new maximum allocation group number by
 	 * searching left for the first allocation group with allocation.
 	 */
-	if ((bmp->db_agfree[agno] == bmp->db_agsize
-	     && agno == bmp->db_maxag) || (agno == bmp->db_numag - 1
-					   && bmp->db_agfree[agno] ==
-					   (bmp-> db_mapsize &
-					    (BPERDMAP - 1)))) {
+	if ((bmp->db_agfree[agno] == bmp->db_agsize && agno == bmp->db_maxag) ||
+	    (agno == bmp->db_numag - 1 &&
+	     bmp->db_agfree[agno] == (bmp-> db_mapsize & (BPERDMAP - 1)))) {
 		while (bmp->db_maxag > 0) {
 			bmp->db_maxag -= 1;
 			if (bmp->db_agfree[bmp->db_maxag] !=
@@ -2368,13 +2382,13 @@
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
 static int
-dbAdjCtl(bmap_t * bmp, s64 blkno, int newval, int alloc, int level)
+dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
 {
-	metapage_t *mp;
+	struct metapage *mp;
 	s8 oldroot;
 	int oldval;
 	s64 lblkno;
-	dmapctl_t *dcp;
+	struct dmapctl *dcp;
 	int rc, leafno, ti;
 
 	/* get the buffer for the dmap control page for the specified
@@ -2384,7 +2398,7 @@
 	mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
 	if (mp == NULL)
 		return (EIO);
-	dcp = (dmapctl_t *) mp->data;
+	dcp = (struct dmapctl *) mp->data;
 
 	/* determine the leaf number corresponding to the block and
 	 * the index within the dmap control tree.
@@ -3064,12 +3078,12 @@
  */
 int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks)
 {
-	metapage_t *mp;
-	dmap_t *dp;
+	struct metapage *mp;
+	struct dmap *dp;
 	int nb, rc;
 	s64 lblkno, rem;
 	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
-	bmap_t *bmp = JFS_SBI(ip->i_sb)->bmap;
+	struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;
 
 	IREAD_LOCK(ipbmap);
 
@@ -3093,7 +3107,7 @@
 			IREAD_UNLOCK(ipbmap);
 			return (EIO);
 		}
-		dp = (dmap_t *) mp->data;
+		dp = (struct dmap *) mp->data;
 
 		/* determine the number of blocks to be allocated from
 		 * this dmap.
@@ -3121,12 +3135,13 @@
 }
 
 
-static int dbAllocDmapBU(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
+			 int nblocks)
 {
 	int rc;
 	int dbitno, word, rembits, nb, nwords, wbitno, agno;
 	s8 oldroot, *leaf;
-	dmaptree_t *tp = (dmaptree_t *) & dp->tree;
+	struct dmaptree *tp = (struct dmaptree *) & dp->tree;
 
 	/* save the current value of the root (i.e. maximum free string)
 	 * of the dmap tree.
@@ -3251,11 +3266,11 @@
 	int i, i0 = TRUE, j, j0 = TRUE, k, n;
 	s64 newsize;
 	s64 p;
-	metapage_t *mp, *l2mp, *l1mp, *l0mp;
-	dmapctl_t *l2dcp, *l1dcp, *l0dcp;
-	dmap_t *dp;
+	struct metapage *mp, *l2mp, *l1mp, *l0mp;
+	struct dmapctl *l2dcp, *l1dcp, *l0dcp;
+	struct dmap *dp;
 	s8 *l0leaf, *l1leaf, *l2leaf;
-	bmap_t *bmp = sbi->bmap;
+	struct bmap *bmp = sbi->bmap;
 	int agno, l2agsize, oldl2agsize;
 	s64 ag_rem;
 
@@ -3331,7 +3346,7 @@
 	p = BMAPBLKNO + nbperpage;	/* L2 page */
 	l2mp = read_metapage(ipbmap, p, PSIZE, 0);
 	assert(l2mp);
-	l2dcp = (dmapctl_t *) l2mp->data;
+	l2dcp = (struct dmapctl *) l2mp->data;
 
 	/* compute start L1 */
 	k = blkno >> L2MAXL1SIZE;
@@ -3348,7 +3363,7 @@
 			l1mp = read_metapage(ipbmap, p, PSIZE, 0);
 			if (l1mp == NULL)
 				goto errout;
-			l1dcp = (dmapctl_t *) l1mp->data;
+			l1dcp = (struct dmapctl *) l1mp->data;
 
 			/* compute start L0 */
 			j = (blkno & (MAXL1SIZE - 1)) >> L2MAXL0SIZE;
@@ -3361,7 +3376,7 @@
 			if (l1mp == NULL)
 				goto errout;
 
-			l1dcp = (dmapctl_t *) l1mp->data;
+			l1dcp = (struct dmapctl *) l1mp->data;
 
 			/* compute start L0 */
 			j = 0;
@@ -3380,7 +3395,7 @@
 				l0mp = read_metapage(ipbmap, p, PSIZE, 0);
 				if (l0mp == NULL)
 					goto errout;
-				l0dcp = (dmapctl_t *) l0mp->data;
+				l0dcp = (struct dmapctl *) l0mp->data;
 
 				/* compute start dmap */
 				i = (blkno & (MAXL0SIZE - 1)) >>
@@ -3395,7 +3410,7 @@
 				if (l0mp == NULL)
 					goto errout;
 
-				l0dcp = (dmapctl_t *) l0mp->data;
+				l0dcp = (struct dmapctl *) l0mp->data;
 
 				/* compute start dmap */
 				i = 0;
@@ -3428,7 +3443,7 @@
 					n = min(nblocks, (s64)BPERDMAP);
 				}
 
-				dp = (dmap_t *) mp->data;
+				dp = (struct dmap *) mp->data;
 				*l0leaf = dbInitDmap(dp, blkno, n);
 
 				bmp->db_nfree += n;
@@ -3510,7 +3525,7 @@
  */
 void dbFinalizeBmap(struct inode *ipbmap)
 {
-	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+	struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
 	int actags, inactags, l2nl;
 	s64 ag_rem, actfree, inactfree, avgfree;
 	int i, n;
@@ -3600,7 +3615,7 @@
  *
  * RETURNS: NONE
  */
-static int dbInitDmap(dmap_t * dp, s64 Blkno, int nblocks)
+static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
 {
 	int blkno, w, b, r, nw, nb, i;
 /*
@@ -3713,9 +3728,9 @@
  *
  * RETURNS:	max free string at the root of the tree
  */
-static int dbInitDmapTree(dmap_t * dp)
+static int dbInitDmapTree(struct dmap * dp)
 {
-	dmaptree_t *tp;
+	struct dmaptree *tp;
 	s8 *cp;
 	int i;
 
@@ -3759,7 +3774,7 @@
  *
  * RETURNS: max free string at the root of the tree
  */
-static int dbInitTree(dmaptree_t * dtp)
+static int dbInitTree(struct dmaptree * dtp)
 {
 	int l2max, l2free, bsize, nextb, i;
 	int child, parent, nparent;
@@ -3834,7 +3849,7 @@
  *
  * function: initialize dmapctl page
  */
-static int dbInitDmapCtl(dmapctl_t * dcp, int level, int i)
+static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i)
 {				/* start leaf index not covered by range */
 	s8 *cp;
 
@@ -3854,7 +3869,7 @@
 		*cp++ = NOFREE;
 
 	/* build the dmap's binary buddy summary tree */
-	return (dbInitTree((dmaptree_t *) dcp));
+	return (dbInitTree((struct dmaptree *) dcp));
 }
 
 
@@ -3969,8 +3984,8 @@
 	u32 *dbmap, *d;
 	int n;
 	s64 lblkno, cur_block;
-	dmap_t *dp;
-	metapage_t *mp;
+	struct dmap *dp;
+	struct metapage *mp;
 
 	npages = size / 32768;
 	npages += (size % 32768) ? 1 : 0;
@@ -3993,7 +4008,7 @@
 		if (mp == NULL) {
 			assert(0);
 		}
-		dp = (dmap_t *) mp->data;
+		dp = (struct dmap *) mp->data;
 
 		for (n = 0; n < LPERDMAP; n++)
 			d[n] = le32_to_cpu(dp->wmap[n]);
@@ -4122,7 +4137,7 @@
 /*
  *	dbPrtMap()
  */
-static void dbPrtMap(bmap_t * bmp)
+static void dbPrtMap(struct bmap * bmp)
 {
 	printk("   mapsize:   %d%d\n", bmp->db_mapsize);
 	printk("   nfree:     %d%d\n", bmp->db_nfree);
@@ -4143,7 +4158,7 @@
 /*
  *	dbPrtCtl()
  */
-static void dbPrtCtl(dmapctl_t * dcp)
+static void dbPrtCtl(struct dmapctl * dcp)
 {
 	int i, j, n;
 
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_dmap.h linux-2.4.20-pre8/fs/jfs/jfs_dmap.h
--- linux-2.4.20-pre7/fs/jfs/jfs_dmap.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_dmap.h	Wed Sep 25 18:22:07 2002
@@ -142,9 +142,9 @@
 /*
  *	dmap summary tree
  *
- * dmaptree_t must be consistent with dmapctl_t.
+ * dmaptree must be consistent with dmapctl.
  */
-typedef struct {
+struct dmaptree {
 	s32 nleafs;		/* 4: number of tree leafs      */
 	s32 l2nleafs;		/* 4: l2 number of tree leafs   */
 	s32 leafidx;		/* 4: index of first tree leaf  */
@@ -152,27 +152,27 @@
 	s8 budmin;		/* 1: min l2 tree leaf value to combine */
 	s8 stree[TREESIZE];	/* TREESIZE: tree               */
 	u8 pad[2];		/* 2: pad to word boundary      */
-} dmaptree_t;			/* - 360 -                      */
+};				/* - 360 -                      */
 
 /*
  *	dmap page per 8K blocks bitmap
  */
-typedef struct {
+struct dmap {
 	s32 nblocks;		/* 4: num blks covered by this dmap     */
 	s32 nfree;		/* 4: num of free blks in this dmap     */
 	s64 start;		/* 8: starting blkno for this dmap      */
-	dmaptree_t tree;	/* 360: dmap tree                       */
+	struct dmaptree tree;	/* 360: dmap tree                       */
 	u8 pad[1672];		/* 1672: pad to 2048 bytes              */
 	u32 wmap[LPERDMAP];	/* 1024: bits of the working map        */
 	u32 pmap[LPERDMAP];	/* 1024: bits of the persistent map     */
-} dmap_t;			/* - 4096 -                             */
+};				/* - 4096 -                             */
 
 /*
  *	disk map control page per level.
  *
- * dmapctl_t must be consistent with dmaptree_t.
+ * dmapctl must be consistent with dmaptree.
  */
-typedef struct {
+struct dmapctl {
 	s32 nleafs;		/* 4: number of tree leafs      */
 	s32 l2nleafs;		/* 4: l2 number of tree leafs   */
 	s32 leafidx;		/* 4: index of the first tree leaf      */
@@ -180,17 +180,17 @@
 	s8 budmin;		/* 1: minimum l2 tree leaf value        */
 	s8 stree[CTLTREESIZE];	/* CTLTREESIZE: dmapctl tree    */
 	u8 pad[2714];		/* 2714: pad to 4096            */
-} dmapctl_t;			/* - 4096 -                     */
+};				/* - 4096 -                     */
 
 /*
- *	common definition for dmaptree_t within dmap and dmapctl
+ *	common definition for dmaptree within dmap and dmapctl
  */
-typedef union {
-	dmaptree_t t1;
-	dmapctl_t t2;
+typedef union dmtree {
+	struct dmaptree t1;
+	struct dmapctl t2;
 } dmtree_t;
 
-/* macros for accessing fields within dmtree_t */
+/* macros for accessing fields within dmtree */
 #define	dmt_nleafs	t1.nleafs
 #define	dmt_l2nleafs 	t1.l2nleafs
 #define	dmt_leafidx 	t1.leafidx
@@ -201,7 +201,7 @@
 /* 
  *	on-disk aggregate disk allocation map descriptor.
  */
-typedef struct {
+struct dbmap {
 	s64 dn_mapsize;		/* 8: number of blocks in aggregate     */
 	s64 dn_nfree;		/* 8: num free blks in aggregate map    */
 	s32 dn_l2nbperpage;	/* 4: number of blks per page           */
@@ -218,17 +218,18 @@
 	s64 dn_agsize;		/* 8: num of blks per alloc group       */
 	s8 dn_maxfreebud;	/* 1: max free buddy system             */
 	u8 pad[3007];		/* 3007: pad to 4096                    */
-} dbmap_t;			/* - 4096 -                             */
+};				/* - 4096 -                             */
 
 /* 
  *	in-memory aggregate disk allocation map descriptor.
  */
-typedef struct bmap {
-	dbmap_t db_bmap;	/* on-disk aggregate map descriptor */
+struct bmap {
+	struct dbmap db_bmap;	/* on-disk aggregate map descriptor */
 	struct inode *db_ipbmap;	/* ptr to aggregate map incore inode */
 	struct semaphore db_bmaplock;	/* aggregate map lock */
+	atomic_t db_active[MAXAG];	/* count of active, open files in AG */
 	u32 *db_DBmap;
-} bmap_t;
+};
 
 /* macros for accessing fields within in-memory aggregate map descriptor */
 #define	db_mapsize	db_bmap.dn_mapsize
@@ -279,7 +280,7 @@
 extern int dbFree(struct inode *ipbmap, s64 blkno, s64 nblocks);
 
 extern int dbUpdatePMap(struct inode *ipbmap,
-			int free, s64 blkno, s64 nblocks, tblock_t * tblk);
+			int free, s64 blkno, s64 nblocks, struct tblock * tblk);
 
 extern int dbNextAG(struct inode *ipbmap);
 
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_dtree.c linux-2.4.20-pre8/fs/jfs/jfs_dtree.c
--- linux-2.4.20-pre7/fs/jfs/jfs_dtree.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_dtree.c	Wed Sep 25 18:22:07 2002
@@ -110,14 +110,14 @@
 #include "jfs_debug.h"
 
 /* dtree split parameter */
-typedef struct {
-	metapage_t *mp;
+struct dtsplit {
+	struct metapage *mp;
 	s16 index;
 	s16 nslot;
-	component_t *key;
+	struct component_name *key;
 	ddata_t *data;
-	pxdlist_t *pxdlist;
-} dtsplit_t;
+	struct pxdlist *pxdlist;
+};
 
 #define DT_PAGE(IP, MP) BT_PAGE(IP, MP, dtpage_t, i_dtroot)
 
@@ -149,51 +149,53 @@
  * forward references
  */
 static int dtSplitUp(tid_t tid, struct inode *ip,
-		     dtsplit_t * split, btstack_t * btstack);
+		     struct dtsplit * split, struct btstack * btstack);
 
-static int dtSplitPage(tid_t tid, struct inode *ip, dtsplit_t * split,
-		       metapage_t ** rmpp, dtpage_t ** rpp, pxd_t * rxdp);
+static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
+		       struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rxdp);
 
 static int dtExtendPage(tid_t tid, struct inode *ip,
-			dtsplit_t * split, btstack_t * btstack);
+			struct dtsplit * split, struct btstack * btstack);
 
 static int dtSplitRoot(tid_t tid, struct inode *ip,
-		       dtsplit_t * split, metapage_t ** rmpp);
+		       struct dtsplit * split, struct metapage ** rmpp);
 
-static int dtDeleteUp(tid_t tid, struct inode *ip, metapage_t * fmp,
-		      dtpage_t * fp, btstack_t * btstack);
+static int dtDeleteUp(tid_t tid, struct inode *ip, struct metapage * fmp,
+		      dtpage_t * fp, struct btstack * btstack);
 
 static int dtSearchNode(struct inode *ip,
-			s64 lmxaddr, pxd_t * kpxd, btstack_t * btstack);
+			s64 lmxaddr, pxd_t * kpxd, struct btstack * btstack);
 
 static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p);
 
-static int dtReadFirst(struct inode *ip, btstack_t * btstack);
+static int dtReadFirst(struct inode *ip, struct btstack * btstack);
 
 static int dtReadNext(struct inode *ip,
-		      loff_t * offset, btstack_t * btstack);
+		      loff_t * offset, struct btstack * btstack);
 
-static int dtCompare(component_t * key, dtpage_t * p, int si);
+static int dtCompare(struct component_name * key, dtpage_t * p, int si);
 
-static int ciCompare(component_t * key, dtpage_t * p, int si, int flag);
+static int ciCompare(struct component_name * key, dtpage_t * p, int si,
+		     int flag);
 
-static void dtGetKey(dtpage_t * p, int i, component_t * key, int flag);
+static void dtGetKey(dtpage_t * p, int i, struct component_name * key,
+		     int flag);
 
 static void ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
-			       int ri, component_t * key, int flag);
+			       int ri, struct component_name * key, int flag);
 
-static void dtInsertEntry(dtpage_t * p, int index, component_t * key,
-			  ddata_t * data, dtlock_t ** dtlock);
+static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
+			  ddata_t * data, struct dt_lock **);
 
 static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp,
-			dtlock_t ** sdtlock, dtlock_t ** ddtlock,
+			struct dt_lock ** sdtlock, struct dt_lock ** ddtlock,
 			int do_index);
 
-static void dtDeleteEntry(dtpage_t * p, int fi, dtlock_t ** dtlock);
+static void dtDeleteEntry(dtpage_t * p, int fi, struct dt_lock ** dtlock);
 
-static void dtTruncateEntry(dtpage_t * p, int ti, dtlock_t ** dtlock);
+static void dtTruncateEntry(dtpage_t * p, int ti, struct dt_lock ** dtlock);
 
-static void dtLinelockFreelist(dtpage_t * p, int m, dtlock_t ** dtlock);
+static void dtLinelockFreelist(dtpage_t * p, int m, struct dt_lock ** dtlock);
 
 #define ciToUpper(c)	UniStrupr((c)->name)
 
@@ -205,14 +207,14 @@
  *
  *	mp must be released by caller.
  */
-static dir_table_slot_t *find_index(struct inode *ip, u32 index,
-				    metapage_t ** mp)
+static struct dir_table_slot *find_index(struct inode *ip, u32 index,
+					 struct metapage ** mp)
 {
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 	s64 blkno;
 	s64 offset;
 	int page_offset;
-	dir_table_slot_t *slot;
+	struct dir_table_slot *slot;
 	static int maxWarnings = 10;
 
 	if (index < 2) {
@@ -236,7 +238,7 @@
 		*mp = 0;
 		slot = &jfs_ip->i_dirtable[index - 2];
 	} else {
-		offset = (index - 2) * sizeof(dir_table_slot_t);
+		offset = (index - 2) * sizeof(struct dir_table_slot);
 		page_offset = offset & (PSIZE - 1);
 		blkno = ((offset + 1) >> L2PSIZE) <<
 		    JFS_SBI(ip->i_sb)->l2nbperpage;
@@ -254,21 +256,21 @@
 		}
 
 		slot =
-		    (dir_table_slot_t *) ((char *) (*mp)->data +
-					  page_offset);
+		    (struct dir_table_slot *) ((char *) (*mp)->data +
+					       page_offset);
 	}
 	return slot;
 }
 
-static inline void lock_index(tid_t tid, struct inode *ip, metapage_t * mp,
+static inline void lock_index(tid_t tid, struct inode *ip, struct metapage * mp,
 			      u32 index)
 {
-	tlock_t *tlck;
-	linelock_t *llck;
-	lv_t *lv;
+	struct tlock *tlck;
+	struct linelock *llck;
+	struct lv *lv;
 
 	tlck = txLock(tid, ip, mp, tlckDATA);
-	llck = (linelock_t *) tlck->lock;
+	llck = (struct linelock *) tlck->lock;
 
 	if (llck->index >= llck->maxcnt)
 		llck = txLinelock(llck);
@@ -296,15 +298,15 @@
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 	u64 blkno;
-	dir_table_slot_t *dirtab_slot;
+	struct dir_table_slot *dirtab_slot;
 	u32 index;
-	linelock_t *llck;
-	lv_t *lv;
-	metapage_t *mp;
+	struct linelock *llck;
+	struct lv *lv;
+	struct metapage *mp;
 	s64 offset;
 	uint page_offset;
 	int rc;
-	tlock_t *tlck;
+	struct tlock *tlck;
 	s64 xaddr;
 
 	ASSERT(DO_INDEX(ip));
@@ -345,7 +347,7 @@
 		 * Save the table, we're going to overwrite it with the
 		 * xtree root
 		 */
-		dir_table_slot_t temp_table[12];
+		struct dir_table_slot temp_table[12];
 		memcpy(temp_table, &jfs_ip->i_dirtable, sizeof(temp_table));
 
 		/*
@@ -372,7 +374,7 @@
 			return -1;
 		}
 		tlck = txLock(tid, ip, mp, tlckDATA);
-		llck = (linelock_t *) & tlck->lock;
+		llck = (struct linelock *) & tlck->lock;
 		ASSERT(llck->index == 0);
 		lv = &llck->lv[0];
 
@@ -391,7 +393,7 @@
 		clear_cflag(COMMIT_Dirtable, ip);
 	}
 
-	offset = (index - 2) * sizeof(dir_table_slot_t);
+	offset = (index - 2) * sizeof(struct dir_table_slot);
 	page_offset = offset & (PSIZE - 1);
 	blkno = ((offset + 1) >> L2PSIZE) << sbi->l2nbperpage;
 	if (page_offset == 0) {
@@ -424,7 +426,7 @@
 	lock_index(tid, ip, mp, index);
 
 	dirtab_slot =
-	    (dir_table_slot_t *) ((char *) mp->data + page_offset);
+	    (struct dir_table_slot *) ((char *) mp->data + page_offset);
 	dirtab_slot->flag = DIR_INDEX_VALID;
 	dirtab_slot->slot = slot;
 	DTSaddress(dirtab_slot, bn);
@@ -442,8 +444,8 @@
  */
 static void free_index(tid_t tid, struct inode *ip, u32 index, u32 next)
 {
-	dir_table_slot_t *dirtab_slot;
-	metapage_t *mp = 0;
+	struct dir_table_slot *dirtab_slot;
+	struct metapage *mp = 0;
 
 	dirtab_slot = find_index(ip, index, &mp);
 
@@ -468,9 +470,9 @@
  *	Changes an entry in the directory index table
  */
 static void modify_index(tid_t tid, struct inode *ip, u32 index, s64 bn,
-			 int slot, metapage_t ** mp)
+			 int slot, struct metapage ** mp)
 {
-	dir_table_slot_t *dirtab_slot;
+	struct dir_table_slot *dirtab_slot;
 
 	dirtab_slot = find_index(ip, index, mp);
 
@@ -493,17 +495,17 @@
  *	reads a directory table slot
  */
 static int get_index(struct inode *ip, u32 index,
-		     dir_table_slot_t * dirtab_slot)
+		     struct dir_table_slot * dirtab_slot)
 {
-	metapage_t *mp = 0;
-	dir_table_slot_t *slot;
+	struct metapage *mp = 0;
+	struct dir_table_slot *slot;
 
 	slot = find_index(ip, index, &mp);
 	if (slot == 0) {
 		return -EIO;
 	}
 
-	memcpy(dirtab_slot, slot, sizeof(dir_table_slot_t));
+	memcpy(dirtab_slot, slot, sizeof(struct dir_table_slot));
 
 	if (mp)
 		release_metapage(mp);
@@ -522,21 +524,21 @@
  * return: 0 - search result on stack, leaf page pinned;
  *	   errno - I/O error
  */
-int dtSearch(struct inode *ip,
-	 component_t * key, ino_t * data, btstack_t * btstack, int flag)
+int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
+	     struct btstack * btstack, int flag)
 {
 	int rc = 0;
 	int cmp = 1;		/* init for empty page */
 	s64 bn;
-	metapage_t *mp;
+	struct metapage *mp;
 	dtpage_t *p;
 	s8 *stbl;
 	int base, index, lim;
-	btframe_t *btsp;
+	struct btframe *btsp;
 	pxd_t *pxd;
 	int psize = 288;	/* initial in-line directory */
 	ino_t inumber;
-	component_t ciKey;
+	struct component_name ciKey;
 	struct super_block *sb = ip->i_sb;
 
 	ciKey.name =
@@ -613,7 +615,7 @@
 				 */
 				if (p->header.flag & BT_LEAF) {
 					inumber = le32_to_cpu(
-			((ldtentry_t *) & p->slot[stbl[index]])->inumber);
+			((struct ldtentry *) & p->slot[stbl[index]])->inumber);
 
 					/*
 					 * search for JFS_LOOKUP
@@ -766,19 +768,19 @@
  *	   errno - failure;
  */
 int dtInsert(tid_t tid, struct inode *ip,
-	 component_t * name, ino_t * fsn, btstack_t * btstack)
+	 struct component_name * name, ino_t * fsn, struct btstack * btstack)
 {
 	int rc = 0;
-	metapage_t *mp;		/* meta-page buffer */
+	struct metapage *mp;	/* meta-page buffer */
 	dtpage_t *p;		/* base B+-tree index page */
 	s64 bn;
 	int index;
-	dtsplit_t split;	/* split information */
+	struct dtsplit split;	/* split information */
 	ddata_t data;
-	dtlock_t *dtlck;
+	struct dt_lock *dtlck;
 	int n;
-	tlock_t *tlck;
-	lv_t *lv;
+	struct tlock *tlck;
+	struct lv *lv;
 
 	/*
 	 *      retrieve search result
@@ -833,9 +835,9 @@
 	 * acquire a transaction lock on the leaf page
 	 */
 	tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
-	dtlck = (dtlock_t *) & tlck->lock;
+	dtlck = (struct dt_lock *) & tlck->lock;
 	ASSERT(dtlck->index == 0);
-	lv = (lv_t *) & dtlck->lv[0];
+	lv = & dtlck->lv[0];
 
 	/* linelock header */
 	lv->offset = 0;
@@ -847,8 +849,8 @@
 	/* linelock stbl of non-root leaf page */
 	if (!(p->header.flag & BT_ROOT)) {
 		if (dtlck->index >= dtlck->maxcnt)
-			dtlck = (dtlock_t *) txLinelock(dtlck);
-		lv = (lv_t *) & dtlck->lv[dtlck->index];
+			dtlck = (struct dt_lock *) txLinelock(dtlck);
+		lv = & dtlck->lv[dtlck->index];
 		n = index >> L2DTSLOTSIZE;
 		lv->offset = p->header.stblindex + n;
 		lv->length =
@@ -875,29 +877,29 @@
  * 	leaf page unpinned;
  */
 static int dtSplitUp(tid_t tid,
-	  struct inode *ip, dtsplit_t * split, btstack_t * btstack)
+	  struct inode *ip, struct dtsplit * split, struct btstack * btstack)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
 	int rc = 0;
-	metapage_t *smp;
+	struct metapage *smp;
 	dtpage_t *sp;		/* split page */
-	metapage_t *rmp;
+	struct metapage *rmp;
 	dtpage_t *rp;		/* new right page split from sp */
 	pxd_t rpxd;		/* new right page extent descriptor */
-	metapage_t *lmp;
+	struct metapage *lmp;
 	dtpage_t *lp;		/* left child page */
 	int skip;		/* index of entry of insertion */
-	btframe_t *parent;	/* parent page entry on traverse stack */
+	struct btframe *parent;	/* parent page entry on traverse stack */
 	s64 xaddr, nxaddr;
 	int xlen, xsize;
-	pxdlist_t pxdlist;
+	struct pxdlist pxdlist;
 	pxd_t *pxd;
-	component_t key = { 0, 0 };
+	struct component_name key = { 0, 0 };
 	ddata_t *data = split->data;
 	int n;
-	dtlock_t *dtlck;
-	tlock_t *tlck;
-	lv_t *lv;
+	struct dt_lock *dtlck;
+	struct tlock *tlck;
+	struct lv *lv;
 
 	/* get split page */
 	smp = split->mp;
@@ -1183,9 +1185,9 @@
 			 * acquire a transaction lock on the parent page
 			 */
 			tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY);
-			dtlck = (dtlock_t *) & tlck->lock;
+			dtlck = (struct dt_lock *) & tlck->lock;
 			ASSERT(dtlck->index == 0);
-			lv = (lv_t *) & dtlck->lv[0];
+			lv = & dtlck->lv[0];
 
 			/* linelock header */
 			lv->offset = 0;
@@ -1243,32 +1245,32 @@
  *	   errno - failure;
  *	return split and new page pinned;
  */
-static int dtSplitPage(tid_t tid, struct inode *ip, dtsplit_t * split,
-	    metapage_t ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp)
+static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
+	    struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp)
 {
 	struct super_block *sb = ip->i_sb;
 	int rc = 0;
-	metapage_t *smp;
+	struct metapage *smp;
 	dtpage_t *sp;
-	metapage_t *rmp;
+	struct metapage *rmp;
 	dtpage_t *rp;		/* new right page allocated */
 	s64 rbn;		/* new right page block number */
-	metapage_t *mp;
+	struct metapage *mp;
 	dtpage_t *p;
 	s64 nextbn;
-	pxdlist_t *pxdlist;
+	struct pxdlist *pxdlist;
 	pxd_t *pxd;
 	int skip, nextindex, half, left, nxt, off, si;
-	ldtentry_t *ldtentry;
-	idtentry_t *idtentry;
+	struct ldtentry *ldtentry;
+	struct idtentry *idtentry;
 	u8 *stbl;
-	dtslot_t *f;
+	struct dtslot *f;
 	int fsi, stblsize;
 	int n;
-	dtlock_t *sdtlck, *rdtlck;
-	tlock_t *tlck;
-	dtlock_t *dtlck;
-	lv_t *slv, *rlv, *lv;
+	struct dt_lock *sdtlck, *rdtlck;
+	struct tlock *tlck;
+	struct dt_lock *dtlck;
+	struct lv *slv, *rlv, *lv;
 
 	/* get split page */
 	smp = split->mp;
@@ -1293,7 +1295,7 @@
 	 * acquire a transaction lock on the new right page
 	 */
 	tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW);
-	rdtlck = (dtlock_t *) & tlck->lock;
+	rdtlck = (struct dt_lock *) & tlck->lock;
 
 	rp = (dtpage_t *) rmp->data;
 	*rpp = rp;
@@ -1306,11 +1308,11 @@
 	 * action:
 	 */
 	tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY);
-	sdtlck = (dtlock_t *) & tlck->lock;
+	sdtlck = (struct dt_lock *) & tlck->lock;
 
 	/* linelock header of split page */
 	ASSERT(sdtlck->index == 0);
-	slv = (lv_t *) & sdtlck->lv[0];
+	slv = & sdtlck->lv[0];
 	slv->offset = 0;
 	slv->length = 1;
 	sdtlck->index++;
@@ -1356,7 +1358,7 @@
 	 */
 	if (nextbn == 0 && split->index == sp->header.nextindex) {
 		/* linelock header + stbl (first slot) of new page */
-		rlv = (lv_t *) & rdtlck->lv[rdtlck->index];
+		rlv = & rdtlck->lv[rdtlck->index];
 		rlv->offset = 0;
 		rlv->length = 2;
 		rdtlck->index++;
@@ -1395,10 +1397,10 @@
 		jEVENT(0,
 		       ("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p\n",
 			tlck, ip, mp));
-		dtlck = (dtlock_t *) & tlck->lock;
+		dtlck = (struct dt_lock *) & tlck->lock;
 
 		/* linelock header of previous right sibling page */
-		lv = (lv_t *) & dtlck->lv[dtlck->index];
+		lv = & dtlck->lv[dtlck->index];
 		lv->offset = 0;
 		lv->length = 1;
 		dtlck->index++;
@@ -1431,7 +1433,7 @@
 			si = stbl[nxt];
 			switch (sp->header.flag & BT_TYPE) {
 			case BT_LEAF:
-				ldtentry = (ldtentry_t *) & sp->slot[si];
+				ldtentry = (struct ldtentry *) & sp->slot[si];
 				if (DO_INDEX(ip))
 					n = NDTLEAF(ldtentry->namlen);
 				else
@@ -1440,7 +1442,7 @@
 				break;
 
 			case BT_INTERNAL:
-				idtentry = (idtentry_t *) & sp->slot[si];
+				idtentry = (struct idtentry *) & sp->slot[si];
 				n = NDTINTERNAL(idtentry->namlen);
 				break;
 
@@ -1467,7 +1469,7 @@
 	 * new/right page moved in entries are linelocked;
 	 */
 	/* linelock header + stbl of new right page */
-	rlv = (lv_t *) & rdtlck->lv[rdtlck->index];
+	rlv = & rdtlck->lv[rdtlck->index];
 	rlv->offset = 0;
 	rlv->length = 5;
 	rdtlck->index++;
@@ -1492,7 +1494,7 @@
 		mp = 0;
 		stbl = DT_GETSTBL(rp);
 		for (n = 0; n < rp->header.nextindex; n++) {
-			ldtentry = (ldtentry_t *) & rp->slot[stbl[n]];
+			ldtentry = (struct ldtentry *) & rp->slot[stbl[n]];
 			modify_index(tid, ip, le32_to_cpu(ldtentry->index),
 				     rbn, n, &mp);
 		}
@@ -1509,8 +1511,8 @@
 
 		/* linelock stbl of split page */
 		if (sdtlck->index >= sdtlck->maxcnt)
-			sdtlck = (dtlock_t *) txLinelock(sdtlck);
-		slv = (lv_t *) & sdtlck->lv[sdtlck->index];
+			sdtlck = (struct dt_lock *) txLinelock(sdtlck);
+		slv = & sdtlck->lv[sdtlck->index];
 		n = skip >> L2DTSLOTSIZE;
 		slv->offset = sp->header.stblindex + n;
 		slv->length =
@@ -1551,28 +1553,28 @@
  *	return extended page pinned;
  */
 static int dtExtendPage(tid_t tid,
-	     struct inode *ip, dtsplit_t * split, btstack_t * btstack)
+	     struct inode *ip, struct dtsplit * split, struct btstack * btstack)
 {
 	struct super_block *sb = ip->i_sb;
 	int rc;
-	metapage_t *smp, *pmp, *mp;
+	struct metapage *smp, *pmp, *mp;
 	dtpage_t *sp, *pp;
-	pxdlist_t *pxdlist;
+	struct pxdlist *pxdlist;
 	pxd_t *pxd, *tpxd;
 	int xlen, xsize;
 	int newstblindex, newstblsize;
 	int oldstblindex, oldstblsize;
 	int fsi, last;
-	dtslot_t *f;
-	btframe_t *parent;
+	struct dtslot *f;
+	struct btframe *parent;
 	int n;
-	dtlock_t *dtlck;
+	struct dt_lock *dtlck;
 	s64 xaddr, txaddr;
-	tlock_t *tlck;
-	pxdlock_t *pxdlock;
-	lv_t *lv;
+	struct tlock *tlck;
+	struct pxd_lock *pxdlock;
+	struct lv *lv;
 	uint type;
-	ldtentry_t *ldtentry;
+	struct ldtentry *ldtentry;
 	u8 *stbl;
 
 	/* get page to extend */
@@ -1605,7 +1607,7 @@
 
 		/* save moved extent descriptor for later free */
 		tlck = txMaplock(tid, ip, tlckDTREE | tlckRELOCATE);
-		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxdlock = (struct pxd_lock *) & tlck->lock;
 		pxdlock->flag = mlckFREEPXD;
 		pxdlock->pxd = sp->header.self;
 		pxdlock->index = 1;
@@ -1618,7 +1620,7 @@
 			stbl = DT_GETSTBL(sp);
 			for (n = 0; n < sp->header.nextindex; n++) {
 				ldtentry =
-				    (ldtentry_t *) & sp->slot[stbl[n]];
+				    (struct ldtentry *) & sp->slot[stbl[n]];
 				modify_index(tid, ip,
 					     le32_to_cpu(ldtentry->index),
 					     xaddr, n, &mp);
@@ -1641,8 +1643,8 @@
 	 * acquire a transaction lock on the extended/leaf page
 	 */
 	tlck = txLock(tid, ip, smp, tlckDTREE | type);
-	dtlck = (dtlock_t *) & tlck->lock;
-	lv = (lv_t *) & dtlck->lv[0];
+	dtlck = (struct dt_lock *) & tlck->lock;
+	lv = & dtlck->lv[0];
 
 	/* update buffer extent descriptor of extended page */
 	xlen = lengthPXD(pxd);
@@ -1750,8 +1752,8 @@
 	 * acquire a transaction lock on the parent/root page
 	 */
 	tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY);
-	dtlck = (dtlock_t *) & tlck->lock;
-	lv = (lv_t *) & dtlck->lv[dtlck->index];
+	dtlck = (struct dt_lock *) & tlck->lock;
+	lv = & dtlck->lv[dtlck->index];
 
 	/* linelock parent entry - 1st slot */
 	lv->offset = 1;
@@ -1800,26 +1802,26 @@
  *	return new page pinned;
  */
 static int dtSplitRoot(tid_t tid,
-	    struct inode *ip, dtsplit_t * split, metapage_t ** rmpp)
+	    struct inode *ip, struct dtsplit * split, struct metapage ** rmpp)
 {
 	struct super_block *sb = ip->i_sb;
-	metapage_t *smp;
+	struct metapage *smp;
 	dtroot_t *sp;
-	metapage_t *rmp;
+	struct metapage *rmp;
 	dtpage_t *rp;
 	s64 rbn;
 	int xlen;
 	int xsize;
-	dtslot_t *f;
+	struct dtslot *f;
 	s8 *stbl;
 	int fsi, stblsize, n;
-	idtentry_t *s;
+	struct idtentry *s;
 	pxd_t *ppxd;
-	pxdlist_t *pxdlist;
+	struct pxdlist *pxdlist;
 	pxd_t *pxd;
-	dtlock_t *dtlck;
-	tlock_t *tlck;
-	lv_t *lv;
+	struct dt_lock *dtlck;
+	struct tlock *tlck;
+	struct lv *lv;
 
 	/* get split root page */
 	smp = split->mp;
@@ -1845,7 +1847,7 @@
 	 * acquire a transaction lock on the new right page
 	 */
 	tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW);
-	dtlck = (dtlock_t *) & tlck->lock;
+	dtlck = (struct dt_lock *) & tlck->lock;
 
 	rp->header.flag =
 	    (sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL;
@@ -1860,7 +1862,7 @@
 	 */
 	/* linelock header + copied entries + new stbl (1st slot) in new page */
 	ASSERT(dtlck->index == 0);
-	lv = (lv_t *) & dtlck->lv[0];
+	lv = & dtlck->lv[0];
 	lv->offset = 0;
 	lv->length = 10;	/* 1 + 8 + 1 */
 	dtlck->index++;
@@ -1909,12 +1911,12 @@
 	 * Update directory index table for entries now in right page
 	 */
 	if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
-		metapage_t *mp = 0;
-		ldtentry_t *ldtentry;
+		struct metapage *mp = 0;
+		struct ldtentry *ldtentry;
 
 		stbl = DT_GETSTBL(rp);
 		for (n = 0; n < rp->header.nextindex; n++) {
-			ldtentry = (ldtentry_t *) & rp->slot[stbl[n]];
+			ldtentry = (struct ldtentry *) & rp->slot[stbl[n]];
 			modify_index(tid, ip, le32_to_cpu(ldtentry->index),
 				     rbn, n, &mp);
 		}
@@ -1941,11 +1943,11 @@
 	 * acquire a transaction lock on the root page (in-memory inode)
 	 */
 	tlck = txLock(tid, ip, smp, tlckDTREE | tlckNEW | tlckBTROOT);
-	dtlck = (dtlock_t *) & tlck->lock;
+	dtlck = (struct dt_lock *) & tlck->lock;
 
 	/* linelock root */
 	ASSERT(dtlck->index == 0);
-	lv = (lv_t *) & dtlck->lv[0];
+	lv = & dtlck->lv[0];
 	lv->offset = 0;
 	lv->length = DTROOTMAXSLOT;
 	dtlck->index++;
@@ -1957,7 +1959,7 @@
 	}
 
 	/* init the first entry */
-	s = (idtentry_t *) & sp->slot[DTENTRYSTART];
+	s = (struct idtentry *) & sp->slot[DTENTRYSTART];
 	ppxd = (pxd_t *) s;
 	*ppxd = *pxd;
 	s->next = -1;
@@ -1996,22 +1998,22 @@
  * return:
  */
 int dtDelete(tid_t tid,
-	 struct inode *ip, component_t * key, ino_t * ino, int flag)
+	 struct inode *ip, struct component_name * key, ino_t * ino, int flag)
 {
 	int rc = 0;
 	s64 bn;
-	metapage_t *mp, *imp;
+	struct metapage *mp, *imp;
 	dtpage_t *p;
 	int index;
-	btstack_t btstack;
-	dtlock_t *dtlck;
-	tlock_t *tlck;
-	lv_t *lv;
+	struct btstack btstack;
+	struct dt_lock *dtlck;
+	struct tlock *tlck;
+	struct lv *lv;
 	int i;
-	ldtentry_t *ldtentry;
+	struct ldtentry *ldtentry;
 	u8 *stbl;
 	u32 table_index, next_index;
-	metapage_t *nmp;
+	struct metapage *nmp;
 	dtpage_t *np;
 
 	/*
@@ -2032,7 +2034,7 @@
 	 */
 	if (DO_INDEX(ip)) {
 		stbl = DT_GETSTBL(p);
-		ldtentry = (ldtentry_t *) & p->slot[stbl[index]];
+		ldtentry = (struct ldtentry *) & p->slot[stbl[index]];
 		table_index = le32_to_cpu(ldtentry->index);
 		if (index == (p->header.nextindex - 1)) {
 			/*
@@ -2050,7 +2052,7 @@
 				else {
 					stbl = DT_GETSTBL(np);
 					ldtentry =
-					    (ldtentry_t *) & np->
+					    (struct ldtentry *) & np->
 					    slot[stbl[0]];
 					next_index =
 					    le32_to_cpu(ldtentry->index);
@@ -2059,7 +2061,7 @@
 			}
 		} else {
 			ldtentry =
-			    (ldtentry_t *) & p->slot[stbl[index + 1]];
+			    (struct ldtentry *) & p->slot[stbl[index + 1]];
 			next_index = le32_to_cpu(ldtentry->index);
 		}
 		free_index(tid, ip, table_index, next_index);
@@ -2082,7 +2084,7 @@
 		 * acquire a transaction lock on the leaf page
 		 */
 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
-		dtlck = (dtlock_t *) & tlck->lock;
+		dtlck = (struct dt_lock *) & tlck->lock;
 
 		/*
 		 * Do not assume that dtlck->index will be zero.  During a
@@ -2092,8 +2094,8 @@
 
 		/* linelock header */
 		if (dtlck->index >= dtlck->maxcnt)
-			dtlck = (dtlock_t *) txLinelock(dtlck);
-		lv = (lv_t *) & dtlck->lv[dtlck->index];
+			dtlck = (struct dt_lock *) txLinelock(dtlck);
+		lv = & dtlck->lv[dtlck->index];
 		lv->offset = 0;
 		lv->length = 1;
 		dtlck->index++;
@@ -2101,8 +2103,8 @@
 		/* linelock stbl of non-root leaf page */
 		if (!(p->header.flag & BT_ROOT)) {
 			if (dtlck->index >= dtlck->maxcnt)
-				dtlck = (dtlock_t *) txLinelock(dtlck);
-			lv = (lv_t *) & dtlck->lv[dtlck->index];
+				dtlck = (struct dt_lock *) txLinelock(dtlck);
+			lv = & dtlck->lv[dtlck->index];
 			i = index >> L2DTSLOTSIZE;
 			lv->offset = p->header.stblindex + i;
 			lv->length =
@@ -2122,7 +2124,7 @@
 			stbl = DT_GETSTBL(p);
 			for (i = index; i < p->header.nextindex; i++) {
 				ldtentry =
-				    (ldtentry_t *) & p->slot[stbl[i]];
+				    (struct ldtentry *) & p->slot[stbl[i]];
 				modify_index(tid, ip,
 					     le32_to_cpu(ldtentry->index),
 					     bn, i, &imp);
@@ -2149,18 +2151,18 @@
  * return:
  */
 static int dtDeleteUp(tid_t tid, struct inode *ip,
-	   metapage_t * fmp, dtpage_t * fp, btstack_t * btstack)
+	   struct metapage * fmp, dtpage_t * fp, struct btstack * btstack)
 {
 	int rc = 0;
-	metapage_t *mp;
+	struct metapage *mp;
 	dtpage_t *p;
 	int index, nextindex;
 	int xlen;
-	btframe_t *parent;
-	dtlock_t *dtlck;
-	tlock_t *tlck;
-	lv_t *lv;
-	pxdlock_t *pxdlock;
+	struct btframe *parent;
+	struct dt_lock *dtlck;
+	struct tlock *tlck;
+	struct lv *lv;
+	struct pxd_lock *pxdlock;
 	int i;
 
 	/*
@@ -2190,7 +2192,7 @@
 	 * the buffer page is freed;
 	 */
 	tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE);
-	pxdlock = (pxdlock_t *) & tlck->lock;
+	pxdlock = (struct pxd_lock *) & tlck->lock;
 	pxdlock->flag = mlckFREEPXD;
 	pxdlock->pxd = fp->header.self;
 	pxdlock->index = 1;
@@ -2262,7 +2264,7 @@
 				tlck =
 				    txMaplock(tid, ip,
 					      tlckDTREE | tlckFREE);
-				pxdlock = (pxdlock_t *) & tlck->lock;
+				pxdlock = (struct pxd_lock *) & tlck->lock;
 				pxdlock->flag = mlckFREEPXD;
 				pxdlock->pxd = p->header.self;
 				pxdlock->index = 1;
@@ -2294,12 +2296,12 @@
 		 * action: router entry deletion
 		 */
 		tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
-		dtlck = (dtlock_t *) & tlck->lock;
+		dtlck = (struct dt_lock *) & tlck->lock;
 
 		/* linelock header */
 		if (dtlck->index >= dtlck->maxcnt)
-			dtlck = (dtlock_t *) txLinelock(dtlck);
-		lv = (lv_t *) & dtlck->lv[dtlck->index];
+			dtlck = (struct dt_lock *) txLinelock(dtlck);
+		lv = & dtlck->lv[dtlck->index];
 		lv->offset = 0;
 		lv->length = 1;
 		dtlck->index++;
@@ -2309,8 +2311,8 @@
 			if (dtlck->index < dtlck->maxcnt)
 				lv++;
 			else {
-				dtlck = (dtlock_t *) txLinelock(dtlck);
-				lv = (lv_t *) & dtlck->lv[0];
+				dtlck = (struct dt_lock *) txLinelock(dtlck);
+				lv = & dtlck->lv[0];
 			}
 			i = index >> L2DTSLOTSIZE;
 			lv->offset = p->header.stblindex + i;
@@ -2349,25 +2351,26 @@
 	       s64 nxaddr)
 {
 	int rc = 0;
-	metapage_t *mp, *pmp, *lmp, *rmp;
+	struct metapage *mp, *pmp, *lmp, *rmp;
 	dtpage_t *p, *pp, *rp = 0, *lp= 0;
 	s64 bn;
 	int index;
-	btstack_t btstack;
+	struct btstack btstack;
 	pxd_t *pxd;
 	s64 oxaddr, nextbn, prevbn;
 	int xlen, xsize;
-	tlock_t *tlck;
-	dtlock_t *dtlck;
-	pxdlock_t *pxdlock;
+	struct tlock *tlck;
+	struct dt_lock *dtlck;
+	struct pxd_lock *pxdlock;
 	s8 *stbl;
-	lv_t *lv;
+	struct lv *lv;
 
 	oxaddr = addressPXD(opxd);
 	xlen = lengthPXD(opxd);
 
 	jEVENT(0, ("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d\n",
-		   (long long)lmxaddr, (long long)oxaddr, (long long)nxaddr, xlen));
+		   (long long)lmxaddr, (long long)oxaddr, (long long)nxaddr,
+		   xlen));
 
 	/*
 	 *      1. get the internal parent dtpage covering
@@ -2426,10 +2429,10 @@
 	 */
 	if (lmp) {
 		tlck = txLock(tid, ip, lmp, tlckDTREE | tlckRELINK);
-		dtlck = (dtlock_t *) & tlck->lock;
+		dtlck = (struct dt_lock *) & tlck->lock;
 		/* linelock header */
 		ASSERT(dtlck->index == 0);
-		lv = (lv_t *) & dtlck->lv[0];
+		lv = & dtlck->lv[0];
 		lv->offset = 0;
 		lv->length = 1;
 		dtlck->index++;
@@ -2440,10 +2443,10 @@
 
 	if (rmp) {
 		tlck = txLock(tid, ip, rmp, tlckDTREE | tlckRELINK);
-		dtlck = (dtlock_t *) & tlck->lock;
+		dtlck = (struct dt_lock *) & tlck->lock;
 		/* linelock header */
 		ASSERT(dtlck->index == 0);
-		lv = (lv_t *) & dtlck->lv[0];
+		lv = & dtlck->lv[0];
 		lv->offset = 0;
 		lv->length = 1;
 		dtlck->index++;
@@ -2462,10 +2465,10 @@
 	 * the dst extent;
 	 */
 	tlck = txLock(tid, ip, mp, tlckDTREE | tlckNEW);
-	dtlck = (dtlock_t *) & tlck->lock;
+	dtlck = (struct dt_lock *) & tlck->lock;
 	/* linelock header */
 	ASSERT(dtlck->index == 0);
-	lv = (lv_t *) & dtlck->lv[0];
+	lv = & dtlck->lv[0];
 
 	/* update the self address in the dtpage header */
 	pxd = &p->header.self;
@@ -2501,7 +2504,7 @@
 	 * dtpage), and upadte bmap for free of the source dtpage;
 	 */
 	tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE);
-	pxdlock = (pxdlock_t *) & tlck->lock;
+	pxdlock = (struct pxd_lock *) & tlck->lock;
 	pxdlock->flag = mlckFREEPXD;
 	PXDaddress(&pxdlock->pxd, oxaddr);
 	PXDlength(&pxdlock->pxd, xlen);
@@ -2515,8 +2518,8 @@
 	 */
 	jEVENT(0, ("dtRelocate: update parent router entry.\n"));
 	tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY);
-	dtlck = (dtlock_t *) & tlck->lock;
-	lv = (lv_t *) & dtlck->lv[dtlck->index];
+	dtlck = (struct dt_lock *) & tlck->lock;
+	lv = & dtlck->lv[dtlck->index];
 
 	/* update the PXD with the new address */
 	stbl = DT_GETSTBL(pp);
@@ -2545,17 +2548,17 @@
  *		dtree level, in which the required dtpage resides.
  */
 static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd,
-			btstack_t * btstack)
+			struct btstack * btstack)
 {
 	int rc = 0;
 	s64 bn;
-	metapage_t *mp;
+	struct metapage *mp;
 	dtpage_t *p;
 	int psize = 288;	/* initial in-line directory */
 	s8 *stbl;
 	int i;
 	pxd_t *pxd;
-	btframe_t *btsp;
+	struct btframe *btsp;
 
 	BT_CLR(btstack);	/* reset stack */
 
@@ -2650,11 +2653,11 @@
 static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p)
 {
 	int rc;
-	metapage_t *mp;
+	struct metapage *mp;
 	s64 nextbn, prevbn;
-	tlock_t *tlck;
-	dtlock_t *dtlck;
-	lv_t *lv;
+	struct tlock *tlck;
+	struct dt_lock *dtlck;
+	struct lv *lv;
 
 	nextbn = le64_to_cpu(p->header.next);
 	prevbn = le64_to_cpu(p->header.prev);
@@ -2675,12 +2678,12 @@
 		jEVENT(0,
 		       ("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n",
 			tlck, ip, mp));
-		dtlck = (dtlock_t *) & tlck->lock;
+		dtlck = (struct dt_lock *) & tlck->lock;
 
 		/* linelock header */
 		if (dtlck->index >= dtlck->maxcnt)
-			dtlck = (dtlock_t *) txLinelock(dtlck);
-		lv = (lv_t *) & dtlck->lv[dtlck->index];
+			dtlck = (struct dt_lock *) txLinelock(dtlck);
+		lv = & dtlck->lv[dtlck->index];
 		lv->offset = 0;
 		lv->length = 1;
 		dtlck->index++;
@@ -2705,12 +2708,12 @@
 		jEVENT(0,
 		       ("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n",
 			tlck, ip, mp));
-		dtlck = (dtlock_t *) & tlck->lock;
+		dtlck = (struct dt_lock *) & tlck->lock;
 
 		/* linelock header */
 		if (dtlck->index >= dtlck->maxcnt)
-			dtlck = (dtlock_t *) txLinelock(dtlck);
-		lv = (lv_t *) & dtlck->lv[dtlck->index];
+			dtlck = (struct dt_lock *) txLinelock(dtlck);
+		lv = & dtlck->lv[dtlck->index];
 		lv->offset = 0;
 		lv->length = 1;
 		dtlck->index++;
@@ -2733,10 +2736,10 @@
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 	dtroot_t *p;
 	int fsi;
-	dtslot_t *f;
-	tlock_t *tlck;
-	dtlock_t *dtlck;
-	lv_t *lv;
+	struct dtslot *f;
+	struct tlock *tlck;
+	struct dt_lock *dtlck;
+	struct lv *lv;
 	u16 xflag_save;
 
 	/*
@@ -2745,7 +2748,7 @@
 	 */
 	if (DO_INDEX(ip)) {
 		if (jfs_ip->next_index > (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
-			tblock_t *tblk = tid_to_tblock(tid);
+			struct tblock *tblk = tid_to_tblock(tid);
 			/*
 			 * We're playing games with the tid's xflag.  If
 			 * we're removing a regular file, the file's xtree
@@ -2784,13 +2787,13 @@
 	 *
 	 * action: directory initialization;
 	 */
-	tlck = txLock(tid, ip, (metapage_t *) & jfs_ip->bxflag,
+	tlck = txLock(tid, ip, (struct metapage *) & jfs_ip->bxflag,
 		      tlckDTREE | tlckENTRY | tlckBTROOT);
-	dtlck = (dtlock_t *) & tlck->lock;
+	dtlck = (struct dt_lock *) & tlck->lock;
 
 	/* linelock root */
 	ASSERT(dtlck->index == 0);
-	lv = (lv_t *) & dtlck->lv[0];
+	lv = & dtlck->lv[0];
 	lv->offset = 0;
 	lv->length = DTROOTMAXSLOT;
 	dtlck->index++;
@@ -2849,14 +2852,14 @@
 		s32 unused;
 	} *dtoffset = (struct dtoffset *) &filp->f_pos;
 	s64 bn;
-	metapage_t *mp;
+	struct metapage *mp;
 	dtpage_t *p;
 	int index;
 	s8 *stbl;
-	btstack_t btstack;
+	struct btstack btstack;
 	int i, next;
-	ldtentry_t *d;
-	dtslot_t *t;
+	struct ldtentry *d;
+	struct dtslot *t;
 	int d_namleft, d_namlen, len, outlen;
 	char *d_name, *name_ptr;
 	int dtlhdrdatalen;
@@ -2880,7 +2883,7 @@
 		dir_index = (u32) filp->f_pos;
 
 		if (dir_index > 1) {
-			dir_table_slot_t dirtab_slot;
+			struct dir_table_slot dirtab_slot;
 
 			if (dtEmpty(ip)) {
 				filp->f_pos = DIREND;
@@ -3017,7 +3020,7 @@
 		stbl = DT_GETSTBL(p);
 
 		for (i = index; i < p->header.nextindex; i++) {
-			d = (ldtentry_t *) & p->slot[stbl[i]];
+			d = (struct ldtentry *) & p->slot[stbl[i]];
 
 			d_namleft = d->namlen;
 			name_ptr = d_name;
@@ -3036,7 +3039,7 @@
 			/* copy name in the additional segment(s) */
 			next = d->next;
 			while (next >= 0) {
-				t = (dtslot_t *) & p->slot[next];
+				t = (struct dtslot *) & p->slot[next];
 				name_ptr += outlen;
 				d_namleft -= len;
 				/* Sanity Check */
@@ -3110,15 +3113,15 @@
  *
  * function: get the leftmost page of the directory
  */
-static int dtReadFirst(struct inode *ip, btstack_t * btstack)
+static int dtReadFirst(struct inode *ip, struct btstack * btstack)
 {
 	int rc = 0;
 	s64 bn;
 	int psize = 288;	/* initial in-line directory */
-	metapage_t *mp;
+	struct metapage *mp;
 	dtpage_t *p;
 	s8 *stbl;
-	btframe_t *btsp;
+	struct btframe *btsp;
 	pxd_t *xd;
 
 	BT_CLR(btstack);	/* reset stack */
@@ -3176,7 +3179,8 @@
  * note: if index > nextindex of the target leaf page,
  * start with 1st entry of next leaf page;
  */
-static int dtReadNext(struct inode *ip, loff_t * offset, btstack_t * btstack)
+static int dtReadNext(struct inode *ip, loff_t * offset,
+		      struct btstack * btstack)
 {
 	int rc = 0;
 	struct dtoffset {
@@ -3185,12 +3189,12 @@
 		s32 unused;
 	} *dtoffset = (struct dtoffset *) offset;
 	s64 bn;
-	metapage_t *mp;
+	struct metapage *mp;
 	dtpage_t *p;
 	int index;
 	int pn;
 	s8 *stbl;
-	btframe_t *btsp, *parent;
+	struct btframe *btsp, *parent;
 	pxd_t *xd;
 
 	/*
@@ -3351,14 +3355,14 @@
  *	= 0 if k is = record
  *	> 0 if k is > record
  */
-static int dtCompare(component_t * key,	/* search key */
+static int dtCompare(struct component_name * key,	/* search key */
 		     dtpage_t * p,	/* directory page */
 		     int si)
 {				/* entry slot index */
 	wchar_t *kname, *name;
 	int klen, namlen, len, rc;
-	idtentry_t *ih;
-	dtslot_t *t;
+	struct idtentry *ih;
+	struct dtslot *t;
 
 	/*
 	 * force the left-most key on internal pages, at any level of
@@ -3379,7 +3383,7 @@
 	kname = key->name;
 	klen = key->namlen;
 
-	ih = (idtentry_t *) & p->slot[si];
+	ih = (struct idtentry *) & p->slot[si];
 	si = ih->next;
 	name = ih->name;
 	namlen = ih->namlen;
@@ -3397,7 +3401,7 @@
 	kname += len;
 	while (klen > 0 && namlen > 0) {
 		/* compare with next name segment */
-		t = (dtslot_t *) & p->slot[si];
+		t = (struct dtslot *) & p->slot[si];
 		len = min(namlen, DTSLOTDATALEN);
 		len = min(klen, len);
 		name = t->name;
@@ -3426,16 +3430,16 @@
  *	= 0 if k is = record
  *	> 0 if k is > record
  */
-static int ciCompare(component_t * key,	/* search key */
+static int ciCompare(struct component_name * key,	/* search key */
 		     dtpage_t * p,	/* directory page */
 		     int si,	/* entry slot index */
 		     int flag)
 {
 	wchar_t *kname, *name, x;
 	int klen, namlen, len, rc;
-	ldtentry_t *lh;
-	idtentry_t *ih;
-	dtslot_t *t;
+	struct ldtentry *lh;
+	struct idtentry *ih;
+	struct dtslot *t;
 	int i;
 
 	/*
@@ -3461,7 +3465,7 @@
 	 * leaf page entry
 	 */
 	if (p->header.flag & BT_LEAF) {
-		lh = (ldtentry_t *) & p->slot[si];
+		lh = (struct ldtentry *) & p->slot[si];
 		si = lh->next;
 		name = lh->name;
 		namlen = lh->namlen;
@@ -3474,7 +3478,7 @@
 	 * internal page entry
 	 */
 	else {
-		ih = (idtentry_t *) & p->slot[si];
+		ih = (struct idtentry *) & p->slot[si];
 		si = ih->next;
 		name = ih->name;
 		namlen = ih->namlen;
@@ -3499,7 +3503,7 @@
 	/* compare with additional segment(s) */
 	while (klen > 0 && namlen > 0) {
 		/* compare with next name segment */
-		t = (dtslot_t *) & p->slot[si];
+		t = (struct dtslot *) & p->slot[si];
 		len = min(namlen, DTSLOTDATALEN);
 		len = min(klen, len);
 		name = t->name;
@@ -3534,14 +3538,14 @@
  *	Number of prefix bytes needed to distinguish b from a.
  */
 static void ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
-			       int ri, component_t * key, int flag)
+			       int ri, struct component_name * key, int flag)
 {
 	int klen, namlen;
 	wchar_t *pl, *pr, *kname;
 	wchar_t lname[JFS_NAME_MAX + 1];
-	component_t lkey = { 0, lname };
+	struct component_name lkey = { 0, lname };
 	wchar_t rname[JFS_NAME_MAX + 1];
-	component_t rkey = { 0, rname };
+	struct component_name rkey = { 0, rname };
 
 	/* get left and right key */
 	dtGetKey(lp, li, &lkey, flag);
@@ -3588,13 +3592,13 @@
  * function: get key of the entry
  */
 static void dtGetKey(dtpage_t * p, int i,	/* entry index */
-		     component_t * key, int flag)
+		     struct component_name * key, int flag)
 {
 	int si;
 	s8 *stbl;
-	ldtentry_t *lh;
-	idtentry_t *ih;
-	dtslot_t *t;
+	struct ldtentry *lh;
+	struct idtentry *ih;
+	struct dtslot *t;
 	int namlen, len;
 	wchar_t *name, *kname;
 
@@ -3602,7 +3606,7 @@
 	stbl = DT_GETSTBL(p);
 	si = stbl[i];
 	if (p->header.flag & BT_LEAF) {
-		lh = (ldtentry_t *) & p->slot[si];
+		lh = (struct ldtentry *) & p->slot[si];
 		si = lh->next;
 		namlen = lh->namlen;
 		name = lh->name;
@@ -3611,7 +3615,7 @@
 		else
 			len = min(namlen, DTLHDRDATALEN_LEGACY);
 	} else {
-		ih = (idtentry_t *) & p->slot[si];
+		ih = (struct idtentry *) & p->slot[si];
 		si = ih->next;
 		namlen = ih->namlen;
 		name = ih->name;
@@ -3650,21 +3654,21 @@
  *
  * return: entry slot index
  */
-static void dtInsertEntry(dtpage_t * p, int index, component_t * key,
-			  ddata_t * data, dtlock_t ** dtlock)
+static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
+			  ddata_t * data, struct dt_lock ** dtlock)
 {
-	dtslot_t *h, *t;
-	ldtentry_t *lh = 0;
-	idtentry_t *ih = 0;
+	struct dtslot *h, *t;
+	struct ldtentry *lh = 0;
+	struct idtentry *ih = 0;
 	int hsi, fsi, klen, len, nextindex;
 	wchar_t *kname, *name;
 	s8 *stbl;
 	pxd_t *xd;
-	dtlock_t *dtlck = *dtlock;
-	lv_t *lv;
+	struct dt_lock *dtlck = *dtlock;
+	struct lv *lv;
 	int xsi, n;
 	s64 bn = 0;
-	metapage_t *mp = 0;
+	struct metapage *mp = 0;
 
 	klen = key->namlen;
 	kname = key->name;
@@ -3677,14 +3681,14 @@
 
 	/* open new linelock */
 	if (dtlck->index >= dtlck->maxcnt)
-		dtlck = (dtlock_t *) txLinelock(dtlck);
+		dtlck = (struct dt_lock *) txLinelock(dtlck);
 
-	lv = (lv_t *) & dtlck->lv[dtlck->index];
+	lv = & dtlck->lv[dtlck->index];
 	lv->offset = hsi;
 
 	/* write head/only segment */
 	if (p->header.flag & BT_LEAF) {
-		lh = (ldtentry_t *) h;
+		lh = (struct ldtentry *) h;
 		lh->next = h->next;
 		lh->inumber = data->leaf.ino;	/* little-endian */
 		lh->namlen = klen;
@@ -3699,7 +3703,7 @@
 		} else
 			len = min(klen, DTLHDRDATALEN_LEGACY);
 	} else {
-		ih = (idtentry_t *) h;
+		ih = (struct idtentry *) h;
 		ih->next = h->next;
 		xd = (pxd_t *) ih;
 		*xd = data->xd;
@@ -3733,8 +3737,8 @@
 			if (dtlck->index < dtlck->maxcnt)
 				lv++;
 			else {
-				dtlck = (dtlock_t *) txLinelock(dtlck);
-				lv = (lv_t *) & dtlck->lv[0];
+				dtlck = (struct dt_lock *) txLinelock(dtlck);
+				lv = & dtlck->lv[0];
 			}
 
 			lv->offset = fsi;
@@ -3780,7 +3784,7 @@
 			 */
 			mp = 0;
 			for (n = index + 1; n <= nextindex; n++) {
-				lh = (ldtentry_t *) & (p->slot[stbl[n]]);
+				lh = (struct ldtentry *) & (p->slot[stbl[n]]);
 				modify_index(data->leaf.tid, data->leaf.ip,
 					     le32_to_cpu(lh->index), bn, n,
 					     &mp);
@@ -3806,7 +3810,7 @@
  *	are updated.
  */
 static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp,
-			dtlock_t ** sdtlock, dtlock_t ** ddtlock,
+			struct dt_lock ** sdtlock, struct dt_lock ** ddtlock,
 			int do_index)
 {
 	int ssi, next;		/* src slot index */
@@ -3814,11 +3818,11 @@
 	int dsi;		/* dst slot index */
 	s8 *sstbl, *dstbl;	/* sorted entry table */
 	int snamlen, len;
-	ldtentry_t *slh, *dlh = 0;
-	idtentry_t *sih, *dih = 0;
-	dtslot_t *h, *s, *d;
-	dtlock_t *sdtlck = *sdtlock, *ddtlck = *ddtlock;
-	lv_t *slv, *dlv;
+	struct ldtentry *slh, *dlh = 0;
+	struct idtentry *sih, *dih = 0;
+	struct dtslot *h, *s, *d;
+	struct dt_lock *sdtlck = *sdtlock, *ddtlck = *ddtlock;
+	struct lv *slv, *dlv;
 	int xssi, ns, nd;
 	int sfsi;
 
@@ -3829,11 +3833,11 @@
 	sfsi = sp->header.freelist;
 
 	/* linelock destination entry slot */
-	dlv = (lv_t *) & ddtlck->lv[ddtlck->index];
+	dlv = & ddtlck->lv[ddtlck->index];
 	dlv->offset = dsi;
 
 	/* linelock source entry slot */
-	slv = (lv_t *) & sdtlck->lv[sdtlck->index];
+	slv = & sdtlck->lv[sdtlck->index];
 	slv->offset = sstbl[si];
 	xssi = slv->offset - 1;
 
@@ -3855,8 +3859,8 @@
 			if (sdtlck->index < sdtlck->maxcnt)
 				slv++;
 			else {
-				sdtlck = (dtlock_t *) txLinelock(sdtlck);
-				slv = (lv_t *) & sdtlck->lv[0];
+				sdtlck = (struct dt_lock *) txLinelock(sdtlck);
+				slv = & sdtlck->lv[0];
 			}
 
 			slv->offset = ssi;
@@ -3873,8 +3877,8 @@
 		s = &sp->slot[ssi];
 		if (sp->header.flag & BT_LEAF) {
 			/* get source entry */
-			slh = (ldtentry_t *) s;
-			dlh = (ldtentry_t *) h;
+			slh = (struct ldtentry *) s;
+			dlh = (struct ldtentry *) h;
 			snamlen = slh->namlen;
 
 			if (do_index) {
@@ -3891,11 +3895,11 @@
 			dsi++;
 			dlh->next = dsi;
 		} else {
-			sih = (idtentry_t *) s;
+			sih = (struct idtentry *) s;
 			snamlen = sih->namlen;
 
 			len = min(snamlen, DTIHDRDATALEN);
-			dih = (idtentry_t *) h;
+			dih = (struct idtentry *) h;
 			memcpy(dih, sih, 10 + len * 2);
 			next = sih->next;
 
@@ -3928,9 +3932,9 @@
 					slv++;
 				else {
 					sdtlck =
-					    (dtlock_t *)
+					    (struct dt_lock *)
 					    txLinelock(sdtlck);
-					slv = (lv_t *) & sdtlck->lv[0];
+					slv = & sdtlck->lv[0];
 				}
 
 				slv->offset = ssi;
@@ -4006,14 +4010,14 @@
  * the entry logged to avoid applying previous updates
  * to the same slots)
  */
-static void dtDeleteEntry(dtpage_t * p, int fi, dtlock_t ** dtlock)
+static void dtDeleteEntry(dtpage_t * p, int fi, struct dt_lock ** dtlock)
 {
 	int fsi;		/* free entry slot index */
 	s8 *stbl;
-	dtslot_t *t;
+	struct dtslot *t;
 	int si, freecnt;
-	dtlock_t *dtlck = *dtlock;
-	lv_t *lv;
+	struct dt_lock *dtlck = *dtlock;
+	struct lv *lv;
 	int xsi, n;
 
 	/* get free entry slot index */
@@ -4022,17 +4026,17 @@
 
 	/* open new linelock */
 	if (dtlck->index >= dtlck->maxcnt)
-		dtlck = (dtlock_t *) txLinelock(dtlck);
-	lv = (lv_t *) & dtlck->lv[dtlck->index];
+		dtlck = (struct dt_lock *) txLinelock(dtlck);
+	lv = & dtlck->lv[dtlck->index];
 
 	lv->offset = fsi;
 
 	/* get the head/only segment */
 	t = &p->slot[fsi];
 	if (p->header.flag & BT_LEAF)
-		si = ((ldtentry_t *) t)->next;
+		si = ((struct ldtentry *) t)->next;
 	else
-		si = ((idtentry_t *) t)->next;
+		si = ((struct idtentry *) t)->next;
 	t->next = si;
 	t->cnt = 1;
 
@@ -4051,8 +4055,8 @@
 			if (dtlck->index < dtlck->maxcnt)
 				lv++;
 			else {
-				dtlck = (dtlock_t *) txLinelock(dtlck);
-				lv = (lv_t *) & dtlck->lv[0];
+				dtlck = (struct dt_lock *) txLinelock(dtlck);
+				lv = & dtlck->lv[0];
 			}
 
 			lv->offset = si;
@@ -4101,14 +4105,14 @@
  * the entry logged to avoid applying previous updates
  * to the same slots)
  */
-static void dtTruncateEntry(dtpage_t * p, int ti, dtlock_t ** dtlock)
+static void dtTruncateEntry(dtpage_t * p, int ti, struct dt_lock ** dtlock)
 {
 	int tsi;		/* truncate entry slot index */
 	s8 *stbl;
-	dtslot_t *t;
+	struct dtslot *t;
 	int si, freecnt;
-	dtlock_t *dtlck = *dtlock;
-	lv_t *lv;
+	struct dt_lock *dtlck = *dtlock;
+	struct lv *lv;
 	int fsi, xsi, n;
 
 	/* get free entry slot index */
@@ -4117,17 +4121,17 @@
 
 	/* open new linelock */
 	if (dtlck->index >= dtlck->maxcnt)
-		dtlck = (dtlock_t *) txLinelock(dtlck);
-	lv = (lv_t *) & dtlck->lv[dtlck->index];
+		dtlck = (struct dt_lock *) txLinelock(dtlck);
+	lv = & dtlck->lv[dtlck->index];
 
 	lv->offset = tsi;
 
 	/* get the head/only segment */
 	t = &p->slot[tsi];
 	ASSERT(p->header.flag & BT_INTERNAL);
-	((idtentry_t *) t)->namlen = 0;
-	si = ((idtentry_t *) t)->next;
-	((idtentry_t *) t)->next = -1;
+	((struct idtentry *) t)->namlen = 0;
+	si = ((struct idtentry *) t)->next;
+	((struct idtentry *) t)->next = -1;
 
 	n = 1;
 	freecnt = 0;
@@ -4146,8 +4150,8 @@
 			if (dtlck->index < dtlck->maxcnt)
 				lv++;
 			else {
-				dtlck = (dtlock_t *) txLinelock(dtlck);
-				lv = (lv_t *) & dtlck->lv[0];
+				dtlck = (struct dt_lock *) txLinelock(dtlck);
+				lv = & dtlck->lv[0];
 			}
 
 			lv->offset = si;
@@ -4183,13 +4187,13 @@
  */
 static void dtLinelockFreelist(dtpage_t * p,	/* directory page */
 			       int m,	/* max slot index */
-			       dtlock_t ** dtlock)
+			       struct dt_lock ** dtlock)
 {
 	int fsi;		/* free entry slot index */
-	dtslot_t *t;
+	struct dtslot *t;
 	int si;
-	dtlock_t *dtlck = *dtlock;
-	lv_t *lv;
+	struct dt_lock *dtlck = *dtlock;
+	struct lv *lv;
 	int xsi, n;
 
 	/* get free entry slot index */
@@ -4197,8 +4201,8 @@
 
 	/* open new linelock */
 	if (dtlck->index >= dtlck->maxcnt)
-		dtlck = (dtlock_t *) txLinelock(dtlck);
-	lv = (lv_t *) & dtlck->lv[dtlck->index];
+		dtlck = (struct dt_lock *) txLinelock(dtlck);
+	lv = & dtlck->lv[dtlck->index];
 
 	lv->offset = fsi;
 
@@ -4220,8 +4224,8 @@
 			if (dtlck->index < dtlck->maxcnt)
 				lv++;
 			else {
-				dtlck = (dtlock_t *) txLinelock(dtlck);
-				lv = (lv_t *) & dtlck->lv[0];
+				dtlck = (struct dt_lock *) txLinelock(dtlck);
+				lv = & dtlck->lv[0];
 			}
 
 			lv->offset = si;
@@ -4262,20 +4266,20 @@
  *	0	- If successfully modified entry
  */
 int dtModify(tid_t tid, struct inode *ip,
-	 component_t * key, ino_t * orig_ino, ino_t new_ino, int flag)
+	 struct component_name * key, ino_t * orig_ino, ino_t new_ino, int flag)
 {
 	int rc;
 	s64 bn;
-	metapage_t *mp;
+	struct metapage *mp;
 	dtpage_t *p;
 	int index;
-	btstack_t btstack;
-	tlock_t *tlck;
-	dtlock_t *dtlck;
-	lv_t *lv;
+	struct btstack btstack;
+	struct tlock *tlck;
+	struct dt_lock *dtlck;
+	struct lv *lv;
 	s8 *stbl;
 	int entry_si;		/* entry slot index */
-	ldtentry_t *entry;
+	struct ldtentry *entry;
 
 	/*
 	 *      search for the entry to modify:
@@ -4293,7 +4297,7 @@
 	 * acquire a transaction lock on the leaf page of named entry
 	 */
 	tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
-	dtlck = (dtlock_t *) & tlck->lock;
+	dtlck = (struct dt_lock *) & tlck->lock;
 
 	/* get slot index of the entry */
 	stbl = DT_GETSTBL(p);
@@ -4301,13 +4305,13 @@
 
 	/* linelock entry */
 	ASSERT(dtlck->index == 0);
-	lv = (lv_t *) & dtlck->lv[0];
+	lv = & dtlck->lv[0];
 	lv->offset = entry_si;
 	lv->length = 1;
 	dtlck->index++;
 
 	/* get the head/only segment */
-	entry = (ldtentry_t *) & p->slot[entry_si];
+	entry = (struct ldtentry *) & p->slot[entry_si];
 
 	/* substitute the inode number of the entry */
 	entry->inumber = cpu_to_le32(new_ino);
@@ -4327,14 +4331,14 @@
 int dtDisplayTree(struct inode *ip)
 {
 	int rc;
-	metapage_t *mp;
+	struct metapage *mp;
 	dtpage_t *p;
 	s64 bn, pbn;
 	int index, lastindex, v, h;
 	pxd_t *xd;
-	btstack_t btstack;
-	btframe_t *btsp;
-	btframe_t *parent;
+	struct btstack btstack;
+	struct btframe *btsp;
+	struct btframe *parent;
 	u8 *stbl;
 	int psize = 256;
 
@@ -4465,14 +4469,14 @@
 int dtDisplayPage(struct inode *ip, s64 bn, dtpage_t * p)
 {
 	int rc;
-	metapage_t *mp;
-	ldtentry_t *lh;
-	idtentry_t *ih;
+	struct metapage *mp;
+	struct ldtentry *lh;
+	struct idtentry *ih;
 	pxd_t *xd;
 	int i, j;
 	u8 *stbl;
 	wchar_t name[JFS_NAME_MAX + 1];
-	component_t key = { 0, name };
+	struct component_name key = { 0, name };
 	int freepage = 0;
 
 	if (p == NULL) {
@@ -4492,11 +4496,11 @@
 		dtGetKey(p, i, &key, JFS_SBI(ip->i_sb)->mntflag);
 		key.name[key.namlen] = '\0';
 		if (p->header.flag & BT_LEAF) {
-			lh = (ldtentry_t *) & p->slot[stbl[i]];
+			lh = (struct ldtentry *) & p->slot[stbl[i]];
 			printf("\t[%d] %s:%d", i, key.name,
 			       le32_to_cpu(lh->inumber));
 		} else {
-			ih = (idtentry_t *) & p->slot[stbl[i]];
+			ih = (struct idtentry *) & p->slot[stbl[i]];
 			xd = (pxd_t *) ih;
 			bn = addressPXD(xd);
 			printf("\t[%d] %s:0x%Lx", i, key.name, bn);
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_dtree.h linux-2.4.20-pre8/fs/jfs/jfs_dtree.h
--- linux-2.4.20-pre7/fs/jfs/jfs_dtree.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_dtree.h	Wed Sep 25 18:22:07 2002
@@ -44,11 +44,11 @@
 /*
  *	directory page slot
  */
-typedef struct {
+struct dtslot {
 	s8 next;		/* 1: */
 	s8 cnt;			/* 1: */
 	wchar_t name[15];	/* 30: */
-} dtslot_t;			/* (32) */
+};				/* (32) */
 
 
 #define DATASLOTSIZE	16
@@ -62,13 +62,13 @@
 /*
  *	 internal node entry head/only segment
  */
-typedef struct {
+struct idtentry {
 	pxd_t xd;		/* 8: child extent descriptor */
 
 	s8 next;		/* 1: */
 	u8 namlen;		/* 1: */
 	wchar_t name[11];	/* 22: 2-byte aligned */
-} idtentry_t;			/* (32) */
+};				/* (32) */
 
 #define DTIHDRSIZE	10
 #define DTIHDRDATALEN	11
@@ -82,13 +82,13 @@
  *
  * 	For legacy filesystems, name contains 13 wchars -- no index field
  */
-typedef struct {
+struct ldtentry {
 	u32 inumber;		/* 4: 4-byte aligned */
 	s8 next;		/* 1: */
 	u8 namlen;		/* 1: */
 	wchar_t name[11];	/* 22: 2-byte aligned */
 	u32 index;		/* 4: index into dir_table */
-} ldtentry_t;			/* (32) */
+};				/* (32) */
 
 #define DTLHDRSIZE	6
 #define DTLHDRDATALEN_LEGACY	13	/* Old (OS/2) format */
@@ -108,14 +108,14 @@
  */
 #define MAX_INLINE_DIRTABLE_ENTRY 13
 
-typedef struct dir_table_slot {
+struct dir_table_slot {
 	u8 rsrvd;		/* 1: */
 	u8 flag;		/* 1: 0 if free */
 	u8 slot;		/* 1: slot within leaf page of entry */
 	u8 addr1;		/* 1: upper 8 bits of leaf page address */
 	u32 addr2;		/* 4: lower 32 bits of leaf page address -OR-
 				   index of next entry when this entry was deleted */
-} dir_table_slot_t;		/* (8) */
+};				/* (8) */
 
 /*
  * flag values
@@ -144,7 +144,7 @@
  */
 typedef union {
 	struct {
-		dasd_t DASD;	/* 16: DASD limit/usage info  F226941 */
+		struct dasd DASD; /* 16: DASD limit/usage info */
 
 		u8 flag;	/* 1: */
 		u8 nextindex;	/* 1: next free entry in stbl */
@@ -156,7 +156,7 @@
 		s8 stbl[8];	/* 8: sorted entry index table */
 	} header;		/* (32) */
 
-	dtslot_t slot[9];
+	struct dtslot slot[9];
 } dtroot_t;
 
 #define PARENT(IP) \
@@ -207,7 +207,7 @@
 		pxd_t self;	/* 8: self pxd */
 	} header;		/* (32) */
 
-	dtslot_t slot[128];
+	struct dtslot slot[128];
 } dtpage_t;
 
 #define DTPAGEMAXSLOT        128
@@ -256,20 +256,20 @@
  */
 extern void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot);
 
-extern int dtSearch(struct inode *ip, component_t * key,
-		    ino_t * data, btstack_t * btstack, int flag);
+extern int dtSearch(struct inode *ip, struct component_name * key,
+		    ino_t * data, struct btstack * btstack, int flag);
 
-extern int dtInsert(tid_t tid, struct inode *ip,
-		    component_t * key, ino_t * ino, btstack_t * btstack);
+extern int dtInsert(tid_t tid, struct inode *ip, struct component_name * key,
+		    ino_t * ino, struct btstack * btstack);
 
-extern int dtDelete(tid_t tid,
-		    struct inode *ip, component_t * key, ino_t * data, int flag);
+extern int dtDelete(tid_t tid, struct inode *ip, struct component_name * key,
+		    ino_t * data, int flag);
 
 extern int dtRelocate(tid_t tid,
 		      struct inode *ip, s64 lmxaddr, pxd_t * opxd, s64 nxaddr);
 
-extern int dtModify(tid_t tid, struct inode *ip,
-		    component_t * key, ino_t * orig_ino, ino_t new_ino, int flag);
+extern int dtModify(tid_t tid, struct inode *ip, struct component_name * key,
+		    ino_t * orig_ino, ino_t new_ino, int flag);
 
 extern int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir);
 
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_extent.c linux-2.4.20-pre8/fs/jfs/jfs_extent.c
--- linux-2.4.20-pre7/fs/jfs/jfs_extent.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_extent.c	Wed Sep 25 18:22:07 2002
@@ -358,8 +358,8 @@
 int extHint(struct inode *ip, s64 offset, xad_t * xp)
 {
 	struct super_block *sb = ip->i_sb;
-	xadlist_t xadl;
-	lxdlist_t lxdl;
+	struct xadlist xadl;
+	struct lxdlist lxdl;
 	lxd_t lxd;
 	s64 prev;
 	int rc, nbperpage = JFS_SBI(sb)->nbperpage;
@@ -514,9 +514,12 @@
 static int
 extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
 {
+	struct jfs_inode_info *ji = JFS_IP(ip);
+	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
 	s64 nb, nblks, daddr, max;
-	int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage;
-	bmap_t *mp = JFS_SBI(ip->i_sb)->bmap;
+	int rc, nbperpage = sbi->nbperpage;
+	struct bmap *bmp = sbi->bmap;
+	int ag;
 
 	/* get the number of blocks to initially attempt to allocate.
 	 * we'll first try the number of blocks requested unless this
@@ -524,7 +527,7 @@
 	 * blocks in the map. in that case, we'll start off with the 
 	 * maximum free.
 	 */
-	max = (s64) 1 << mp->db_maxfreebud;
+	max = (s64) 1 << bmp->db_maxfreebud;
 	if (*nblocks >= max && *nblocks > nbperpage)
 		nb = nblks = (max > nbperpage) ? max : nbperpage;
 	else
@@ -549,6 +552,18 @@
 	*nblocks = nb;
 	*blkno = daddr;
 
+	if (S_ISREG(ip->i_mode) && (ji->fileset == FILESYSTEM_I)) {
+		ag = BLKTOAG(daddr, sbi);
+		if (ji->active_ag == -1) {
+			atomic_inc(&bmp->db_active[ag]);
+			ji->active_ag = ag;
+		} else if (ji->active_ag != ag) {
+			atomic_dec(&bmp->db_active[ji->active_ag]);
+			atomic_inc(&bmp->db_active[ag]);
+			ji->active_ag = ag;
+		}
+	}
+
 	return (0);
 }
 
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_imap.c linux-2.4.20-pre8/fs/jfs/jfs_imap.c
--- linux-2.4.20-pre7/fs/jfs/jfs_imap.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_imap.c	Wed Sep 25 18:22:07 2002
@@ -73,19 +73,19 @@
 /*
  * forward references
  */
-static int diAllocAG(imap_t *, int, boolean_t, struct inode *);
-static int diAllocAny(imap_t *, int, boolean_t, struct inode *);
-static int diAllocBit(imap_t *, iag_t *, int);
-static int diAllocExt(imap_t *, int, struct inode *);
-static int diAllocIno(imap_t *, int, struct inode *);
+static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
+static int diAllocAny(struct inomap *, int, boolean_t, struct inode *);
+static int diAllocBit(struct inomap *, struct iag *, int);
+static int diAllocExt(struct inomap *, int, struct inode *);
+static int diAllocIno(struct inomap *, int, struct inode *);
 static int diFindFree(u32, int);
-static int diNewExt(imap_t *, iag_t *, int);
-static int diNewIAG(imap_t *, int *, int, metapage_t **);
+static int diNewExt(struct inomap *, struct iag *, int);
+static int diNewIAG(struct inomap *, int *, int, struct metapage **);
 static void duplicateIXtree(struct super_block *, s64, int, s64 *);
 
-static int diIAGRead(imap_t * imap, int, metapage_t **);
-static int copy_from_dinode(dinode_t *, struct inode *);
-static void copy_to_dinode(dinode_t *, struct inode *);
+static int diIAGRead(struct inomap * imap, int, struct metapage **);
+static int copy_from_dinode(struct dinode *, struct inode *);
+static void copy_to_dinode(struct dinode *, struct inode *);
 
 /*
  *	debug code for double-checking inode map
@@ -97,9 +97,9 @@
 #define DBG_DIALLOC(imap, ino)	DBGdiAlloc(imap, ino)
 #define DBG_DIFREE(imap, ino)	DBGdiFree(imap, ino)
 
-static void *DBGdiInit(imap_t * imap);
-static void DBGdiAlloc(imap_t * imap, ino_t ino);
-static void DBGdiFree(imap_t * imap, ino_t ino);
+static void *DBGdiInit(struct inomap * imap);
+static void DBGdiAlloc(struct inomap * imap, ino_t ino);
+static void DBGdiFree(struct inomap * imap, ino_t ino);
 #else
 #define DBG_DIINIT(imap)
 #define DBG_DIALLOC(imap, ino)
@@ -112,7 +112,7 @@
  * FUNCTION:    initialize the incore inode map control structures for
  *		a fileset or aggregate init time.
  *
- *              the inode map's control structure (dinomap_t) is 
+ *              the inode map's control structure (dinomap) is 
  *              brought in from disk and placed in virtual memory.
  *
  * PARAMETERS:
@@ -125,16 +125,16 @@
  */
 int diMount(struct inode *ipimap)
 {
-	imap_t *imap;
-	metapage_t *mp;
+	struct inomap *imap;
+	struct metapage *mp;
 	int index;
-	dinomap_t *dinom_le;
+	struct dinomap *dinom_le;
 
 	/*
 	 * allocate/initialize the in-memory inode map control structure
 	 */
 	/* allocate the in-memory inode map control structure. */
-	imap = (imap_t *) kmalloc(sizeof(imap_t), GFP_KERNEL);
+	imap = (struct inomap *) kmalloc(sizeof(struct inomap), GFP_KERNEL);
 	if (imap == NULL) {
 		jERROR(1, ("diMount: kmalloc returned NULL!\n"));
 		return (ENOMEM);
@@ -151,7 +151,7 @@
 	}
 
 	/* copy the on-disk version to the in-memory version. */
-	dinom_le = (dinomap_t *) mp->data;
+	dinom_le = (struct dinomap *) mp->data;
 	imap->im_freeiag = le32_to_cpu(dinom_le->in_freeiag);
 	imap->im_nextiag = le32_to_cpu(dinom_le->in_nextiag);
 	atomic_set(&imap->im_numinos, le32_to_cpu(dinom_le->in_numinos));
@@ -211,7 +211,7 @@
  */
 int diUnmount(struct inode *ipimap, int mounterror)
 {
-	imap_t *imap = JFS_IP(ipimap)->i_imap;
+	struct inomap *imap = JFS_IP(ipimap)->i_imap;
 
 	/*
 	 * update the on-disk inode map control structure
@@ -239,9 +239,9 @@
  */
 int diSync(struct inode *ipimap)
 {
-	dinomap_t *dinom_le;
-	imap_t *imp = JFS_IP(ipimap)->i_imap;
-	metapage_t *mp;
+	struct dinomap *dinom_le;
+	struct inomap *imp = JFS_IP(ipimap)->i_imap;
+	struct metapage *mp;
 	int index;
 
 	/*
@@ -257,8 +257,7 @@
 	}
 
 	/* copy the in-memory version to the on-disk version */
-	//memcpy(mp->data, &imp->im_imap,sizeof(dinomap_t));
-	dinom_le = (dinomap_t *) mp->data;
+	dinom_le = (struct dinomap *) mp->data;
 	dinom_le->in_freeiag = cpu_to_le32(imp->im_freeiag);
 	dinom_le->in_nextiag = cpu_to_le32(imp->im_nextiag);
 	dinom_le->in_numinos = cpu_to_le32(atomic_read(&imp->im_numinos));
@@ -328,11 +327,11 @@
 	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
 	int iagno, ino, extno, rc;
 	struct inode *ipimap;
-	dinode_t *dp;
-	iag_t *iagp;
-	metapage_t *mp;
+	struct dinode *dp;
+	struct iag *iagp;
+	struct metapage *mp;
 	s64 blkno, agstart;
-	imap_t *imap;
+	struct inomap *imap;
 	int block_offset;
 	int inodes_left;
 	uint pageno;
@@ -356,7 +355,7 @@
 		return (rc);
 	}
 
-	iagp = (iag_t *) mp->data;
+	iagp = (struct iag *) mp->data;
 
 	/* determine inode extent that holds the disk inode */
 	ino = ip->i_ino & (INOSPERIAG - 1);
@@ -408,7 +407,7 @@
 	}
 
 	/* locate the the disk inode requested */
-	dp = (dinode_t *) mp->data;
+	dp = (struct dinode *) mp->data;
 	dp += rel_inode;
 
 	if (ip->i_ino != le32_to_cpu(dp->di_number)) {
@@ -428,6 +427,7 @@
 
 	/* set the ag for the inode */
 	JFS_IP(ip)->agno = BLKTOAG(agstart, sbi);
+	JFS_IP(ip)->active_ag = -1;
 
 	return (rc);
 }
@@ -459,9 +459,9 @@
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
 	uint address;
-	dinode_t *dp;
+	struct dinode *dp;
 	struct inode *ip;
-	metapage_t *mp;
+	struct metapage *mp;
 	int rc;
 
 	ip = new_inode(sb);
@@ -505,7 +505,7 @@
 	}
 
 	/* get the pointer to the disk inode of interest */
-	dp = (dinode_t *) (mp->data);
+	dp = (struct dinode *) (mp->data);
 	dp += inum % 8;		/* 8 inodes per 4K page */
 
 	/* copy on-disk inode to in-memory inode */
@@ -550,9 +550,9 @@
 {
 	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
 	uint address;
-	dinode_t *dp;
+	struct dinode *dp;
 	ino_t inum = ip->i_ino;
-	metapage_t *mp;
+	struct metapage *mp;
 
 	ip->i_state &= ~I_DIRTY;
 
@@ -577,7 +577,7 @@
 	}
 
 	/* get the pointer to the disk inode of interest */
-	dp = (dinode_t *) (mp->data);
+	dp = (struct dinode *) (mp->data);
 	dp += inum % 8;		/* 8 inodes per 4K page */
 
 	/* copy on-disk inode to in-memory inode */
@@ -639,20 +639,20 @@
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 	int rc = 0;
 	s32 ino;
-	dinode_t *dp;
+	struct dinode *dp;
 	s64 blkno;
 	int block_offset;
 	int inodes_left;
-	metapage_t *mp;
+	struct metapage *mp;
 	uint pageno;
 	int rel_inode;
 	int dioffset;
 	struct inode *ipimap;
 	uint type;
 	lid_t lid;
-	tlock_t *ditlck, *tlck;
-	linelock_t *dilinelock, *ilinelock;
-	lv_t *lv;
+	struct tlock *ditlck, *tlck;
+	struct linelock *dilinelock, *ilinelock;
+	struct lv *lv;
 	int n;
 
 	ipimap = jfs_ip->ipimap;
@@ -693,7 +693,7 @@
 		return (EIO);
 
 	/* get the pointer to the disk inode */
-	dp = (dinode_t *) mp->data;
+	dp = (struct dinode *) mp->data;
 	dp += rel_inode;
 
 	dioffset = (ino & (INOSPERPAGE - 1)) << L2DISIZE;
@@ -705,7 +705,7 @@
 	if ((ditlck =
 	     txLock(tid, ipimap, mp, tlckINODE | tlckENTRY)) == NULL)
 		goto retry;
-	dilinelock = (linelock_t *) & ditlck->lock;
+	dilinelock = (struct linelock *) & ditlck->lock;
 
 	/*
 	 * copy btree root from in-memory inode to on-disk inode
@@ -733,14 +733,14 @@
 		assert(tlck->type & tlckXTREE);
 		tlck->type |= tlckBTROOT;
 		tlck->mp = mp;
-		ilinelock = (linelock_t *) & tlck->lock;
+		ilinelock = (struct linelock *) & tlck->lock;
 
 		/*
 		 * copy xtree root from inode to dinode:
 		 */
 		p = &jfs_ip->i_xtroot;
 		xp = (xtpage_t *) &dp->di_dirtable;
-		lv = (lv_t *) & ilinelock->lv;
+		lv = ilinelock->lv;
 		for (n = 0; n < ilinelock->index; n++, lv++) {
 			memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
 			       lv->length << L2XTSLOTSIZE);
@@ -762,7 +762,7 @@
 	type = tlck->type;
 	tlck->type |= tlckBTROOT;
 	tlck->mp = mp;
-	ilinelock = (linelock_t *) & tlck->lock;
+	ilinelock = (struct linelock *) & tlck->lock;
 
 	/*
 	 *      regular file: 16 byte (XAD slot) granularity
@@ -776,7 +776,7 @@
 		 */
 		p = &jfs_ip->i_xtroot;
 		xp = &dp->di_xtroot;
-		lv = (lv_t *) & ilinelock->lv;
+		lv = ilinelock->lv;
 		for (n = 0; n < ilinelock->index; n++, lv++) {
 			memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
 			       lv->length << L2XTSLOTSIZE);
@@ -800,7 +800,7 @@
 		 */
 		p = (dtpage_t *) &jfs_ip->i_dtroot;
 		xp = (dtpage_t *) & dp->di_dtroot;
-		lv = (lv_t *) & ilinelock->lv;
+		lv = ilinelock->lv;
 		for (n = 0; n < ilinelock->index; n++, lv++) {
 			memcpy(&xp->slot[lv->offset], &p->slot[lv->offset],
 			       lv->length << L2DTSLOTSIZE);
@@ -814,7 +814,7 @@
 	 * copy inline symlink from in-memory inode to on-disk inode
 	 */
 	if (S_ISLNK(ip->i_mode) && ip->i_size < IDATASIZE) {
-		lv = (lv_t *) & dilinelock->lv[dilinelock->index];
+		lv = & dilinelock->lv[dilinelock->index];
 		lv->offset = (dioffset + 2 * 128) >> L2INODESLOTSIZE;
 		lv->length = 2;
 		memcpy(&dp->di_fastsymlink, jfs_ip->i_inline, IDATASIZE);
@@ -825,7 +825,7 @@
 	 * 128 byte slot granularity
 	 */
 	if (test_cflag(COMMIT_Inlineea, ip)) {
-		lv = (lv_t *) & dilinelock->lv[dilinelock->index];
+		lv = & dilinelock->lv[dilinelock->index];
 		lv->offset = (dioffset + 3 * 128) >> L2INODESLOTSIZE;
 		lv->length = 1;
 		memcpy(&dp->di_inlineea, jfs_ip->i_inline_ea, INODESLOTSIZE);
@@ -838,7 +838,7 @@
 	 *      lock/copy inode base: 128 byte slot granularity
 	 */
 // baseDinode:
-	lv = (lv_t *) & dilinelock->lv[dilinelock->index];
+	lv = & dilinelock->lv[dilinelock->index];
 	lv->offset = dioffset >> L2INODESLOTSIZE;
 	copy_to_dinode(dp, ip);
 	if (test_and_clear_cflag(COMMIT_Dirtable, ip)) {
@@ -856,7 +856,7 @@
 	 */
 	if (S_ISDIR(ip->i_mode)
 	    && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED))
-		bcopy(&ip->i_DASD, &dp->di_DASD, sizeof(dasd_t));
+		bcopy(&ip->i_DASD, &dp->di_DASD, sizeof(struct dasd));
 #endif				/*  _JFS_FASTDASD */
 
 	/* release the buffer holding the updated on-disk inode. 
@@ -910,18 +910,18 @@
 {
 	int rc;
 	ino_t inum = ip->i_ino;
-	iag_t *iagp, *aiagp, *biagp, *ciagp, *diagp;
-	metapage_t *mp, *amp, *bmp, *cmp, *dmp;
+	struct iag *iagp, *aiagp, *biagp, *ciagp, *diagp;
+	struct metapage *mp, *amp, *bmp, *cmp, *dmp;
 	int iagno, ino, extno, bitno, sword, agno;
 	int back, fwd;
 	u32 bitmap, mask;
 	struct inode *ipimap = JFS_SBI(ip->i_sb)->ipimap;
-	imap_t *imap = JFS_IP(ipimap)->i_imap;
+	struct inomap *imap = JFS_IP(ipimap)->i_imap;
 	pxd_t freepxd;
 	tid_t tid;
 	struct inode *iplist[3];
-	tlock_t *tlck;
-	pxdlock_t *pxdlock;
+	struct tlock *tlck;
+	struct pxd_lock *pxdlock;
 
 	/*
 	 * This is just to suppress compiler warnings.  The same logic that
@@ -965,7 +965,7 @@
 		AG_UNLOCK(imap, agno);
 		return (rc);
 	}
-	iagp = (iag_t *) mp->data;
+	iagp = (struct iag *) mp->data;
 
 	/* get the inode number and extent number of the inode within
 	 * the iag and the inode number within the extent.
@@ -1022,7 +1022,7 @@
 					release_metapage(mp);
 					return (rc);
 				}
-				aiagp = (iag_t *) amp->data;
+				aiagp = (struct iag *) amp->data;
 
 				/* make current head point back to the iag.
 				 */
@@ -1101,7 +1101,7 @@
 		if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
 			if ((rc = diIAGRead(imap, fwd, &amp)))
 				goto error_out;
-			aiagp = (iag_t *) amp->data;
+			aiagp = (struct iag *) amp->data;
 		}
 	} else {
 		/* iag has free extents. check if the addition of a free
@@ -1118,13 +1118,13 @@
 			if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
 				if ((rc = diIAGRead(imap, fwd, &amp)))
 					goto error_out;
-				aiagp = (iag_t *) amp->data;
+				aiagp = (struct iag *) amp->data;
 			}
 
 			if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
 				if ((rc = diIAGRead(imap, back, &bmp)))
 					goto error_out;
-				biagp = (iag_t *) bmp->data;
+				biagp = (struct iag *) bmp->data;
 			}
 		}
 	}
@@ -1147,30 +1147,30 @@
 		if (inofreefwd >= 0) {
 
 			if (inofreefwd == fwd)
-				ciagp = (iag_t *) amp->data;
+				ciagp = (struct iag *) amp->data;
 			else if (inofreefwd == back)
-				ciagp = (iag_t *) bmp->data;
+				ciagp = (struct iag *) bmp->data;
 			else {
 				if ((rc =
 				     diIAGRead(imap, inofreefwd, &cmp)))
 					goto error_out;
 				assert(cmp != NULL);
-				ciagp = (iag_t *) cmp->data;
+				ciagp = (struct iag *) cmp->data;
 			}
 			assert(ciagp != NULL);
 		}
 
 		if (inofreeback >= 0) {
 			if (inofreeback == fwd)
-				diagp = (iag_t *) amp->data;
+				diagp = (struct iag *) amp->data;
 			else if (inofreeback == back)
-				diagp = (iag_t *) bmp->data;
+				diagp = (struct iag *) bmp->data;
 			else {
 				if ((rc =
 				     diIAGRead(imap, inofreeback, &dmp)))
 					goto error_out;
 				assert(dmp != NULL);
-				diagp = (iag_t *) dmp->data;
+				diagp = (struct iag *) dmp->data;
 			}
 			assert(diagp != NULL);
 		}
@@ -1302,7 +1302,7 @@
 	 * N.B. linelock is overlaid as freed extent descriptor;
 	 */
 	tlck = txLock(tid, ipimap, mp, tlckINODE | tlckFREE);
-	pxdlock = (pxdlock_t *) & tlck->lock;
+	pxdlock = (struct pxd_lock *) & tlck->lock;
 	pxdlock->flag = mlckFREEPXD;
 	pxdlock->pxd = freepxd;
 	pxdlock->index = 1;
@@ -1355,7 +1355,7 @@
  * the inode.
  */
 static inline void
-diInitInode(struct inode *ip, int iagno, int ino, int extno, iag_t * iagp)
+diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
@@ -1364,6 +1364,7 @@
 	DBG_DIALLOC(JFS_IP(ipimap)->i_imap, ip->i_ino);
 	jfs_ip->ixpxd = iagp->inoext[extno];
 	jfs_ip->agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
+	jfs_ip->active_ag = -1;
 }
 
 
@@ -1389,10 +1390,10 @@
 	int nwords, rem, i, agno;
 	u32 mask, inosmap, extsmap;
 	struct inode *ipimap;
-	metapage_t *mp;
+	struct metapage *mp;
 	ino_t inum;
-	iag_t *iagp;
-	imap_t *imap;
+	struct iag *iagp;
+	struct inomap *imap;
 
 	/* get the pointers to the inode map inode and the
 	 * corresponding imap control structure.
@@ -1419,6 +1420,21 @@
 	 * moving backward on the disk.)  compute the hint within the
 	 * file system and the iag.
 	 */
+
+	/* get the ag number of this iag */
+	agno = JFS_IP(pip)->agno;
+
+	if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) {
+		/*
+		 * There is an open file actively growing.  We want to
+		 * allocate new inodes from a different ag to avoid
+		 * fragmentation problems.
+		 */
+		agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
+		AG_LOCK(imap, agno);
+		goto tryag;
+	}
+
 	inum = pip->i_ino + 1;
 	ino = inum & (INOSPERIAG - 1);
 
@@ -1426,9 +1442,6 @@
 	if (ino == 0)
 		inum = pip->i_ino;
 
-	/* get the ag number of this iag */
-	agno = JFS_IP(pip)->agno;
-
 	/* lock the AG inode map information */
 	AG_LOCK(imap, agno);
 
@@ -1441,7 +1454,7 @@
 		IREAD_UNLOCK(ipimap);
 		return (rc);
 	}
-	iagp = (iag_t *) mp->data;
+	iagp = (struct iag *) mp->data;
 
 	/* determine if new inode extent is allowed to be added to the iag.
 	 * new inode extent can be added to the iag if the ag
@@ -1672,7 +1685,7 @@
  *      EIO  	- i/o error.
  */
 static int
-diAllocAG(imap_t * imap, int agno, boolean_t dir, struct inode *ip)
+diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
 {
 	int rc, addext, numfree, numinos;
 
@@ -1743,7 +1756,7 @@
  *      EIO  	- i/o error.
  */
 static int
-diAllocAny(imap_t * imap, int agno, boolean_t dir, struct inode *ip)
+diAllocAny(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
 {
 	int ag, rc;
 	int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
@@ -1807,11 +1820,11 @@
  *      ENOSPC 	- insufficient disk resources.
  *      EIO  	- i/o error.
  */
-static int diAllocIno(imap_t * imap, int agno, struct inode *ip)
+static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
 {
 	int iagno, ino, rc, rem, extno, sword;
-	metapage_t *mp;
-	iag_t *iagp;
+	struct metapage *mp;
+	struct iag *iagp;
 
 	/* check if there are iags on the ag's free inode list.
 	 */
@@ -1827,7 +1840,7 @@
 		IREAD_UNLOCK(imap->im_ipimap);
 		return (rc);
 	}
-	iagp = (iag_t *) mp->data;
+	iagp = (struct iag *) mp->data;
 
 	/* better be free inodes in this iag if it is on the
 	 * list.
@@ -1918,11 +1931,11 @@
  *      ENOSPC 	- insufficient disk resources.
  *      EIO  	- i/o error.
  */
-static int diAllocExt(imap_t * imap, int agno, struct inode *ip)
+static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
 {
 	int rem, iagno, sword, extno, rc;
-	metapage_t *mp;
-	iag_t *iagp;
+	struct metapage *mp;
+	struct iag *iagp;
 
 	/* check if the ag has any iags with free extents.  if not,
 	 * allocate a new iag for the ag.
@@ -1934,7 +1947,7 @@
 		if ((rc = diNewIAG(imap, &iagno, agno, &mp))) {
 			return (rc);
 		}
-		iagp = (iag_t *) mp->data;
+		iagp = (struct iag *) mp->data;
 
 		/* set the ag number if this a brand new iag
 		 */
@@ -1947,7 +1960,7 @@
 		if ((rc = diIAGRead(imap, iagno, &mp))) {
 			assert(0);
 		}
-		iagp = (iag_t *) mp->data;
+		iagp = (struct iag *) mp->data;
 	}
 
 	/* using the free extent summary map, find a free extent.
@@ -2023,11 +2036,11 @@
  *      ENOSPC 	- insufficient disk resources.
  *      EIO  	- i/o error.
  */
-static int diAllocBit(imap_t * imap, iag_t * iagp, int ino)
+static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
 {
 	int extno, bitno, agno, sword, rc;
-	metapage_t *amp, *bmp;
-	iag_t *aiagp = 0, *biagp = 0;
+	struct metapage *amp, *bmp;
+	struct iag *aiagp = 0, *biagp = 0;
 	u32 mask;
 
 	/* check if this is the last free inode within the iag.
@@ -2043,7 +2056,7 @@
 			     diIAGRead(imap, le32_to_cpu(iagp->inofreefwd),
 				       &amp)))
 				return (rc);
-			aiagp = (iag_t *) amp->data;
+			aiagp = (struct iag *) amp->data;
 		}
 
 		if ((int) le32_to_cpu(iagp->inofreeback) >= 0) {
@@ -2055,7 +2068,7 @@
 					release_metapage(amp);
 				return (rc);
 			}
-			biagp = (iag_t *) bmp->data;
+			biagp = (struct iag *) bmp->data;
 		}
 	}
 
@@ -2163,17 +2176,17 @@
  *      ENOSPC 	- insufficient disk resources.
  *      EIO  	- i/o error.
  */
-static int diNewExt(imap_t * imap, iag_t * iagp, int extno)
+static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
 {
 	int agno, iagno, fwd, back, freei = 0, sword, rc;
-	iag_t *aiagp = 0, *biagp = 0, *ciagp = 0;
-	metapage_t *amp, *bmp, *cmp, *dmp;
+	struct iag *aiagp = 0, *biagp = 0, *ciagp = 0;
+	struct metapage *amp, *bmp, *cmp, *dmp;
 	struct inode *ipimap;
 	s64 blkno, hint;
 	int i, j;
 	u32 mask;
 	ino_t ino;
-	dinode_t *dp;
+	struct dinode *dp;
 	struct jfs_sb_info *sbi;
 
 	/* better have free extents.
@@ -2201,13 +2214,13 @@
 		if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
 			if ((rc = diIAGRead(imap, fwd, &amp)))
 				return (rc);
-			aiagp = (iag_t *) amp->data;
+			aiagp = (struct iag *) amp->data;
 		}
 
 		if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
 			if ((rc = diIAGRead(imap, back, &bmp)))
 				goto error_out;
-			biagp = (iag_t *) bmp->data;
+			biagp = (struct iag *) bmp->data;
 		}
 	} else {
 		/* the iag has free extents.  if all extents are free
@@ -2221,7 +2234,7 @@
 			if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
 				if ((rc = diIAGRead(imap, fwd, &amp)))
 					goto error_out;
-				aiagp = (iag_t *) amp->data;
+				aiagp = (struct iag *) amp->data;
 			}
 		}
 	}
@@ -2244,7 +2257,7 @@
 			} else {
 				if ((rc = diIAGRead(imap, freei, &cmp)))
 					goto error_out;
-				ciagp = (iag_t *) cmp->data;
+				ciagp = (struct iag *) cmp->data;
 			}
 			assert(ciagp != NULL);
 		}
@@ -2277,7 +2290,7 @@
 			rc = EIO;
 			goto error_out;
 		}
-		dp = (dinode_t *) dmp->data;
+		dp = (struct dinode *) dmp->data;
 
 		/* initialize the inode number, mode, link count and
 		 * inode extent address.
@@ -2438,15 +2451,15 @@
  *   new imap size;
  */
 static int
-diNewIAG(imap_t * imap, int *iagnop, int agno, metapage_t ** mpp)
+diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
 {
 	int rc;
 	int iagno, i, xlen;
 	struct inode *ipimap;
 	struct super_block *sb;
 	struct jfs_sb_info *sbi;
-	metapage_t *mp;
-	iag_t *iagp;
+	struct metapage *mp;
+	struct iag *iagp;
 	s64 xaddr = 0;
 	s64 blkno;
 	tid_t tid;
@@ -2526,10 +2539,10 @@
 			rc = EIO;
 			goto out;
 		}
-		iagp = (iag_t *) mp->data;
+		iagp = (struct iag *) mp->data;
 
 		/* init the iag */
-		memset(iagp, 0, sizeof(iag_t));
+		memset(iagp, 0, sizeof(struct iag));
 		iagp->iagnum = cpu_to_le32(iagno);
 		iagp->inofreefwd = iagp->inofreeback = -1;
 		iagp->extfreefwd = iagp->extfreeback = -1;
@@ -2624,7 +2637,7 @@
 		rc = EIO;
 		goto out;
 	}
-	iagp = (iag_t *) mp->data;
+	iagp = (struct iag *) mp->data;
 
 	/* remove the iag from the iag free list */
 	imap->im_freeiag = le32_to_cpu(iagp->iagfree);
@@ -2662,7 +2675,7 @@
  *      0       - success.
  *      EIO  	- i/o error.
  */
-static int diIAGRead(imap_t * imap, int iagno, metapage_t ** mpp)
+static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
 {
 	struct inode *ipimap = imap->im_ipimap;
 	s64 blkno;
@@ -2724,15 +2737,15 @@
  */
 int
 diUpdatePMap(struct inode *ipimap,
-	     unsigned long inum, boolean_t is_free, tblock_t * tblk)
+	     unsigned long inum, boolean_t is_free, struct tblock * tblk)
 {
 	int rc;
-	iag_t *iagp;
-	metapage_t *mp;
+	struct iag *iagp;
+	struct metapage *mp;
 	int iagno, ino, extno, bitno;
-	imap_t *imap;
+	struct inomap *imap;
 	u32 mask;
-	log_t *log;
+	struct jfs_log *log;
 	int lsn, difft, diffp;
 
 	imap = JFS_IP(ipimap)->i_imap;
@@ -2746,7 +2759,7 @@
 	IREAD_UNLOCK(ipimap);
 	if (rc)
 		return (rc);
-	iagp = (iag_t *) mp->data;
+	iagp = (struct iag *) mp->data;
 	/* get the inode number and extent number of the inode within
 	 * the iag and the inode number within the extent.
 	 */
@@ -2843,10 +2856,10 @@
 int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
 {
 	int rc, rcx = 0;
-	imap_t *imap = JFS_IP(ipimap)->i_imap;
-	iag_t *iagp = 0, *hiagp = 0;
-	bmap_t *mp = JFS_SBI(ipbmap->i_sb)->bmap;
-	metapage_t *bp, *hbp;
+	struct inomap *imap = JFS_IP(ipimap)->i_imap;
+	struct iag *iagp = 0, *hiagp = 0;
+	struct bmap *mp = JFS_SBI(ipbmap->i_sb)->bmap;
+	struct metapage *bp, *hbp;
 	int i, n, head;
 	int numinos, xnuminos = 0, xnumfree = 0;
 	s64 agstart;
@@ -2872,7 +2885,7 @@
 	}
 
 	/*
-	 *      process each iag_t page of the map.
+	 *      process each iag page of the map.
 	 *
 	 * rebuild AG Free Inode List, AG Free Inode Extent List;
 	 */
@@ -2881,7 +2894,7 @@
 			rcx = rc;
 			continue;
 		}
-		iagp = (iag_t *) bp->data;
+		iagp = (struct iag *) bp->data;
 		assert(le32_to_cpu(iagp->iagnum) == i);
 
 		/* leave free iag in the free iag list */
@@ -2916,7 +2929,7 @@
 					rcx = rc;
 					goto nextiag;
 				}
-				hiagp = (iag_t *) hbp->data;
+				hiagp = (struct iag *) hbp->data;
 				hiagp->inofreeback =
 				    le32_to_cpu(iagp->iagnum);
 				iagp->inofreefwd = cpu_to_le32(head);
@@ -2942,7 +2955,7 @@
 					rcx = rc;
 					goto nextiag;
 				}
-				hiagp = (iag_t *) hbp->data;
+				hiagp = (struct iag *) hbp->data;
 				hiagp->extfreeback = iagp->iagnum;
 				iagp->extfreefwd = cpu_to_le32(head);
 				iagp->extfreeback = -1;
@@ -3025,7 +3038,7 @@
  *      0       - success
  *      ENOMEM	- insufficient memory
  */
-static int copy_from_dinode(dinode_t * dip, struct inode *ip)
+static int copy_from_dinode(struct dinode * dip, struct inode *ip)
 {
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 
@@ -3078,7 +3091,7 @@
  *
  * FUNCTION:    Copies inode info from in-memory inode to disk inode
  */
-static void copy_to_dinode(dinode_t * dip, struct inode *ip)
+static void copy_to_dinode(struct dinode * dip, struct inode *ip)
 {
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 
@@ -3118,7 +3131,7 @@
 /*
  *	DBGdiInit()
  */
-static void *DBGdiInit(imap_t * imap)
+static void *DBGdiInit(struct inomap * imap)
 {
 	u32 *dimap;
 	int size;
@@ -3132,7 +3145,7 @@
 /*
  *	DBGdiAlloc()
  */
-static void DBGdiAlloc(imap_t * imap, ino_t ino)
+static void DBGdiAlloc(struct inomap * imap, ino_t ino)
 {
 	u32 *dimap = imap->im_DBGdimap;
 	int w, b;
@@ -3150,7 +3163,7 @@
 /*
  *	DBGdiFree()
  */
-static void DBGdiFree(imap_t * imap, ino_t ino)
+static void DBGdiFree(struct inomap * imap, ino_t ino)
 {
 	u32 *dimap = imap->im_DBGdimap;
 	int w, b;
@@ -3165,7 +3178,7 @@
 	dimap[w] &= ~m;
 }
 
-static void dump_cp(imap_t * ipimap, char *function, int line)
+static void dump_cp(struct inomap * ipimap, char *function, int line)
 {
 	printk("\n* ********* *\nControl Page %s %d\n", function, line);
 	printk("FreeIAG %d\tNextIAG %d\n", ipimap->im_freeiag,
@@ -3179,7 +3192,7 @@
 	       ipimap->im_agctl[0].numinos, ipimap->im_agctl[0].numfree);
 }
 
-static void dump_iag(iag_t * iag, char *function, int line)
+static void dump_iag(struct iag * iag, char *function, int line)
 {
 	printk("\n* ********* *\nIAG %s %d\n", function, line);
 	printk("IagNum %d\tIAG Free %d\n", le32_to_cpu(iag->iagnum),
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_imap.h linux-2.4.20-pre8/fs/jfs/jfs_imap.h
--- linux-2.4.20-pre7/fs/jfs/jfs_imap.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_imap.h	Wed Sep 25 18:22:07 2002
@@ -59,7 +59,7 @@
 /*
  *	inode allocation group page (per 4096 inodes of an AG)
  */
-typedef struct {
+struct iag {
 	s64 agstart;		/* 8: starting block of ag              */
 	s32 iagnum;		/* 4: inode allocation group number     */
 	s32 inofreefwd;		/* 4: ag inode free list forward        */
@@ -87,22 +87,22 @@
 	u32 wmap[EXTSPERIAG];	/* 512: working allocation map  */
 	u32 pmap[EXTSPERIAG];	/* 512: persistent allocation map */
 	pxd_t inoext[EXTSPERIAG];	/* 1024: inode extent addresses */
-} iag_t;			/* (4096) */
+};				/* (4096) */
 
 /*
  *	per AG control information (in inode map control page)
  */
-typedef struct {
+struct iagctl {
 	s32 inofree;		/* 4: free inode list anchor            */
 	s32 extfree;		/* 4: free extent list anchor           */
 	s32 numinos;		/* 4: number of backed inodes           */
 	s32 numfree;		/* 4: number of free inodes             */
-} iagctl_t;			/* (16) */
+};				/* (16) */
 
 /*
  *	per fileset/aggregate inode map control page
  */
-typedef struct {
+struct dinomap {
 	s32 in_freeiag;		/* 4: free iag list anchor     */
 	s32 in_nextiag;		/* 4: next free iag number     */
 	s32 in_numinos;		/* 4: num of backed inodes */
@@ -112,22 +112,22 @@
 	s32 in_diskblock;	/* 4: for standalone test driver  */
 	s32 in_maxag;		/* 4: for standalone test driver  */
 	u8 pad[2016];		/* 2016: pad to 2048 */
-	iagctl_t in_agctl[MAXAG];	/* 2048: AG control information */
-} dinomap_t;			/* (4096) */
+	struct iagctl in_agctl[MAXAG];	/* 2048: AG control information */
+};				/* (4096) */
 
 
 /*
  *	In-core inode map control page
  */
-typedef struct inomap {
-	dinomap_t im_imap;	/* 4096: inode allocation control */
+struct inomap {
+	struct dinomap im_imap;		/* 4096: inode allocation control */
 	struct inode *im_ipimap;	/* 4: ptr to inode for imap   */
 	struct semaphore im_freelock;	/* 4: iag free list lock      */
 	struct semaphore im_aglock[MAXAG];	/* 512: per AG locks          */
 	u32 *im_DBGdimap;
 	atomic_t im_numinos;	/* num of backed inodes */
 	atomic_t im_numfree;	/* num of free backed inodes */
-} imap_t;
+};
 
 #define	im_freeiag	im_imap.in_freeiag
 #define	im_nextiag	im_imap.in_nextiag
@@ -145,7 +145,7 @@
 extern int diSync(struct inode *);
 /* external references */
 extern int diUpdatePMap(struct inode *ipimap, unsigned long inum,
-			boolean_t is_free, tblock_t * tblk);
+			boolean_t is_free, struct tblock * tblk);
 extern int diExtendFS(struct inode *ipimap, struct inode *ipbmap);
 extern int diMount(struct inode *);
 extern int diUnmount(struct inode *, int);
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_incore.h linux-2.4.20-pre8/fs/jfs/jfs_incore.h
--- linux-2.4.20-pre7/fs/jfs/jfs_incore.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_incore.h	Wed Sep 25 18:22:07 2002
@@ -50,7 +50,7 @@
 	long	cflag;		/* commit flags		*/
 	u16	bxflag;		/* xflag of pseudo buffer?	*/
 	unchar	agno;		/* ag number			*/
-	unchar	pad;		/* pad			*/
+	signed char active_ag;	/* ag currently allocating from	*/
 	lid_t	blid;		/* lid of pseudo buffer?	*/
 	lid_t	atlhead;	/* anonymous tlock list head	*/
 	lid_t	atltail;	/* anonymous tlock list tail	*/
@@ -76,7 +76,7 @@
 			struct inomap *_imap;	/* 4: inode map header	*/
 		} file;
 		struct {
-			dir_table_slot_t _table[12]; /* 96: directory index */
+			struct dir_table_slot _table[12]; /* 96: dir index */
 			dtroot_t _dtroot;	/* 288: dtree root */
 		} dir;
 		struct {
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_logmgr.c linux-2.4.20-pre8/fs/jfs/jfs_logmgr.c
--- linux-2.4.20-pre7/fs/jfs/jfs_logmgr.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_logmgr.c	Wed Sep 25 18:22:07 2002
@@ -75,7 +75,7 @@
 /*
  * lbuf's ready to be redriven.  Protected by log_redrive_lock (jfsIO thread)
  */
-static lbuf_t *log_redrive_list;
+static struct lbuf *log_redrive_list;
 static spinlock_t log_redrive_lock = SPIN_LOCK_UNLOCKED;
 DECLARE_WAIT_QUEUE_HEAD(jfs_IO_thread_wait);
 
@@ -159,32 +159,33 @@
 /*
  * external references
  */
-extern void txLazyUnlock(tblock_t * tblk);
+extern void txLazyUnlock(struct tblock * tblk);
 extern int jfs_stop_threads;
 extern struct completion jfsIOwait;
 
 /*
  * forward references
  */
-static int lmWriteRecord(log_t * log, tblock_t * tblk, lrd_t * lrd,
-			 tlock_t * tlck);
+static int lmWriteRecord(struct jfs_log * log, struct tblock * tblk,
+			 struct lrd * lrd, struct tlock * tlck);
 
-static int lmNextPage(log_t * log);
-static int lmLogFileSystem(log_t * log, char *uuid, int activate);
+static int lmNextPage(struct jfs_log * log);
+static int lmLogFileSystem(struct jfs_log * log, char *uuid, int activate);
 
-static int lbmLogInit(log_t * log);
-static void lbmLogShutdown(log_t * log);
-static lbuf_t *lbmAllocate(log_t * log, int);
-static void lbmFree(lbuf_t * bp);
-static void lbmfree(lbuf_t * bp);
-static int lbmRead(log_t * log, int pn, lbuf_t ** bpp);
-static void lbmWrite(log_t * log, lbuf_t * bp, int flag, int cant_block);
-static void lbmDirectWrite(log_t * log, lbuf_t * bp, int flag);
-static int lbmIOWait(lbuf_t * bp, int flag);
+static int lbmLogInit(struct jfs_log * log);
+static void lbmLogShutdown(struct jfs_log * log);
+static struct lbuf *lbmAllocate(struct jfs_log * log, int);
+static void lbmFree(struct lbuf * bp);
+static void lbmfree(struct lbuf * bp);
+static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp);
+static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag,
+		     int cant_block);
+static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag);
+static int lbmIOWait(struct lbuf * bp, int flag);
 static void lbmIODone(struct buffer_head *bh, int);
 
-void lbmStartIO(lbuf_t * bp);
-void lmGCwrite(log_t * log, int cant_block);
+void lbmStartIO(struct lbuf * bp);
+void lmGCwrite(struct jfs_log * log, int cant_block);
 
 
 /*
@@ -211,11 +212,12 @@
  *
  * note: todo: log error handler
  */
-int lmLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	  struct tlock * tlck)
 {
 	int lsn;
 	int diffp, difft;
-	metapage_t *mp = NULL;
+	struct metapage *mp = NULL;
 
 	jFYI(1, ("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p\n",
 		 log, tblk, lrd, tlck));
@@ -330,11 +332,12 @@
  * serialization: LOG_LOCK() held on entry/exit
  */
 static int
-lmWriteRecord(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	      struct tlock * tlck)
 {
 	int lsn = 0;		/* end-of-log address */
-	lbuf_t *bp;		/* dst log page buffer */
-	logpage_t *lp;		/* dst log page */
+	struct lbuf *bp;	/* dst log page buffer */
+	struct logpage *lp;	/* dst log page */
 	caddr_t dst;		/* destination address in log page */
 	int dstoffset;		/* end-of-log offset in log page */
 	int freespace;		/* free space in log page */
@@ -344,16 +347,16 @@
 	int nbytes;		/* number of bytes to move */
 	int i;
 	int len;
-	linelock_t *linelock;
-	lv_t *lv;
-	lvd_t *lvd;
+	struct linelock *linelock;
+	struct lv *lv;
+	struct lvd *lvd;
 	int l2linesize;
 
 	len = 0;
 
 	/* retrieve destination log page to write */
-	bp = (lbuf_t *) log->bp;
-	lp = (logpage_t *) bp->l_ldata;
+	bp = (struct lbuf *) log->bp;
+	lp = (struct logpage *) bp->l_ldata;
 	dstoffset = log->eor;
 
 	/* any log data to write ? */
@@ -366,7 +369,7 @@
 	/* retrieve source meta-data page to log */
 	if (tlck->flag & tlckPAGELOCK) {
 		p = (caddr_t) (tlck->mp->data);
-		linelock = (linelock_t *) & tlck->lock;
+		linelock = (struct linelock *) & tlck->lock;
 	}
 	/* retrieve source in-memory inode to log */
 	else if (tlck->flag & tlckINODELOCK) {
@@ -374,14 +377,14 @@
 			p = (caddr_t) &JFS_IP(tlck->ip)->i_dtroot;
 		else
 			p = (caddr_t) &JFS_IP(tlck->ip)->i_xtroot;
-		linelock = (linelock_t *) & tlck->lock;
+		linelock = (struct linelock *) & tlck->lock;
 	}
 #ifdef	_JFS_WIP
 	else if (tlck->flag & tlckINLINELOCK) {
 
-		inlinelock = (inlinelock_t *) & tlck;
+		inlinelock = (struct inlinelock *) & tlck;
 		p = (caddr_t) & inlinelock->pxd;
-		linelock = (linelock_t *) & tlck;
+		linelock = (struct linelock *) & tlck;
 	}
 #endif				/* _JFS_WIP */
 	else {
@@ -393,7 +396,7 @@
       moveData:
 	ASSERT(linelock->index <= linelock->maxcnt);
 
-	lv = (lv_t *) & linelock->lv;
+	lv = linelock->lv;
 	for (i = 0; i < linelock->index; i++, lv++) {
 		if (lv->length == 0)
 			continue;
@@ -404,7 +407,7 @@
 			lmNextPage(log);
 
 			bp = log->bp;
-			lp = (logpage_t *) bp->l_ldata;
+			lp = (struct logpage *) bp->l_ldata;
 			dstoffset = LOGPHDRSIZE;
 		}
 
@@ -428,8 +431,8 @@
 			/* page become full: move on to next page */
 			lmNextPage(log);
 
-			bp = (lbuf_t *) log->bp;
-			lp = (logpage_t *) bp->l_ldata;
+			bp = (struct lbuf *) log->bp;
+			lp = (struct logpage *) bp->l_ldata;
 			dstoffset = LOGPHDRSIZE;
 
 			srclen -= nbytes;
@@ -440,7 +443,7 @@
 		 * move log vector descriptor
 		 */
 		len += 4;
-		lvd = (lvd_t *) ((caddr_t) lp + dstoffset);
+		lvd = (struct lvd *) ((caddr_t) lp + dstoffset);
 		lvd->offset = cpu_to_le16(lv->offset);
 		lvd->length = cpu_to_le16(lv->length);
 		dstoffset += 4;
@@ -450,7 +453,7 @@
 	}
 
 	if ((i = linelock->next)) {
-		linelock = (linelock_t *) lid_to_tlock(i);
+		linelock = (struct linelock *) lid_to_tlock(i);
 		goto moveData;
 	}
 
@@ -534,8 +537,8 @@
 		/* page become full: move on to next page */
 		lmNextPage(log);
 
-		bp = (lbuf_t *) log->bp;
-		lp = (logpage_t *) bp->l_ldata;
+		bp = (struct lbuf *) log->bp;
+		lp = (struct logpage *) bp->l_ldata;
 		dstoffset = LOGPHDRSIZE;
 		src += nbytes;
 	}
@@ -555,21 +558,21 @@
  *			
  * serialization: LOG_LOCK() held on entry/exit
  */
-static int lmNextPage(log_t * log)
+static int lmNextPage(struct jfs_log * log)
 {
-	logpage_t *lp;
+	struct logpage *lp;
 	int lspn;		/* log sequence page number */
 	int pn;			/* current page number */
-	lbuf_t *bp;
-	lbuf_t *nextbp;
-	tblock_t *tblk;
+	struct lbuf *bp;
+	struct lbuf *nextbp;
+	struct tblock *tblk;
 
 	jFYI(1, ("lmNextPage\n"));
 
 	/* get current log page number and log sequence page number */
 	pn = log->page;
 	bp = log->bp;
-	lp = (logpage_t *) bp->l_ldata;
+	lp = (struct logpage *) bp->l_ldata;
 	lspn = le32_to_cpu(lp->h.page);
 
 	LOGGC_LOCK(log);
@@ -637,7 +640,7 @@
 	log->bp = nextbp;
 
 	/* initialize next log page */
-	lp = (logpage_t *) nextbp->l_ldata;
+	lp = (struct logpage *) nextbp->l_ldata;
 	lp->h.page = lp->t.page = cpu_to_le32(lspn + 1);
 	lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE);
 
@@ -661,7 +664,7 @@
  *	transaction blocks on the commit queue.
  *	N.B. LOG_LOCK is NOT held during lmGroupCommit().
  */
-int lmGroupCommit(log_t * log, tblock_t * tblk)
+int lmGroupCommit(struct jfs_log * log, struct tblock * tblk)
 {
 	int rc = 0;
 
@@ -738,13 +741,13 @@
  *	LOGGC_LOCK must be held by caller.
  *	N.B. LOG_LOCK is NOT held during lmGroupCommit().
  */
-void lmGCwrite(log_t * log, int cant_write)
+void lmGCwrite(struct jfs_log * log, int cant_write)
 {
-	lbuf_t *bp;
-	logpage_t *lp;
+	struct lbuf *bp;
+	struct logpage *lp;
 	int gcpn;		/* group commit page number */
-	tblock_t *tblk;
-	tblock_t *xtblk;
+	struct tblock *tblk;
+	struct tblock *xtblk;
 
 	/*
 	 * build the commit group of a log page
@@ -768,8 +771,8 @@
 	/*
 	 * pageout to commit transactions on the log page.
 	 */
-	bp = (lbuf_t *) tblk->bp;
-	lp = (logpage_t *) bp->l_ldata;
+	bp = (struct lbuf *) tblk->bp;
+	lp = (struct logpage *) bp->l_ldata;
 	/* is page already full ? */
 	if (tblk->flag & tblkGC_EOP) {
 		/* mark page to free at end of group commit of the page */
@@ -806,12 +809,12 @@
  * NOTE:
  *	This routine is called a interrupt time by lbmIODone
  */
-void lmPostGC(lbuf_t * bp)
+void lmPostGC(struct lbuf * bp)
 {
 	unsigned long flags;
-	log_t *log = bp->l_log;
-	logpage_t *lp;
-	tblock_t *tblk;
+	struct jfs_log *log = bp->l_log;
+	struct logpage *lp;
+	struct tblock *tblk;
 
 	//LOGGC_LOCK(log);
 	spin_lock_irqsave(&log->gclock, flags);
@@ -866,7 +869,7 @@
 		 */
 		else if (tblk->flag & tblkGC_EOP) {
 			/* finalize the page */
-			lp = (logpage_t *) bp->l_ldata;
+			lp = (struct logpage *) bp->l_ldata;
 			bp->l_ceor = bp->l_eor;
 			lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
 			jEVENT(0, ("lmPostGC: calling lbmWrite\n"));
@@ -921,14 +924,14 @@
  *			
  * serialization: LOG_LOCK() held on entry/exit
  */
-int lmLogSync(log_t * log, int nosyncwait)
+int lmLogSync(struct jfs_log * log, int nosyncwait)
 {
 	int logsize;
 	int written;		/* written since last syncpt */
 	int free;		/* free space left available */
 	int delta;		/* additional delta to write normally */
 	int more;		/* additional write granted */
-	lrd_t lrd;
+	struct lrd lrd;
 	int lsn;
 	struct logsyncblk *lp;
 
@@ -1053,15 +1056,15 @@
  *
  * serialization:
  */
-int lmLogOpen(struct super_block *sb, log_t ** logptr)
+int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr)
 {
 	int rc;
 	struct block_device *bdev;
-	log_t *log;
+	struct jfs_log *log;
 
-	if (!(log = kmalloc(sizeof(log_t), GFP_KERNEL)))
+	if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL)))
 		return ENOMEM;
-	memset(log, 0, sizeof(log_t));
+	memset(log, 0, sizeof(struct jfs_log));
 	init_waitqueue_head(&log->syncwait);
 
 	log->sb = sb;		/* This should be a list */
@@ -1166,14 +1169,14 @@
  *			
  * serialization: single first open thread
  */
-int lmLogInit(log_t * log)
+int lmLogInit(struct jfs_log * log)
 {
 	int rc = 0;
-	lrd_t lrd;
-	logsuper_t *logsuper;
-	lbuf_t *bpsuper;
-	lbuf_t *bp;
-	logpage_t *lp;
+	struct lrd lrd;
+	struct logsuper *logsuper;
+	struct lbuf *bpsuper;
+	struct lbuf *bp;
+	struct logpage *lp;
 	int lsn;
 
 	jFYI(1, ("lmLogInit: log:0x%p\n", log));
@@ -1199,7 +1202,7 @@
 	if ((rc = lbmRead(log, 1, &bpsuper)))
 		goto errout10;
 
-	logsuper = (logsuper_t *) bpsuper->l_ldata;
+	logsuper = (struct logsuper *) bpsuper->l_ldata;
 
 	if (logsuper->magic != cpu_to_le32(LOGMAGIC)) {
 		jERROR(1, ("*** Log Format Error ! ***\n"));
@@ -1245,7 +1248,7 @@
 	if ((rc = lbmRead(log, log->page, &bp)))
 		goto errout20;
 
-	lp = (logpage_t *) bp->l_ldata;
+	lp = (struct logpage *) bp->l_ldata;
 
 	jFYI(1, ("lmLogInit: lsn:0x%x page:%d eor:%d:%d\n",
 		 le32_to_cpu(logsuper->end), log->page, log->eor,
@@ -1284,7 +1287,7 @@
 	lsn = lmWriteRecord(log, NULL, &lrd, NULL);
 	bp = log->bp;
 	bp->l_ceor = bp->l_eor;
-	lp = (logpage_t *) bp->l_ldata;
+	lp = (struct logpage *) bp->l_ldata;
 	lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
 	lbmWrite(log, bp, lbmWRITE | lbmSYNC, 0);
 	if ((rc = lbmIOWait(bp, 0)))
@@ -1356,7 +1359,7 @@
  *
  * serialization:
  */
-int lmLogClose(struct super_block *sb, log_t * log)
+int lmLogClose(struct super_block *sb, struct jfs_log * log)
 {
 	int rc;
 
@@ -1390,7 +1393,7 @@
  *
  * FUNCTION:	wait for all outstanding log records to be written to disk
  */
-void lmLogWait(log_t *log)
+void lmLogWait(struct jfs_log *log)
 {
 	int i;
 
@@ -1428,15 +1431,15 @@
  *			
  * serialization: single last close thread
  */
-int lmLogShutdown(log_t * log)
+int lmLogShutdown(struct jfs_log * log)
 {
 	int rc;
-	lrd_t lrd;
+	struct lrd lrd;
 	int lsn;
-	logsuper_t *logsuper;
-	lbuf_t *bpsuper;
-	lbuf_t *bp;
-	logpage_t *lp;
+	struct logsuper *logsuper;
+	struct lbuf *bpsuper;
+	struct lbuf *bp;
+	struct logpage *lp;
 
 	jFYI(1, ("lmLogShutdown: log:0x%p\n", log));
 
@@ -1459,7 +1462,7 @@
 	lrd.log.syncpt.sync = 0;
 	lsn = lmWriteRecord(log, NULL, &lrd, NULL);
 	bp = log->bp;
-	lp = (logpage_t *) bp->l_ldata;
+	lp = (struct logpage *) bp->l_ldata;
 	lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
 	lbmWrite(log, log->bp, lbmWRITE | lbmRELEASE | lbmSYNC, 0);
 	lbmIOWait(log->bp, lbmFREE);
@@ -1472,7 +1475,7 @@
 	if ((rc = lbmRead(log, 1, &bpsuper)))
 		goto out;
 
-	logsuper = (logsuper_t *) bpsuper->l_ldata;
+	logsuper = (struct logsuper *) bpsuper->l_ldata;
 	logsuper->state = cpu_to_le32(LOGREDONE);
 	logsuper->end = cpu_to_le32(lsn);
 	lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
@@ -1508,12 +1511,12 @@
  * RETURN:	0	- success
  *		errors returned by vms_iowait().
  */
-static int lmLogFileSystem(log_t * log, char *uuid, int activate)
+static int lmLogFileSystem(struct jfs_log * log, char *uuid, int activate)
 {
 	int rc = 0;
 	int i;
-	logsuper_t *logsuper;
-	lbuf_t *bpsuper;
+	struct logsuper *logsuper;
+	struct lbuf *bpsuper;
 
 	/*
 	 * insert/remove file system device to log active file system list.
@@ -1521,7 +1524,7 @@
 	if ((rc = lbmRead(log, 1, &bpsuper)))
 		return rc;
 
-	logsuper = (logsuper_t *) bpsuper->l_ldata;
+	logsuper = (struct logsuper *) bpsuper->l_ldata;
 	if (activate) {
 		for (i = 0; i < MAX_ACTIVE; i++)
 			if (!memcmp(logsuper->active[i].uuid, NULL_UUID, 16)) {
@@ -1579,10 +1582,10 @@
  *
  * initialize per log I/O setup at lmLogInit()
  */
-static int lbmLogInit(log_t * log)
+static int lbmLogInit(struct jfs_log * log)
 {				/* log inode */
 	int i;
-	lbuf_t *lbuf;
+	struct lbuf *lbuf;
 
 	jFYI(1, ("lbmLogInit: log:0x%p\n", log));
 
@@ -1606,7 +1609,7 @@
 	log->lbuf_free = NULL;
 
 	for (i = 0; i < LOGPAGES; i++) {
-		lbuf = kmalloc(sizeof(lbuf_t), GFP_KERNEL);
+		lbuf = kmalloc(sizeof(struct lbuf), GFP_KERNEL);
 		if (lbuf == 0)
 			goto error;
 		lbuf->l_bh.b_data = lbuf->l_ldata =
@@ -1643,15 +1646,15 @@
  *
  * finalize per log I/O setup at lmLogShutdown()
  */
-static void lbmLogShutdown(log_t * log)
+static void lbmLogShutdown(struct jfs_log * log)
 {
-	lbuf_t *lbuf;
+	struct lbuf *lbuf;
 
 	jFYI(1, ("lbmLogShutdown: log:0x%p\n", log));
 
 	lbuf = log->lbuf_free;
 	while (lbuf) {
-		lbuf_t *next = lbuf->l_freelist;
+		struct lbuf *next = lbuf->l_freelist;
 		free_page((unsigned long) lbuf->l_ldata);
 		kfree(lbuf);
 		lbuf = next;
@@ -1666,9 +1669,9 @@
  *
  * allocate an empty log buffer
  */
-static lbuf_t *lbmAllocate(log_t * log, int pn)
+static struct lbuf *lbmAllocate(struct jfs_log * log, int pn)
 {
-	lbuf_t *bp;
+	struct lbuf *bp;
 	unsigned long flags;
 
 	/*
@@ -1698,7 +1701,7 @@
  *
  * release a log buffer to freelist
  */
-static void lbmFree(lbuf_t * bp)
+static void lbmFree(struct lbuf * bp)
 {
 	unsigned long flags;
 
@@ -1709,9 +1712,9 @@
 	LCACHE_UNLOCK(flags);
 }
 
-static void lbmfree(lbuf_t * bp)
+static void lbmfree(struct lbuf * bp)
 {
-	log_t *log = bp->l_log;
+	struct jfs_log *log = bp->l_log;
 
 	assert(bp->l_wqnext == NULL);
 
@@ -1737,7 +1740,7 @@
  * NOTES:
  *	Takes log_redrive_lock.
  */
-static inline void lbmRedrive(lbuf_t *bp)
+static inline void lbmRedrive(struct lbuf *bp)
 {
 	unsigned long flags;
 
@@ -1753,9 +1756,9 @@
 /*
  *	lbmRead()
  */
-static int lbmRead(log_t * log, int pn, lbuf_t ** bpp)
+static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp)
 {
-	lbuf_t *bp;
+	struct lbuf *bp;
 
 	/*
 	 * allocate a log buffer
@@ -1795,9 +1798,10 @@
  * LOGGC_LOCK() serializes lbmWrite() by lmNextPage() and lmGroupCommit().
  * LCACHE_LOCK() serializes xflag between lbmWrite() and lbmIODone()
  */
-static void lbmWrite(log_t * log, lbuf_t * bp, int flag, int cant_block)
+static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag,
+		     int cant_block)
 {
-	lbuf_t *tail;
+	struct lbuf *tail;
 	unsigned long flags;
 
 	jFYI(1, ("lbmWrite: bp:0x%p flag:0x%x pn:0x%x\n",
@@ -1863,7 +1867,7 @@
  * initiate pageout bypassing write queue for sidestream
  * (e.g., log superblock) write;
  */
-static void lbmDirectWrite(log_t * log, lbuf_t * bp, int flag)
+static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag)
 {
 	jEVENT(0, ("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x\n",
 		   bp, flag, bp->l_pn));
@@ -1893,7 +1897,7 @@
  *
  * serialization: LCACHE_LOCK() is NOT held during log i/o;
  */
-void lbmStartIO(lbuf_t * bp)
+void lbmStartIO(struct lbuf * bp)
 {
 	jFYI(1, ("lbmStartIO\n"));
 
@@ -1919,7 +1923,7 @@
 /*
  *	lbmIOWait()
  */
-static int lbmIOWait(lbuf_t * bp, int flag)
+static int lbmIOWait(struct lbuf * bp, int flag)
 {
 	unsigned long flags;
 	int rc = 0;
@@ -1952,9 +1956,9 @@
  */
 static void lbmIODone(struct buffer_head *bh, int uptodate)
 {
-	lbuf_t *bp = bh->b_private;
-	lbuf_t *nextbp, *tail;
-	log_t *log;
+	struct lbuf *bp = bh->b_private;
+	struct lbuf *nextbp, *tail;
+	struct jfs_log *log;
 	unsigned long flags;
 
 	/*
@@ -2092,7 +2096,7 @@
 
 int jfsIOWait(void *arg)
 {
-	lbuf_t *bp;
+	struct lbuf *bp;
 
 	jFYI(1, ("jfsIOWait is here!\n"));
 
@@ -2151,16 +2155,16 @@
  * XXX: We're synchronously writing one page at a time.  This needs to
  *	be improved by writing multiple pages at once.
  */
-int lmLogFormat(log_t *log, s64 logAddress, int logSize)
+int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
 {
 	int rc = -EIO;
 	struct jfs_sb_info *sbi = JFS_SBI(log->sb);
-	logsuper_t *logsuper;
-	logpage_t *lp;
+	struct logsuper *logsuper;
+	struct logpage *lp;
 	int lspn;		/* log sequence page number */
 	struct lrd *lrd_ptr;
 	int npages = 0;
-	lbuf_t *bp;
+	struct lbuf *bp;
 
 	jFYI(0, ("lmLogFormat: logAddress:%Ld logSize:%d\n",
 		 (long long)logAddress, logSize));
@@ -2182,7 +2186,7 @@
 	/*
 	 *      init log superblock: log page 1
 	 */
-	logsuper = (logsuper_t *) bp->l_ldata;
+	logsuper = (struct logsuper *) bp->l_ldata;
 
 	logsuper->magic = cpu_to_le32(LOGMAGIC);
 	logsuper->version = cpu_to_le32(LOGVERSION);
@@ -2221,7 +2225,7 @@
 	 * the succeeding log pages will have ascending order of
 	 * the lspn starting from 0, ... (N-2)
 	 */
-	lp = (logpage_t *) bp->l_ldata;
+	lp = (struct logpage *) bp->l_ldata;
 	/*
 	 * initialize 1st log page to be written: lpsn = N - 1,
 	 * write a SYNCPT log record is written to this page
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_logmgr.h linux-2.4.20-pre8/fs/jfs/jfs_logmgr.h
--- linux-2.4.20-pre7/fs/jfs/jfs_logmgr.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_logmgr.h	Wed Sep 25 18:22:07 2002
@@ -61,7 +61,7 @@
 
 #define MAX_ACTIVE	128	/* Max active file systems sharing log */
 
-typedef struct {
+struct logsuper {
 	u32 magic;		/* 4: log lv identifier */
 	s32 version;		/* 4: version number */
 	s32 serial;		/* 4: log open/mount counter */
@@ -78,7 +78,7 @@
 	struct {
 		char uuid[16];
 	} active[MAX_ACTIVE];	/* 2048: active file systems list */
-} logsuper_t;
+};
 
 #define NULL_UUID "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 
@@ -119,7 +119,7 @@
  * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only) 
  * h.eor != t.eor they were set to the smaller of their two values.
  */
-typedef struct {
+struct logpage {
 	struct {		/* header */
 		s32 page;	/* 4: log sequence page number */
 		s16 rsrvd;	/* 2: */
@@ -133,7 +133,7 @@
 		s16 rsrvd;	/* 2: */
 		s16 eor;	/* 2: normally the same as h.eor */
 	} t;
-} logpage_t;
+};
 
 #define LOGPHDRSIZE	8	/* log page header size */
 #define LOGPTLRSIZE	8	/* log page trailer size */
@@ -198,7 +198,7 @@
 #define	LOG_FREEPXD		0x0001
 
 
-typedef struct lrd {
+struct lrd {
 	/*
 	 * type independent area
 	 */
@@ -349,23 +349,23 @@
 		 * no type-dependent information
 		 */
 	} log;
-} lrd_t;			/* (36) */
+};					/* (36) */
 
 #define	LOGRDSIZE	(sizeof(struct lrd))
 
 /*
  *	line vector descriptor
  */
-typedef struct {
+struct lvd {
 	s16 offset;
 	s16 length;
-} lvd_t;
+};
 
 
 /*
  *	log logical volume
  */
-typedef struct jfs_log {
+struct jfs_log {
 
 	struct super_block *sb;	/* 4: This is used to sync metadata
 				 *    before writing syncpt.  Will
@@ -416,7 +416,7 @@
 	struct lbuf *wqueue;	/* 4: log pageout queue */
 	int count;		/* 4: count */
 	char uuid[16];		/* 16: 128-bit uuid of log device */
-} log_t;
+};
 
 /*
  * Log flag
@@ -428,10 +428,10 @@
 /*
  * group commit flag
  */
-/* log_t */
+/* jfs_log */
 #define logGC_PAGEOUT	0x00000001
 
-/* tblock_t/lbuf_t */
+/* tblock/lbuf */
 #define tblkGC_QUEUE		0x0001
 #define tblkGC_READY		0x0002
 #define tblkGC_COMMIT		0x0004
@@ -446,9 +446,9 @@
 /*
  *		log cache buffer header
  */
-typedef struct lbuf {
+struct lbuf {
 	struct buffer_head l_bh;	/* for doing I/O */
-	log_t *l_log;		/* 4: log associated with buffer */
+	struct jfs_log *l_log;		/* 4: log associated with buffer */
 
 	/*
 	 * data buffer base area
@@ -467,7 +467,7 @@
 
 	wait_queue_head_t l_ioevent;	/* 4: i/o done event */
 	struct page *l_page;	/* The page itself */
-} lbuf_t;
+};
 
 /* Reuse l_freelist for redrive list */
 #define l_redrive_next l_freelist
@@ -475,15 +475,15 @@
 /*
  *	logsynclist block
  *
- * common logsyncblk prefix for jbuf_t and tblock_t
+ * common logsyncblk prefix for jbuf_t and tblock
  */
-typedef struct logsyncblk {
+struct logsyncblk {
 	u16 xflag;		/* flags */
-	u16 flag;		/* only meaninful in tblock_t */
+	u16 flag;		/* only meaninful in tblock */
 	lid_t lid;		/* lock id */
 	s32 lsn;		/* log sequence number */
 	struct list_head synclist;	/* log sync list link */
-} logsyncblk_t;
+};
 
 /*
  *	logsynclist serialization (per log)
@@ -501,12 +501,12 @@
 		diff += (log)->logsize;\
 }
 
-extern int lmLogOpen(struct super_block *sb, log_t ** log);
-extern void lmLogWait(log_t * log);
-extern int lmLogClose(struct super_block *sb, log_t * log);
-extern int lmLogSync(log_t * log, int nosyncwait);
-extern int lmLogShutdown(log_t * log);
-extern int lmLogInit(log_t * log);
-extern int lmLogFormat(log_t *log, s64 logAddress, int logSize);
+extern int lmLogOpen(struct super_block *sb, struct jfs_log ** log);
+extern void lmLogWait(struct jfs_log * log);
+extern int lmLogClose(struct super_block *sb, struct jfs_log * log);
+extern int lmLogSync(struct jfs_log * log, int nosyncwait);
+extern int lmLogShutdown(struct jfs_log * log);
+extern int lmLogInit(struct jfs_log * log);
+extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize);
 
 #endif				/* _H_JFS_LOGMGR */
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_metapage.c linux-2.4.20-pre8/fs/jfs/jfs_metapage.c
--- linux-2.4.20-pre7/fs/jfs/jfs_metapage.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_metapage.c	Wed Sep 25 18:22:07 2002
@@ -41,7 +41,7 @@
 
 #define HASH_BITS 10		/* This makes hash_table 1 4K page */
 #define HASH_SIZE (1 << HASH_BITS)
-static metapage_t **hash_table = NULL;
+static struct metapage **hash_table = NULL;
 static unsigned long hash_order;
 
 
@@ -94,13 +94,13 @@
  * memory allocation could cause deadlock
  */
 #define METAPOOL_MIN_PAGES 32
-static metapage_t *reserved_metapages[METAPOOL_MIN_PAGES];
+static struct metapage *reserved_metapages[METAPOOL_MIN_PAGES];
 static int num_reserved = 0;
 kmem_cache_t *metapage_cache;
 
 static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
 {
-	metapage_t *mp = (metapage_t *)foo;
+	struct metapage *mp = (struct metapage *)foo;
 
 	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 	    SLAB_CTOR_CONSTRUCTOR) {
@@ -122,9 +122,9 @@
 				reserved_metapages[num_reserved]);
 }
 
-static metapage_t *alloc_metapage(int *dropped_lock, int no_wait)
+static struct metapage *alloc_metapage(int *dropped_lock, int no_wait)
 {
-	metapage_t *new;
+	struct metapage *new;
 
 	*dropped_lock = 0;
 
@@ -146,7 +146,7 @@
 	return new;
 }
 
-static void __free_metapage(metapage_t *mp)
+static void __free_metapage(struct metapage *mp)
 {
 	mp->flag = 0;
 	set_bit(META_free, &mp->flag);
@@ -157,7 +157,7 @@
 		kmem_cache_free(metapage_cache, mp);
 }
 
-static inline void free_metapage(metapage_t * mp)
+static inline void free_metapage(struct metapage * mp)
 {
 	spin_lock(&meta_lock);
 	__free_metapage(mp);
@@ -166,7 +166,7 @@
 
 int __init metapage_init(void)
 {
-	metapage_t *mp;
+	struct metapage *mp;
 
 	/*
 	 * Initialize wait queue
@@ -176,8 +176,8 @@
 	/*
 	 * Allocate the metapage structures
 	 */
-	metapage_cache = kmem_cache_create("jfs_mp", sizeof(metapage_t), 0, 0,
-					   init_once, NULL);
+	metapage_cache = kmem_cache_create("jfs_mp", sizeof(struct metapage),
+					   0, 0, init_once, NULL);
 	if (metapage_cache == NULL)
 		return -ENOMEM;
 
@@ -198,7 +198,7 @@
 	     ((PAGE_SIZE << hash_order) / sizeof(void *)) < HASH_SIZE;
 	     hash_order++);
 	hash_table =
-	    (metapage_t **) __get_free_pages(GFP_KERNEL, hash_order);
+	    (struct metapage **) __get_free_pages(GFP_KERNEL, hash_order);
 	assert(hash_table);
 	memset(hash_table, 0, PAGE_SIZE << hash_order);
 
@@ -214,8 +214,8 @@
 /*
  * Basically same hash as in pagemap.h, but using our hash table
  */
-static metapage_t **meta_hash(struct address_space *mapping,
-			      unsigned long index)
+static struct metapage **meta_hash(struct address_space *mapping,
+				   unsigned long index)
 {
 #define i (((unsigned long)mapping)/ \
 	   (sizeof(struct inode) & ~(sizeof(struct inode) -1 )))
@@ -225,11 +225,11 @@
 #undef s
 }
 
-static metapage_t *search_hash(metapage_t ** hash_ptr,
-			       struct address_space *mapping,
+static struct metapage *search_hash(struct metapage ** hash_ptr,
+				    struct address_space *mapping,
 			       unsigned long index)
 {
-	metapage_t *ptr;
+	struct metapage *ptr;
 
 	for (ptr = *hash_ptr; ptr; ptr = ptr->hash_next) {
 		if ((ptr->mapping == mapping) && (ptr->index == index))
@@ -239,7 +239,7 @@
 	return NULL;
 }
 
-static void add_to_hash(metapage_t * mp, metapage_t ** hash_ptr)
+static void add_to_hash(struct metapage * mp, struct metapage ** hash_ptr)
 {
 	if (*hash_ptr)
 		(*hash_ptr)->hash_prev = mp;
@@ -249,7 +249,7 @@
 	*hash_ptr = mp;
 }
 
-static void remove_from_hash(metapage_t * mp, metapage_t ** hash_ptr)
+static void remove_from_hash(struct metapage * mp, struct metapage ** hash_ptr)
 {
 	if (mp->hash_prev)
 		mp->hash_prev->hash_next = mp->hash_next;
@@ -262,17 +262,17 @@
 		mp->hash_next->hash_prev = mp->hash_prev;
 }
 
-metapage_t *__get_metapage(struct inode *inode,
-			   unsigned long lblock, unsigned int size,
-			   int absolute, unsigned long new)
+struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
+				unsigned int size, int absolute,
+				unsigned long new)
 {
 	int dropped_lock;
-	metapage_t **hash_ptr;
+	struct metapage **hash_ptr;
 	int l2BlocksPerPage;
 	int l2bsize;
 	int no_wait;
 	struct address_space *mapping;
-	metapage_t *mp;
+	struct metapage *mp;
 	unsigned long page_index;
 	unsigned long page_offset;
 
@@ -332,7 +332,7 @@
 			/* alloc_metapage blocked, we need to search the hash
 			 * again.
 			 */
-			metapage_t *mp2;
+			struct metapage *mp2;
 			mp2 = search_hash(hash_ptr, mapping, lblock);
 			if (mp2) {
 				__free_metapage(mp);
@@ -392,7 +392,7 @@
 	return NULL;
 }
 
-void hold_metapage(metapage_t * mp, int force)
+void hold_metapage(struct metapage * mp, int force)
 {
 	spin_lock(&meta_lock);
 
@@ -408,7 +408,7 @@
 	spin_unlock(&meta_lock);
 }
 
-static void __write_metapage(metapage_t * mp)
+static void __write_metapage(struct metapage * mp)
 {
 	int l2bsize = mp->mapping->host->i_blkbits;
 	int l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize;
@@ -452,7 +452,7 @@
 	jFYI(1, ("__write_metapage done\n"));
 }
 
-static inline void sync_metapage(metapage_t *mp)
+static inline void sync_metapage(struct metapage *mp)
 {
 	struct page *page = mp->page;
 
@@ -469,9 +469,9 @@
 	page_cache_release(page);
 }
 
-void release_metapage(metapage_t * mp)
+void release_metapage(struct metapage * mp)
 {
-	log_t *log;
+	struct jfs_log *log;
 
 	jFYI(1,
 	     ("release_metapage: mp = 0x%p, flag = 0x%lx\n", mp,
@@ -537,11 +537,11 @@
 
 void __invalidate_metapages(struct inode *ip, s64 addr, int len)
 {
-	metapage_t **hash_ptr;
+	struct metapage **hash_ptr;
 	unsigned long lblock;
 	int l2BlocksPerPage = PAGE_CACHE_SHIFT - ip->i_blkbits;
 	struct address_space *mapping = ip->i_mapping;
-	metapage_t *mp;
+	struct metapage *mp;
 	struct page *page;
 
 	/*
@@ -574,11 +574,11 @@
 void invalidate_inode_metapages(struct inode *inode)
 {
 	struct list_head *ptr;
-	metapage_t *mp;
+	struct metapage *mp;
 
 	spin_lock(&meta_lock);
 	list_for_each(ptr, &JFS_IP(inode)->mp_list) {
-		mp = list_entry(ptr, metapage_t, inode_list);
+		mp = list_entry(ptr, struct metapage, inode_list);
 		clear_bit(META_dirty, &mp->flag);
 		set_bit(META_discard, &mp->flag);
 		kunmap(mp->page);
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_metapage.h linux-2.4.20-pre8/fs/jfs/jfs_metapage.h
--- linux-2.4.20-pre7/fs/jfs/jfs_metapage.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_metapage.h	Wed Sep 25 18:22:07 2002
@@ -21,7 +21,7 @@
 
 #include <linux/pagemap.h>
 
-typedef struct metapage {
+struct metapage {
 	/* Common logsyncblk prefix (see jfs_logmgr.h) */
 	u16 xflag;
 	u16 unused;
@@ -55,7 +55,7 @@
 	int clsn;
 	atomic_t nohomeok;
 	struct jfs_log *log;
-} metapage_t;
+};
 
 /* metapage flag */
 #define META_locked	0
@@ -69,7 +69,7 @@
 #define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag)
 
 /* function prototypes */
-extern metapage_t *__get_metapage(struct inode *inode,
+extern struct metapage *__get_metapage(struct inode *inode,
 				  unsigned long lblock, unsigned int size,
 				  int absolute, unsigned long new);
 
@@ -79,22 +79,22 @@
 #define get_metapage(inode, lblock, size, absolute)\
 	 __get_metapage(inode, lblock, size, absolute, TRUE)
 
-extern void release_metapage(metapage_t *);
-extern void hold_metapage(metapage_t *, int);
+extern void release_metapage(struct metapage *);
+extern void hold_metapage(struct metapage *, int);
 
-static inline void write_metapage(metapage_t *mp)
+static inline void write_metapage(struct metapage *mp)
 {
 	set_bit(META_dirty, &mp->flag);
 	release_metapage(mp);
 }
 
-static inline void flush_metapage(metapage_t *mp)
+static inline void flush_metapage(struct metapage *mp)
 {
 	set_bit(META_sync, &mp->flag);
 	write_metapage(mp);
 }
 
-static inline void discard_metapage(metapage_t *mp)
+static inline void discard_metapage(struct metapage *mp)
 {
 	clear_bit(META_dirty, &mp->flag);
 	set_bit(META_discard, &mp->flag);
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_mount.c linux-2.4.20-pre8/fs/jfs/jfs_mount.c
--- linux-2.4.20-pre7/fs/jfs/jfs_mount.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_mount.c	Wed Sep 25 18:22:07 2002
@@ -249,7 +249,7 @@
 int jfs_mount_rw(struct super_block *sb, int remount)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);  
-	log_t *log;
+	struct jfs_log *log;
 	int rc;
 
 	/*
@@ -506,8 +506,8 @@
  */
 static int logMOUNT(struct super_block *sb)
 {
-	log_t *log = JFS_SBI(sb)->log;
-	lrd_t lrd;
+	struct jfs_log *log = JFS_SBI(sb)->log;
+	struct lrd lrd;
 
 	lrd.logtid = 0;
 	lrd.backchain = 0;
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_txnmgr.c linux-2.4.20-pre8/fs/jfs/jfs_txnmgr.c
--- linux-2.4.20-pre7/fs/jfs/jfs_txnmgr.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_txnmgr.c	Wed Sep 25 18:22:07 2002
@@ -61,18 +61,18 @@
  */
 static struct {
 	/* tblock */
-	int freetid;		/* 4: index of a free tid structure */
-	wait_queue_head_t freewait;	/* 4: eventlist of free tblock */
+	int freetid;		/* index of a free tid structure */
+	wait_queue_head_t freewait;	/* eventlist of free tblock */
 
 	/* tlock */
-	int freelock;		/* 4: index first free lock word */
-	wait_queue_head_t freelockwait;	/* 4: eventlist of free tlock */
-	wait_queue_head_t lowlockwait;	/* 4: eventlist of ample tlocks */
-	int tlocksInUse;	/* 4: Number of tlocks in use */
-	spinlock_t LazyLock;	/* 4: synchronize sync_queue & unlock_queue */
-/*	tblock_t *sync_queue;	 * 4: Transactions waiting for data sync */
-	tblock_t *unlock_queue;	/* 4: Transactions waiting to be released */
-	tblock_t *unlock_tail;	/* 4: Tail of unlock_queue */
+	int freelock;		/* index first free lock word */
+	wait_queue_head_t freelockwait;	/* eventlist of free tlock */
+	wait_queue_head_t lowlockwait;	/* eventlist of ample tlocks */
+	int tlocksInUse;	/* Number of tlocks in use */
+	spinlock_t LazyLock;	/* synchronize sync_queue & unlock_queue */
+/*	struct tblock *sync_queue; * Transactions waiting for data sync */
+	struct tblock *unlock_queue;	/* Txns waiting to be released */
+	struct tblock *unlock_tail;	/* Tail of unlock_queue */
 	struct list_head anon_list;	/* inodes having anonymous txns */
 	struct list_head anon_list2;	/* inodes having anonymous txns
 					   that couldn't be sync'ed */
@@ -142,8 +142,8 @@
 /*
  * external references
  */
-extern int lmGroupCommit(log_t * log, tblock_t * tblk);
-extern void lmSync(log_t *);
+extern int lmGroupCommit(struct jfs_log * log, struct tblock * tblk);
+extern void lmSync(struct jfs_log *);
 extern int jfs_commit_inode(struct inode *, int);
 extern int jfs_stop_threads;
 
@@ -153,22 +153,27 @@
 /*
  * forward references
  */
-int diLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck,
-	  commit_t * cd);
-int dataLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
-void dtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
-void inlineLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
-void mapLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
-void txAbortCommit(commit_t * cd, int exval);
-static void txAllocPMap(struct inode *ip, maplock_t * maplock,
-			tblock_t * tblk);
-void txForce(tblock_t * tblk);
-static int txLog(log_t * log, tblock_t * tblk, commit_t * cd);
+int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	  struct tlock * tlck, struct commit * cd);
+int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	    struct tlock * tlck);
+void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	   struct tlock * tlck);
+void inlineLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	       struct tlock * tlck);
+void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	    struct tlock * tlck);
+void txAbortCommit(struct commit * cd, int exval);
+static void txAllocPMap(struct inode *ip, struct maplock * maplock,
+			struct tblock * tblk);
+void txForce(struct tblock * tblk);
+static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd);
 int txMoreLock(void);
-static void txUpdateMap(tblock_t * tblk);
-static void txRelease(tblock_t * tblk);
-void xtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
-static void LogSyncRelease(metapage_t * mp);
+static void txUpdateMap(struct tblock * tblk);
+static void txRelease(struct tblock * tblk);
+void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	   struct tlock * tlck);
+static void LogSyncRelease(struct metapage * mp);
 
 /*
  *              transaction block/lock management
@@ -229,8 +234,8 @@
 	 * transaction id (tid) = tblock index
 	 * tid = 0 is reserved.
 	 */
-	size = sizeof(tblock_t) * nTxBlock;
-	TxBlock = (tblock_t *) vmalloc(size);
+	size = sizeof(struct tblock) * nTxBlock;
+	TxBlock = (struct tblock *) vmalloc(size);
 	if (TxBlock == NULL)
 		return ENOMEM;
 
@@ -254,8 +259,8 @@
 	 * transaction lock id = tlock index
 	 * tlock id = 0 is reserved.
 	 */
-	size = sizeof(tlock_t) * nTxLock;
-	TxLock = (tlock_t *) vmalloc(size);
+	size = sizeof(struct tlock) * nTxLock;
+	TxLock = (struct tlock *) vmalloc(size);
 	if (TxLock == NULL) {
 		vfree(TxBlock);
 		return ENOMEM;
@@ -308,11 +313,11 @@
 tid_t txBegin(struct super_block *sb, int flag)
 {
 	tid_t t;
-	tblock_t *tblk;
-	log_t *log;
+	struct tblock *tblk;
+	struct jfs_log *log;
 
 	jFYI(1, ("txBegin: flag = 0x%x\n", flag));
-	log = (log_t *) JFS_SBI(sb)->log;
+	log = JFS_SBI(sb)->log;
 
 	TXN_LOCK();
 
@@ -367,7 +372,7 @@
 	 * We can't zero the whole thing or we screw up another thread being
 	 * awakened after sleeping on tblk->waitor
 	 *
-	 * memset(tblk, 0, sizeof(tblock_t));
+	 * memset(tblk, 0, sizeof(struct tblock));
 	 */
 	tblk->next = tblk->last = tblk->xflag = tblk->flag = tblk->lsn = 0;
 
@@ -401,9 +406,9 @@
  */
 void txBeginAnon(struct super_block *sb)
 {
-	log_t *log;
+	struct jfs_log *log;
 
-	log = (log_t *) JFS_SBI(sb)->log;
+	log = JFS_SBI(sb)->log;
 
 	TXN_LOCK();
 
@@ -439,8 +444,8 @@
  */
 void txEnd(tid_t tid)
 {
-	tblock_t *tblk = tid_to_tblock(tid);
-	log_t *log;
+	struct tblock *tblk = tid_to_tblock(tid);
+	struct jfs_log *log;
 
 	jFYI(1, ("txEnd: tid = %d\n", tid));
 	TXN_LOCK();
@@ -451,7 +456,7 @@
 	 */
 	TXN_WAKEUP(&tblk->waitor);
 
-	log = (log_t *) JFS_SBI(tblk->sb)->log;
+	log = JFS_SBI(tblk->sb)->log;
 
 	/*
 	 * Lazy commit thread can't free this guy until we mark it UNLOCKED,
@@ -525,17 +530,18 @@
  *
  * serialization:
  */
-tlock_t *txLock(tid_t tid, struct inode *ip, metapage_t * mp, int type)
+struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
+		     int type)
 {
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 	int dir_xtree = 0;
 	lid_t lid;
 	tid_t xtid;
-	tlock_t *tlck;
-	xtlock_t *xtlck;
-	linelock_t *linelock;
+	struct tlock *tlck;
+	struct xtlock *xtlck;
+	struct linelock *linelock;
 	xtpage_t *p;
-	tblock_t *tblk;
+	struct tblock *tblk;
 
 	assert(!test_cflag(COMMIT_Nolink, ip));
 
@@ -697,7 +703,7 @@
 	}
 
 	/* initialize type dependent area for linelock */
-	linelock = (linelock_t *) & tlck->lock;
+	linelock = (struct linelock *) & tlck->lock;
 	linelock->next = 0;
 	linelock->flag = tlckLINELOCK;
 	linelock->maxcnt = TLOCKSHORT;
@@ -711,7 +717,7 @@
 	case tlckXTREE:
 		linelock->l2linesize = L2XTSLOTSIZE;
 
-		xtlck = (xtlock_t *) linelock;
+		xtlck = (struct xtlock *) linelock;
 		xtlck->header.offset = 0;
 		xtlck->header.length = 2;
 
@@ -763,10 +769,10 @@
 	if (jfs_ip->fileset != AGGREGATE_I) {
 		jERROR(1, ("txLock: trying to lock locked page!\n"));
 		dump_mem("ip", ip, sizeof(struct inode));
-		dump_mem("mp", mp, sizeof(metapage_t));
+		dump_mem("mp", mp, sizeof(struct metapage));
 		dump_mem("Locker's tblk", tid_to_tblock(tid),
-			 sizeof(tblock_t));
-		dump_mem("Tlock", tlck, sizeof(tlock_t));
+			 sizeof(struct tblock));
+		dump_mem("Tlock", tlck, sizeof(struct tlock));
 		BUG();
 	}
 	INCREMENT(stattx.waitlock);	/* statistics */
@@ -794,11 +800,11 @@
  *
  * RETURN:      Errors from subroutines.
  */
-static void txRelease(tblock_t * tblk)
+static void txRelease(struct tblock * tblk)
 {
-	metapage_t *mp;
+	struct metapage *mp;
 	lid_t lid;
-	tlock_t *tlck;
+	struct tlock *tlck;
 
 	TXN_LOCK();
 
@@ -827,17 +833,17 @@
  * FUNCTION:    Initiates pageout of pages modified by tid in journalled
  *              objects and frees their lockwords.
  */
-static void txUnlock(tblock_t * tblk)
+static void txUnlock(struct tblock * tblk)
 {
-	tlock_t *tlck;
-	linelock_t *linelock;
+	struct tlock *tlck;
+	struct linelock *linelock;
 	lid_t lid, next, llid, k;
-	metapage_t *mp;
-	log_t *log;
+	struct metapage *mp;
+	struct jfs_log *log;
 	int difft, diffp;
 
 	jFYI(1, ("txUnlock: tblk = 0x%p\n", tblk));
-	log = (log_t *) JFS_SBI(tblk->sb)->log;
+	log = JFS_SBI(tblk->sb)->log;
 
 	/*
 	 * mark page under tlock homeok (its log has been written):
@@ -891,9 +897,9 @@
 		 */
 		TXN_LOCK();
 
-		llid = ((linelock_t *) & tlck->lock)->next;
+		llid = ((struct linelock *) & tlck->lock)->next;
 		while (llid) {
-			linelock = (linelock_t *) lid_to_tlock(llid);
+			linelock = (struct linelock *) lid_to_tlock(llid);
 			k = linelock->next;
 			txLockFree(llid);
 			llid = k;
@@ -924,13 +930,13 @@
  * function: allocate a transaction lock for freed page/entry;
  *      for freed page, maplock is used as xtlock/dtlock type;
  */
-tlock_t *txMaplock(tid_t tid, struct inode *ip, int type)
+struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
 {
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 	lid_t lid;
-	tblock_t *tblk;
-	tlock_t *tlck;
-	maplock_t *maplock;
+	struct tblock *tblk;
+	struct tlock *tlck;
+	struct maplock *maplock;
 
 	TXN_LOCK();
 
@@ -982,7 +988,7 @@
 	TXN_UNLOCK();
 
 	/* initialize type dependent area for maplock */
-	maplock = (maplock_t *) & tlck->lock;
+	maplock = (struct maplock *) & tlck->lock;
 	maplock->next = 0;
 	maplock->maxcnt = 0;
 	maplock->index = 0;
@@ -996,11 +1002,11 @@
  *
  * function: allocate a transaction lock for log vector list
  */
-linelock_t *txLinelock(linelock_t * tlock)
+struct linelock *txLinelock(struct linelock * tlock)
 {
 	lid_t lid;
-	tlock_t *tlck;
-	linelock_t *linelock;
+	struct tlock *tlck;
+	struct linelock *linelock;
 
 	TXN_LOCK();
 
@@ -1011,7 +1017,7 @@
 	TXN_UNLOCK();
 
 	/* initialize linelock */
-	linelock = (linelock_t *) tlck;
+	linelock = (struct linelock *) tlck;
 	linelock->next = 0;
 	linelock->flag = tlckLINELOCK;
 	linelock->maxcnt = TLOCKLONG;
@@ -1069,10 +1075,10 @@
 	     int flag)
 {
 	int rc = 0, rc1 = 0;
-	commit_t cd;
-	log_t *log;
-	tblock_t *tblk;
-	lrd_t *lrd;
+	struct commit cd;
+	struct jfs_log *log;
+	struct tblock *tblk;
+	struct lrd *lrd;
 	int lsn;
 	struct inode *ip;
 	struct jfs_inode_info *jfs_ip;
@@ -1097,7 +1103,7 @@
 	/*
 	 * initialize commit structure
 	 */
-	log = (log_t *) JFS_SBI(sb)->log;
+	log = JFS_SBI(sb)->log;
 	cd.log = log;
 
 	/* initialize log record descriptor in commit */
@@ -1282,13 +1288,13 @@
  *
  * RETURN :
  */
-static int txLog(log_t * log, tblock_t * tblk, commit_t * cd)
+static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd)
 {
 	int rc = 0;
 	struct inode *ip;
 	lid_t lid;
-	tlock_t *tlck;
-	lrd_t *lrd = &cd->lrd;
+	struct tlock *tlck;
+	struct lrd *lrd = &cd->lrd;
 
 	/*
 	 * write log record(s) for each tlock of transaction,
@@ -1345,13 +1351,13 @@
  *
  * function:    log inode tlock and format maplock to update bmap;
  */
-int diLog(log_t * log,
-	  tblock_t * tblk, lrd_t * lrd, tlock_t * tlck, commit_t * cd)
+int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	  struct tlock * tlck, struct commit * cd)
 {
 	int rc = 0;
-	metapage_t *mp;
+	struct metapage *mp;
 	pxd_t *pxd;
-	pxdlock_t *pxdlock;
+	struct pxd_lock *pxdlock;
 
 	mp = tlck->mp;
 
@@ -1407,7 +1413,7 @@
 		lrd->log.noredoinoext.inoext_idx =
 		    cpu_to_le32((u32) (size_t) cd->iplist[2]);
 
-		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxdlock = (struct pxd_lock *) & tlck->lock;
 		*pxd = pxdlock->pxd;
 		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
 
@@ -1433,7 +1439,7 @@
 		 * alloc of new (and free of old) external EA extent;
 		 */
 		lrd->type = cpu_to_le16(LOG_UPDATEMAP);
-		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxdlock = (struct pxd_lock *) & tlck->lock;
 		nlock = pxdlock->index;
 		for (i = 0; i < nlock; i++, pxdlock++) {
 			if (pxdlock->flag & mlckALLOCPXD)
@@ -1462,9 +1468,10 @@
  *
  * function:    log data tlock
  */
-int dataLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	    struct tlock * tlck)
 {
-	metapage_t *mp;
+	struct metapage *mp;
 	pxd_t *pxd;
 	int rc;
 	s64 xaddr;
@@ -1517,11 +1524,12 @@
  *
  * function:    log dtree tlock and format maplock to update bmap;
  */
-void dtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	   struct tlock * tlck)
 {
 	struct inode *ip;
-	metapage_t *mp;
-	pxdlock_t *pxdlock;
+	struct metapage *mp;
+	struct pxd_lock *pxdlock;
 	pxd_t *pxd;
 
 	ip = tlck->ip;
@@ -1564,7 +1572,7 @@
 		if (tlck->type & tlckBTROOT)
 			return;
 		tlck->flag |= tlckUPDATEMAP;
-		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxdlock = (struct pxd_lock *) & tlck->lock;
 		pxdlock->flag = mlckALLOCPXD;
 		pxdlock->pxd = *pxd;
 
@@ -1605,7 +1613,7 @@
 		 * of the deletd page
 		 */
 		lrd->type = cpu_to_le16(LOG_NOREDOPAGE);
-		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxdlock = (struct pxd_lock *) & tlck->lock;
 		*pxd = pxdlock->pxd;
 		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
 
@@ -1623,15 +1631,16 @@
  *
  * function:    log xtree tlock and format maplock to update bmap;
  */
-void xtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	   struct tlock * tlck)
 {
 	struct inode *ip;
-	metapage_t *mp;
+	struct metapage *mp;
 	xtpage_t *p;
-	xtlock_t *xtlck;
-	maplock_t *maplock;
-	xdlistlock_t *xadlock;
-	pxdlock_t *pxdlock;
+	struct xtlock *xtlck;
+	struct maplock *maplock;
+	struct xdlistlock *xadlock;
+	struct pxd_lock *pxdlock;
 	pxd_t *pxd;
 	int next, lwm, hwm;
 
@@ -1654,10 +1663,10 @@
 		p = (xtpage_t *) mp->data;
 	next = le16_to_cpu(p->header.nextindex);
 
-	xtlck = (xtlock_t *) & tlck->lock;
+	xtlck = (struct xtlock *) & tlck->lock;
 
-	maplock = (maplock_t *) & tlck->lock;
-	xadlock = (xdlistlock_t *) maplock;
+	maplock = (struct maplock *) & tlck->lock;
+	xadlock = (struct xdlistlock *) maplock;
 
 	/*
 	 *      entry insertion/extension;
@@ -1775,7 +1784,7 @@
 		 */
 		lrd->type = cpu_to_le16(LOG_UPDATEMAP);
 		lrd->log.updatemap.type = cpu_to_le16(LOG_FREEXADLIST);
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 		hwm = xtlck->hwm.offset;
 		lrd->log.updatemap.nxd =
 		    cpu_to_le16(hwm - XTENTRYSTART + 1);
@@ -1894,7 +1903,7 @@
 			 * entry XAD[next - 1]:
 			 * (xtlck->pxdlock = truncated delta extent);
 			 */
-			pxdlock = (pxdlock_t *) & xtlck->pxdlock;
+			pxdlock = (struct pxd_lock *) & xtlck->pxdlock;
 			/* assert(pxdlock->type & tlckTRUNCATE); */
 			lrd->type = cpu_to_le16(LOG_UPDATEMAP);
 			lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD);
@@ -1916,7 +1925,7 @@
 			lrd->type = cpu_to_le16(LOG_UPDATEMAP);
 			lrd->log.updatemap.type =
 			    cpu_to_le16(LOG_FREEXADLIST);
-			xtlck = (xtlock_t *) & tlck->lock;
+			xtlck = (struct xtlock *) & tlck->lock;
 			hwm = xtlck->hwm.offset;
 			lrd->log.updatemap.nxd =
 			    cpu_to_le16(hwm - next + 1);
@@ -1958,7 +1967,7 @@
 		 * truncate entry XAD[twm == next - 1]:
 		 */
 		if (twm == next - 1) {
-			pxdlock_t *pxdlock;
+			struct pxd_lock *pxdlock;
 
 			/* format a maplock for txUpdateMap() to update bmap
 			 * to free truncated delta extent of the truncated
@@ -1966,7 +1975,7 @@
 			 * (xtlck->pxdlock = truncated delta extent);
 			 */
 			tlck->flag |= tlckUPDATEMAP;
-			pxdlock = (pxdlock_t *) xadlock;
+			pxdlock = (struct pxd_lock *) xadlock;
 			pxdlock->flag = mlckFREEPXD;
 			pxdlock->count = 1;
 			pxdlock->pxd = tpxd;
@@ -2009,9 +2018,10 @@
  *
  * function:    log from maplock of freed data extents;
  */
-void mapLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+	    struct tlock * tlck)
 {
-	pxdlock_t *pxdlock;
+	struct pxd_lock *pxdlock;
 	int i, nlock;
 	pxd_t *pxd;
 
@@ -2027,7 +2037,7 @@
 		 * for logredo() to start NoRedoPage filter;
 		 */
 		lrd->type = cpu_to_le16(LOG_NOREDOPAGE);
-		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxdlock = (struct pxd_lock *) & tlck->lock;
 		pxd = &lrd->log.redopage.pxd;
 		*pxd = pxdlock->pxd;
 		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
@@ -2066,7 +2076,7 @@
 		 * from xtTailgate();
 		 */
 		lrd->type = cpu_to_le16(LOG_UPDATEMAP);
-		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxdlock = (struct pxd_lock *) & tlck->lock;
 		nlock = pxdlock->index;
 		for (i = 0; i < nlock; i++, pxdlock++) {
 			if (pxdlock->flag & mlckALLOCPXD)
@@ -2098,8 +2108,8 @@
  */
 void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
 {
-	tlock_t *tlck = NULL;
-	pxdlock_t *maplock = NULL, *pxdlock = NULL;
+	struct tlock *tlck = NULL;
+	struct pxd_lock *maplock = NULL, *pxdlock = NULL;
 
 	/*
 	 * format maplock for alloc of new EA extent
@@ -2111,8 +2121,8 @@
 		 */
 		if (newea->flag & DXD_EXTENT) {
 			tlck = txMaplock(tid, ip, tlckMAP);
-			maplock = (pxdlock_t *) & tlck->lock;
-			pxdlock = (pxdlock_t *) maplock;
+			maplock = (struct pxd_lock *) & tlck->lock;
+			pxdlock = (struct pxd_lock *) maplock;
 			pxdlock->flag = mlckALLOCPXD;
 			PXDaddress(&pxdlock->pxd, addressDXD(newea));
 			PXDlength(&pxdlock->pxd, lengthDXD(newea));
@@ -2131,8 +2141,8 @@
 	if (!test_cflag(COMMIT_Nolink, ip) && oldea->flag & DXD_EXTENT) {
 		if (tlck == NULL) {
 			tlck = txMaplock(tid, ip, tlckMAP);
-			maplock = (pxdlock_t *) & tlck->lock;
-			pxdlock = (pxdlock_t *) maplock;
+			maplock = (struct pxd_lock *) & tlck->lock;
+			pxdlock = (struct pxd_lock *) maplock;
 			maplock->index = 0;
 		}
 		pxdlock->flag = mlckFREEPXD;
@@ -2149,11 +2159,11 @@
  * function: synchronously write pages locked by transaction
  *              after txLog() but before txUpdateMap();
  */
-void txForce(tblock_t * tblk)
+void txForce(struct tblock * tblk)
 {
-	tlock_t *tlck;
+	struct tlock *tlck;
 	lid_t lid, next;
-	metapage_t *mp;
+	struct metapage *mp;
 
 	/*
 	 * reverse the order of transaction tlocks in
@@ -2204,17 +2214,17 @@
  *
  * parameter:
  */
-static void txUpdateMap(tblock_t * tblk)
+static void txUpdateMap(struct tblock * tblk)
 {
 	struct inode *ip;
 	struct inode *ipimap;
 	lid_t lid;
-	tlock_t *tlck;
-	maplock_t *maplock;
-	pxdlock_t pxdlock;
+	struct tlock *tlck;
+	struct maplock *maplock;
+	struct pxd_lock pxdlock;
 	int maptype;
 	int k, nlock;
-	metapage_t *mp = 0;
+	struct metapage *mp = 0;
 
 	ipimap = JFS_SBI(tblk->sb)->ipimap;
 
@@ -2257,7 +2267,7 @@
 		 * . in-line PXD list:
 		 * . out-of-line XAD list:
 		 */
-		maplock = (maplock_t *) & tlck->lock;
+		maplock = (struct maplock *) & tlck->lock;
 		nlock = maplock->index;
 
 		for (k = 0; k < nlock; k++, maplock++) {
@@ -2328,7 +2338,7 @@
 		pxdlock.flag = mlckALLOCPXD;
 		pxdlock.pxd = JFS_IP(ip)->ixpxd;
 		pxdlock.index = 1;
-		txAllocPMap(ip, (maplock_t *) & pxdlock, tblk);
+		txAllocPMap(ip, (struct maplock *) & pxdlock, tblk);
 		iput(ip);
 	} else if (tblk->xflag & COMMIT_DELETE) {
 		ip = tblk->ip;
@@ -2363,16 +2373,16 @@
  *
  *      lsn     - log sequence number;
  */
-static void txAllocPMap(struct inode *ip, maplock_t * maplock,
-			tblock_t * tblk)
+static void txAllocPMap(struct inode *ip, struct maplock * maplock,
+			struct tblock * tblk)
 {
 	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
-	xdlistlock_t *xadlistlock;
+	struct xdlistlock *xadlistlock;
 	xad_t *xad;
 	s64 xaddr;
 	int xlen;
-	pxdlock_t *pxdlock;
-	xdlistlock_t *pxdlistlock;
+	struct pxd_lock *pxdlock;
+	struct xdlistlock *pxdlistlock;
 	pxd_t *pxd;
 	int n;
 
@@ -2380,7 +2390,7 @@
 	 * allocate from persistent map;
 	 */
 	if (maplock->flag & mlckALLOCXADLIST) {
-		xadlistlock = (xdlistlock_t *) maplock;
+		xadlistlock = (struct xdlistlock *) maplock;
 		xad = xadlistlock->xdlist;
 		for (n = 0; n < xadlistlock->count; n++, xad++) {
 			if (xad->flag & (XAD_NEW | XAD_EXTENDED)) {
@@ -2395,7 +2405,7 @@
 			}
 		}
 	} else if (maplock->flag & mlckALLOCPXD) {
-		pxdlock = (pxdlock_t *) maplock;
+		pxdlock = (struct pxd_lock *) maplock;
 		xaddr = addressPXD(&pxdlock->pxd);
 		xlen = lengthPXD(&pxdlock->pxd);
 		dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk);
@@ -2404,7 +2414,7 @@
 		      xlen));
 	} else {		/* (maplock->flag & mlckALLOCPXDLIST) */
 
-		pxdlistlock = (xdlistlock_t *) maplock;
+		pxdlistlock = (struct xdlistlock *) maplock;
 		pxd = pxdlistlock->xdlist;
 		for (n = 0; n < pxdlistlock->count; n++, pxd++) {
 			xaddr = addressPXD(pxd);
@@ -2427,15 +2437,15 @@
  * todo: optimization
  */
 void txFreeMap(struct inode *ip,
-	       maplock_t * maplock, tblock_t * tblk, int maptype)
+	       struct maplock * maplock, struct tblock * tblk, int maptype)
 {
 	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
-	xdlistlock_t *xadlistlock;
+	struct xdlistlock *xadlistlock;
 	xad_t *xad;
 	s64 xaddr;
 	int xlen;
-	pxdlock_t *pxdlock;
-	xdlistlock_t *pxdlistlock;
+	struct pxd_lock *pxdlock;
+	struct xdlistlock *pxdlistlock;
 	pxd_t *pxd;
 	int n;
 
@@ -2448,7 +2458,7 @@
 	 */
 	if (maptype == COMMIT_PMAP || maptype == COMMIT_PWMAP) {
 		if (maplock->flag & mlckFREEXADLIST) {
-			xadlistlock = (xdlistlock_t *) maplock;
+			xadlistlock = (struct xdlistlock *) maplock;
 			xad = xadlistlock->xdlist;
 			for (n = 0; n < xadlistlock->count; n++, xad++) {
 				if (!(xad->flag & XAD_NEW)) {
@@ -2462,7 +2472,7 @@
 				}
 			}
 		} else if (maplock->flag & mlckFREEPXD) {
-			pxdlock = (pxdlock_t *) maplock;
+			pxdlock = (struct pxd_lock *) maplock;
 			xaddr = addressPXD(&pxdlock->pxd);
 			xlen = lengthPXD(&pxdlock->pxd);
 			dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen,
@@ -2472,7 +2482,7 @@
 			      (ulong) xaddr, xlen));
 		} else {	/* (maplock->flag & mlckALLOCPXDLIST) */
 
-			pxdlistlock = (xdlistlock_t *) maplock;
+			pxdlistlock = (struct xdlistlock *) maplock;
 			pxd = pxdlistlock->xdlist;
 			for (n = 0; n < pxdlistlock->count; n++, pxd++) {
 				xaddr = addressPXD(pxd);
@@ -2491,7 +2501,7 @@
 	 */
 	if (maptype == COMMIT_PWMAP || maptype == COMMIT_WMAP) {
 		if (maplock->flag & mlckFREEXADLIST) {
-			xadlistlock = (xdlistlock_t *) maplock;
+			xadlistlock = (struct xdlistlock *) maplock;
 			xad = xadlistlock->xdlist;
 			for (n = 0; n < xadlistlock->count; n++, xad++) {
 				xaddr = addressXAD(xad);
@@ -2503,7 +2513,7 @@
 				      (ulong) xaddr, xlen));
 			}
 		} else if (maplock->flag & mlckFREEPXD) {
-			pxdlock = (pxdlock_t *) maplock;
+			pxdlock = (struct pxd_lock *) maplock;
 			xaddr = addressPXD(&pxdlock->pxd);
 			xlen = lengthPXD(&pxdlock->pxd);
 			dbFree(ip, xaddr, (s64) xlen);
@@ -2512,7 +2522,7 @@
 			      (ulong) xaddr, xlen));
 		} else {	/* (maplock->flag & mlckFREEPXDLIST) */
 
-			pxdlistlock = (xdlistlock_t *) maplock;
+			pxdlistlock = (struct xdlistlock *) maplock;
 			pxd = pxdlistlock->xdlist;
 			for (n = 0; n < pxdlistlock->count; n++, pxd++) {
 				xaddr = addressPXD(pxd);
@@ -2535,13 +2545,13 @@
 void txFreelock(struct inode *ip)
 {
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
-	tlock_t *xtlck, *tlck;
+	struct tlock *xtlck, *tlck;
 	lid_t xlid = 0, lid;
 
 	if (!jfs_ip->atlhead)
 		return;
 
-	xtlck = (tlock_t *) &jfs_ip->atlhead;
+	xtlck = (struct tlock *) &jfs_ip->atlhead;
 
 	while ((lid = xtlck->next)) {
 		tlck = lid_to_tlock(lid);
@@ -2582,8 +2592,8 @@
 void txAbort(tid_t tid, int dirty)
 {
 	lid_t lid, next;
-	metapage_t *mp;
-	tblock_t *tblk = tid_to_tblock(tid);
+	struct metapage *mp;
+	struct tblock *tblk = tid_to_tblock(tid);
 
 	jEVENT(1, ("txAbort: tid:%d dirty:0x%x\n", tid, dirty));
 
@@ -2640,12 +2650,12 @@
  * log age of page-frames in memory for which caller has
  * are reset to 0 (to avoid logwarap).
  */
-void txAbortCommit(commit_t * cd, int exval)
+void txAbortCommit(struct commit * cd, int exval)
 {
-	tblock_t *tblk;
+	struct tblock *tblk;
 	tid_t tid;
 	lid_t lid, next;
-	metapage_t *mp;
+	struct metapage *mp;
 
 	assert(exval == EIO || exval == ENOMEM);
 	jEVENT(1, ("txAbortCommit: cd:0x%p\n", cd));
@@ -2695,9 +2705,9 @@
  *	allocation maps are updated in order.  For synchronous transactions,
  *	let the user thread finish processing after txUpdateMap() is called.
  */
-void txLazyCommit(tblock_t * tblk)
+void txLazyCommit(struct tblock * tblk)
 {
-	log_t *log;
+	struct jfs_log *log;
 
 	while (((tblk->flag & tblkGC_READY) == 0) &&
 	       ((tblk->flag & tblkGC_UNLOCKED) == 0)) {
@@ -2711,7 +2721,7 @@
 
 	txUpdateMap(tblk);
 
-	log = (log_t *) JFS_SBI(tblk->sb)->log;
+	log = (struct jfs_log *) JFS_SBI(tblk->sb)->log;
 
 	spin_lock_irq(&log->gclock);	// LOGGC_LOCK
 
@@ -2744,7 +2754,7 @@
 int jfs_lazycommit(void *arg)
 {
 	int WorkDone;
-	tblock_t *tblk;
+	struct tblock *tblk;
 	unsigned long flags;
 
 	lock_kernel();
@@ -2820,7 +2830,7 @@
 	return 0;
 }
 
-void txLazyUnlock(tblock_t * tblk)
+void txLazyUnlock(struct tblock * tblk)
 {
 	unsigned long flags;
 
@@ -2836,9 +2846,9 @@
 	wake_up(&jfs_commit_thread_wait);
 }
 
-static void LogSyncRelease(metapage_t * mp)
+static void LogSyncRelease(struct metapage * mp)
 {
-	log_t *log = mp->log;
+	struct jfs_log *log = mp->log;
 
 	assert(atomic_read(&mp->nohomeok));
 	assert(log);
@@ -2874,7 +2884,7 @@
 {
 	struct inode *ip;
 	struct jfs_inode_info *jfs_ip;
-	log_t *log = JFS_SBI(sb)->log;
+	struct jfs_log *log = JFS_SBI(sb)->log;
 	int rc;
 	tid_t tid;
 
@@ -2925,7 +2935,7 @@
  */
 void txResume(struct super_block *sb)
 {
-	log_t *log = JFS_SBI(sb)->log;
+	struct jfs_log *log = JFS_SBI(sb)->log;
 
 	clear_bit(log_QUIESCE, &log->flag);
 	TXN_WAKEUP(&log->syncwait);
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_txnmgr.h linux-2.4.20-pre8/fs/jfs/jfs_txnmgr.h
--- linux-2.4.20-pre7/fs/jfs/jfs_txnmgr.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_txnmgr.h	Wed Sep 25 18:22:07 2002
@@ -30,9 +30,9 @@
 /*
  *	transaction block
  */
-typedef struct tblock {
+struct tblock {
 	/*
-	 * tblock_t and jbuf_t common area: struct logsyncblk
+	 * tblock and jbuf_t common area: struct logsyncblk
 	 *
 	 * the following 5 fields are the same as struct logsyncblk
 	 * which is common to tblock and jbuf to form logsynclist
@@ -44,28 +44,26 @@
 	struct list_head synclist;	/* logsynclist link */
 
 	/* lock management */
-	struct super_block *sb;	/* 4: super block */
-	lid_t next;		/* 2: index of first tlock of tid */
-	lid_t last;		/* 2: index of last tlock of tid */
-	wait_queue_head_t waitor;	/* 4: tids waiting on this tid */
+	struct super_block *sb;	/* super block */
+	lid_t next;		/* index of first tlock of tid */
+	lid_t last;		/* index of last tlock of tid */
+	wait_queue_head_t waitor;	/* tids waiting on this tid */
 
 	/* log management */
-	u32 logtid;		/* 4: log transaction id */
-				/* (32) */
+	u32 logtid;		/* log transaction id */
 
 	/* commit management */
-	struct tblock *cqnext;	/* 4: commit queue link */
-	s32 clsn;		/* 4: commit lsn */
-	struct lbuf *bp;	/* 4: */
-	s32 pn;			/* 4: commit record log page number */
-	s32 eor;		/* 4: commit record eor */
-	wait_queue_head_t gcwait;	/* 4: group commit event list:
-					 *    ready transactions wait on this
-					 *    event for group commit completion.
+	struct tblock *cqnext;	/* commit queue link */
+	s32 clsn;		/* commit lsn */
+	struct lbuf *bp;
+	s32 pn;			/* commit record log page number */
+	s32 eor;		/* commit record eor */
+	wait_queue_head_t gcwait;	/* group commit event list:
+					 * ready transactions wait on this
+					 * event for group commit completion.
 					 */
-	struct inode *ip;	/* 4: inode being created or deleted */
-	s32 rsrvd;		/* 4: */
-} tblock_t;			/* (64) */
+	struct inode *ip;	/* inode being created or deleted */
+};
 
 extern struct tblock *TxBlock;	/* transaction block table */
 
@@ -90,7 +88,7 @@
 /*
  *	transaction lock
  */
-typedef struct tlock {
+struct tlock {
 	lid_t next;		/* index next lockword on tid locklist
 				 *          next lockword on freelist
 				 */
@@ -104,7 +102,7 @@
 	/* (16) */
 
 	s16 lock[24];		/* 48: overlay area */
-} tlock_t;			/* (64) */
+};				/* (64) */
 
 extern struct tlock *TxLock;	/* transaction lock table */
 
@@ -153,18 +151,18 @@
 /*
  *	linelock for lmLog()
  *
- * note: linelock_t and its variations are overlaid
+ * note: linelock and its variations are overlaid
  * at tlock.lock: watch for alignment;
  */
-typedef struct {
+struct lv {
 	u8 offset;		/* 1: */
 	u8 length;		/* 1: */
-} lv_t;				/* (2) */
+};				/* (2) */
 
 #define	TLOCKSHORT	20
 #define	TLOCKLONG	28
 
-typedef struct {
+struct linelock {
 	u16 next;		/* 2: next linelock */
 
 	s8 maxcnt;		/* 1: */
@@ -175,13 +173,12 @@
 	u8 l2linesize;		/* 1: log2 of linesize */
 	/* (8) */
 
-	lv_t lv[20];		/* 40: */
-} linelock_t;			/* (48) */
+	struct lv lv[20];	/* 40: */
+}; 				/* (48) */
 
-#define dtlock_t	linelock_t
-#define itlock_t	linelock_t
+#define dt_lock	linelock
 
-typedef struct {
+struct xtlock {
 	u16 next;		/* 2: */
 
 	s8 maxcnt;		/* 1: */
@@ -192,27 +189,27 @@
 	u8 l2linesize;		/* 1: log2 of linesize */
 				/* (8) */
 
-	lv_t header;		/* 2: */
-	lv_t lwm;		/* 2: low water mark */
-	lv_t hwm;		/* 2: high water mark */
-	lv_t twm;		/* 2: */
+	struct lv header;	/* 2: */
+	struct lv lwm;		/* 2: low water mark */
+	struct lv hwm;		/* 2: high water mark */
+	struct lv twm;		/* 2: */
 				/* (16) */
 
 	s32 pxdlock[8];		/* 32: */
-} xtlock_t;			/* (48) */
+};				/* (48) */
 
 
 /*
  *	maplock for txUpdateMap()
  *
- * note: maplock_t and its variations are overlaid
+ * note: maplock and its variations are overlaid
  * at tlock.lock/linelock: watch for alignment;
  * N.B. next field may be set by linelock, and should not
  * be modified by maplock;
  * N.B. index of the first pxdlock specifies index of next 
  * free maplock (i.e., number of maplock) in the tlock; 
  */
-typedef struct {
+struct maplock {
 	u16 next;		/* 2: */
 
 	u8 maxcnt;		/* 2: */
@@ -224,7 +221,7 @@
 				/* (8) */
 
 	pxd_t pxd;		/* 8: */
-} maplock_t;			/* (16): */
+};				/* (16): */
 
 /* maplock flag */
 #define	mlckALLOC		0x00f0
@@ -238,9 +235,9 @@
 #define	mlckFREEXAD		0x0002
 #define	mlckFREEPXD		0x0001
 
-#define	pxdlock_t	maplock_t
+#define	pxd_lock	maplock
 
-typedef struct {
+struct xdlistlock {
 	u16 next;		/* 2: */
 
 	u8 maxcnt;		/* 2: */
@@ -252,14 +249,14 @@
 				/* (8) */
 
 	/*
-	 * We need xdlistlock_t to be 64 bits (8 bytes), regardless of
+	 * We need xdlist to be 64 bits (8 bytes), regardless of
 	 * whether void * is 32 or 64 bits
 	 */
 	union {
 		void *_xdlist;	/* pxd/xad list */
 		s64 pad;	/* 8: Force 64-bit xdlist size */
 	} union64;
-} xdlistlock_t;			/* (16): */
+};				/* (16): */
 
 #define xdlist union64._xdlist
 
@@ -268,26 +265,26 @@
  *
  * parameter to the commit manager routines
  */
-typedef struct commit {
-	tid_t tid;		/* 4: tid = index of tblock */
-	int flag;		/* 4: flags */
-	log_t *log;		/* 4: log */
-	struct super_block *sb;	/* 4: superblock */
-
-	int nip;		/* 4: number of entries in iplist */
-	struct inode **iplist;	/* 4: list of pointers to inodes */
-				/* (32) */
+struct commit {
+	tid_t tid;		/* tid = index of tblock */
+	int flag;		/* flags */
+	struct jfs_log *log;	/* log */
+	struct super_block *sb;	/* superblock */
+
+	int nip;		/* number of entries in iplist */
+	struct inode **iplist;	/* list of pointers to inodes */
 
 	/* log record descriptor on 64-bit boundary */
-	lrd_t lrd;		/* : log record descriptor */
-} commit_t;
+	struct lrd lrd;		/* : log record descriptor */
+};
 
 /*
  * external declarations
  */
-extern tlock_t *txLock(tid_t tid, struct inode *ip, struct metapage *mp, int flag);
+extern struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage *mp,
+			    int flag);
 
-extern tlock_t *txMaplock(tid_t tid, struct inode *ip, int flag);
+extern struct tlock *txMaplock(tid_t tid, struct inode *ip, int flag);
 
 extern int txCommit(tid_t tid, int nip, struct inode **iplist, int flag);
 
@@ -299,16 +296,17 @@
 
 extern void txAbort(tid_t tid, int dirty);
 
-extern linelock_t *txLinelock(linelock_t * tlock);
+extern struct linelock *txLinelock(struct linelock * tlock);
 
-extern void txFreeMap(struct inode *ip,
-		      maplock_t * maplock, tblock_t * tblk, int maptype);
+extern void txFreeMap(struct inode *ip, struct maplock * maplock,
+		      struct tblock * tblk, int maptype);
 
 extern void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea);
 
 extern void txFreelock(struct inode *ip);
 
-extern int lmLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
+extern int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
+		 struct tlock * tlck);
 
 extern void txQuiesce(struct super_block *sb);
 
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_types.h linux-2.4.20-pre8/fs/jfs/jfs_types.h
--- linux-2.4.20-pre7/fs/jfs/jfs_types.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_types.h	Wed Sep 25 18:22:07 2002
@@ -79,11 +79,11 @@
 	( ((s64)((lxd)->off1)) << 32 | (lxd)->off2 )
 
 /* lxd list */
-typedef struct {
+struct lxdlist {
 	s16 maxnlxd;
 	s16 nlxd;
 	lxd_t *lxd;
-} lxdlist_t;
+};
 
 /*
  *	physical xd (pxd)
@@ -109,11 +109,11 @@
 	( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2))
 
 /* pxd list */
-typedef struct {
+struct pxdlist {
 	s16 maxnpxd;
 	s16 npxd;
 	pxd_t pxd[8];
-} pxdlist_t;
+};
 
 
 /*
@@ -148,16 +148,16 @@
 /*
  *      directory entry argument
  */
-typedef struct component_name {
+struct component_name {
 	int namlen;
 	wchar_t *name;
-} component_t;
+};
 
 
 /*
  *	DASD limit information - stored in directory inode
  */
-typedef struct dasd {
+struct dasd {
 	u8 thresh;		/* Alert Threshold (in percent) */
 	u8 delta;		/* Alert Threshold delta (in percent)   */
 	u8 rsrvd1;
@@ -166,7 +166,7 @@
 	u8 rsrvd2[3];
 	u8 used_hi;		/* DASD usage (in logical blocks)       */
 	u32 used_lo;		/* DASD usage (in logical blocks)       */
-} dasd_t;
+};
 
 #define DASDLIMIT(dasdp) \
 	(((u64)((dasdp)->limit_hi) << 32) + __le32_to_cpu((dasdp)->limit_lo))
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_umount.c linux-2.4.20-pre8/fs/jfs/jfs_umount.c
--- linux-2.4.20-pre7/fs/jfs/jfs_umount.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_umount.c	Wed Sep 25 18:22:07 2002
@@ -54,7 +54,7 @@
 	struct inode *ipimap = sbi->ipimap;
 	struct inode *ipaimap = sbi->ipaimap;
 	struct inode *ipaimap2 = sbi->ipaimap2;
-	log_t *log;
+	struct jfs_log *log;
 	int rc = 0;
 
 	jFYI(1, ("\n	UnMount JFS: sb:0x%p\n", sb));
@@ -140,7 +140,7 @@
 int jfs_umount_rw(struct super_block *sb)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
-	log_t *log = sbi->log;
+	struct jfs_log *log = sbi->log;
 
 	if (!log)
 		return 0;
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_unicode.c linux-2.4.20-pre8/fs/jfs/jfs_unicode.c
--- linux-2.4.20-pre7/fs/jfs/jfs_unicode.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_unicode.c	Wed Sep 25 18:22:07 2002
@@ -89,7 +89,7 @@
  * FUNCTION:	Allocate and translate to unicode string
  *
  */
-int get_UCSname(component_t * uniName, struct dentry *dentry,
+int get_UCSname(struct component_name * uniName, struct dentry *dentry,
 		struct nls_table *nls_tab)
 {
 	int length = dentry->d_name.len;
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_unicode.h linux-2.4.20-pre8/fs/jfs/jfs_unicode.h
--- linux-2.4.20-pre7/fs/jfs/jfs_unicode.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_unicode.h	Wed Sep 25 18:22:07 2002
@@ -30,7 +30,8 @@
 
 extern signed char UniUpperTable[512];
 extern UNICASERANGE UniUpperRange[];
-extern int get_UCSname(component_t *, struct dentry *, struct nls_table *);
+extern int get_UCSname(struct component_name *, struct dentry *,
+		       struct nls_table *);
 extern int jfs_strfromUCS_le(char *, const wchar_t *, int, struct nls_table *);
 
 #define free_UCSname(COMP) kfree((COMP)->name)
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_xtree.c linux-2.4.20-pre8/fs/jfs/jfs_xtree.c
--- linux-2.4.20-pre7/fs/jfs/jfs_xtree.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_xtree.c	Wed Sep 25 18:22:07 2002
@@ -84,15 +84,15 @@
 #define XT_GETSEARCH(IP, LEAF, BN, MP,  P, INDEX) \
 	BT_GETSEARCH(IP, LEAF, BN, MP, xtpage_t, P, INDEX, i_xtroot)
 /* xtree entry parameter descriptor */
-typedef struct {
-	metapage_t *mp;
+struct xtsplit {
+	struct metapage *mp;
 	s16 index;
 	u8 flag;
 	s64 off;
 	s64 addr;
 	int len;
-	pxdlist_t *pxdlist;
-} xtsplit_t;
+	struct pxdlist *pxdlist;
+};
 
 
 /*
@@ -111,29 +111,25 @@
  * forward references
  */
 static int xtSearch(struct inode *ip,
-		    s64 xoff, int *cmpp, btstack_t * btstack, int flag);
+		    s64 xoff, int *cmpp, struct btstack * btstack, int flag);
 
 static int xtSplitUp(tid_t tid,
 		     struct inode *ip,
-		     xtsplit_t * split, btstack_t * btstack);
+		     struct xtsplit * split, struct btstack * btstack);
 
-static int xtSplitPage(tid_t tid,
-		       struct inode *ip,
-		       xtsplit_t * split, metapage_t ** rmpp, s64 * rbnp);
-
-static int xtSplitRoot(tid_t tid,
-		       struct inode *ip,
-		       xtsplit_t * split, metapage_t ** rmpp);
+static int xtSplitPage(tid_t tid, struct inode *ip, struct xtsplit * split,
+		       struct metapage ** rmpp, s64 * rbnp);
+
+static int xtSplitRoot(tid_t tid, struct inode *ip,
+		       struct xtsplit * split, struct metapage ** rmpp);
 
 #ifdef _STILL_TO_PORT
-static int xtDeleteUp(tid_t tid,
-		      struct inode *ip,
-		      metapage_t * fmp,
-		      xtpage_t * fp, btstack_t * btstack);
+static int xtDeleteUp(tid_t tid, struct inode *ip, struct metapage * fmp,
+		      xtpage_t * fp, struct btstack * btstack);
 
 static int xtSearchNode(struct inode *ip,
 			xad_t * xad,
-			int *cmpp, btstack_t * btstack, int flag);
+			int *cmpp, struct btstack * btstack, int flag);
 
 static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp);
 #endif				/*  _STILL_TO_PORT */
@@ -155,10 +151,10 @@
 	     s64 llen, int *pflag, s64 * paddr, s32 * plen, int no_check)
 {
 	int rc = 0;
-	btstack_t btstack;
+	struct btstack btstack;
 	int cmp;
 	s64 bn;
-	metapage_t *mp;
+	struct metapage *mp;
 	xtpage_t *p;
 	int index;
 	xad_t *xad;
@@ -240,8 +236,8 @@
  *
  * parameter:
  *      struct inode    *ip,
- *      lxdlist_t       *lxdlist,       lxd list (in)
- *      xadlist_t       *xadlist,       xad list (in/out)
+ *      struct lxdlist  *lxdlist,       lxd list (in)
+ *      struct xadlist  *xadlist,       xad list (in/out)
  *      int		flag)
  *
  * coverage of lxd by xad under assumption of
@@ -256,15 +252,14 @@
  *      required to cover the last byte;
  *      the extent backing a page is fully contained within an xad;
  */
-int xtLookupList(struct inode *ip, lxdlist_t * lxdlist,	/* lxd list (in) */
-		 xadlist_t * xadlist,	/* xad list (in/out) */
-		 int flag)
+int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
+		 struct xadlist * xadlist, int flag)
 {
 	int rc = 0;
-	btstack_t btstack;
+	struct btstack btstack;
 	int cmp;
 	s64 bn;
-	metapage_t *mp;
+	struct metapage *mp;
 	xtpage_t *p;
 	int index;
 	lxd_t *lxd;
@@ -509,17 +504,17 @@
  *      the page containing the entry is pinned at exit.
  */
 static int xtSearch(struct inode *ip, s64 xoff,	/* offset of extent */
-		    int *cmpp, btstack_t * btstack, int flag)
+		    int *cmpp, struct btstack * btstack, int flag)
 {
 	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 	int rc = 0;
 	int cmp = 1;		/* init for empty page */
 	s64 bn;			/* block number */
-	metapage_t *mp;		/* page buffer */
+	struct metapage *mp;	/* page buffer */
 	xtpage_t *p;		/* page */
 	xad_t *xad;
 	int base, index, lim, btindex;
-	btframe_t *btsp;
+	struct btframe *btsp;
 	int nsplit = 0;		/* number of pages to split */
 	s64 t64;
 
@@ -796,16 +791,16 @@
 {
 	int rc = 0;
 	s64 xaddr, hint;
-	metapage_t *mp;		/* meta-page buffer */
+	struct metapage *mp;	/* meta-page buffer */
 	xtpage_t *p;		/* base B+-tree index page */
 	s64 bn;
 	int index, nextindex;
-	btstack_t btstack;	/* traverse stack */
-	xtsplit_t split;	/* split information */
+	struct btstack btstack;	/* traverse stack */
+	struct xtsplit split;	/* split information */
 	xad_t *xad;
 	int cmp;
-	tlock_t *tlck;
-	xtlock_t *xtlck;
+	struct tlock *tlck;
+	struct xtlock *xtlck;
 
 	jFYI(1,
 	     ("xtInsert: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen));
@@ -903,7 +898,7 @@
 	/* Don't log it if there are no links to the file */
 	if (!test_cflag(COMMIT_Nolink, ip)) {
 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 		xtlck->lwm.offset =
 		    (xtlck->lwm.offset) ? min(index,
 					      (int)xtlck->lwm.offset) : index;
@@ -937,27 +932,27 @@
  */
 static int
 xtSplitUp(tid_t tid,
-	  struct inode *ip, xtsplit_t * split, btstack_t * btstack)
+	  struct inode *ip, struct xtsplit * split, struct btstack * btstack)
 {
 	int rc = 0;
-	metapage_t *smp;
+	struct metapage *smp;
 	xtpage_t *sp;		/* split page */
-	metapage_t *rmp;
+	struct metapage *rmp;
 	s64 rbn;		/* new right page block number */
-	metapage_t *rcmp;
+	struct metapage *rcmp;
 	xtpage_t *rcp;		/* right child page */
 	s64 rcbn;		/* right child page block number */
 	int skip;		/* index of entry of insertion */
 	int nextindex;		/* next available entry index of p */
-	btframe_t *parent;	/* parent page entry on traverse stack */
+	struct btframe *parent;	/* parent page entry on traverse stack */
 	xad_t *xad;
 	s64 xaddr;
 	int xlen;
 	int nsplit;		/* number of pages split */
-	pxdlist_t pxdlist;
+	struct pxdlist pxdlist;
 	pxd_t *pxd;
-	tlock_t *tlck;
-	xtlock_t *xtlck;
+	struct tlock *tlck;
+	struct xtlock *xtlck;
 
 	smp = split->mp;
 	sp = XT_PAGE(ip, smp);
@@ -995,7 +990,7 @@
 		/* Don't log it if there are no links to the file */
 		if (!test_cflag(COMMIT_Nolink, ip)) {
 			tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW);
-			xtlck = (xtlock_t *) & tlck->lock;
+			xtlck = (struct xtlock *) & tlck->lock;
 			xtlck->lwm.offset = (xtlck->lwm.offset) ?
 			    min(skip, (int)xtlck->lwm.offset) : skip;
 			xtlck->lwm.length =
@@ -1163,7 +1158,7 @@
 			if (!test_cflag(COMMIT_Nolink, ip)) {
 				tlck = txLock(tid, ip, smp,
 					      tlckXTREE | tlckGROW);
-				xtlck = (xtlock_t *) & tlck->lock;
+				xtlck = (struct xtlock *) & tlck->lock;
 				xtlck->lwm.offset = (xtlck->lwm.offset) ?
 				    min(skip, (int)xtlck->lwm.offset) : skip;
 				xtlck->lwm.length =
@@ -1210,8 +1205,8 @@
  * parameter:
  *      int		tid,
  *      struct inode    *ip,
- *      xtsplit_t       *split,
- *      metapage_t	**rmpp,
+ *      struct xtsplit  *split,
+ *      struct metapage	**rmpp,
  *      u64		*rbnp,
  *
  * return:
@@ -1219,23 +1214,23 @@
  */
 static int
 xtSplitPage(tid_t tid, struct inode *ip,
-	    xtsplit_t * split, metapage_t ** rmpp, s64 * rbnp)
+	    struct xtsplit * split, struct metapage ** rmpp, s64 * rbnp)
 {
 	int rc = 0;
-	metapage_t *smp;
+	struct metapage *smp;
 	xtpage_t *sp;
-	metapage_t *rmp;
+	struct metapage *rmp;
 	xtpage_t *rp;		/* new right page allocated */
 	s64 rbn;		/* new right page block number */
-	metapage_t *mp;
+	struct metapage *mp;
 	xtpage_t *p;
 	s64 nextbn;
 	int skip, maxentry, middle, righthalf, n;
 	xad_t *xad;
-	pxdlist_t *pxdlist;
+	struct pxdlist *pxdlist;
 	pxd_t *pxd;
-	tlock_t *tlck;
-	xtlock_t *sxtlck = 0, *rxtlck = 0;
+	struct tlock *tlck;
+	struct xtlock *sxtlck = 0, *rxtlck = 0;
 
 	smp = split->mp;
 	sp = XT_PAGE(ip, smp);
@@ -1274,13 +1269,13 @@
 		 * acquire a transaction lock on the new right page;
 		 */
 		tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW);
-		rxtlck = (xtlock_t *) & tlck->lock;
+		rxtlck = (struct xtlock *) & tlck->lock;
 		rxtlck->lwm.offset = XTENTRYSTART;
 		/*
 		 * acquire a transaction lock on the split page
 		 */
 		tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW);
-		sxtlck = (xtlock_t *) & tlck->lock;
+		sxtlck = (struct xtlock *) & tlck->lock;
 	}
 
 	/*
@@ -1465,26 +1460,26 @@
  * parameter:
  *      int		tid,
  *      struct inode    *ip,
- *      xtsplit_t       *split,
- *      metapage_t	**rmpp)
+ *      struct xtsplit  *split,
+ *      struct metapage	**rmpp)
  *
  * return:
  *      Pointer to page in which to insert or NULL on error.
  */
 static int
 xtSplitRoot(tid_t tid,
-	    struct inode *ip, xtsplit_t * split, metapage_t ** rmpp)
+	    struct inode *ip, struct xtsplit * split, struct metapage ** rmpp)
 {
 	xtpage_t *sp;
-	metapage_t *rmp;
+	struct metapage *rmp;
 	xtpage_t *rp;
 	s64 rbn;
 	int skip, nextindex;
 	xad_t *xad;
 	pxd_t *pxd;
-	pxdlist_t *pxdlist;
-	tlock_t *tlck;
-	xtlock_t *xtlck;
+	struct pxdlist *pxdlist;
+	struct tlock *tlck;
+	struct xtlock *xtlck;
 
 	sp = &JFS_IP(ip)->i_xtroot;
 
@@ -1546,7 +1541,7 @@
 
 	if (!test_cflag(COMMIT_Nolink, ip)) {
 		tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW);
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 		xtlck->lwm.offset = XTENTRYSTART;
 		xtlck->lwm.length = le16_to_cpu(rp->header.nextindex) -
 		    XTENTRYSTART;
@@ -1577,7 +1572,7 @@
 
 	if (!test_cflag(COMMIT_Nolink, ip)) {
 		tlck = txLock(tid, ip, split->mp, tlckXTREE | tlckGROW);
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 		xtlck->lwm.offset = XTENTRYSTART;
 		xtlck->lwm.length = 1;
 	}
@@ -1608,16 +1603,16 @@
 {
 	int rc = 0;
 	int cmp;
-	metapage_t *mp;		/* meta-page buffer */
+	struct metapage *mp;	/* meta-page buffer */
 	xtpage_t *p;		/* base B+-tree index page */
 	s64 bn;
 	int index, nextindex, len;
-	btstack_t btstack;	/* traverse stack */
-	xtsplit_t split;	/* split information */
+	struct btstack btstack;	/* traverse stack */
+	struct xtsplit split;	/* split information */
 	xad_t *xad;
 	s64 xaddr;
-	tlock_t *tlck;
-	xtlock_t *xtlck = 0;
+	struct tlock *tlck;
+	struct xtlock *xtlck = 0;
 	int rootsplit = 0;
 
 	jFYI(1,
@@ -1646,7 +1641,7 @@
 	BT_MARK_DIRTY(mp, ip);
 	if (!test_cflag(COMMIT_Nolink, ip)) {
 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 	}
 
 	/* extend will overflow extent ? */
@@ -1701,7 +1696,7 @@
 					tlck = txLock(tid, ip, mp,
 						      tlckXTREE |
 						      tlckGROW);
-					xtlck = (xtlock_t *) & tlck->lock;
+					xtlck = (struct xtlock *) & tlck->lock;
 				}
 			}
 		} else
@@ -1768,17 +1763,17 @@
 {
 	int rc = 0;
 	int cmp;
-	metapage_t *mp;		/* meta-page buffer */
+	struct metapage *mp;	/* meta-page buffer */
 	xtpage_t *p;		/* base B+-tree index page */
 	s64 bn;
 	int index, nextindex, llen, rlen;
-	btstack_t btstack;	/* traverse stack */
-	xtsplit_t split;	/* split information */
+	struct btstack btstack;	/* traverse stack */
+	struct xtsplit split;	/* split information */
 	xad_t *xad;
-	tlock_t *tlck;
-	xtlock_t *xtlck = 0;
-	tlock_t *mtlck;
-	maplock_t *pxdlock;
+	struct tlock *tlck;
+	struct xtlock *xtlck = 0;
+	struct tlock *mtlck;
+	struct maplock *pxdlock;
 	int rootsplit = 0;
 
 /*
@@ -1804,7 +1799,7 @@
 	 */
 	if (!test_cflag(COMMIT_Nolink, ip)) {
 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 	}
 
 	/* completely replace extent ? */
@@ -1859,7 +1854,7 @@
 					tlck = txLock(tid, ip, mp,
 						      tlckXTREE |
 						      tlckGROW);
-					xtlck = (xtlock_t *) & tlck->lock;
+					xtlck = (struct xtlock *) & tlck->lock;
 				}
 			}
 		} else
@@ -1892,7 +1887,7 @@
 		/* free from PWMAP at commit */
 		if (!test_cflag(COMMIT_Nolink, ip)) {
 			mtlck = txMaplock(tid, ip, tlckMAP);
-			pxdlock = (maplock_t *) & mtlck->lock;
+			pxdlock = (struct maplock *) & mtlck->lock;
 			pxdlock->flag = mlckFREEPXD;
 			PXDaddress(&pxdlock->pxd, addressXAD(xad) + llen);
 			PXDlength(&pxdlock->pxd, rlen);
@@ -1944,19 +1939,19 @@
 {				/* new XAD */
 	int rc = 0;
 	int cmp;
-	metapage_t *mp;		/* meta-page buffer */
+	struct metapage *mp;	/* meta-page buffer */
 	xtpage_t *p;		/* base B+-tree index page */
 	s64 bn;
 	int index0, index, newindex, nextindex;
-	btstack_t btstack;	/* traverse stack */
-	xtsplit_t split;	/* split information */
+	struct btstack btstack;	/* traverse stack */
+	struct xtsplit split;	/* split information */
 	xad_t *xad, *lxad, *rxad;
 	int xflag;
 	s64 nxoff, xoff;
 	int nxlen, xlen, lxlen, rxlen;
 	s64 nxaddr, xaddr;
-	tlock_t *tlck;
-	xtlock_t *xtlck = 0;
+	struct tlock *tlck;
+	struct xtlock *xtlck = 0;
 	int rootsplit = 0, newpage = 0;
 
 	/* there must exist extent to be tailgated */
@@ -1980,7 +1975,7 @@
 	 */
 	if (!test_cflag(COMMIT_Nolink, ip)) {
 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 	}
 
 	xad = &p->xad[index0];
@@ -2192,7 +2187,7 @@
 					tlck = txLock(tid, ip, mp,
 						      tlckXTREE |
 						      tlckGROW);
-					xtlck = (xtlock_t *) & tlck->lock;
+					xtlck = (struct xtlock *) & tlck->lock;
 				}
 			}
 		} else {
@@ -2255,7 +2250,7 @@
 		BT_MARK_DIRTY(mp, ip);
 		if (!test_cflag(COMMIT_Nolink, ip)) {
 			tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
-			xtlck = (xtlock_t *) & tlck->lock;
+			xtlck = (struct xtlock *) & tlck->lock;
 		}
 
 		index0 = index = newindex;
@@ -2337,7 +2332,7 @@
 					tlck = txLock(tid, ip, mp,
 						      tlckXTREE |
 						      tlckGROW);
-					xtlck = (xtlock_t *) & tlck->lock;
+					xtlck = (struct xtlock *) & tlck->lock;
 				}
 			}
 		} else
@@ -2397,18 +2392,18 @@
 	     int flag)
 {
 	int rc = 0;
-	metapage_t *mp;		/* meta-page buffer */
+	struct metapage *mp;	/* meta-page buffer */
 	xtpage_t *p;		/* base B+-tree index page */
 	s64 bn, xaddr;
 	int index, nextindex;
-	btstack_t btstack;	/* traverse stack */
-	xtsplit_t split;	/* split information */
+	struct btstack btstack;	/* traverse stack */
+	struct xtsplit split;	/* split information */
 	xad_t *xad;
 	int cmp;
-	tlock_t *tlck;
-	xtlock_t *xtlck;
+	struct tlock *tlck;
+	struct xtlock *xtlck;
 	int nsplit, nblocks, xlen;
-	pxdlist_t pxdlist;
+	struct pxdlist pxdlist;
 	pxd_t *pxd;
 
 	xaddr = *xaddrp;
@@ -2516,7 +2511,7 @@
 	 * action: xad insertion/extension;
 	 */
 	tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
-	xtlck = (xtlock_t *) & tlck->lock;
+	xtlck = (struct xtlock *) & tlck->lock;
 
 	/* insert the new entry: mark the entry NEW */
 	xad = &p->xad[index];
@@ -2561,14 +2556,14 @@
 int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag)
 {
 	int rc = 0;
-	btstack_t btstack;
+	struct btstack btstack;
 	int cmp;
 	s64 bn;
-	metapage_t *mp;
+	struct metapage *mp;
 	xtpage_t *p;
 	int index, nextindex;
-	tlock_t *tlck;
-	xtlock_t *xtlck;
+	struct tlock *tlck;
+	struct xtlock *xtlck;
 
 	/*
 	 * find the matching entry; xtSearch() pins the page
@@ -2603,7 +2598,7 @@
 	 * action:xad deletion;
 	 */
 	tlck = txLock(tid, ip, mp, tlckXTREE);
-	xtlck = (xtlock_t *) & tlck->lock;
+	xtlck = (struct xtlock *) & tlck->lock;
 	xtlck->lwm.offset =
 	    (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index;
 
@@ -2630,19 +2625,18 @@
  * return:
  */
 static int
-xtDeleteUp(tid_t tid,
-	   struct inode *ip,
-	   metapage_t * fmp, xtpage_t * fp, btstack_t * btstack)
+xtDeleteUp(tid_t tid, struct inode *ip,
+	   struct metapage * fmp, xtpage_t * fp, struct btstack * btstack)
 {
 	int rc = 0;
-	metapage_t *mp;
+	struct metapage *mp;
 	xtpage_t *p;
 	int index, nextindex;
 	s64 xaddr;
 	int xlen;
-	btframe_t *parent;
-	tlock_t *tlck;
-	xtlock_t *xtlck;
+	struct btframe *parent;
+	struct tlock *tlck;
+	struct xtlock *xtlck;
 
 	/*
 	 * keep root leaf page which has become empty
@@ -2736,7 +2730,7 @@
 			 * action:xad deletion;
 			 */
 			tlck = txLock(tid, ip, mp, tlckXTREE);
-			xtlck = (xtlock_t *) & tlck->lock;
+			xtlck = (struct xtlock *) & tlck->lock;
 			xtlck->lwm.offset =
 			    (xtlck->lwm.offset) ? min(index,
 						      xtlck->lwm.
@@ -2785,10 +2779,10 @@
 	   int xtype)
 {				/* extent type: XTPAGE or DATAEXT */
 	int rc = 0;
-	tblock_t *tblk;
-	tlock_t *tlck;
-	xtlock_t *xtlck;
-	metapage_t *mp, *pmp, *lmp, *rmp;	/* meta-page buffer */
+	struct tblock *tblk;
+	struct tlock *tlck;
+	struct xtlock *xtlck;
+	struct metapage *mp, *pmp, *lmp, *rmp;	/* meta-page buffer */
 	xtpage_t *p, *pp, *rp, *lp;	/* base B+-tree index page */
 	xad_t *xad;
 	pxd_t *pxd;
@@ -2801,8 +2795,8 @@
 	s64 bn;
 	int cmp;
 	int index;
-	pxdlock_t *pxdlock;
-	btstack_t btstack;	/* traverse stack */
+	struct pxd_lock *pxdlock;
+	struct btstack btstack;	/* traverse stack */
 
 	xtype = xtype & EXTENT_TYPE;
 
@@ -3016,7 +3010,7 @@
 		BT_MARK_DIRTY(mp, ip);
 		/* tlckNEW init  xtlck->lwm.offset = XTENTRYSTART; */
 		tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW);
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 
 		/* update the self address in the xtpage header */
 		pxd = &p->header.self;
@@ -3060,7 +3054,7 @@
 	else			/* (xtype  == XTPAGE) */
 		tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE);
 
-	pxdlock = (pxdlock_t *) & tlck->lock;
+	pxdlock = (struct pxd_lock *) & tlck->lock;
 	pxdlock->flag = mlckFREEPXD;
 	PXDaddress(&pxdlock->pxd, oxaddr);
 	PXDlength(&pxdlock->pxd, xlen);
@@ -3076,7 +3070,7 @@
 	jEVENT(0, ("xtRelocate: update parent xad entry.\n"));
 	BT_MARK_DIRTY(pmp, ip);
 	tlck = txLock(tid, ip, pmp, tlckXTREE | tlckGROW);
-	xtlck = (xtlock_t *) & tlck->lock;
+	xtlck = (struct xtlock *) & tlck->lock;
 
 	/* update the XAD with the new destination extent; */
 	xad = &pp->xad[index];
@@ -3113,17 +3107,17 @@
  *      the page containing the entry is pinned at exit.
  */
 static int xtSearchNode(struct inode *ip, xad_t * xad,	/* required XAD entry */
-			int *cmpp, btstack_t * btstack, int flag)
+			int *cmpp, struct btstack * btstack, int flag)
 {
 	int rc = 0;
 	s64 xoff, xaddr;
 	int xlen;
 	int cmp = 1;		/* init for empty page */
 	s64 bn;			/* block number */
-	metapage_t *mp;		/* meta-page buffer */
+	struct metapage *mp;	/* meta-page buffer */
 	xtpage_t *p;		/* page */
 	int base, index, lim;
-	btframe_t *btsp;
+	struct btframe *btsp;
 	s64 t64;
 
 	BT_CLR(btstack);
@@ -3233,9 +3227,9 @@
 static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p)
 {
 	int rc = 0;
-	metapage_t *mp;
+	struct metapage *mp;
 	s64 nextbn, prevbn;
-	tlock_t *tlck;
+	struct tlock *tlck;
 
 	nextbn = le64_to_cpu(p->header.next);
 	prevbn = le64_to_cpu(p->header.prev);
@@ -3295,14 +3289,14 @@
 void xtInitRoot(tid_t tid, struct inode *ip)
 {
 	xtpage_t *p;
-	tlock_t *tlck;
+	struct tlock *tlck;
 
 	/*
 	 * acquire a transaction lock on the root
 	 *
 	 * action:
 	 */
-	tlck = txLock(tid, ip, (metapage_t *) &JFS_IP(ip)->bxflag,
+	tlck = txLock(tid, ip, (struct metapage *) &JFS_IP(ip)->bxflag,
 		      tlckXTREE | tlckNEW);
 	p = &JFS_IP(ip)->i_xtroot;
 
@@ -3386,20 +3380,20 @@
 {
 	int rc = 0;
 	s64 teof;
-	metapage_t *mp;
+	struct metapage *mp;
 	xtpage_t *p;
 	s64 bn;
 	int index, nextindex;
 	xad_t *xad;
 	s64 xoff, xaddr;
 	int xlen, len, freexlen;
-	btstack_t btstack;
-	btframe_t *parent;
-	tblock_t *tblk = 0;
-	tlock_t *tlck = 0;
-	xtlock_t *xtlck = 0;
-	xdlistlock_t xadlock;	/* maplock for COMMIT_WMAP */
-	pxdlock_t *pxdlock;	/* maplock for COMMIT_WMAP */
+	struct btstack btstack;
+	struct btframe *parent;
+	struct tblock *tblk = 0;
+	struct tlock *tlck = 0;
+	struct xtlock *xtlck = 0;
+	struct xdlistlock xadlock;	/* maplock for COMMIT_WMAP */
+	struct pxd_lock *pxdlock;		/* maplock for COMMIT_WMAP */
 	s64 nfreed;
 	int freed, log;
 	int locked_leaves = 0;
@@ -3509,7 +3503,7 @@
 		}
 		tlck = txLock(tid, ip, mp, tlckXTREE);
 		tlck->type = tlckXTREE | tlckTRUNCATE;
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 		xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1;
 	}
 	BT_MARK_DIRTY(mp, ip);
@@ -3574,7 +3568,7 @@
 				xtlck->lwm.length = index + 1 -
 				    xtlck->lwm.offset;
 				xtlck->twm.offset = index;
-				pxdlock = (pxdlock_t *) & xtlck->pxdlock;
+				pxdlock = (struct pxd_lock *) & xtlck->pxdlock;
 				pxdlock->flag = mlckFREEPXD;
 				PXDaddress(&pxdlock->pxd, xaddr);
 				PXDlength(&pxdlock->pxd, freexlen);
@@ -3582,7 +3576,7 @@
 			/* free truncated extent */
 			else {	/* COMMIT_WMAP */
 
-				pxdlock = (pxdlock_t *) & xadlock;
+				pxdlock = (struct pxd_lock *) & xadlock;
 				pxdlock->flag = mlckFREEPXD;
 				PXDaddress(&pxdlock->pxd, xaddr);
 				PXDlength(&pxdlock->pxd, freexlen);
@@ -3614,7 +3608,7 @@
 				xadlock.count =
 				    le16_to_cpu(p->header.nextindex) -
 				    nextindex;
-				txFreeMap(ip, (maplock_t *) & xadlock, 0,
+				txFreeMap(ip, (struct maplock *) & xadlock, 0,
 					  COMMIT_WMAP);
 			}
 			p->header.nextindex = cpu_to_le16(nextindex);
@@ -3644,7 +3638,7 @@
 		xadlock.xdlist = &p->xad[XTENTRYSTART];
 		xadlock.count =
 		    le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
-		txFreeMap(ip, (maplock_t *) & xadlock, 0, COMMIT_WMAP);
+		txFreeMap(ip, (struct maplock *) & xadlock, 0, COMMIT_WMAP);
 	}
 
 	if (p->header.flag & BT_ROOT) {
@@ -3704,7 +3698,7 @@
 				 * free child extents covered by parent [);
 				 */
 				tlck = txLock(tid, ip, mp, tlckXTREE);
-				xtlck = (xtlock_t *) & tlck->lock;
+				xtlck = (struct xtlock *) & tlck->lock;
 				if (!(tlck->type & tlckTRUNCATE)) {
 					xtlck->hwm.offset =
 					    le16_to_cpu(p->header.
@@ -3719,7 +3713,7 @@
 				xadlock.count =
 				    le16_to_cpu(p->header.nextindex) -
 				    index - 1;
-				txFreeMap(ip, (maplock_t *) & xadlock, 0,
+				txFreeMap(ip, (struct maplock *) & xadlock, 0,
 					  COMMIT_WMAP);
 			}
 			BT_MARK_DIRTY(mp, ip);
@@ -3751,7 +3745,7 @@
 	if (log && mp->lid && (tblk->last != mp->lid) &&
 	    lid_to_tlock(mp->lid)->tid) {
 		lid_t lid = mp->lid;
-		tlock_t *prev;
+		struct tlock *prev;
 
 		tlck = lid_to_tlock(lid);
 
@@ -3780,7 +3774,7 @@
 			 * invalidate parent if COMMIT_PWMAP;
 			 */
 			tlck = txLock(tid, ip, mp, tlckXTREE);
-			xtlck = (xtlock_t *) & tlck->lock;
+			xtlck = (struct xtlock *) & tlck->lock;
 			xtlck->hwm.offset =
 			    le16_to_cpu(p->header.nextindex) - 1;
 			tlck->type = tlckXTREE | tlckFREE;
@@ -3791,7 +3785,7 @@
 			xadlock.count =
 			    le16_to_cpu(p->header.nextindex) -
 			    XTENTRYSTART;
-			txFreeMap(ip, (maplock_t *) & xadlock, 0,
+			txFreeMap(ip, (struct maplock *) & xadlock, 0,
 				  COMMIT_WMAP);
 		}
 		BT_MARK_DIRTY(mp, ip);
@@ -3919,20 +3913,20 @@
 s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
 {
 	s64 bn;
-	btstack_t btstack;
+	struct btstack btstack;
 	int cmp;
 	int index;
 	int locked_leaves = 0;
-	metapage_t *mp;
+	struct metapage *mp;
 	xtpage_t *p;
-	btframe_t *parent;
+	struct btframe *parent;
 	int rc;
-	tblock_t *tblk;
-	tlock_t *tlck = 0;
+	struct tblock *tblk;
+	struct tlock *tlck = 0;
 	xad_t *xad;
 	int xlen;
 	s64 xoff;
-	xtlock_t *xtlck = 0;
+	struct xtlock *xtlck = 0;
 
 	/* save object truncation type */
 	tblk = tid_to_tblock(tid);
@@ -3988,7 +3982,7 @@
 	}
 	tlck = txLock(tid, ip, mp, tlckXTREE);
 	tlck->type = tlckXTREE | tlckFREE;
-	xtlck = (xtlock_t *) & tlck->lock;
+	xtlck = (struct xtlock *) & tlck->lock;
 	xtlck->hwm.offset = index;
 
 
@@ -4020,7 +4014,7 @@
 		 * invalidate parent if COMMIT_PWMAP;
 		 */
 		tlck = txLock(tid, ip, mp, tlckXTREE);
-		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck = (struct xtlock *) & tlck->lock;
 		xtlck->hwm.offset =
 		    le16_to_cpu(p->header.nextindex) - 1;
 		tlck->type = tlckXTREE | tlckFREE;
@@ -4074,14 +4068,14 @@
 int xtDisplayTree(struct inode *ip)
 {
 	int rc = 0;
-	metapage_t *mp;
+	struct metapage *mp;
 	xtpage_t *p;
 	s64 bn, pbn;
 	int index, lastindex, v, h;
 	xad_t *xad;
-	btstack_t btstack;
-	btframe_t *btsp;
-	btframe_t *parent;
+	struct btstack btstack;
+	struct btframe *btsp;
+	struct btframe *parent;
 
 	printk("display B+-tree.\n");
 
@@ -4195,7 +4189,7 @@
 int xtDisplayPage(struct inode *ip, s64 bn, xtpage_t * p)
 {
 	int rc = 0;
-	metapage_t *mp;
+	struct metapage *mp;
 	xad_t *xad;
 	s64 xaddr, xoff;
 	int xlen, i, j;
@@ -4254,7 +4248,7 @@
 	u64 bn;
 	int index;
 	btentry_t *e;
-	btstack_t btstack;
+	struct btstack btstack;
 	struct btsf *parent;
 
 	/* clear stack */
diff -urN linux-2.4.20-pre7/fs/jfs/jfs_xtree.h linux-2.4.20-pre8/fs/jfs/jfs_xtree.h
--- linux-2.4.20-pre7/fs/jfs/jfs_xtree.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/jfs_xtree.h	Wed Sep 25 18:22:07 2002
@@ -64,11 +64,11 @@
 #define lengthXAD(xad)  __le24_to_cpu((xad)->len)
 
 /* xad list */
-typedef struct {
+struct xadlist {
 	s16 maxnxad;
 	s16 nxad;
 	xad_t *xad;
-} xadlist_t;
+};
 
 /* xad_t flags */
 #define XAD_NEW         0x01	/* new */
@@ -110,8 +110,8 @@
  */
 extern int xtLookup(struct inode *ip, s64 lstart, s64 llen,
 		    int *pflag, s64 * paddr, int *plen, int flag);
-extern int xtLookupList(struct inode *ip, lxdlist_t * lxdlist,
-			xadlist_t * xadlist, int flag);
+extern int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
+			struct xadlist * xadlist, int flag);
 extern void xtInitRoot(tid_t tid, struct inode *ip);
 extern int xtInsert(tid_t tid, struct inode *ip,
 		    int xflag, s64 xoff, int xlen, s64 * xaddrp, int flag);
diff -urN linux-2.4.20-pre7/fs/jfs/namei.c linux-2.4.20-pre8/fs/jfs/namei.c
--- linux-2.4.20-pre7/fs/jfs/namei.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/namei.c	Wed Sep 25 18:22:07 2002
@@ -62,10 +62,10 @@
 	tid_t tid;		/* transaction id */
 	struct inode *ip = NULL;	/* child directory inode */
 	ino_t ino;
-	component_t dname;	/* child directory name */
-	btstack_t btstack;
+	struct component_name dname;	/* child directory name */
+	struct btstack btstack;
 	struct inode *iplist[2];
-	tblock_t *tblk;
+	struct tblock *tblk;
 
 	jFYI(1, ("jfs_create: dip:0x%p name:%s\n", dip, dentry->d_name.name));
 
@@ -177,10 +177,10 @@
 	tid_t tid;		/* transaction id */
 	struct inode *ip = NULL;	/* child directory inode */
 	ino_t ino;
-	component_t dname;	/* child directory name */
-	btstack_t btstack;
+	struct component_name dname;	/* child directory name */
+	struct btstack btstack;
 	struct inode *iplist[2];
-	tblock_t *tblk;
+	struct tblock *tblk;
 
 	jFYI(1, ("jfs_mkdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
 
@@ -305,9 +305,9 @@
 	tid_t tid;		/* transaction id */
 	struct inode *ip = dentry->d_inode;
 	ino_t ino;
-	component_t dname;
+	struct component_name dname;
 	struct inode *iplist[2];
-	tblock_t *tblk;
+	struct tblock *tblk;
 
 	jFYI(1, ("jfs_rmdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
 
@@ -428,9 +428,9 @@
 	tid_t tid;		/* transaction id */
 	struct inode *ip = dentry->d_inode;
 	ino_t ino;
-	component_t dname;	/* object name */
+	struct component_name dname;	/* object name */
 	struct inode *iplist[2];
-	tblock_t *tblk;
+	struct tblock *tblk;
 	s64 new_size = 0;
 	int commit_flag;
 
@@ -579,7 +579,7 @@
 s64 commitZeroLink(tid_t tid, struct inode *ip)
 {
 	int filetype;
-	tblock_t *tblk;
+	struct tblock *tblk;
 
 	jFYI(1, ("commitZeroLink: tid = %d, ip = 0x%p\n", tid, ip));
 
@@ -674,15 +674,15 @@
 	if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
 		s64 xaddr = addressDXD(&JFS_IP(ip)->ea);
 		int xlen = lengthDXD(&JFS_IP(ip)->ea);
-		maplock_t maplock;	/* maplock for COMMIT_WMAP */
-		pxdlock_t *pxdlock;	/* maplock for COMMIT_WMAP */
+		struct maplock maplock;	/* maplock for COMMIT_WMAP */
+		struct pxd_lock *pxdlock;	/* maplock for COMMIT_WMAP */
 
 		/* free EA pages from cache */
 		invalidate_dxd_metapages(ip, JFS_IP(ip)->ea);
 
 		/* free EA extent from working block map */
 		maplock.index = 1;
-		pxdlock = (pxdlock_t *) & maplock;
+		pxdlock = (struct pxd_lock *) & maplock;
 		pxdlock->flag = mlckFREEPXD;
 		PXDaddress(&pxdlock->pxd, xaddr);
 		PXDlength(&pxdlock->pxd, xlen);
@@ -695,14 +695,14 @@
 	if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
 		s64 xaddr = addressDXD(&JFS_IP(ip)->acl);
 		int xlen = lengthDXD(&JFS_IP(ip)->acl);
-		maplock_t maplock;	/* maplock for COMMIT_WMAP */
-		pxdlock_t *pxdlock;	/* maplock for COMMIT_WMAP */
+		struct maplock maplock;	/* maplock for COMMIT_WMAP */
+		struct pxd_lock *pxdlock;	/* maplock for COMMIT_WMAP */
 
 		invalidate_dxd_metapages(ip, JFS_IP(ip)->acl);
 
 		/* free ACL extent from working block map */
 		maplock.index = 1;
-		pxdlock = (pxdlock_t *) & maplock;
+		pxdlock = (struct pxd_lock *) & maplock;
 		pxdlock->flag = mlckFREEPXD;
 		PXDaddress(&pxdlock->pxd, xaddr);
 		PXDlength(&pxdlock->pxd, xlen);
@@ -751,8 +751,8 @@
 	tid_t tid;
 	struct inode *ip = old_dentry->d_inode;
 	ino_t ino;
-	component_t dname;
-	btstack_t btstack;
+	struct component_name dname;
+	struct btstack btstack;
 	struct inode *iplist[2];
 
 	jFYI(1,
@@ -833,17 +833,17 @@
 	int rc;
 	tid_t tid;
 	ino_t ino = 0;
-	component_t dname;
+	struct component_name dname;
 	int ssize;		/* source pathname size */
-	btstack_t btstack;
+	struct btstack btstack;
 	struct inode *ip = dentry->d_inode;
 	unchar *i_fastsymlink;
 	s64 xlen = 0;
 	int bmask = 0, xsize;
 	s64 xaddr;
-	metapage_t *mp;
+	struct metapage *mp;
 	struct super_block *sb;
-	tblock_t *tblk;
+	struct tblock *tblk;
 
 	struct inode *iplist[2];
 
@@ -1033,20 +1033,20 @@
 int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 	       struct inode *new_dir, struct dentry *new_dentry)
 {
-	btstack_t btstack;
+	struct btstack btstack;
 	ino_t ino;
-	component_t new_dname;
+	struct component_name new_dname;
 	struct inode *new_ip;
-	component_t old_dname;
+	struct component_name old_dname;
 	struct inode *old_ip;
 	int rc;
 	tid_t tid;
-	tlock_t *tlck;
-	dtlock_t *dtlck;
-	lv_t *lv;
+	struct tlock *tlck;
+	struct dt_lock *dtlck;
+	struct lv *lv;
 	int ipcount;
 	struct inode *iplist[4];
-	tblock_t *tblk;
+	struct tblock *tblk;
 	s64 new_size = 0;
 	int commit_flag;
 
@@ -1197,11 +1197,11 @@
 
 			/* Linelock header of dtree */
 			tlck = txLock(tid, old_ip,
-				      (metapage_t *) & JFS_IP(old_ip)->bxflag,
+				    (struct metapage *) &JFS_IP(old_ip)->bxflag,
 				      tlckDTREE | tlckBTROOT);
-			dtlck = (dtlock_t *) & tlck->lock;
+			dtlck = (struct dt_lock *) & tlck->lock;
 			ASSERT(dtlck->index == 0);
-			lv = (lv_t *) & dtlck->lv[0];
+			lv = & dtlck->lv[0];
 			lv->offset = 0;
 			lv->length = 1;
 			dtlck->index++;
@@ -1304,14 +1304,14 @@
  */
 int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
 {
-	btstack_t btstack;
-	component_t dname;
+	struct btstack btstack;
+	struct component_name dname;
 	ino_t ino;
 	struct inode *ip;
 	struct inode *iplist[2];
 	int rc;
 	tid_t tid;
-	tblock_t *tblk;
+	struct tblock *tblk;
 
 	jFYI(1, ("jfs_mknod: %s\n", dentry->d_name.name));
 
@@ -1374,10 +1374,10 @@
 
 static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry)
 {
-	btstack_t btstack;
+	struct btstack btstack;
 	ino_t inum;
 	struct inode *ip;
-	component_t key;
+	struct component_name key;
 	const char *name = dentry->d_name.name;
 	int len = dentry->d_name.len;
 	int rc;
diff -urN linux-2.4.20-pre7/fs/jfs/resize.c linux-2.4.20-pre8/fs/jfs/resize.c
--- linux-2.4.20-pre7/fs/jfs/resize.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/resize.c	Wed Sep 25 18:22:07 2002
@@ -66,8 +66,8 @@
 	struct inode *ipbmap = sbi->ipbmap;
 	struct inode *ipbmap2;
 	struct inode *ipimap = sbi->ipimap;
-	log_t *log = sbi->log;
-	bmap_t *bmp = sbi->bmap;
+	struct jfs_log *log = sbi->log;
+	struct bmap *bmp = sbi->bmap;
 	s64 newLogAddress, newFSCKAddress;
 	int newFSCKSize;
 	s64 newMapSize = 0, mapSize;
diff -urN linux-2.4.20-pre7/fs/jfs/super.c linux-2.4.20-pre8/fs/jfs/super.c
--- linux-2.4.20-pre7/fs/jfs/super.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/super.c	Wed Sep 25 18:22:07 2002
@@ -80,7 +80,7 @@
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
 	s64 maxinodes;
-	imap_t *imap = JFS_IP(sbi->ipimap)->i_imap;
+	struct inomap *imap = JFS_IP(sbi->ipimap)->i_imap;
 
 	jFYI(1, ("In jfs_statfs\n"));
 	buf->f_type = JFS_SUPER_MAGIC;
@@ -318,7 +318,7 @@
 static void jfs_write_super_lockfs(struct super_block *sb)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
-	log_t *log = sbi->log;
+	struct jfs_log *log = sbi->log;
 
 	if (!(sb->s_flags & MS_RDONLY)) {
 		txQuiesce(sb);
@@ -329,7 +329,7 @@
 static void jfs_unlockfs(struct super_block *sb)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
-	log_t *log = sbi->log;
+	struct jfs_log *log = sbi->log;
 	int rc = 0;
 
 	if (!(sb->s_flags & MS_RDONLY)) {
@@ -378,6 +378,7 @@
 		init_rwsem(&jfs_ip->rdwrlock);
 		init_MUTEX(&jfs_ip->commit_sem);
 		jfs_ip->atlhead = 0;
+		jfs_ip->active_ag = -1;
 	}
 }
 
diff -urN linux-2.4.20-pre7/fs/jfs/xattr.c linux-2.4.20-pre8/fs/jfs/xattr.c
--- linux-2.4.20-pre7/fs/jfs/xattr.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/jfs/xattr.c	Wed Sep 25 18:22:07 2002
@@ -78,6 +78,68 @@
 #define EA_NEW		0x0004
 #define EA_MALLOC	0x0008
 
+/* Namespaces */
+#define XATTR_SYSTEM_PREFIX "system."
+#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
+
+#define XATTR_USER_PREFIX "user."
+#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
+
+#define XATTR_OS2_PREFIX "os2."
+#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
+
+/*
+ * These three routines are used to recognize on-disk extended attributes
+ * that are in a recognized namespace.  If the attribute is not recognized,
+ * "os2." is prepended to the name
+ */
+static inline int is_os2_xattr(struct jfs_ea *ea)
+{
+	/*
+	 * Check for "system."
+	 */
+	if ((ea->namelen >= XATTR_SYSTEM_PREFIX_LEN) &&
+	    !strncmp(ea->name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
+		return FALSE;
+	/*
+	 * Check for "user."
+	 */
+	if ((ea->namelen >= XATTR_USER_PREFIX_LEN) &&
+	    !strncmp(ea->name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
+		return FALSE;
+	/*
+	 * Add any other valid namespace prefixes here
+	 */
+
+	/*
+	 * We assume it's OS/2's flat namespace
+	 */
+	return TRUE;
+}
+
+static inline int name_size(struct jfs_ea *ea)
+{
+	if (is_os2_xattr(ea))
+		return ea->namelen + XATTR_OS2_PREFIX_LEN;
+	else
+		return ea->namelen;
+}
+
+static inline int copy_name(char *buffer, struct jfs_ea *ea)
+{
+	int len = ea->namelen;
+
+	if (is_os2_xattr(ea)) {
+		memcpy(buffer, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN);
+		buffer += XATTR_OS2_PREFIX_LEN;
+		len += XATTR_OS2_PREFIX_LEN;
+	}
+	memcpy(buffer, ea->name, ea->namelen);
+	buffer[ea->namelen] = 0;
+
+	return len;
+}
+
 /* Forward references */
 static void ea_release(struct inode *inode, struct ea_buffer *ea_buf);
 
@@ -174,7 +236,7 @@
 	char *cp;
 	s32 nbytes, nb;
 	s32 bytes_to_write;
-	metapage_t *mp;
+	struct metapage *mp;
 
 	/*
 	 * Quick check to see if this is an in-linable EA.  Short EAs
@@ -311,7 +373,7 @@
 	int i;
 	int nbytes, nb;
 	s32 bytes_to_read;
-	metapage_t *mp;
+	struct metapage *mp;
 
 	/* quick check for in-line EA */
 	if (ji->ea.flag & DXD_INLINE)
@@ -577,7 +639,8 @@
 	return rc;
 }
 
-static int can_set_xattr(struct inode *inode, const char *name)
+static int can_set_xattr(struct inode *inode, const char *name,
+			 void *value, size_t value_len)
 {
 	if (IS_RDONLY(inode))
 		return -EROFS;
@@ -585,6 +648,10 @@
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))
 		return -EPERM;
 
+	if((strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) != 0) &&
+	   (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) != 0))
+		return -EOPNOTSUPP;
+
 	if (!S_ISREG(inode->i_mode) &&
 	    (!S_ISDIR(inode->i_mode) || inode->i_mode &S_ISVTX))
 		return -EPERM;
@@ -602,13 +669,24 @@
 	int xattr_size;
 	int new_size;
 	int namelen = strlen(name);
+	char *os2name = NULL;
 	int found = 0;
 	int rc;
 	int length;
 
-	if ((rc = can_set_xattr(inode, name)))
+	if ((rc = can_set_xattr(inode, name, value, value_len)))
 		return rc;
 
+	if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
+		os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1,
+				  GFP_KERNEL);
+		if (!os2name)
+			return -ENOMEM;
+		strcpy(os2name, name + XATTR_OS2_PREFIX_LEN);
+		name = os2name;
+		namelen -= XATTR_OS2_PREFIX_LEN;
+	}
+
 	xattr_size = ea_get(inode, &ea_buf, 0);
 	if (xattr_size < 0) {
 		rc = xattr_size;
@@ -714,6 +792,9 @@
       release:
 	ea_release(inode, &ea_buf);
       out:
+	if (os2name)
+		kfree(os2name);
+
 	return rc;
 }
 
@@ -728,7 +809,7 @@
 	return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags);
 }
 
-static int can_get_xattr(struct inode *inode, const char *name)
+static inline int can_get_xattr(struct inode *inode, const char *name)
 {
 	return permission(inode, MAY_READ);
 }
@@ -742,12 +823,23 @@
 	int xattr_size;
 	ssize_t size;
 	int namelen = strlen(name);
+	char *os2name = NULL;
 	int rc;
 	char *value;
 
 	if ((rc = can_get_xattr(inode, name)))
 		return rc;
 
+	if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
+		os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1,
+				  GFP_KERNEL);
+		if (!os2name)
+			return -ENOMEM;
+		strcpy(os2name, name + XATTR_OS2_PREFIX_LEN);
+		name = os2name;
+		namelen -= XATTR_OS2_PREFIX_LEN;
+	}
+
 	xattr_size = ea_get(inode, &ea_buf, 0);
 	if (xattr_size < 0) {
 		size = xattr_size;
@@ -780,6 +872,8 @@
       release:
 	ea_release(inode, &ea_buf);
       out:
+	if (os2name)
+		kfree(os2name);
 
 	return size;
 }
@@ -813,7 +907,7 @@
 
 	/* compute required size of list */
 	for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea))
-		size += ea->namelen + 1;
+		size += name_size(ea) + 1;
 
 	if (!data)
 		goto release;
@@ -826,9 +920,8 @@
 	/* Copy attribute names to buffer */
 	buffer = data;
 	for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
-		memcpy(buffer, ea->name, ea->namelen);
-		buffer[ea->namelen] = 0;
-		buffer += ea->namelen + 1;
+		int namelen = copy_name(buffer, ea);
+		buffer += namelen + 1;
 	}
 
       release:
diff -urN linux-2.4.20-pre7/fs/partitions/efi.h linux-2.4.20-pre8/fs/partitions/efi.h
--- linux-2.4.20-pre7/fs/partitions/efi.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/fs/partitions/efi.h	Wed Sep 25 18:22:07 2002
@@ -33,11 +33,7 @@
 #include <linux/major.h>
 #include <linux/string.h>
 #include <linux/blk.h>
-/*
- * Yes, specifying asm-ia64 is ugly, but this lets it build on
- * other platforms too, until efi.h moves to include/linux.
- */
-#include <asm-ia64/efi.h>
+#include <linux/efi.h>
 
 #define MSDOS_MBR_SIGNATURE 0xaa55
 #define EFI_PMBR_OSTYPE_EFI 0xEF
diff -urN linux-2.4.20-pre7/fs/smbfs/smb_debug.h linux-2.4.20-pre8/fs/smbfs/smb_debug.h
--- linux-2.4.20-pre7/fs/smbfs/smb_debug.h	Mon Jan  1 09:57:08 2001
+++ linux-2.4.20-pre8/fs/smbfs/smb_debug.h	Wed Sep 25 18:22:07 2002
@@ -7,20 +7,20 @@
 	(dentry)->d_parent->d_name.name,(dentry)->d_name.name
 
 /*
- * safety checks that should never happen ??? 
+ * safety checks that should never happen ???
  * these are normally enabled.
  */
 #ifdef SMBFS_PARANOIA
-#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " x)
+# define PARANOIA(f, a...) printk(KERN_NOTICE "%s: " f, __FUNCTION__ , ## a)
 #else
-#define PARANOIA(x...) do { ; } while(0)
+# define PARANOIA(f, a...) do { ; } while(0)
 #endif
 
 /* lots of debug messages */
 #ifdef SMBFS_DEBUG_VERBOSE
-#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " x)
+# define VERBOSE(f, a...) printk(KERN_DEBUG "%s: " f, __FUNCTION__ , ## a)
 #else
-#define VERBOSE(x...) do { ; } while(0)
+# define VERBOSE(f, a...) do { ; } while(0)
 #endif
 
 /*
@@ -28,7 +28,7 @@
  * too common name.
  */
 #ifdef SMBFS_DEBUG
-#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " x)
+# define DEBUG1(f, a...) printk(KERN_DEBUG "%s: " f, __FUNCTION__ , ## a)
 #else
-#define DEBUG1(x...) do { ; } while(0)
+# define DEBUG1(f, a...) do { ; } while(0)
 #endif
diff -urN linux-2.4.20-pre7/include/asm-i386/msr.h linux-2.4.20-pre8/include/asm-i386/msr.h
--- linux-2.4.20-pre7/include/asm-i386/msr.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre8/include/asm-i386/msr.h	Wed Sep 25 18:22:07 2002
@@ -54,6 +54,11 @@
 #define MSR_IA32_MCG_STATUS		0x17a
 #define MSR_IA32_MCG_CTL		0x17b
 
+#define MSR_IA32_THERM_CONTROL		0x19a
+#define MSR_IA32_THERM_INTERRUPT	0x19b
+#define MSR_IA32_THERM_STATUS		0x19c
+#define MSR_IA32_MISC_ENABLE		0x1a0
+
 #define MSR_IA32_DEBUGCTLMSR		0x1d9
 #define MSR_IA32_LASTBRANCHFROMIP	0x1db
 #define MSR_IA32_LASTBRANCHTOIP		0x1dc
@@ -75,12 +80,15 @@
 #define MSR_K6_STAR			0xC0000081
 #define MSR_K6_WHCR			0xC0000082
 #define MSR_K6_UWCCR			0xC0000085
+#define MSR_K6_EPMR			0xC0000086
 #define MSR_K6_PSOR			0xC0000087
 #define MSR_K6_PFIR			0xC0000088
 
 #define MSR_K7_EVNTSEL0			0xC0010000
 #define MSR_K7_PERFCTR0			0xC0010004
 #define MSR_K7_HWCR			0xC0010015
+#define MSR_K7_FID_VID_CTL		0xC0010041
+#define MSR_K7_VID_STATUS		0xC0010042
 
 /* Centaur-Hauls/IDT defined MSRs. */
 #define MSR_IDT_FCR1			0x107
@@ -100,5 +108,11 @@
 
 /* VIA Cyrix defined MSRs*/
 #define MSR_VIA_FCR			0x1107
+#define MSR_VIA_LONGHAUL		0x110a
+#define MSR_VIA_BCR2			0x1147
+
+/* Transmeta defined MSRs */
+#define MSR_TMTA_LONGRUN_CTRL		0x80868010
+#define MSR_TMTA_LONGRUN_FLAGS		0x80868011
 
 #endif /* __ASM_MSR_H */
diff -urN linux-2.4.20-pre7/include/asm-i386/termios.h linux-2.4.20-pre8/include/asm-i386/termios.h
--- linux-2.4.20-pre7/include/asm-i386/termios.h	Mon Jun 11 19:15:27 2001
+++ linux-2.4.20-pre8/include/asm-i386/termios.h	Wed Sep 25 18:22:07 2002
@@ -37,6 +37,8 @@
 #define TIOCM_OUT2	0x4000
 #define TIOCM_LOOP	0x8000
 
+#define TIOCM_MODEM_BITS       TIOCM_OUT2      /* IRDA support */
+
 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
 
 /* line disciplines */
diff -urN linux-2.4.20-pre7/include/asm-ia64/efi.h linux-2.4.20-pre8/include/asm-ia64/efi.h
--- linux-2.4.20-pre7/include/asm-ia64/efi.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre8/include/asm-ia64/efi.h	Wed Dec 31 16:00:00 1969
@@ -1,262 +0,0 @@
-#ifndef _ASM_IA64_EFI_H
-#define _ASM_IA64_EFI_H
-
-/*
- * Extensible Firmware Interface
- * Based on 'Extensible Firmware Interface Specification' version 0.9, April 30, 1999
- *
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999 Hewlett-Packard Co.
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
- */
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-
-#include <asm/page.h>
-#include <asm/system.h>
-
-#define EFI_SUCCESS		0
-#define EFI_LOAD_ERROR          (1L | (1L << 63))
-#define EFI_INVALID_PARAMETER	(2L | (1L << 63))
-#define EFI_UNSUPPORTED		(3L | (1L << 63))
-#define EFI_BAD_BUFFER_SIZE     (4L | (1L << 63))
-#define EFI_BUFFER_TOO_SMALL	(5L | (1L << 63))
-#define EFI_NOT_FOUND          (14L | (1L << 63))
-
-typedef unsigned long efi_status_t;
-typedef u8 efi_bool_t;
-typedef u16 efi_char16_t;		/* UNICODE character */
-
-typedef struct {
-	u32 data1;
-	u16 data2;
-	u16 data3;
-	u8 data4[8];
-} efi_guid_t;
-
-/*
- * Generic EFI table header
- */
-typedef	struct {
-	u64 signature;
-	u32 revision;
-	u32 headersize;
-	u32 crc32;
-	u32 reserved;
-} efi_table_hdr_t;
-
-/*
- * Memory map descriptor:
- */
-
-/* Memory types: */
-#define EFI_RESERVED_TYPE		 0
-#define EFI_LOADER_CODE			 1
-#define EFI_LOADER_DATA			 2
-#define EFI_BOOT_SERVICES_CODE		 3
-#define EFI_BOOT_SERVICES_DATA		 4
-#define EFI_RUNTIME_SERVICES_CODE	 5
-#define EFI_RUNTIME_SERVICES_DATA	 6
-#define EFI_CONVENTIONAL_MEMORY		 7
-#define EFI_UNUSABLE_MEMORY		 8
-#define EFI_ACPI_RECLAIM_MEMORY		 9
-#define EFI_ACPI_MEMORY_NVS		10
-#define EFI_MEMORY_MAPPED_IO		11
-#define EFI_MEMORY_MAPPED_IO_PORT_SPACE	12
-#define EFI_PAL_CODE			13
-#define EFI_MAX_MEMORY_TYPE		14
-
-/* Attribute values: */
-#define EFI_MEMORY_UC		0x0000000000000001	/* uncached */
-#define EFI_MEMORY_WC		0x0000000000000002	/* write-coalescing */
-#define EFI_MEMORY_WT		0x0000000000000004	/* write-through */
-#define EFI_MEMORY_WB		0x0000000000000008	/* write-back */
-#define EFI_MEMORY_WP		0x0000000000001000	/* write-protect */
-#define EFI_MEMORY_RP		0x0000000000002000	/* read-protect */
-#define EFI_MEMORY_XP		0x0000000000004000	/* execute-protect */
-#define EFI_MEMORY_RUNTIME	0x8000000000000000	/* range requires runtime mapping */
-#define EFI_MEMORY_DESCRIPTOR_VERSION	1
-
-typedef struct {
-	u32 type;
-	u32 pad;
-	u64 phys_addr;
-	u64 virt_addr;
-	u64 num_pages;
-	u64 attribute;
-} efi_memory_desc_t;
-
-typedef int efi_freemem_callback_t (u64 start, u64 end, void *arg);
-
-/*
- * Types and defines for Time Services
- */
-#define EFI_TIME_ADJUST_DAYLIGHT 0x1
-#define EFI_TIME_IN_DAYLIGHT     0x2
-#define EFI_UNSPECIFIED_TIMEZONE 0x07ff
-
-typedef struct {
-	u16 year;
-	u8 month;
-	u8 day;
-	u8 hour;
-	u8 minute;
-	u8 second;
-	u8 pad1;
-	u32 nanosecond;
-	s16 timezone;
-	u8 daylight;
-	u8 pad2;
-} efi_time_t;
-
-typedef struct {
-	u32 resolution;
-	u32 accuracy;
-	u8 sets_to_zero;
-} efi_time_cap_t;
-
-/*
- * Types and defines for EFI ResetSystem
- */
-#define EFI_RESET_COLD 0
-#define EFI_RESET_WARM 1
-
-/*
- * EFI Runtime Services table
- */
-#define EFI_RUNTIME_SERVICES_SIGNATURE 0x5652453544e5552
-#define EFI_RUNTIME_SERVICES_REVISION  0x00010000
-
-typedef struct {
-	efi_table_hdr_t hdr;
-	u64 get_time;
-	u64 set_time;
-	u64 get_wakeup_time;
-	u64 set_wakeup_time;
-	u64 set_virtual_address_map;
-	u64 convert_pointer;
-	u64 get_variable;
-	u64 get_next_variable;
-	u64 set_variable;
-	u64 get_next_high_mono_count;
-	u64 reset_system;
-} efi_runtime_services_t;
-
-typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc);
-typedef efi_status_t efi_set_time_t (efi_time_t *tm);
-typedef efi_status_t efi_get_wakeup_time_t (efi_bool_t *enabled, efi_bool_t *pending,
-					    efi_time_t *tm);
-typedef efi_status_t efi_set_wakeup_time_t (efi_bool_t enabled, efi_time_t *tm);
-typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
-					 unsigned long *data_size, void *data);
-typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char16_t *name,
-					      efi_guid_t *vendor);
-typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 attr,
-					 unsigned long data_size, void *data);
-typedef efi_status_t efi_get_next_high_mono_count_t (u64 *count);
-typedef void efi_reset_system_t (int reset_type, efi_status_t status,
-				 unsigned long data_size, efi_char16_t *data);
-
-/*
- *  EFI Configuration Table and GUID definitions
- */
-
-#define MPS_TABLE_GUID    \
-    ((efi_guid_t) { 0xeb9d2d2f, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
-
-#define ACPI_TABLE_GUID    \
-    ((efi_guid_t) { 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
-
-#define ACPI_20_TABLE_GUID    \
-    ((efi_guid_t) { 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 }})
-
-#define SMBIOS_TABLE_GUID    \
-    ((efi_guid_t) { 0xeb9d2d31, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
-
-#define SAL_SYSTEM_TABLE_GUID    \
-    ((efi_guid_t) { 0xeb9d2d32, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
-
-#define HCDP_TABLE_GUID	\
-    ((efi_guid_t) { 0xf951938d, 0x620b, 0x42ef, {0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98}})
-
-typedef struct {
-	efi_guid_t guid;
-	u64 table;
-} efi_config_table_t;
-
-#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
-#define EFI_SYSTEM_TABLE_REVISION  ((1 << 16) | 00)
-
-typedef struct {
-	efi_table_hdr_t hdr;
-	u64 fw_vendor;		/* physical addr of CHAR16 vendor string */
-	u32 fw_revision;
-	u64 con_in_handle;
-	u64 con_in;
-	u64 con_out_handle;
-	u64 con_out;
-	u64 stderr_handle;
-	u64 stderr;
-	u64 runtime;
-	u64 boottime;
-	u64 nr_tables;
-	u64 tables;
-} efi_system_table_t;
-
-/*
- * All runtime access to EFI goes through this structure:
- */
-extern struct efi {
-	efi_system_table_t *systab;	/* EFI system table */
-	void *mps;			/* MPS table */
-	void *acpi;			/* ACPI table  (IA64 ext 0.71) */
-	void *acpi20;			/* ACPI table  (ACPI 2.0) */
-	void *smbios;			/* SM BIOS table */
-	void *sal_systab;		/* SAL system table */
-	void *hcdp;			/* HCDP table */
-	void *boot_info;		/* boot info table */
-	efi_get_time_t *get_time;
-	efi_set_time_t *set_time;
-	efi_get_wakeup_time_t *get_wakeup_time;
-	efi_set_wakeup_time_t *set_wakeup_time;
-	efi_get_variable_t *get_variable;
-	efi_get_next_variable_t *get_next_variable;
-	efi_set_variable_t *set_variable;
-	efi_get_next_high_mono_count_t *get_next_high_mono_count;
-	efi_reset_system_t *reset_system;
-} efi;
-
-static inline int
-efi_guidcmp (efi_guid_t left, efi_guid_t right)
-{
-	return memcmp(&left, &right, sizeof (efi_guid_t));
-}
-
-extern void efi_init (void);
-extern void efi_map_pal_code (void);
-extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
-extern void efi_gettimeofday (struct timeval *tv);
-extern void efi_enter_virtual_mode (void);	/* switch EFI to virtual mode, if possible */
-extern u64  efi_get_iobase (void);
-
-/*
- * Variable Attributes
- */
-#define EFI_VARIABLE_NON_VOLATILE       0x0000000000000001
-#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
-#define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
-
-
-/*
- * efi_dir is allocated in arch/ia64/kernel/efi.c.
- */
-#ifdef CONFIG_PROC_FS
-extern struct proc_dir_entry *efi_dir;
-#endif
-
-#endif /* _ASM_IA64_EFI_H */
diff -urN linux-2.4.20-pre7/include/asm-x86_64/apic.h linux-2.4.20-pre8/include/asm-x86_64/apic.h
--- linux-2.4.20-pre7/include/asm-x86_64/apic.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/apic.h	Wed Sep 25 18:22:08 2002
@@ -23,6 +23,7 @@
 static __inline void apic_write(unsigned long reg, unsigned int v)
 {
 	*((volatile unsigned int *)(APIC_BASE+reg)) = v;
+	barrier();
 }
 
 static __inline void apic_write_atomic(unsigned long reg, unsigned int v)
@@ -87,6 +88,7 @@
 
 extern unsigned int apic_timer_irqs [NR_CPUS];
 extern int check_nmi_watchdog (void);
+extern void enable_NMI_through_LVT0 (void * dummy);
 
 extern unsigned int nmi_watchdog;
 #define NMI_NONE	0
diff -urN linux-2.4.20-pre7/include/asm-x86_64/bitops.h linux-2.4.20-pre8/include/asm-x86_64/bitops.h
--- linux-2.4.20-pre7/include/asm-x86_64/bitops.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/bitops.h	Wed Sep 25 18:22:08 2002
@@ -372,7 +372,7 @@
 	__asm__("bsfl %1,%0\n\t"
 		"jnz 1f\n\t"
 		"movl $-1,%0\n"
-		"1:" : "=r" (r) : "g" (x));
+		"1:" : "=r" (r) : "rm" (x));
 	return r+1;
 }
 
diff -urN linux-2.4.20-pre7/include/asm-x86_64/bugs.h linux-2.4.20-pre8/include/asm-x86_64/bugs.h
--- linux-2.4.20-pre7/include/asm-x86_64/bugs.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/bugs.h	Wed Sep 25 18:22:08 2002
@@ -1,5 +1,5 @@
 /*
- *  include/asm-i386/bugs.h
+ *  include/asm-x86_64/bugs.h
  *
  *  Copyright (C) 1994  Linus Torvalds
  *  Copyright (C) 2000  SuSE
@@ -21,20 +21,14 @@
 	extern void __bad_fxsave_alignment(void);
 	if (offsetof(struct task_struct, thread.i387.fxsave) & 15)
 		__bad_fxsave_alignment();
+
+	/* This should not be here */	
 	set_in_cr4(X86_CR4_OSFXSR);
 	set_in_cr4(X86_CR4_OSXMMEXCPT);
 }
 
-/*
- * If we configured ourselves for FXSR, we'd better have it.
- */
-
 static void __init check_bugs(void)
 {
 	identify_cpu(&boot_cpu_data);
 	check_fpu();
-#if !defined(CONFIG_SMP)
-	printk("CPU: ");
-	print_cpu_info(&boot_cpu_data);
-#endif
 }
diff -urN linux-2.4.20-pre7/include/asm-x86_64/e820.h linux-2.4.20-pre8/include/asm-x86_64/e820.h
--- linux-2.4.20-pre7/include/asm-x86_64/e820.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/e820.h	Wed Sep 25 18:22:08 2002
@@ -2,16 +2,17 @@
  * structures and definitions for the int 15, ax=e820 memory map
  * scheme.
  *
- * In a nutshell, arch/i386/boot/setup.S populates a scratch table
- * in the empty_zero_block that contains a list of usable address/size
- * duples.   In arch/i386/kernel/setup.c, this information is
- * transferred into the e820map, and in arch/i386/mm/init.c, that
- * new information is used to mark pages reserved or not.
- *
+ * In a nutshell, setup.S populates a scratch table in the
+ * empty_zero_block that contains a list of usable address/size
+ * duples.  setup.c, this information is transferred into the e820map,
+ * and in init.c/numa.c, that new information is used to mark pages
+ * reserved or not.
  */
 #ifndef __E820_HEADER
 #define __E820_HEADER
 
+#include <linux/mmzone.h>
+
 #define E820MAP	0x2d0		/* our map */
 #define E820MAX	32		/* number of entries in E820MAP */
 #define E820NR	0x1e8		/* # entries in E820MAP */
@@ -23,19 +24,38 @@
 
 #define HIGH_MEMORY	(1024*1024)
 
+#define LOWMEMSIZE()	(0x9f000)
+
+#define MAXMEM		(120UL * 1024 * 1024 * 1024 * 1024)  /* 120TB */ 
+
+
 #ifndef __ASSEMBLY__
+struct e820entry {
+	u64 addr;	/* start of memory segment */
+	u64 size;	/* size of memory segment */
+	u32 type;	/* type of memory segment */
+} __attribute__((packed));
 
 struct e820map {
-    int nr_map;
-    struct e820entry {
-      /* Maybe even i386 should be changed to look like this? it is
-	 cleaner than relying on long long               --pavel */
-	u64 addr __attribute__((packed));	/* start of memory segment */
-	u64 size __attribute__((packed));	/* size of memory segment */
-	u32 type __attribute__((packed));	/* type of memory segment */
-    } map[E820MAX];
+	int nr_map;
+	struct e820entry map[E820MAX];
 };
 
+extern unsigned long find_e820_area(unsigned long start, unsigned long end, 
+				    unsigned size);
+extern void add_memory_region(unsigned long start, unsigned long size, 
+			      int type);
+extern void setup_memory_region(void);
+extern void contig_e820_setup(void); 
+extern void e820_end_of_ram(void);
+extern void e820_reserve_resources(void);
+extern void e820_print_map(char *who);
+extern int e820_mapped(unsigned long start, unsigned long end, int type);
+
+extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
+
+extern void parse_mem_cmdline (char ** cmdline_p);
+
 extern struct e820map e820;
 #endif/*!__ASSEMBLY__*/
 
diff -urN linux-2.4.20-pre7/include/asm-x86_64/hdreg.h linux-2.4.20-pre8/include/asm-x86_64/hdreg.h
--- linux-2.4.20-pre7/include/asm-x86_64/hdreg.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/hdreg.h	Wed Sep 25 18:22:08 2002
@@ -1,12 +1,12 @@
 /*
- *  linux/include/asm-i386/hdreg.h
+ *  linux/include/asm-x86_64/hdreg.h
  *
  *  Copyright (C) 1994-1996  Linus Torvalds & authors
  */
 
-#ifndef __ASMi386_HDREG_H
-#define __ASMi386_HDREG_H
+#ifndef __ASMx86_64_HDREG_H
+#define __ASMx86_64_HDREG_H
 
 typedef unsigned short ide_ioreg_t;
 
-#endif /* __ASMi386_HDREG_H */
+#endif /* __ASMx86_64_HDREG_H */
diff -urN linux-2.4.20-pre7/include/asm-x86_64/ia32_unistd.h linux-2.4.20-pre8/include/asm-x86_64/ia32_unistd.h
--- linux-2.4.20-pre7/include/asm-x86_64/ia32_unistd.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/ia32_unistd.h	Wed Sep 25 18:22:08 2002
@@ -232,7 +232,22 @@
 #define __NR_ia32_security		223
 #define __NR_ia32_gettid		224
 #define __NR_ia32_readahead		225
+#define __NR_ia32_sendfile64		239
+#define __NR_ia32_futex		240
+#define __NR_ia32_sched_setaffinity	241
+#define __NR_ia32_sched_getaffinity	242
+#define __NR_ia32_set_thread_area	243
+#define __NR_ia32_get_thread_area	244
+#define __NR_ia32_io_setup		245
+#define __NR_ia32_io_destroy		246
+#define __NR_ia32_io_getevents	247
+#define __NR_ia32_io_submit		248
+#define __NR_ia32_io_cancel		249
+#define __NR_ia32_alloc_hugepages	250
+#define __NR_ia32_free_hugepages	251
+#define __NR_ia32_exit_group		252
 
-#define IA32_NR_syscalls 230
+
+#define IA32_NR_syscalls 260
 
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
diff -urN linux-2.4.20-pre7/include/asm-x86_64/ide.h linux-2.4.20-pre8/include/asm-x86_64/ide.h
--- linux-2.4.20-pre7/include/asm-x86_64/ide.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/ide.h	Wed Sep 25 18:22:08 2002
@@ -1,15 +1,15 @@
 /*
- *  linux/include/asm-i386/ide.h
+ *  linux/include/asm-x86_64/ide.h
  *
  *  Copyright (C) 1994-1996  Linus Torvalds & authors
  */
 
 /*
- *  This file contains the i386 architecture specific IDE code.
+ *  This file contains the x86_64 architecture specific IDE code.
  */
 
-#ifndef __ASMi386_IDE_H
-#define __ASMi386_IDE_H
+#ifndef __ASMx86_64_IDE_H
+#define __ASMx86_64_IDE_H
 
 #ifdef __KERNEL__
 
@@ -125,4 +125,4 @@
 
 #endif /* __KERNEL__ */
 
-#endif /* __ASMi386_IDE_H */
+#endif /* __ASMx86_64_IDE_H */
diff -urN linux-2.4.20-pre7/include/asm-x86_64/io.h linux-2.4.20-pre8/include/asm-x86_64/io.h
--- linux-2.4.20-pre7/include/asm-x86_64/io.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/io.h	Wed Sep 25 18:22:08 2002
@@ -1,6 +1,8 @@
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
+#include <linux/config.h>
+
 /*
  * This file contains the definitions for the x86 IO instructions
  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
@@ -138,7 +140,11 @@
 /*
  * Change "struct page" to physical address.
  */
+#ifdef CONFIG_DISCONTIGMEM
+#include <asm/mmzone.h>
+#else
 #define page_to_phys(page)	(((page) - mem_map) << PAGE_SHIFT)
+#endif
 
 extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 
@@ -214,7 +220,7 @@
 
 
 /*
- * Again, i386 does not require mem IO specific function.
+ * Again, x86-64 does not require mem IO specific function.
  */
 
 #define eth_io_copy_and_sum(a,b,c,d)		eth_copy_and_sum((a),__io_virt(b),(c),(d))
diff -urN linux-2.4.20-pre7/include/asm-x86_64/ioctl32.h linux-2.4.20-pre8/include/asm-x86_64/ioctl32.h
--- linux-2.4.20-pre7/include/asm-x86_64/ioctl32.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/ioctl32.h	Wed Sep 25 18:22:08 2002
@@ -1,6 +1,8 @@
 #ifndef IOCTL32_H
 #define IOCTL32_H 1
 
+struct file;
+
 int sys_ioctl(unsigned int, unsigned int, unsigned long);
 
 /* 
diff -urN linux-2.4.20-pre7/include/asm-x86_64/ipcbuf.h linux-2.4.20-pre8/include/asm-x86_64/ipcbuf.h
--- linux-2.4.20-pre7/include/asm-x86_64/ipcbuf.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/ipcbuf.h	Wed Sep 25 18:22:08 2002
@@ -1,8 +1,8 @@
-#ifndef __i386_IPCBUF_H__
-#define __i386_IPCBUF_H__
+#ifndef __x86_64_IPCBUF_H__
+#define __x86_64_IPCBUF_H__
 
 /*
- * The ipc64_perm structure for i386 architecture.
+ * The ipc64_perm structure for x86-64 architecture.
  * Note extra padding because this structure is passed back and forth
  * between kernel and user space.
  *
@@ -26,4 +26,4 @@
 	unsigned long		__unused2;
 };
 
-#endif /* __i386_IPCBUF_H__ */
+#endif /* __x86_64_IPCBUF_H__ */
diff -urN linux-2.4.20-pre7/include/asm-x86_64/kmap_types.h linux-2.4.20-pre8/include/asm-x86_64/kmap_types.h
--- linux-2.4.20-pre7/include/asm-x86_64/kmap_types.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/kmap_types.h	Wed Sep 25 18:22:08 2002
@@ -3,10 +3,11 @@
 
 enum km_type {
 	KM_BOUNCE_READ,
-	KM_SKB_DATA,
+	KM_SKB_SUNRPC_DATA,
 	KM_SKB_DATA_SOFTIRQ,
 	KM_USER0,
 	KM_USER1,
+	KM_BH_IRQ,
 	KM_TYPE_NR
 };
 
diff -urN linux-2.4.20-pre7/include/asm-x86_64/mmzone.h linux-2.4.20-pre8/include/asm-x86_64/mmzone.h
--- linux-2.4.20-pre7/include/asm-x86_64/mmzone.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre8/include/asm-x86_64/mmzone.h	Wed Sep 25 18:22:08 2002
@@ -0,0 +1,170 @@
+/*
+ * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99
+ * Adapted for K8/x86-64 Jul 2002 by Andi Kleen.
+ */
+#ifndef _ASM_MMZONE_H_
+#define _ASM_MMZONE_H_
+
+#include <linux/config.h>
+
+typedef struct plat_pglist_data {
+	pg_data_t	gendata;
+	unsigned long   start_pfn, end_pfn;
+} plat_pg_data_t;
+
+struct bootmem_data_t;
+
+/*
+ * Following are macros that are specific to this numa platform.
+ * 
+ * XXX check what the compiler generates for all this
+ */
+
+extern plat_pg_data_t *plat_node_data[];
+
+#define MAXNODE 8 
+#define MAX_NUMNODES MAXNODE
+#define NODEMAPSIZE 0xff
+
+/* Simple perfect hash to map physical addresses to node numbers */
+extern int memnode_shift; 
+extern u8  memnodemap[NODEMAPSIZE]; 
+extern int maxnode;
+
+#if 0
+#define VIRTUAL_BUG_ON(x) do { if (x) out_of_line_bug(); } while(0)
+#else
+#define VIRTUAL_BUG_ON(x) do {} while (0) 
+#endif
+
+/* VALID_PAGE below hardcodes the same algorithm*/
+static inline int phys_to_nid(unsigned long addr) 
+{ 
+	int nid; 
+	VIRTUAL_BUG_ON((addr >> memnode_shift) >= NODEMAPSIZE);
+	nid = memnodemap[addr >> memnode_shift]; 
+	VIRTUAL_BUG_ON(nid > maxnode); 
+	return nid; 
+} 
+
+#define PLAT_NODE_DATA(n)		(plat_node_data[(n)])
+#define PLAT_NODE_DATA_STARTNR(n)	\
+	(PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
+#define PLAT_NODE_DATA_SIZE(n)		(PLAT_NODE_DATA(n)->gendata.node_size)
+
+#define PLAT_NODE_DATA_LOCALNR(p, n)	\
+	(((p) - PLAT_NODE_DATA(n)->gendata.node_start_paddr) >> PAGE_SHIFT)
+
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * Following are macros that each numa implmentation must define.
+ */
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(kaddr)	phys_to_nid(__pa(kaddr))
+
+/*
+ * 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 the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr) \
+			NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
+
+/*
+ * 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_paddr))
+
+#define LOCAL_MAP_NR(kvaddr) \
+	(((unsigned long)(kvaddr)-LOCAL_BASE_ADDR(kvaddr)) >> PAGE_SHIFT)
+
+#define BAD_PAGE 0xffffffffffff
+
+/* this really should be optimized a bit */
+static inline unsigned long 
+paddr_to_local_pfn(unsigned long phys_addr, struct page **mem_map, int check) 
+{ 
+	unsigned long nid;
+	if (check) { /* we rely on gcc optimizing this way for most cases */ 
+		unsigned long index = phys_addr >> memnode_shift; 
+		if (index >= NODEMAPSIZE || memnodemap[index] == 0xff) { 
+			*mem_map = NULL;
+			return BAD_PAGE;
+		} 
+		nid = memnodemap[index];
+	} else { 
+		nid = phys_to_nid(phys_addr); 
+	} 			   
+	plat_pg_data_t *plat_pgdat = plat_node_data[nid]; 
+	unsigned long pfn = phys_addr >> PAGE_SHIFT; 
+	VIRTUAL_BUG_ON(pfn >= plat_pgdat->end_pfn);
+	VIRTUAL_BUG_ON(pfn < plat_pgdat->start_pfn);
+	*mem_map = plat_pgdat->gendata.node_mem_map; 
+	return pfn - plat_pgdat->start_pfn;
+} 
+#define virt_to_page(kaddr) \
+	({ struct page *lmemmap; \
+	   unsigned long lpfn = paddr_to_local_pfn(__pa(kaddr),&lmemmap,0); \
+	   lmemmap + lpfn;  })
+
+/* needs to handle bad addresses too */
+#define pte_page(pte) \
+	({ struct page *lmemmap; \
+	   unsigned long addr = pte_val(pte) & PHYSICAL_PAGE_MASK; \
+	   unsigned long lpfn = paddr_to_local_pfn(addr,&lmemmap,1); \
+	   lmemmap + lpfn;  })
+
+#define pfn_to_page(pfn)	virt_to_page(__va((unsigned long)(pfn) << PAGE_SHIFT))
+#define page_to_pfn(page)	({ \
+	int nodeid = phys_to_nid(__pa(page));  \
+	plat_pg_data_t *nd = PLAT_NODE_DATA(nodeid); \
+	(page - nd->gendata.node_mem_map) + nd->start_pfn; \
+})
+
+#define VALID_PAGE(page_ptr) ({ \
+	int ok = 0; 						\
+	unsigned long phys = __pa(page_ptr); 			\
+        unsigned long index = phys >> memnode_shift; 		\
+	if (index <= NODEMAPSIZE) { 					  \
+		unsigned nodeid = memnodemap[index]; 			  \
+		pg_data_t *nd = NODE_DATA(nodeid); 			  \
+		struct page *lmemmap = nd->node_mem_map;		  \
+		ok = (nodeid != 0xff) && \
+		     (page_ptr >= lmemmap && page_ptr < lmemmap + nd->node_size); \
+	} 			\
+	ok; 			\
+})
+
+#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
+
+
+
+extern void setup_node_bootmem(int nodeid, unsigned long start_, unsigned long end_);
+
+
+#ifdef CONFIG_NUMA
+extern int fake_node;
+#define cputonode(cpu) (fake_node ? 0 : (cpu))
+#define numa_node_id()	cputonode(smp_processor_id())
+#endif /* CONFIG_NUMA */
+
+#define MAX_NR_NODES 8
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* _ASM_MMZONE_H_ */
diff -urN linux-2.4.20-pre7/include/asm-x86_64/mpspec.h linux-2.4.20-pre8/include/asm-x86_64/mpspec.h
--- linux-2.4.20-pre7/include/asm-x86_64/mpspec.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/mpspec.h	Wed Sep 25 18:22:08 2002
@@ -156,8 +156,8 @@
  *	7	2 CPU MCA+PCI
  */
 
-#define MAX_IRQ_SOURCES 256
-#define MAX_MP_BUSSES 32
+#define MAX_MP_BUSSES 257
+#define MAX_IRQ_SOURCES (MAX_MP_BUSSES*4)
 enum mp_bustype {
 	MP_BUS_ISA = 1,
 	MP_BUS_EISA,
diff -urN linux-2.4.20-pre7/include/asm-x86_64/namei.h linux-2.4.20-pre8/include/asm-x86_64/namei.h
--- linux-2.4.20-pre7/include/asm-x86_64/namei.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/namei.h	Wed Sep 25 18:22:08 2002
@@ -1,9 +1,3 @@
-/* $Id: namei.h,v 1.2 2001/07/04 09:08:13 ak Exp $
- * linux/include/asm-i386/namei.h
- *
- * Included from linux/fs/namei.c
- */
-
 #ifndef __X8664_NAMEI_H
 #define __X8664_NAMEI_H
 
diff -urN linux-2.4.20-pre7/include/asm-x86_64/page.h linux-2.4.20-pre8/include/asm-x86_64/page.h
--- linux-2.4.20-pre7/include/asm-x86_64/page.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/page.h	Wed Sep 25 18:22:08 2002
@@ -10,8 +10,8 @@
 #endif
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
-#define __PHYSICAL_MASK		0x0000ffffffffffff
-#define PHYSICAL_PAGE_MASK	(PAGE_MASK & __PHYSICAL_MASK)
+#define __PHYSICAL_MASK		0x0000ffffffffffffUL
+#define PHYSICAL_PAGE_MASK	0x0000fffffffff000UL
 
 #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
 #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
@@ -73,6 +73,10 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/config.h>
+#include <linux/stringify.h>
+
+
 /*
  * Tell the user there is some problem.  The exception handler decodes this frame.
  */
@@ -83,6 +87,8 @@
 } __attribute__((packed)); 
 #define BUG() asm volatile("ud2 ; .quad %c1 ; .short %c0" :: "i"(__LINE__), \
 		"i" (__stringify(KBUILD_BASENAME)))
+#define HEADER_BUG() asm volatile("ud2 ; .quad %c1 ; .short %c0" :: "i"(__LINE__), \
+		"i" (__stringify(__FILE__)))
 #define PAGE_BUG(page) BUG()
 
 /* Pure 2^n version of get_order */
@@ -118,12 +124,15 @@
 	  __pa(v); })
 
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
+#ifndef CONFIG_DISCONTIGMEM
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define pfn_to_page(pfn)	(mem_map + (pfn)) 
 #define page_to_pfn(page)   ((page) - mem_map)
-#define phys_to_pfn(phys)	((phys) >> PAGE_SHIFT)
 #define page_to_phys(page)	(((page) - mem_map) << PAGE_SHIFT)
 #define VALID_PAGE(page)	(((page) - mem_map) < max_mapnr)
+#endif
+
+#define phys_to_pfn(phys)	((phys) >> PAGE_SHIFT)
 
 
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
diff -urN linux-2.4.20-pre7/include/asm-x86_64/pci-direct.h linux-2.4.20-pre8/include/asm-x86_64/pci-direct.h
--- linux-2.4.20-pre7/include/asm-x86_64/pci-direct.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre8/include/asm-x86_64/pci-direct.h	Wed Sep 25 18:22:08 2002
@@ -0,0 +1,29 @@
+#ifndef ASM_PCI_DIRECT_H
+#define ASM_PCI_DIRECT_H 1
+
+#include <linux/types.h>
+#include <asm/io.h>
+
+/* Direct PCI access. This is used for PCI accesses in early boot before
+   the PCI subsystem works. */ 
+
+#define PDprintk(x...)
+
+static inline u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
+{
+	u32 v; 
+	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
+	v = inl(0xcfc); 
+	PDprintk("%x reading from %x: %x\n", slot, offset, v);
+	return v;
+}
+
+static inline void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
+				    u32 val)
+{
+	PDprintk("%x writing to %x: %x\n", slot, offset, val); 
+	outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
+	outl(val, 0xcfc); 
+}
+
+#endif
diff -urN linux-2.4.20-pre7/include/asm-x86_64/pci.h linux-2.4.20-pre8/include/asm-x86_64/pci.h
--- linux-2.4.20-pre7/include/asm-x86_64/pci.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/pci.h	Wed Sep 25 18:22:08 2002
@@ -6,6 +6,8 @@
 
 #ifdef __KERNEL__
 
+extern dma_addr_t bad_dma_address;
+
 /* Can be used to override the logic in pci_scan_bus for skipping
    already-configured bus numbers - to be used for buggy BIOSes
    or architectures with incomplete PCI setup by the loader */
@@ -31,6 +33,7 @@
 #include <linux/string.h>
 #include <asm/io.h>
 #include <asm/page.h>
+#include <asm/mmzone.h>
 
 struct pci_dev;
 
diff -urN linux-2.4.20-pre7/include/asm-x86_64/pgalloc.h linux-2.4.20-pre8/include/asm-x86_64/pgalloc.h
--- linux-2.4.20-pre7/include/asm-x86_64/pgalloc.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/pgalloc.h	Wed Sep 25 18:22:08 2002
@@ -19,10 +19,7 @@
 
 extern __inline__ pmd_t *get_pmd_slow(void)
 {
-	pmd_t *ret = (pmd_t *)__get_free_page(GFP_KERNEL);
-	if (ret)
-		clear_page(ret);
-	return ret;
+	return (pmd_t *)get_zeroed_page(GFP_KERNEL);
 }
 
 extern __inline__ pmd_t *get_pmd_fast(void)
@@ -56,7 +53,7 @@
 {
 	unsigned long *ret = (unsigned long *)read_pda(pmd_quick);
 
-	if (__builtin_expect(ret != NULL, 1)) {
+	if (ret != NULL) {
 		write_pda(pmd_quick, (unsigned long *)(*ret));
 		ret[0] = 0;
 		dec_pgcache_size();
@@ -66,24 +63,18 @@
 
 static inline pmd_t *pmd_alloc_one (struct mm_struct *mm, unsigned long addr)
 {
-	pmd_t *pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
-
-	if (__builtin_expect(pmd != NULL, 1))
-		clear_page(pmd);
-	return pmd;
+	return (pmd_t *)get_zeroed_page(GFP_KERNEL); 
 }
 
-
 static inline pgd_t *pgd_alloc_one_fast (void)
 {
 	unsigned long *ret = read_pda(pgd_quick);
 
-	if (__builtin_expect(ret != NULL, 1)) {
+	if (ret) {
 		write_pda(pgd_quick,(unsigned long *)(*ret));
 		ret[0] = 0;
 		dec_pgcache_size();
-	} else
-		ret = NULL;
+	}
 	return (pgd_t *) ret;
 }
 
@@ -92,11 +83,8 @@
 	/* the VM system never calls pgd_alloc_one_fast(), so we do it here. */
 	pgd_t *pgd = pgd_alloc_one_fast();
 
-	if (__builtin_expect(pgd == NULL, 0)) {
-		pgd = (pgd_t *)__get_free_page(GFP_KERNEL);
-		if (__builtin_expect(pgd != NULL, 1))
-			clear_page(pgd);
-	}
+	if (pgd == NULL)
+		pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL); 
 	return pgd;
 }
 
@@ -118,19 +106,14 @@
 
 static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	pte_t *pte;
-
-	pte = (pte_t *) __get_free_page(GFP_KERNEL);
-	if (pte)
-		clear_page(pte);
-	return pte;
+	return (pte_t *)get_zeroed_page(GFP_KERNEL); 
 }
 
 extern __inline__ pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
 {
 	unsigned long *ret;
 
-	if(__builtin_expect((ret = read_pda(pte_quick)) != NULL, !0)) {  
+	if ((ret = read_pda(pte_quick)) != NULL) {  
 		write_pda(pte_quick, (unsigned long *)(*ret));
 		ret[0] = ret[1];
 		dec_pgcache_size();
diff -urN linux-2.4.20-pre7/include/asm-x86_64/pgtable.h linux-2.4.20-pre8/include/asm-x86_64/pgtable.h
--- linux-2.4.20-pre7/include/asm-x86_64/pgtable.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/pgtable.h	Wed Sep 25 18:22:08 2002
@@ -17,6 +17,7 @@
 #include <asm/bitops.h>
 #include <asm/pda.h>
 #include <linux/threads.h>
+#include <linux/config.h>
 
 extern pgd_t level3_kernel_pgt[512];
 extern pgd_t level3_physmem_pgt[512];
@@ -65,7 +66,7 @@
 			"movq %0, %%cr3;                     \n"	\
 			"movq %2, %%cr4;  # turn PGE back on \n"	\
 			: "=&r" (tmpreg)				\
-			: "r" (mmu_cr4_features & ~X86_CR4_PGE),	\
+			: "r" (mmu_cr4_features & ~(u64)X86_CR4_PGE),	\
 			  "r" (mmu_cr4_features)			\
 			: "memory");					\
 	} while (0)
@@ -161,6 +162,8 @@
 #define pte_same(a, b)		((a).pte == (b).pte)
 #define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
 
+#define PML4_SIZE	(1UL << PML4_SHIFT)
+#define PML4_MASK	(~(PML4_SIZE-1))
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
@@ -172,15 +175,19 @@
 #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
 #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
 
-#define TWOLEVEL_PGDIR_SHIFT	20
 #define BOOT_USER_L4_PTRS 1
 #define BOOT_KERNEL_L4_PTRS 511	/* But we will do it in 4rd level */
 
 
 
 #ifndef __ASSEMBLY__
+/* IO mappings are the 509th slot in the PML4. We map them high up to make sure
+   they never appear in the node hash table in DISCONTIG configs. */
+#define IOMAP_START      0xfffffe8000000000
+
 /* vmalloc space occupies the 510th slot in the PML4. You can have upto 512GB of
    vmalloc/ioremap space. */ 
+
 #define VMALLOC_START	 0xffffff0000000000
 #define VMALLOC_END      0xffffff7fffffffff
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
@@ -295,10 +302,11 @@
 #define	pmd_bad(x)	\
 	((pmd_val(x) & (~PAGE_MASK & (~_PAGE_USER))) != _KERNPG_TABLE )
 
-#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))	/* FIXME: is this
-						   right? */
-#define pte_page(x) (pfn_to_page((pte_val(x) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT))
+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
+#ifndef CONFIG_DISCONTIGMEM
+#define pte_page(x) (pfn_to_page((pte_val(x) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT))
+#endif
 /*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
@@ -353,7 +361,7 @@
 }
 
 #define page_pte(page) page_pte_prot(page, __pgprot(0))
-#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+#define __pmd_page(pmd) (__va(pmd_val(pmd) & PHYSICAL_PAGE_MASK))
 
 /* to find an entry in a page-table-directory. */
 #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
@@ -376,7 +384,7 @@
 /* Find an entry in the third-level page table.. */
 #define __pte_offset(address) \
 		((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
-#define pte_offset(dir, address) ((pte_t *) pmd_page(*(dir)) + \
+#define pte_offset(dir, address) ((pte_t *) __pmd_page(*(dir)) + \
 			__pte_offset(address))
 
 /* never use these in the common code */
@@ -400,6 +408,7 @@
 #define pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
 #define swp_entry_to_pte(x)		((pte_t) { (x).val })
 
+struct page;
 /* 
  * Change attributes of an kernel page.
  */
@@ -417,7 +426,7 @@
 
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 #define PageSkip(page)		(0)
-#define kern_addr_valid(addr)	(1)
+#define kern_addr_valid(kaddr)  ((kaddr)>>PAGE_SHIFT < max_mapnr)
 
 #define io_remap_page_range remap_page_range
 
diff -urN linux-2.4.20-pre7/include/asm-x86_64/proto.h linux-2.4.20-pre8/include/asm-x86_64/proto.h
--- linux-2.4.20-pre7/include/asm-x86_64/proto.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/proto.h	Wed Sep 25 18:22:08 2002
@@ -19,10 +19,26 @@
 extern void sys_ni_syscall(void);
 extern void config_acpi_tables(void);
 extern void ia32_syscall(void);
+extern void iommu_hole_init(void);
 
 extern void do_softirq_thunk(void);
 
 extern int setup_early_printk(char *); 
 extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2)));
 
+extern int k8_scan_nodes(unsigned long start, unsigned long end);
+
+extern int numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn);
+extern unsigned long numa_free_all_bootmem(void);
+
+extern void reserve_bootmem_generic(unsigned long phys, unsigned len);
+extern void free_bootmem_generic(unsigned long phys, unsigned len);
+
+extern unsigned long start_pfn, end_pfn; 
+
+extern void show_stack(unsigned long * rsp);
+
+#define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
+#define round_down(x,y) ((x) & ~((y)-1))
+
 #endif
diff -urN linux-2.4.20-pre7/include/asm-x86_64/rwsem.h linux-2.4.20-pre8/include/asm-x86_64/rwsem.h
--- linux-2.4.20-pre7/include/asm-x86_64/rwsem.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/rwsem.h	Wed Sep 25 18:22:08 2002
@@ -5,6 +5,7 @@
  *
  * Derived from asm-i386/semaphore.h and asm-i386/rwsem.h
  *
+ * Trylock by Brian Watson (Brian.J.Watson@compaq.com).
  *
  * The MSW of the count is the negated number of active writers and waiting
  * lockers, and the LSW is the total number of active locks
@@ -113,6 +114,30 @@
 		: "memory", "cc");
 }
 
+
+/*
+ * trylock for reading -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+	__s32 result, tmp;
+	__asm__ __volatile__(
+		"# beginning __down_read_trylock\n\t"
+		"  movl      %0,%1\n\t"
+		"1:\n\t"
+		"  movl	     %1,%2\n\t"
+		"  addl      %3,%2\n\t"
+		"  jle	     2f\n\t"
+LOCK_PREFIX	"  cmpxchgl  %2,%0\n\t"
+		"  jnz	     1b\n\t"
+		"2:\n\t"
+		"# ending __down_read_trylock\n\t"
+		: "+m"(sem->count), "=&a"(result), "=&r"(tmp)
+		: "i"(RWSEM_ACTIVE_READ_BIAS)
+		: "memory", "cc");
+	return result>=0 ? 1 : 0;
+}
+
 /*
  * lock for writing
  */
@@ -139,6 +164,19 @@
 }
 
 /*
+ * trylock for writing -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+	signed long ret = cmpxchg(&sem->count,
+				  RWSEM_UNLOCKED_VALUE, 
+				  RWSEM_ACTIVE_WRITE_BIAS);
+	if (ret == RWSEM_UNLOCKED_VALUE)
+		return 1;
+	return 0;
+}
+
+/*
  * unlock after reading
  */
 static inline void __up_read(struct rw_semaphore *sem)
diff -urN linux-2.4.20-pre7/include/asm-x86_64/scatterlist.h linux-2.4.20-pre8/include/asm-x86_64/scatterlist.h
--- linux-2.4.20-pre7/include/asm-x86_64/scatterlist.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/scatterlist.h	Wed Sep 25 18:22:08 2002
@@ -1,6 +1,24 @@
 #ifndef _X8664_SCATTERLIST_H
 #define _X8664_SCATTERLIST_H
 
+/*
+ * Drivers must set either ->address or (preferred) ->page and ->offset
+ * to indicate where data must be transferred to/from.
+ *
+ * Using ->page is recommended since it handles highmem data as well as
+ * low mem. ->address is restricted to data which has a virtual mapping, and
+ * it will go away in the future. Updating to ->page can be automated very
+ * easily -- something like
+ *
+ * sg->address = some_ptr;
+ *
+ * can be rewritten as
+ *
+ * sg->page = virt_to_page(some_ptr);
+ * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK;
+ *
+ * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
+ */
 struct scatterlist {
     char *  address;    /* Location data is to be transferred to, NULL for
 			 * highmem page */
diff -urN linux-2.4.20-pre7/include/asm-x86_64/semaphore.h linux-2.4.20-pre8/include/asm-x86_64/semaphore.h
--- linux-2.4.20-pre7/include/asm-x86_64/semaphore.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/semaphore.h	Wed Sep 25 18:22:08 2002
@@ -111,7 +111,7 @@
 /*
  * This is ugly, but we want the default case to fall through.
  * "__down_failed" is a special asm handler that calls the C
- * routine that actually waits. See arch/i386/kernel/semaphore.c
+ * routine that actually waits. See arch/x86_64/kernel/semaphore.c
  */
 static inline void down(struct semaphore * sem)
 {
@@ -225,5 +225,11 @@
 		:"D" (sem)
 		:"memory");
 }
+
+static inline int sem_getcount(struct semaphore *sem)
+{
+       return atomic_read(&sem->count);
+}
+
 #endif /* __KERNEL__ */
 #endif
diff -urN linux-2.4.20-pre7/include/asm-x86_64/signal.h linux-2.4.20-pre8/include/asm-x86_64/signal.h
--- linux-2.4.20-pre7/include/asm-x86_64/signal.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/signal.h	Wed Sep 25 18:22:08 2002
@@ -1,5 +1,5 @@
-#ifndef _ASMi386_SIGNAL_H
-#define _ASMi386_SIGNAL_H
+#ifndef _ASMx86_64_SIGNAL_H
+#define _ASMx86_64_SIGNAL_H
 
 #include <linux/types.h>
 
@@ -132,7 +132,6 @@
 #define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
 #define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
 
-#ifdef __KERNEL__
 struct sigaction {
 	__sighandler_t sa_handler;
 	unsigned long sa_flags;
@@ -143,7 +142,6 @@
 struct k_sigaction {
 	struct sigaction sa;
 };
-#endif /* __KERNEL__ */
 
 typedef struct sigaltstack {
 	void *ss_sp;
diff -urN linux-2.4.20-pre7/include/asm-x86_64/spinlock.h linux-2.4.20-pre8/include/asm-x86_64/spinlock.h
--- linux-2.4.20-pre7/include/asm-x86_64/spinlock.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/spinlock.h	Wed Sep 25 18:22:08 2002
@@ -4,6 +4,7 @@
 #include <asm/atomic.h>
 #include <asm/rwlock.h>
 #include <asm/page.h>
+#include <linux/kernel.h>
 #include <linux/config.h>
 
 extern int printk(const char * fmt, ...)
@@ -49,7 +50,7 @@
  * We make no fairness assumptions. They have a cost.
  */
 
-#define spin_is_locked(x)	(*(volatile char *)(&(x)->lock) <= 0)
+#define spin_is_locked(x)	(*(volatile signed char *)(&(x)->lock) <= 0)
 #define spin_unlock_wait(x)	do { barrier(); } while(spin_is_locked(x))
 
 #define spin_lock_string \
diff -urN linux-2.4.20-pre7/include/asm-x86_64/unistd.h linux-2.4.20-pre8/include/asm-x86_64/unistd.h
--- linux-2.4.20-pre7/include/asm-x86_64/unistd.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/unistd.h	Wed Sep 25 18:22:08 2002
@@ -465,13 +465,29 @@
 __SYSCALL(__NR_time, sys_time)
 #define __NR_futex		202 /* 2.5 only */
 __SYSCALL(__NR_futex, sys_ni_syscall)
+#define __NR_sched_setaffinity    203
+__SYSCALL(__NR_sched_setaffinity, sys_ni_syscall)
+#define __NR_sched_getaffinity     204
+__SYSCALL(__NR_sched_getaffinity, sys_ni_syscall)
+#define __NR_set_thread_area	205
+__SYSCALL(__NR_set_thread_area, sys_ni_syscall)
+#define __NR_io_setup	206
+__SYSCALL(__NR_io_setup, sys_ni_syscall)
+#define __NR_io_destroy	207
+__SYSCALL(__NR_io_destroy, sys_ni_syscall)
+#define __NR_io_getevents	208
+__SYSCALL(__NR_io_getevents, sys_ni_syscall)
+#define __NR_io_submit	209
+__SYSCALL(__NR_io_submit, sys_ni_syscall)
+#define __NR_io_cancel	210
+__SYSCALL(__NR_io_cancel, sys_ni_syscall)
+#define __NR_get_thread_area	211
+__SYSCALL(__NR_get_thread_area, sys_ni_syscall)
 
-#define __NR_syscall_max __NR_futex
+#define __NR_syscall_max __NR_get_thread_area
 
 #ifndef __NO_STUBS
 
-/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
-
 #define __syscall_clobber "r11","rcx","memory" 
 
 #define __syscall_return(type, res) \
@@ -487,7 +503,7 @@
 
 #define __syscall "syscall"
 
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+
 #define _syscall0(type,name) \
 type name(void) \
 { \
@@ -498,31 +514,26 @@
 __syscall_return(type,__res); \
 }
 
-#define __syscall1(type,rtype,name,type1,arg1) \
+#define _syscall1(type,name,type1,arg1) \
 type name(type1 arg1) \
 { \
 long __res; \
 __asm__ volatile (__syscall \
 	: "=a" (__res) \
 	: "0" (__NR_##name),"D" ((long)(arg1)) : __syscall_clobber ); \
-__syscall_return(rtype,__res); \
+__syscall_return(type,__res); \
 }
 
-#define __syscall2(type,rtype,name,type1,arg1,type2,arg2) \
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
 type name(type1 arg1,type2 arg2) \
 { \
 long __res; \
 __asm__ volatile (__syscall \
 	: "=a" (__res) \
 	: "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)) : __syscall_clobber ); \
-__syscall_return(rtype,__res); \
+__syscall_return(type,__res); \
 }
 
-#define _syscall1(type,name,type1,arg1)  __syscall1(type,type,name,type1,arg2)
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-	__syscall2(type,type,name,type1,arg1,type2,arg2)
-
-
 #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
 type name(type1 arg1,type2 arg2,type3 arg3) \
 { \
@@ -530,7 +541,7 @@
 __asm__ volatile (__syscall \
 	: "=a" (__res) \
 	: "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \
-		  "d" ((long)(arg3)) : __syscall_clobber, "r9" ); \
+		  "d" ((long)(arg3)) : __syscall_clobber); \
 __syscall_return(type,__res); \
 }
 
@@ -550,11 +561,25 @@
 type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
 { \
 long __res; \
-__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r9 ; " __syscall \
+__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall \
 	: "=a" (__res) \
 	: "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \
 	  "d" ((long)(arg3)),"g" ((long)(arg4)),"g" ((long)(arg5)) : \
-	__syscall_clobber,"r8","r9","r10" ); \
+	__syscall_clobber,"r8","r10" ); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+long __res; \
+__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; movq %7,%%r9" __syscall \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \
+	  "d" ((long)(arg3)),"g" ((long)(arg4)),"g" ((long)(arg5), \
+	  "g" ((long)(arg6),) : \
+	__syscall_clobber,"r8","r10","r9" ); \
 __syscall_return(type,__res); \
 }
 
diff -urN linux-2.4.20-pre7/include/asm-x86_64/vsyscall.h linux-2.4.20-pre8/include/asm-x86_64/vsyscall.h
--- linux-2.4.20-pre7/include/asm-x86_64/vsyscall.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/asm-x86_64/vsyscall.h	Wed Sep 25 18:22:08 2002
@@ -1,6 +1,8 @@
 #ifndef _ASM_X86_64_VSYSCALL_H_
 #define _ASM_X86_64_VSYSCALL_H_
 
+#include <linux/time.h>
+
 enum vsyscall_num {
 	__NR_vgettimeofday,
 	__NR_vtime,
@@ -22,9 +24,12 @@
 
 struct hpet_data {
 	long address;		/* base address */
-	unsigned long quotient;	/* 2^32 * usec / clock */
 	unsigned long hz;	/* HPET clocks / sec */
 	int trigger;		/* value at last interrupt */
+	int last;
+	int offset;
+	unsigned long last_tsc;
+	long ticks;
 };
 
 #define hpet_readl(a)           readl(fix_to_virt(FIX_HPET_BASE) + a)
diff -urN linux-2.4.20-pre7/include/linux/agp_backend.h linux-2.4.20-pre8/include/linux/agp_backend.h
--- linux-2.4.20-pre7/include/linux/agp_backend.h	Fri Aug  2 17:39:45 2002
+++ linux-2.4.20-pre8/include/linux/agp_backend.h	Wed Sep 25 18:22:08 2002
@@ -65,6 +65,7 @@
 	AMD_IRONGATE,
 	AMD_761,
 	AMD_762,
+	AMD_8151,
 	ALI_M1541,
 	ALI_M1621,
 	ALI_M1631,
@@ -161,7 +162,7 @@
  * 
  */
 
-extern void agp_copy_info(agp_kern_info *);
+extern int agp_copy_info(agp_kern_info *);
 
 /*
  * agp_copy_info :
@@ -257,7 +258,7 @@
 	void       (*enable)(u32);
 	int        (*acquire)(void);
 	void       (*release)(void);
-	void       (*copy_info)(agp_kern_info *);
+	int        (*copy_info)(agp_kern_info *);
 } drm_agp_t;
 
 extern const drm_agp_t *drm_agp_p;
diff -urN linux-2.4.20-pre7/include/linux/efi.h linux-2.4.20-pre8/include/linux/efi.h
--- linux-2.4.20-pre7/include/linux/efi.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre8/include/linux/efi.h	Wed Sep 25 18:22:08 2002
@@ -0,0 +1,284 @@
+#ifndef _LINUX_EFI_H
+#define _LINUX_EFI_H
+
+/*
+ * Extensible Firmware Interface
+ * Based on 'Extensible Firmware Interface Specification' version 0.9, April 30, 1999
+ *
+ * Copyright (C) 1999 VA Linux Systems
+ * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
+ * Copyright (C) 1999, 2002 Hewlett-Packard Co.
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/time.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+
+#include <asm/page.h>
+#include <asm/system.h>
+
+#define EFI_SUCCESS		0
+#define EFI_LOAD_ERROR          (1L | (1L << 63))
+#define EFI_INVALID_PARAMETER	(2L | (1L << 63))
+#define EFI_UNSUPPORTED		(3L | (1L << 63))
+#define EFI_BAD_BUFFER_SIZE     (4L | (1L << 63))
+#define EFI_BUFFER_TOO_SMALL	(5L | (1L << 63))
+#define EFI_NOT_FOUND          (14L | (1L << 63))
+
+typedef unsigned long efi_status_t;
+typedef u8 efi_bool_t;
+typedef u16 efi_char16_t;		/* UNICODE character */
+
+
+typedef struct {
+	u8 b[16];
+} efi_guid_t;
+
+#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+((efi_guid_t) \
+{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
+  (b) & 0xff, ((b) >> 8) & 0xff, \
+  (c) & 0xff, ((c) >> 8) & 0xff, \
+  (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
+
+/*
+ * Generic EFI table header
+ */
+typedef	struct {
+	u64 signature;
+	u32 revision;
+	u32 headersize;
+	u32 crc32;
+	u32 reserved;
+} efi_table_hdr_t;
+
+/*
+ * Memory map descriptor:
+ */
+
+/* Memory types: */
+#define EFI_RESERVED_TYPE		 0
+#define EFI_LOADER_CODE			 1
+#define EFI_LOADER_DATA			 2
+#define EFI_BOOT_SERVICES_CODE		 3
+#define EFI_BOOT_SERVICES_DATA		 4
+#define EFI_RUNTIME_SERVICES_CODE	 5
+#define EFI_RUNTIME_SERVICES_DATA	 6
+#define EFI_CONVENTIONAL_MEMORY		 7
+#define EFI_UNUSABLE_MEMORY		 8
+#define EFI_ACPI_RECLAIM_MEMORY		 9
+#define EFI_ACPI_MEMORY_NVS		10
+#define EFI_MEMORY_MAPPED_IO		11
+#define EFI_MEMORY_MAPPED_IO_PORT_SPACE	12
+#define EFI_PAL_CODE			13
+#define EFI_MAX_MEMORY_TYPE		14
+
+/* Attribute values: */
+#define EFI_MEMORY_UC		0x0000000000000001	/* uncached */
+#define EFI_MEMORY_WC		0x0000000000000002	/* write-coalescing */
+#define EFI_MEMORY_WT		0x0000000000000004	/* write-through */
+#define EFI_MEMORY_WB		0x0000000000000008	/* write-back */
+#define EFI_MEMORY_WP		0x0000000000001000	/* write-protect */
+#define EFI_MEMORY_RP		0x0000000000002000	/* read-protect */
+#define EFI_MEMORY_XP		0x0000000000004000	/* execute-protect */
+#define EFI_MEMORY_RUNTIME	0x8000000000000000	/* range requires runtime mapping */
+#define EFI_MEMORY_DESCRIPTOR_VERSION	1
+
+#define EFI_PAGE_SHIFT		12
+
+typedef struct {
+	u32 type;
+	u32 pad;
+	u64 phys_addr;
+	u64 virt_addr;
+	u64 num_pages;
+	u64 attribute;
+} efi_memory_desc_t;
+
+typedef int efi_freemem_callback_t (u64 start, u64 end, void *arg);
+
+/*
+ * Types and defines for Time Services
+ */
+#define EFI_TIME_ADJUST_DAYLIGHT 0x1
+#define EFI_TIME_IN_DAYLIGHT     0x2
+#define EFI_UNSPECIFIED_TIMEZONE 0x07ff
+
+typedef struct {
+	u16 year;
+	u8 month;
+	u8 day;
+	u8 hour;
+	u8 minute;
+	u8 second;
+	u8 pad1;
+	u32 nanosecond;
+	s16 timezone;
+	u8 daylight;
+	u8 pad2;
+} efi_time_t;
+
+typedef struct {
+	u32 resolution;
+	u32 accuracy;
+	u8 sets_to_zero;
+} efi_time_cap_t;
+
+/*
+ * Types and defines for EFI ResetSystem
+ */
+#define EFI_RESET_COLD 0
+#define EFI_RESET_WARM 1
+
+/*
+ * EFI Runtime Services table
+ */
+#define EFI_RUNTIME_SERVICES_SIGNATURE 0x5652453544e5552
+#define EFI_RUNTIME_SERVICES_REVISION  0x00010000
+
+typedef struct {
+	efi_table_hdr_t hdr;
+	u64 get_time;
+	u64 set_time;
+	u64 get_wakeup_time;
+	u64 set_wakeup_time;
+	u64 set_virtual_address_map;
+	u64 convert_pointer;
+	u64 get_variable;
+	u64 get_next_variable;
+	u64 set_variable;
+	u64 get_next_high_mono_count;
+	u64 reset_system;
+} efi_runtime_services_t;
+
+typedef efi_status_t efi_get_time_t (efi_time_t *tm, efi_time_cap_t *tc);
+typedef efi_status_t efi_set_time_t (efi_time_t *tm);
+typedef efi_status_t efi_get_wakeup_time_t (efi_bool_t *enabled, efi_bool_t *pending,
+					    efi_time_t *tm);
+typedef efi_status_t efi_set_wakeup_time_t (efi_bool_t enabled, efi_time_t *tm);
+typedef efi_status_t efi_get_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 *attr,
+					 unsigned long *data_size, void *data);
+typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char16_t *name,
+					      efi_guid_t *vendor);
+typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, u32 attr,
+					 unsigned long data_size, void *data);
+typedef efi_status_t efi_get_next_high_mono_count_t (u64 *count);
+typedef void efi_reset_system_t (int reset_type, efi_status_t status,
+				 unsigned long data_size, efi_char16_t *data);
+
+/*
+ *  EFI Configuration Table and GUID definitions
+ */
+#define NULL_GUID \
+    EFI_GUID(  0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
+
+#define MPS_TABLE_GUID    \
+    EFI_GUID(  0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
+#define ACPI_TABLE_GUID    \
+    EFI_GUID(  0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
+#define ACPI_20_TABLE_GUID    \
+    EFI_GUID(  0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 )
+
+#define SMBIOS_TABLE_GUID    \
+    EFI_GUID(  0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
+#define SAL_SYSTEM_TABLE_GUID    \
+    EFI_GUID(  0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
+
+#define HCDP_TABLE_GUID	\
+    EFI_GUID(  0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 )
+
+typedef struct {
+	efi_guid_t guid;
+	u64 table;
+} efi_config_table_t;
+
+#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
+#define EFI_SYSTEM_TABLE_REVISION  ((1 << 16) | 00)
+
+typedef struct {
+	efi_table_hdr_t hdr;
+	u64 fw_vendor;		/* physical addr of CHAR16 vendor string */
+	u32 fw_revision;
+	u64 con_in_handle;
+	u64 con_in;
+	u64 con_out_handle;
+	u64 con_out;
+	u64 stderr_handle;
+	u64 stderr;
+	u64 runtime;
+	u64 boottime;
+	u64 nr_tables;
+	u64 tables;
+} efi_system_table_t;
+
+/*
+ * All runtime access to EFI goes through this structure:
+ */
+extern struct efi {
+	efi_system_table_t *systab;	/* EFI system table */
+	void *mps;			/* MPS table */
+	void *acpi;			/* ACPI table  (IA64 ext 0.71) */
+	void *acpi20;			/* ACPI table  (ACPI 2.0) */
+	void *smbios;			/* SM BIOS table */
+	void *sal_systab;		/* SAL system table */
+	void *hcdp;			/* HCDP table */
+	void *boot_info;		/* boot info table */
+	efi_get_time_t *get_time;
+	efi_set_time_t *set_time;
+	efi_get_wakeup_time_t *get_wakeup_time;
+	efi_set_wakeup_time_t *set_wakeup_time;
+	efi_get_variable_t *get_variable;
+	efi_get_next_variable_t *get_next_variable;
+	efi_set_variable_t *set_variable;
+	efi_get_next_high_mono_count_t *get_next_high_mono_count;
+	efi_reset_system_t *reset_system;
+} efi;
+
+static inline int
+efi_guidcmp (efi_guid_t left, efi_guid_t right)
+{
+	return memcmp(&left, &right, sizeof (efi_guid_t));
+}
+
+static inline char *
+efi_guid_unparse(efi_guid_t *guid, char *out)
+{
+	sprintf(out, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		guid->b[3], guid->b[2], guid->b[1], guid->b[0],
+		guid->b[5], guid->b[4], guid->b[7], guid->b[6],
+		guid->b[8], guid->b[9], guid->b[10], guid->b[11],
+		guid->b[12], guid->b[13], guid->b[14], guid->b[15]);
+        return out;
+}
+
+extern void efi_init (void);
+extern void efi_map_pal_code (void);
+extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
+extern void efi_gettimeofday (struct timeval *tv);
+extern void efi_enter_virtual_mode (void);	/* switch EFI to virtual mode, if possible */
+extern u64 efi_get_iobase (void);
+extern u32 efi_mem_type (unsigned long phys_addr);
+extern u64 efi_mem_attributes (unsigned long phys_addr);
+
+/*
+ * Variable Attributes
+ */
+#define EFI_VARIABLE_NON_VOLATILE       0x0000000000000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
+#define EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
+
+
+/*
+ * efi_dir is allocated in arch/ia64/kernel/efi.c.
+ */
+#ifdef CONFIG_PROC_FS
+extern struct proc_dir_entry *efi_dir;
+#endif
+
+#endif /* _LINUX_EFI_H */
diff -urN linux-2.4.20-pre7/include/linux/ioport.h linux-2.4.20-pre8/include/linux/ioport.h
--- linux-2.4.20-pre7/include/linux/ioport.h	Mon Nov 27 17:51:34 2000
+++ linux-2.4.20-pre8/include/linux/ioport.h	Wed Sep 25 18:22:08 2002
@@ -92,7 +92,8 @@
 			     unsigned long size,
 			     unsigned long min, unsigned long max,
 			     unsigned long align,
-			     void (*alignf)(void *, struct resource *, unsigned long),
+			     void (*alignf)(void *, struct resource *,
+					    unsigned long, unsigned long),
 			     void *alignf_data);
 
 /* Convenience shorthand with allocation */
diff -urN linux-2.4.20-pre7/include/linux/mmzone.h linux-2.4.20-pre8/include/linux/mmzone.h
--- linux-2.4.20-pre7/include/linux/mmzone.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/linux/mmzone.h	Wed Sep 25 18:22:08 2002
@@ -223,7 +223,9 @@
 #include <asm/mmzone.h>
 
 /* page->zone is currently 8 bits ... */
+#ifndef MAX_NR_NODES
 #define MAX_NR_NODES		(255 / MAX_NR_ZONES)
+#endif
 
 #endif /* !CONFIG_DISCONTIGMEM */
 
diff -urN linux-2.4.20-pre7/include/linux/pci.h linux-2.4.20-pre8/include/linux/pci.h
--- linux-2.4.20-pre7/include/linux/pci.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/linux/pci.h	Wed Sep 25 18:22:08 2002
@@ -439,6 +439,7 @@
 extern struct list_head pci_root_buses;	/* list of all known PCI buses */
 extern struct list_head pci_devices;	/* list of all devices */
 
+extern struct proc_dir_entry *proc_bus_pci_dir;
 /*
  * Error values that may be returned by PCI functions.
  */
@@ -463,9 +464,9 @@
 
 struct pbus_set_ranges_data
 {
-	int found_vga;
 	unsigned long io_start, io_end;
 	unsigned long mem_start, mem_end;
+	unsigned long prefetch_start, prefetch_end;
 };
 
 struct pci_device_id {
@@ -500,7 +501,8 @@
 char *pcibios_setup (char *str);
 
 /* Used only when drivers/pci/setup.c is used */
-void pcibios_align_resource(void *, struct resource *, unsigned long);
+void pcibios_align_resource(void *, struct resource *,
+			    unsigned long, unsigned long);
 void pcibios_update_resource(struct pci_dev *, struct resource *,
 			     struct resource *, int);
 void pcibios_update_irq(struct pci_dev *, int irq);
@@ -584,7 +586,7 @@
 int pci_claim_resource(struct pci_dev *, int);
 void pci_assign_unassigned_resources(void);
 void pdev_enable_device(struct pci_dev *);
-void pdev_sort_resources(struct pci_dev *, struct resource_list *, u32);
+void pdev_sort_resources(struct pci_dev *, struct resource_list *);
 unsigned long pci_bridge_check_io(struct pci_dev *);
 void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
 		    int (*)(struct pci_dev *, u8, u8));
diff -urN linux-2.4.20-pre7/include/linux/pci_gameport.h linux-2.4.20-pre8/include/linux/pci_gameport.h
--- linux-2.4.20-pre7/include/linux/pci_gameport.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.20-pre8/include/linux/pci_gameport.h	Wed Sep 25 18:22:08 2002
@@ -0,0 +1,39 @@
+#ifndef __LINUX_PCI_GAMEPORT_H
+#define __LINUX_PCI_GAMEPORT_H
+
+/*
+ *	Public interfaces for attaching a PCI gameport directly to the
+ *	soundcard when it shares the same PCI ident
+ */
+ 
+#define PCIGAME_4DWAVE		0
+#define PCIGAME_VORTEX		1
+#define PCIGAME_VORTEX2		2
+
+
+struct pcigame_data {
+	int gcr;	/* Gameport control register */
+	int legacy;	/* Legacy port location */
+	int axes;	/* Axes start */
+	int axsize;	/* Axis field size */
+	int axmax;	/* Axis field max value */
+	int adcmode;	/* Value to enable ADC mode in GCR */
+};
+
+struct pcigame {
+	struct gameport gameport;
+	struct pci_dev *dev;
+        unsigned char *base;
+	struct pcigame_data *data;
+};
+
+
+#if defined(CONFIG_INPUT_PCIGAME) || defined(CONFIG_INPUT_PCIGAME_MODULE)
+extern struct pcigame *pcigame_attach(struct pci_dev *dev, int type);
+extern void pcigame_detach(struct pcigame *game);
+#else
+#define pcigame_attach(a,b)	NULL
+#define pcigame_detach(a)
+#endif
+
+#endif
diff -urN linux-2.4.20-pre7/include/linux/pci_ids.h linux-2.4.20-pre8/include/linux/pci_ids.h
--- linux-2.4.20-pre7/include/linux/pci_ids.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/linux/pci_ids.h	Wed Sep 25 18:22:08 2002
@@ -598,6 +598,7 @@
 #define PCI_VENDOR_ID_MOTOROLA_OOPS	0x1507
 #define PCI_DEVICE_ID_MOTOROLA_MPC105	0x0001
 #define PCI_DEVICE_ID_MOTOROLA_MPC106	0x0002
+#define PCI_DEVICE_ID_MOTOROLA_MPC107	0x0004
 #define PCI_DEVICE_ID_MOTOROLA_RAVEN	0x4801
 #define PCI_DEVICE_ID_MOTOROLA_FALCON	0x4802
 #define PCI_DEVICE_ID_MOTOROLA_HAWK	0x4803
@@ -1536,6 +1537,7 @@
 #define PCI_DEVICE_ID_TIGON3_5701	0x1645
 #define PCI_DEVICE_ID_TIGON3_5702	0x1646
 #define PCI_DEVICE_ID_TIGON3_5703	0x1647
+#define PCI_DEVICE_ID_TIGON3_5704	0x1648
 #define PCI_DEVICE_ID_TIGON3_5702FE	0x164d
 #define PCI_DEVICE_ID_TIGON3_5702X	0x16a6
 #define PCI_DEVICE_ID_TIGON3_5703X	0x16a7
diff -urN linux-2.4.20-pre7/include/linux/spinlock.h linux-2.4.20-pre8/include/linux/spinlock.h
--- linux-2.4.20-pre7/include/linux/spinlock.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/linux/spinlock.h	Wed Sep 25 18:22:08 2002
@@ -71,7 +71,7 @@
  * Some older gcc versions had a nasty bug with empty initializers.
  * (XXX: could someone please confirm whether egcs 1.1 still has this bug?)
  */
-#if (__GNUC__ > 2 || __GNUC_MINOR__ > 91)
+#if (__GNUC__ > 2 || __GNUC_MINOR__ > 95)
   typedef struct { } spinlock_t;
   #define SPIN_LOCK_UNLOCKED (spinlock_t) { }
 #else
diff -urN linux-2.4.20-pre7/include/linux/tty.h linux-2.4.20-pre8/include/linux/tty.h
--- linux-2.4.20-pre7/include/linux/tty.h	Thu Nov 22 11:46:19 2001
+++ linux-2.4.20-pre8/include/linux/tty.h	Wed Sep 25 18:22:08 2002
@@ -57,38 +57,38 @@
  */
 
 struct screen_info {
-	unsigned char  orig_x;			/* 0x00 */
-	unsigned char  orig_y;			/* 0x01 */
-	unsigned short dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
-	unsigned short orig_video_page;		/* 0x04 */
-	unsigned char  orig_video_mode;		/* 0x06 */
-	unsigned char  orig_video_cols;		/* 0x07 */
-	unsigned short unused2;			/* 0x08 */
-	unsigned short orig_video_ega_bx;	/* 0x0a */
-	unsigned short unused3;			/* 0x0c */
-	unsigned char  orig_video_lines;	/* 0x0e */
-	unsigned char  orig_video_isVGA;	/* 0x0f */
-	unsigned short orig_video_points;	/* 0x10 */
+	u8  orig_x;		/* 0x00 */
+	u8  orig_y;		/* 0x01 */
+	u16 dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
+	u16 orig_video_page;	/* 0x04 */
+	u8  orig_video_mode;	/* 0x06 */
+	u8  orig_video_cols;	/* 0x07 */
+	u16 unused2;		/* 0x08 */
+	u16 orig_video_ega_bx;	/* 0x0a */
+	u16 unused3;		/* 0x0c */
+	u8  orig_video_lines;	/* 0x0e */
+	u8  orig_video_isVGA;	/* 0x0f */
+	u16 orig_video_points;	/* 0x10 */
 
 	/* VESA graphic mode -- linear frame buffer */
-	unsigned short lfb_width;		/* 0x12 */
-	unsigned short lfb_height;		/* 0x14 */
-	unsigned short lfb_depth;		/* 0x16 */
-	unsigned long  lfb_base;		/* 0x18 */
-	unsigned long  lfb_size;		/* 0x1c */
-	unsigned short dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
-	unsigned short lfb_linelength;		/* 0x24 */
-	unsigned char  red_size;		/* 0x26 */
-	unsigned char  red_pos;			/* 0x27 */
-	unsigned char  green_size;		/* 0x28 */
-	unsigned char  green_pos;		/* 0x29 */
-	unsigned char  blue_size;		/* 0x2a */
-	unsigned char  blue_pos;		/* 0x2b */
-	unsigned char  rsvd_size;		/* 0x2c */
-	unsigned char  rsvd_pos;		/* 0x2d */
-	unsigned short vesapm_seg;		/* 0x2e */
-	unsigned short vesapm_off;		/* 0x30 */
-	unsigned short pages;			/* 0x32 */
+	u16 lfb_width;				/* 0x12 */
+	u16 lfb_height;		/* 0x14 */
+	u16 lfb_depth;		/* 0x16 */
+	u32 lfb_base;		/* 0x18 */
+	u32 lfb_size;		/* 0x1c */
+	u16 dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
+	u16 lfb_linelength;	/* 0x24 */
+	u8  red_size;		/* 0x26 */
+	u8  red_pos;		/* 0x27 */
+	u8  green_size;		/* 0x28 */
+	u8  green_pos;		/* 0x29 */
+	u8  blue_size;		/* 0x2a */
+	u8  blue_pos;		/* 0x2b */
+	u8  rsvd_size;		/* 0x2c */
+	u8  rsvd_pos;		/* 0x2d */
+	u16 vesapm_seg;		/* 0x2e */
+	u16 vesapm_off;		/* 0x30 */
+	u16 pages;		/* 0x32 */
 						/* 0x34 -- 0x3f reserved for future expansion */
 };
 
diff -urN linux-2.4.20-pre7/include/linux/usb.h linux-2.4.20-pre8/include/linux/usb.h
--- linux-2.4.20-pre7/include/linux/usb.h	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/include/linux/usb.h	Wed Sep 25 18:22:08 2002
@@ -398,7 +398,53 @@
 	unsigned long	driver_info;
 };
 
+/**
+ * struct usb_driver - identifies USB driver to usbcore
+ * @owner: Pointer to the module owner of this driver; initialize
+ *      it using THIS_MODULE.
+ * @name: The driver name should be unique among USB drivers,
+ *      and should normally be the same as the module name.
+ * @probe: Called to see if the driver is willing to manage a particular
+ *      interface on a device.  The probe routine returns a handle that 
+ *      will later be provided to disconnect(), or a null pointer to
+ *      indicate that the driver will not handle the interface.
+ *      The handle is normally a pointer to driver-specific data.
+ *      If the probe() routine needs to access the interface
+ *      structure itself, use usb_ifnum_to_if() to make sure it's using
+ *      the right one.
+ * @disconnect: Called when the interface is no longer accessible, usually
+ *      because its device has been (or is being) disconnected.  The
+ *      handle passed is what was returned by probe(), or was provided
+ *      to usb_driver_claim_interface().
+ * @ioctl: Used for drivers that want to talk to userspace through
+ *      the "usbfs" filesystem.  This lets devices provide ways to
+ *      expose information to user space regardless of where they
+ *      do (or don't) show up otherwise in the filesystem.
+ * @fops: pointer to a fops structure if the driver wants to use the USB
+ *	major number.
+ * @minor: the starting minor number for this driver, if the fops
+ *	pointer is set.
+ * @id_table: USB drivers use ID table to support hotplugging.
+ *      Export this with MODULE_DEVICE_TABLE(usb,...), or use NULL to
+ *      say that probe() should be called for any unclaimed interface.
+ *
+ * USB drivers must provide a name, probe() and disconnect() methods,
+ * and an id_table.  Other driver fields are optional.
+ *
+ * The id_table is used in hotplugging.  It holds a set of descriptors,
+ * and specialized data may be associated with each entry.  That table
+ * is used by both user and kernel mode hotplugging support.
+ * The probe() and disconnect() methods are called in a context where
+ * they can sleep, but they should avoid abusing the privilege.  Most
+ * work to connect to a device should be done when the device is opened,
+ * and undone at the last close.  The disconnect code needs to address
+ * concurrency issues with respect to open() and close() methods, as
+ * well as forcing all pending I/O requests to complete (by unlinking
+ * them as necessary, and blocking until the unlinks complete).
+ */
 struct usb_driver {
+	struct module *owner;
+
 	const char *name;
 
 	void *(*probe)(
@@ -415,18 +461,9 @@
 
 	struct semaphore serialize;
 
-	/* ioctl -- userspace apps can talk to drivers through usbdevfs */
 	int (*ioctl)(struct usb_device *dev, unsigned int code, void *buf);
 
-	/* support for "new-style" USB hotplugging
-	 * binding policy can be driven from user mode too
-	 */
 	const struct usb_device_id *id_table;
-
-	/* suspend before the bus suspends;
-	 * disconnect or resume when the bus resumes */
-	// void (*suspend)(struct usb_device *dev);
-	// void (*resume)(struct usb_device *dev);
 };
 	
 /*----------------------------------------------------------------------------* 
diff -urN linux-2.4.20-pre7/init/do_mounts.c linux-2.4.20-pre8/init/do_mounts.c
--- linux-2.4.20-pre7/init/do_mounts.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/init/do_mounts.c	Wed Sep 25 18:22:08 2002
@@ -181,6 +181,13 @@
 	{ "ida/c0d13p",0x48D0 },
 	{ "ida/c0d14p",0x48E0 },
 	{ "ida/c0d15p",0x48F0 },
+	{ "ida/c1d0p",0x4900 },
+	{ "ida/c2d0p",0x4A00 },
+	{ "ida/c3d0p",0x4B00 },
+	{ "ida/c4d0p",0x4C00 },
+	{ "ida/c5d0p",0x4D00 },
+	{ "ida/c6d0p",0x4E00 },
+	{ "ida/c7d0p",0x4F00 }, 
 #endif
 #if defined(CONFIG_BLK_CPQ_CISS_DA) || defined(CONFIG_BLK_CPQ_CISS_DA_MODULE)
 	{ "cciss/c0d0p",0x6800 },
@@ -199,6 +206,13 @@
 	{ "cciss/c0d13p",0x68D0 },
 	{ "cciss/c0d14p",0x68E0 },
 	{ "cciss/c0d15p",0x68F0 },
+	{ "cciss/c1d0p",0x6900 },
+	{ "cciss/c2d0p",0x6A00 },
+	{ "cciss/c3d0p",0x6B00 },
+	{ "cciss/c4d0p",0x6C00 },
+	{ "cciss/c5d0p",0x6D00 },
+	{ "cciss/c6d0p",0x6E00 },
+	{ "cciss/c7d0p",0x6F00 },
 #endif
 	{ "ataraid/d0p",0x7200 },
 	{ "ataraid/d1p",0x7210 },
diff -urN linux-2.4.20-pre7/kernel/ksyms.c linux-2.4.20-pre8/kernel/ksyms.c
--- linux-2.4.20-pre7/kernel/ksyms.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/kernel/ksyms.c	Wed Sep 25 18:22:08 2002
@@ -47,6 +47,7 @@
 #include <linux/in6.h>
 #include <linux/completion.h>
 #include <linux/seq_file.h>
+#include <linux/dnotify.h>
 #include <asm/checksum.h>
 
 #if defined(CONFIG_PROC_FS)
@@ -531,6 +532,7 @@
 EXPORT_SYMBOL(is_bad_inode);
 EXPORT_SYMBOL(event);
 EXPORT_SYMBOL(brw_page);
+EXPORT_SYMBOL(__inode_dir_notify);
 
 #ifdef CONFIG_UID16
 EXPORT_SYMBOL(overflowuid);
diff -urN linux-2.4.20-pre7/kernel/panic.c linux-2.4.20-pre8/kernel/panic.c
--- linux-2.4.20-pre7/kernel/panic.c	Fri Aug  2 17:39:46 2002
+++ linux-2.4.20-pre8/kernel/panic.c	Wed Sep 25 18:22:08 2002
@@ -96,7 +96,7 @@
 #endif
 	sti();
 	for(;;) {
-#if defined(__i386__) && defined(CONFIG_VT) 
+#if defined(CONFIG_X86) && defined(CONFIG_VT) 
 		extern void panic_blink(void);
 		panic_blink(); 
 #endif
diff -urN linux-2.4.20-pre7/kernel/resource.c linux-2.4.20-pre8/kernel/resource.c
--- linux-2.4.20-pre7/kernel/resource.c	Mon May 21 18:10:36 2001
+++ linux-2.4.20-pre8/kernel/resource.c	Wed Sep 25 18:22:08 2002
@@ -152,7 +152,8 @@
 			 unsigned long size,
 			 unsigned long min, unsigned long max,
 			 unsigned long align,
-			 void (*alignf)(void *, struct resource *, unsigned long),
+			 void (*alignf)(void *, struct resource *,
+					unsigned long, unsigned long),
 			 void *alignf_data)
 {
 	struct resource *this = root->child;
@@ -169,7 +170,7 @@
 			new->end = max;
 		new->start = (new->start + align - 1) & ~(align - 1);
 		if (alignf)
-			alignf(alignf_data, new, size);
+			alignf(alignf_data, new, size, align);
 		if (new->start < new->end && new->end - new->start + 1 >= size) {
 			new->end = new->start + size - 1;
 			return 0;
@@ -189,7 +190,8 @@
 		      unsigned long size,
 		      unsigned long min, unsigned long max,
 		      unsigned long align,
-		      void (*alignf)(void *, struct resource *, unsigned long),
+		      void (*alignf)(void *, struct resource *,
+				     unsigned long, unsigned long),
 		      void *alignf_data)
 {
 	int err;
diff -urN linux-2.4.20-pre7/mm/shmem.c linux-2.4.20-pre8/mm/shmem.c
--- linux-2.4.20-pre7/mm/shmem.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/mm/shmem.c	Wed Sep 25 18:22:08 2002
@@ -34,6 +34,14 @@
 #define TMPFS_MAGIC	0x01021994
 
 #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
+#define BLOCKS_PER_PAGE  (PAGE_CACHE_SIZE/512)
+
+#define SHMEM_MAX_INDEX  (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE * (ENTRIES_PER_PAGE/2) * (ENTRIES_PER_PAGE+1))
+#define SHMEM_MAX_BYTES  ((unsigned long long)SHMEM_MAX_INDEX << PAGE_CACHE_SHIFT)
+#define VM_ACCT(size)    (((size) + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT)
+
+/* Pretend that each entry is of this size in directory's i_size */
+#define BOGO_DIRENT_SIZE 20
 
 #define SHMEM_SB(sb) (&sb->u.shmem_sb)
 
@@ -50,8 +58,6 @@
 
 static struct page *shmem_getpage_locked(struct shmem_inode_info *, struct inode *, unsigned long);
 
-#define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
-
 /*
  * shmem_recalc_inode - recalculate the size of an inode
  *
@@ -127,9 +133,6 @@
  * 	      	       +-> 48-51
  * 	      	       +-> 52-55
  */
-
-#define SHMEM_MAX_BLOCKS (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE * ENTRIES_PER_PAGE/2*(ENTRIES_PER_PAGE+1))
-
 static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned long index, unsigned long page) 
 {
 	unsigned long offset;
@@ -182,7 +185,7 @@
 	unsigned long page = 0;
 	swp_entry_t * res;
 
-	if (index >= SHMEM_MAX_BLOCKS)
+	if (index >= SHMEM_MAX_INDEX)
 		return ERR_PTR(-EFBIG);
 
 	if (info->next_index <= index)
@@ -358,11 +361,11 @@
 {
 	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 
-	inode->i_size = 0;
-	if (inode->i_op->truncate == shmem_truncate){ 
+	if (inode->i_op->truncate == shmem_truncate) {
 		spin_lock (&shmem_ilock);
 		list_del (&SHMEM_I(inode)->list);
 		spin_unlock (&shmem_ilock);
+		inode->i_size = 0;
 		shmem_truncate (inode);
 	}
 	spin_lock (&sbinfo->stat_lock);
@@ -557,7 +560,7 @@
 		unsigned long flags;
 
 		/* Look it up and read it in.. */
-		page = find_get_page(&swapper_space, entry->val);
+		page = lookup_swap_cache(*entry);
 		if (!page) {
 			swp_entry_t swap = *entry;
 			spin_unlock (&info->lock);
@@ -731,13 +734,13 @@
 			inode->i_op = &shmem_inode_operations;
 			inode->i_fop = &shmem_file_operations;
 			spin_lock (&shmem_ilock);
-			list_add_tail(&SHMEM_I(inode)->list, &shmem_inodes);
+			list_add_tail(&info->list, &shmem_inodes);
 			spin_unlock (&shmem_ilock);
 			break;
 		case S_IFDIR:
 			inode->i_nlink++;
 			/* Some things misbehave if size == 0 on a directory */
-			inode->i_size = 1;
+			inode->i_size = 2 * BOGO_DIRENT_SIZE;
 			inode->i_op = &shmem_dir_inode_operations;
 			inode->i_fop = &dcache_dir_ops;
 			break;
@@ -1001,7 +1004,7 @@
 	buf->f_files = sbinfo->max_inodes;
 	buf->f_ffree = sbinfo->free_inodes;
 	spin_unlock (&sbinfo->stat_lock);
-	buf->f_namelen = 255;
+	buf->f_namelen = NAME_MAX;
 	return 0;
 }
 
@@ -1024,6 +1027,7 @@
 	int error = -ENOSPC;
 
 	if (inode) {
+		dir->i_size += BOGO_DIRENT_SIZE;
 		dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 		d_instantiate(dentry, inode);
 		dget(dentry); /* Extra count - pin the dentry in core */
@@ -1057,6 +1061,7 @@
 	if (S_ISDIR(inode->i_mode))
 		return -EPERM;
 
+	dir->i_size += BOGO_DIRENT_SIZE;
 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	inode->i_nlink++;
 	atomic_inc(&inode->i_count);	/* New dentry reference */
@@ -1101,6 +1106,8 @@
 static int shmem_unlink(struct inode * dir, struct dentry *dentry)
 {
 	struct inode *inode = dentry->d_inode;
+
+	dir->i_size -= BOGO_DIRENT_SIZE;
 	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
 	inode->i_nlink--;
 	dput(dentry);	/* Undo the count from "create" - this does all the work */
@@ -1124,65 +1131,63 @@
  */
 static int shmem_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
 {
-	struct inode *inode;
+	struct inode *inode = old_dentry->d_inode;
+	int they_are_dirs = S_ISDIR(inode->i_mode);
 
 	if (!shmem_empty(new_dentry)) 
 		return -ENOTEMPTY;
 
-	inode = new_dentry->d_inode;
-	if (inode) {
-		inode->i_ctime = CURRENT_TIME;
-		inode->i_nlink--;
-		dput(new_dentry);
-	}
-	inode = old_dentry->d_inode;
-	if (S_ISDIR(inode->i_mode)) {
+	if (new_dentry->d_inode) {
+		(void) shmem_unlink(new_dir, new_dentry);
+		if (they_are_dirs)
+			old_dir->i_nlink--;
+	} else if (they_are_dirs) {
 		old_dir->i_nlink--;
 		new_dir->i_nlink++;
 	}
 
-	inode->i_ctime = old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_size -= BOGO_DIRENT_SIZE;
+	new_dir->i_size += BOGO_DIRENT_SIZE;
+	old_dir->i_ctime = old_dir->i_mtime =
+	new_dir->i_ctime = new_dir->i_mtime =
+	inode->i_ctime = CURRENT_TIME;
 	return 0;
 }
 
 static int shmem_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
 {
-	int error;
 	int len;
 	struct inode *inode;
 	struct page *page;
 	char *kaddr;
 	struct shmem_inode_info * info;
 
-	error = shmem_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0);
-	if (error)
-		return error;
-
 	len = strlen(symname) + 1;
-	inode = dentry->d_inode;
+	if (len > PAGE_CACHE_SIZE)
+		return -ENAMETOOLONG;
+
+	inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
+	if (!inode)
+		return -ENOSPC;
+
 	info = SHMEM_I(inode);
 	inode->i_size = len-1;
-	inode->i_op = &shmem_symlink_inline_operations;
-
 	if (len <= sizeof(struct shmem_inode_info)) {
 		/* do it inline */
 		memcpy(info, symname, len);
+		inode->i_op = &shmem_symlink_inline_operations;
 	} else {
-		if (len > PAGE_CACHE_SIZE) {
-			error = -ENAMETOOLONG;
-			goto rmnod;
-		}
-		inode->i_op = &shmem_symlink_inode_operations;
-		spin_lock (&shmem_ilock);
-		list_add_tail(&info->list, &shmem_inodes);
-		spin_unlock (&shmem_ilock);
 		down(&info->sem);
 		page = shmem_getpage_locked(info, inode, 0);
 		if (IS_ERR(page)) {
 			up(&info->sem);
-			error = PTR_ERR(page);
-			goto rmnod;
+			iput(inode);
+			return PTR_ERR(page);
 		}
+		inode->i_op = &shmem_symlink_inode_operations;
+		spin_lock (&shmem_ilock);
+		list_add_tail(&info->list, &shmem_inodes);
+		spin_unlock (&shmem_ilock);
 		kaddr = kmap(page);
 		memcpy(kaddr, symname, len);
 		kunmap(page);
@@ -1191,13 +1196,11 @@
 		page_cache_release(page);
 		up(&info->sem);
 	}
+	dir->i_size += BOGO_DIRENT_SIZE;
 	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	d_instantiate(dentry, inode);
+	dget(dentry);
 	return 0;
-
-rmnod:
-	if (!shmem_unlink(dir, dentry))
-		d_delete(dentry);
-	return error;
 }
 
 static int shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)
@@ -1357,7 +1360,7 @@
 	sbinfo->free_blocks = blocks;
 	sbinfo->max_inodes = inodes;
 	sbinfo->free_inodes = inodes;
-	sb->s_maxbytes = (unsigned long long) SHMEM_MAX_BLOCKS << PAGE_CACHE_SHIFT;
+	sb->s_maxbytes = SHMEM_MAX_BYTES;
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = TMPFS_MAGIC;
@@ -1491,10 +1494,10 @@
 	struct qstr this;
 	int vm_enough_memory(long pages);
 
-	if (size > (unsigned long long) SHMEM_MAX_BLOCKS << PAGE_CACHE_SHIFT)
+	if (size > SHMEM_MAX_BYTES)
 		return ERR_PTR(-EINVAL);
 
-	if (!vm_enough_memory((size) >> PAGE_CACHE_SHIFT))
+	if (!vm_enough_memory(VM_ACCT(size)))
 		return ERR_PTR(-ENOMEM);
 
 	this.name = name;
@@ -1516,13 +1519,12 @@
 		goto close_file;
 
 	d_instantiate(dentry, inode);
-	dentry->d_inode->i_size = size;
-	shmem_truncate(inode);
+	inode->i_size = size;
+	inode->i_nlink = 0;	/* It is unlinked */
 	file->f_vfsmnt = mntget(shm_mnt);
 	file->f_dentry = dentry;
 	file->f_op = &shmem_file_operations;
 	file->f_mode = FMODE_WRITE | FMODE_READ;
-	inode->i_nlink = 0;	/* It is unlinked */
 	return(file);
 
 close_file:
@@ -1531,6 +1533,7 @@
 	dput (dentry);
 	return ERR_PTR(error);	
 }
+
 /*
  * shmem_zero_setup - setup a shared anonymous mapping
  *
diff -urN linux-2.4.20-pre7/mm/vmalloc.c linux-2.4.20-pre8/mm/vmalloc.c
--- linux-2.4.20-pre7/mm/vmalloc.c	Mon Feb 25 11:38:14 2002
+++ linux-2.4.20-pre8/mm/vmalloc.c	Wed Sep 25 18:22:08 2002
@@ -177,6 +177,8 @@
 	if (!area)
 		return NULL;
 	size += PAGE_SIZE;
+	if(!size)
+		return NULL;
 	addr = VMALLOC_START;
 	write_lock(&vmlist_lock);
 	for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
diff -urN linux-2.4.20-pre7/net/8021q/vlan.c linux-2.4.20-pre8/net/8021q/vlan.c
--- linux-2.4.20-pre7/net/8021q/vlan.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/net/8021q/vlan.c	Wed Sep 25 18:22:08 2002
@@ -626,7 +626,7 @@
 			ret = unregister_vlan_dev(dev,
 						  VLAN_DEV_INFO(vlandev)->vlan_id);
 
-			unregister_netdev(vlandev);
+			unregister_netdevice(vlandev);
 
 			/* Group was destroyed? */
 			if (ret == 1)
diff -urN linux-2.4.20-pre7/net/core/dev.c linux-2.4.20-pre8/net/core/dev.c
--- linux-2.4.20-pre7/net/core/dev.c	Wed Sep 25 18:21:10 2002
+++ linux-2.4.20-pre8/net/core/dev.c	Wed Sep 25 18:22:08 2002
@@ -700,10 +700,14 @@
 	 *	Call device private open method
 	 */
 	if (try_inc_mod_count(dev->owner)) {
+		set_bit(__LINK_STATE_START, &dev->state);
 		if (dev->open) {
 			ret = dev->open(dev);
-			if (ret != 0 && dev->owner)
-				__MOD_DEC_USE_COUNT(dev->owner);
+			if (ret != 0) {
+				clear_bit(__LINK_STATE_START, &dev->state);
+				if (dev->owner)
+					__MOD_DEC_USE_COUNT(dev->owner);
+			}
 		}
 	} else {
 		ret = -ENODEV;
@@ -720,8 +724,6 @@
 		 */
 		dev->flags |= IFF_UP;
 
-		set_bit(__LINK_STATE_START, &dev->state);
-
 		/*
 		 *	Initialize multicasting status 
 		 */
diff -urN linux-2.4.20-pre7/net/ipv4/ip_options.c linux-2.4.20-pre8/net/ipv4/ip_options.c
--- linux-2.4.20-pre7/net/ipv4/ip_options.c	Fri Sep  7 11:01:21 2001
+++ linux-2.4.20-pre8/net/ipv4/ip_options.c	Wed Sep 25 18:22:09 2002
@@ -266,7 +266,7 @@
 	for (l = opt->optlen; l > 0; ) {
 		switch (*optptr) {
 		      case IPOPT_END:
-			for (optptr++, l--; l>0; l--) {
+			for (optptr++, l--; l>0; optptr++, l--) {
 				if (*optptr != IPOPT_END) {
 					*optptr = IPOPT_END;
 					opt->is_changed = 1;
