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

diff -urN linux-2.4.22-bk25/Documentation/Configure.help linux-2.4.22-bk26/Documentation/Configure.help
--- linux-2.4.22-bk25/Documentation/Configure.help	2003-09-29 02:49:35.000000000 -0700
+++ linux-2.4.22-bk26/Documentation/Configure.help	2003-09-29 02:49:40.000000000 -0700
@@ -4006,7 +4006,7 @@
 
 CONFIG_AGP_AMD_8151
   This option gives you AGP support for the GLX component of
-  XFree86 on AMD K8 with an AGP 8151 chipset.
+  XFree86 on an AMD Opteron/Athlon64 using the on-CPU GART.
 
   You should say Y here if you use XFree86 3.3.6 or 4.x and want to
   use GLX or DRI.  If unsure, say N.
@@ -11646,49 +11646,58 @@
   Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
   compliant Gigabit Ethernet Adapter. The following adapters are supported
   by this driver:
-  - 3Com 3C940 Gigabit LOM Ethernet Adapter
-  - 3Com 3C941 Gigabit LOM Ethernet Adapter
-  - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
-  - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
-  - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
-  - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
-  - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
-  - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
-  - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
-  - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
-  - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
-  - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
-  - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
-  - Marvell RDK-8001 Adapter
-  - Marvell RDK-8002 Adapter
-  - Marvell RDK-8003 Adapter
-  - Marvell RDK-8004 Adapter
-  - Marvell RDK-8006 Adapter
-  - Marvell RDK-8007 Adapter
-  - Marvell RDK-8008 Adapter
-  - Marvell RDK-8009 Adapter
-  - Marvell RDK-8011 Adapter
-  - Marvell RDK-8012 Adapter
-  - SK-9521 V2.0 10/100/1000Base-T Adapter
-  - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
-  - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
-  - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-  - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-  - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-  - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
-  - SK-9521 10/100/1000Base-T Adapter
-  - DGE-530T Gigabit Ethernet Adapter
-  - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter
-  - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
-  - EG1032 v2 Instant Gigabit Network Adapter
-  - EG1064 v2 Instant Gigabit Network Adapter
+	    - 3Com 3C940 Gigabit LOM Ethernet Adapter
+	    - 3Com 3C941 Gigabit LOM Ethernet Adapter
+	    - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
+	    - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
+	    - DGE-530T Gigabit Ethernet Adapter
+	    - EG1032 v2 Instant Gigabit Network Adapter
+	    - EG1064 v2 Instant Gigabit Network Adapter
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
+	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
+	    - Marvell RDK-8001 Adapter
+	    - Marvell RDK-8002 Adapter
+	    - Marvell RDK-8003 Adapter
+	    - Marvell RDK-8004 Adapter
+	    - Marvell RDK-8006 Adapter
+	    - Marvell RDK-8007 Adapter
+	    - Marvell RDK-8008 Adapter
+	    - Marvell RDK-8009 Adapter
+	    - Marvell RDK-8010 Adapter
+	    - Marvell RDK-8011 Adapter
+	    - Marvell RDK-8012 Adapter
+	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
+	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
+	    - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
+	    - SK-9521 10/100/1000Base-T Adapter
+	    - SK-9521 V2.0 10/100/1000Base-T Adapter
+	    - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
+	    - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
+	    - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
+	    - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
+	    - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
+	    - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
+	    - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
+	    - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+	    - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
+	    - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+	    - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
+	    - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
+	    - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
+	    - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
+	    - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
+	    - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
+	    - SMC EZ Card 1000 (SMC9452TXV.2)
 
   The adapters support Jumbo Frames.
   The dual link adapters support link-failover and dual port features.
@@ -11704,121 +11713,6 @@
   say M here and read Documentation/modules.txt. This is recommended.
   The module will be called sk98lin.o.
 
-Marvell Yukon Chipset
-CONFIG_SK98LIN_T1
-  This driver supports:
-
-  - 3Com 3C940 Gigabit LOM Ethernet Adapter
-  - 3Com 3C941 Gigabit LOM Ethernet Adapter
-
-  Questions concerning this driver may be addressed to:
-    linux@syskonnect.de
-
-SysKonnect SK98xx Support
-CONFIG_SK98LIN_T2
-  This driver supports:
-
-  - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
-  - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
-  - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
-  - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
-  - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
-  - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
-  - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
-  - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
-  - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
-  - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
-
-  Questions concerning this driver may be addressed to:
-    linux@syskonnect.de
-
-SysKonnect SK98xx Support
-CONFIG_SK98LIN_T3
-  This driver supports:
-
-  - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
-  - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
-
-  Questions concerning this driver may be addressed to:
-    linux@syskonnect.de
-
-Marvell Yukon Chipset
-CONFIG_SK98LIN_T4
-  This driver supports:
-
-  - Marvell RDK-8001 Adapter
-  - Marvell RDK-8002 Adapter
-  - Marvell RDK-8003 Adapter
-  - Marvell RDK-8004 Adapter
-  - Marvell RDK-8006 Adapter
-  - Marvell RDK-8007 Adapter
-  - Marvell RDK-8008 Adapter
-  - Marvell RDK-8009 Adapter
-  - Marvell RDK-8011 Adapter
-  - Marvell RDK-8012 Adapter
-
-  Questions concerning this driver may be addressed to:
-    linux@syskonnect.de
-
-Marvell Yukon Chipset
-CONFIG_SK98LIN_T5
-  This driver supports:
-
-  - SK-9521 V2.0 10/100/1000Base-T Adapter
-  - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
-  - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
-  - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-  - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-  - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-  - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
-  - SK-9521 10/100/1000Base-T Adapter
-
-  Questions concerning this driver may be addressed to:
-    linux@syskonnect.de
-
-Marvell Yukon Chipset
-CONFIG_SK98LIN_T6
-  This driver supports:
-
-  - DGE-530T Gigabit Ethernet Adapter
-
-  Questions concerning this driver may be addressed to:
-    linux@syskonnect.de
-
-Marvell Yukon Chipset
-CONFIG_SK98LIN_T7
-  This driver supports:
-
-  - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter
-
-  Questions concerning this driver may be addressed to:
-    linux@syskonnect.de
-
-Marvell Yukon Chipset
-CONFIG_SK98LIN_T8
-  This driver supports:
-
-  - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
-
-  Questions concerning this driver may be addressed to:
-    linux@syskonnect.de
-
-Marvell Yukon Chipset
-CONFIG_SK98LIN_T9
-  This driver supports:
-
-  - EG1032 v2 Instant Gigabit Network Adapter
-  - EG1064 v2 Instant Gigabit Network Adapter
-
-  Questions concerning this driver may be addressed to:
-    linux@syskonnect.de
-
 
 Sun GEM support
 CONFIG_SUNGEM
diff -urN linux-2.4.22-bk25/Documentation/cciss.txt linux-2.4.22-bk26/Documentation/cciss.txt
--- linux-2.4.22-bk25/Documentation/cciss.txt	2003-09-29 02:49:35.000000000 -0700
+++ linux-2.4.22-bk26/Documentation/cciss.txt	2003-09-29 02:49:40.000000000 -0700
@@ -53,6 +53,56 @@
 /dev/cciss/c1d1p2		Controller 1, disk 1, partition 2
 /dev/cciss/c1d1p3		Controller 1, disk 1, partition 3
 
+Support for more than 8 controllers
+-----------------------------------
+Originally the driver only supports 8 controllers in the system,
+and this is due to the major numbers assigned to the driver
+(104 thru 111).
+
+The driver can now support up to 32 controllers in the system.
+
+For the ninth controller and beyond, the major numbers will be
+assigned dynamically by the kernel when it is discovered,
+and there is no guarantee what the major number you will get,
+but most likely it will start from 254 and goes down from there.
+
+You can check the assigned major numbers by typing
+	cat /proc/devices
+And look for cciss controllers
+
+Once you have this, you need to create device nodes in
+/dev/cciss directory. The nodes for the first 8 controllers
+should already be created by mkdev.cciss script or
+/etc/makedev.d/cciss script. You can add the major number(s)
+in those scripts, or create the nodes manually by using
+the mknod command.
+
+You can also use mknod_dyn.cciss and rmnod_dyn.cciss scripts
+to create or remove nodes easily. These scripts can be found
+in the Documentation directory.
+
+Then you can mount the devices and create partitions
+(You also need to make nodes for these partitions).
+
+As for the minor number, the disk device will have a minor
+number divisible by 16 (e.g: 0, 16, 32 etc), and the 
+partitions on those disk devices will have the minor number
+of the disk device plus the partition number (1-15).
+For example, disk d2 will have minor number 32, and its
+partitions 1 and 2 will have minor numbers 33 and 34.
+
+Look at the mkdev.cciss script for example.
+ 
+Note:
+ In 2.4 kernel, partition names are hard coded in
+ /usr/src/linux/fs/partitions/check.c
+ and only for the first 8 cciss controllers. The rest
+ will be reported as ccissXX. This should not affect 
+ I/O operation or performance. Please apply the 
+ cciss_2.4_partition_name.patch to address this. This 
+ will not be an issue under 2.5 kernel, since partition
+ names will be handled by the driver.
+
 SCSI tape drive and medium changer support
 ------------------------------------------
 
diff -urN linux-2.4.22-bk25/Documentation/mkdev_dyn.cciss linux-2.4.22-bk26/Documentation/mkdev_dyn.cciss
--- linux-2.4.22-bk25/Documentation/mkdev_dyn.cciss	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-bk26/Documentation/mkdev_dyn.cciss	2003-09-29 02:49:40.000000000 -0700
@@ -0,0 +1,171 @@
+#!/bin/sh
+#
+# Author: Francis Wiran <Francis.Wiran@hp.com>
+#
+# Script to create device nodes for SMART Array controllers, idea from
+# mkdev.cciss found in Documentation. The argument syntax is different,
+# hence, the name change.
+#
+# Usage:
+# 	mkdev_dyn.cciss [ctlr num] [major num] [num log vol] [num partitions]
+#
+# With no arguments, the script will check to see if there are any cciss
+# nodes already created in the /dev directory. If so, then it will assume
+# that the nodes for the first 8 controllers are already created by
+# /etc/makedev.d, which is likely. If not, then the script will create 
+# them, using the major numbers reserved for cciss controllers (104 thru 111).
+#
+# After that, it will start creating nodes for the controllers which major
+# numbers are dynamically allocated by the kernel. It will check 
+# /proc/devices for any cciss controllers with major numbers other than
+# 104 thru 111 and creates the nodes.
+#
+# Note that it is a good idea to run rmdev_dyn.cciss script if you remove
+# those controllers (the ones which major numbers were dynamically allocated)
+# This will unclutter /dev, as well as preventing possible problems due to 
+# referenced devices and major numbers no longer available or taken by
+# other non-cciss drivers.
+#
+# With no arguments, the script assumes 16 logical volumes per controller
+# and 16 partitions per volume; 
+#
+# Passing arguments:
+# If you know that one of your controllers, say cciss8, has been dynamically 
+# assigned major number 254, and were planning on no more than 2 logical 
+# volumes, using a maximum of 4 partitions per volume, you could do:
+#
+# mkdev_dyn.cciss 8 254 2 4
+#
+# Of course, this has no real benefit over "mkdev_dyn.cciss 8 254" except 
+# that it doesn't create as many device nodes in /dev/cciss.
+#
+
+# Inputs
+NR_CTLR=${1-8}
+NR_MAJOR=${2-254}
+NR_VOL=${3-16}
+NR_PART=${4-16}
+
+echo_usage()
+{
+	echo "Usage: mkdev_dyn.cciss [ctlr num] [maj] [volumes] [partitions]"
+	echo "The script assumes that ctlr 0 thru 7 is statically created"
+	echo "Therefore, if you want to pass arguments make sure that"
+	echo "ctlr num is equal or greater than 8, and the major number"
+	echo "is not one that's statically assigned for cciss controller."
+	echo "Check the correct major number in /proc/devices"
+
+	# Hmm... we don't support volumes and partitions greater than 16
+	# either.
+}
+
+echo_create()
+{
+	echo "created /dev/cciss/c${1}* nodes using major number ${2}"
+}
+
+
+# Function: do_mknod()
+#           Creates devices nodes under /dev/cciss
+# Inputs: $1 - ctlr number
+#	  $2 - major number
+#	  $3 - number of devices on controller
+#	  $4 - number of partitions per device
+do_mknod()
+{
+	D=0;
+	while [ $D -lt $3 ]; do
+		P=0;
+		while [ $P -lt $4 ]; do
+			MIN=`expr $D \* 16 + $P`;
+			if [ $P -eq 0 ]; then
+				mknod /dev/cciss/c${1}d${D} b $2 $MIN
+			else
+				mknod /dev/cciss/c${1}d${D}p${P} b $2 $MIN
+			fi
+			P=`expr $P + 1`;
+		done
+		D=`expr $D + 1`;
+	done
+}
+
+# Function: do_dyn
+#           Search and create cciss nodes for the controllers which
+#           major numbers are allocated dynamically by the kernel
+#           instead of using kernel.org 's value of 104 to 111.
+#
+# Input: $1 - ctlr num - will create nodes /dev/cciss/c${1}
+#	 $2 - major num - the major number to assign to the nodes
+#	 $3 - volumes - max number of volumes per controller
+#	 $4 - partitions - max number of partitions per volume
+#
+# Note: Without input, this function will start creating nodes
+#       for controller c8 and above, making assumption that 
+#       c0 thru c7 are already made, and the name c8 and above 
+#       are not already taken.
+do_dyn()
+{
+	if [ $# -eq 0 ]; then
+		C=0;
+		for MAJ in `cat /proc/devices |\
+			grep cciss |\
+			awk '/cciss[0-9]$/ { sub("cciss", "cciss0") }; {print}' |\
+			sort -k 2,2 |\
+			awk '{print $1-i}'`;
+		do
+			if [ `ls -l /dev/cciss/c* |\
+				awk '{print $5-i}' |\
+				uniq |\
+				grep $MAJ |\
+				wc -l` -gt 0 ]; then
+				:
+			else
+				do_mknod $C $MAJ $NR_VOL $NR_PART;
+				echo_create $C $MAJ;
+			fi
+			C=`expr $C + 1`;
+		done
+	else
+		do_mknod $1 $2 $3 $4;
+		echo_create $1 $2;
+	fi
+	
+	exit
+}
+
+# Start here
+
+# Check the input values
+if [ $NR_CTLR -lt 8 ]; then
+	echo_usage;
+	exit
+fi
+
+if [ $NR_CTLR -ge 8 ]; then
+	if [ \( $NR_MAJOR -ge 104 \) -a \( $NR_MAJOR -le 111 \) ]; then
+		echo_usage;
+		exit
+	fi
+fi
+
+if [ ! -d /dev/cciss ]; then
+        mkdir -p /dev/cciss
+fi
+
+# Assume that if c0d0p1 node already exist, then all nodes from c0d0p1
+# to c7d15p15 have been created for us.
+if [ ! -b /dev/cciss/c0d0p1 ]; then
+	C=0; 
+	while [ $C -lt 8 ]; do
+		MAJ=`expr $C + 104`;
+		do_mknod $C $MAJ $NR_VOL $NR_PART;
+		echo_create $C $MAJ;
+		C=`expr $C + 1`;
+	done
+fi
+
+if [ $# -gt 0 ]; then
+	do_dyn $NR_CTLR $NR_MAJOR $NR_VOL $NR_PART;
+else
+	do_dyn;
+fi
diff -urN linux-2.4.22-bk25/Documentation/networking/sk98lin.txt linux-2.4.22-bk26/Documentation/networking/sk98lin.txt
--- linux-2.4.22-bk25/Documentation/networking/sk98lin.txt	2003-09-29 02:49:35.000000000 -0700
+++ linux-2.4.22-bk26/Documentation/networking/sk98lin.txt	2003-09-29 02:49:40.000000000 -0700
@@ -2,9 +2,9 @@
 All rights reserved
 ===========================================================================
 
-sk98lin.txt created 26-Aug-2003
+sk98lin.txt created 23-Sep-2003
 
-Readme File for sk98lin v6.17
+Readme File for sk98lin v6.18
 Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
 
 This file contains
diff -urN linux-2.4.22-bk25/Documentation/rmdev_dyn.cciss linux-2.4.22-bk26/Documentation/rmdev_dyn.cciss
--- linux-2.4.22-bk25/Documentation/rmdev_dyn.cciss	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-bk26/Documentation/rmdev_dyn.cciss	2003-09-29 02:49:40.000000000 -0700
@@ -0,0 +1,87 @@
+#!/bin/sh 
+#
+# Author: Francis Wiran <Francis.Wiran@hp.com>
+#
+# Script to remove device nodes for SMART Array controllers. This will
+# be the device nodes with major numbers which are dynamically allocated
+# by the kernel. This script will not attempt to remove the device
+# nodes with major number 104 thru 111 (c0 thru c7), which are 
+# the major numbers that's allocated for cciss controllers by kernel.org.
+#
+# Usage:
+# rmdev_dyn.cciss [ctlr num]
+#
+# With no arguments, the script will check to see if there are any nodes
+# under /dev/cciss, whose major number no longer shows in /proc/partitions,
+# or to be exact, no longer shows to be owned by cciss driver.
+# If there is, then it will be removed.
+#
+# Note that it is a good idea to run rmdev_dyn.cciss script if you remove
+# those controllers (the ones which major numbers were dynamically allocated)
+# This will unclutter /dev, as well as preventing possible problems due to
+# referenced devices and major numbers no longer available or taken by
+# other non-cciss drivers.
+#
+# Passing arguments:
+# If you know that one of your controllers, say cciss8, has been removed
+# and the nodes are no longer valid, you could do
+#
+# rmdev_dyn.cciss 8 
+#
+# This is the same as doing `rm -f /dev/cciss/c8*` 
+
+# Inputs
+NR_CTLR=${1}
+
+echo_usage()
+{
+	echo "Usage: rmdev_dyn.cciss [ctlr num]"
+	echo "The script will not attempt to remove nodes for controllers"
+	echo "0 thru 7, therefore if you want to pass an argument,"
+	echo "make sure that ctlr num is equal or greater than 8"
+}
+
+rm_nod1()
+{
+	if [ $1 -lt 8 ]; then
+		echo_usage;
+		exit
+	else
+		rm -f /dev/cciss/c${1}*
+		echo "removed /dev/cciss/c${1}*"
+	fi
+}
+
+rm_nod2()
+{
+	for X in `ls -l /dev/cciss/c* |\
+		awk '{print $5-i}' |\
+		uniq`; do
+		if [ \( $X -ge 104 \) -a \( $X -le 111 \) ]; then
+			:
+		elif [ `cat /proc/devices |\
+			grep cciss |\
+			grep $X |\
+			wc -l` -eq 0 ]; then
+
+			Y=`ls -l /dev/cciss/ |\
+				awk '{print $5-i ":"  $10}'|\
+				tr d ':' |\
+				grep $X |\
+				awk -F: '{print $2}' |\
+				uniq`
+
+			Z="/dev/cciss/${Y}*"
+
+			rm -f $Z
+			echo "removed $Z"
+		fi
+	done
+}
+
+# Start here
+if [ $# -gt 0 ]; then
+	rm_nod1 $NR_CTLR;
+else
+	rm_nod2;
+fi
diff -urN linux-2.4.22-bk25/Documentation/x86_64/boot-options.txt linux-2.4.22-bk26/Documentation/x86_64/boot-options.txt
--- linux-2.4.22-bk25/Documentation/x86_64/boot-options.txt	2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.22-bk26/Documentation/x86_64/boot-options.txt	2003-09-29 02:49:40.000000000 -0700
@@ -65,13 +65,14 @@
   0 don't use an NMI watchdog
   1 use the IO-APIC timer for the NMI watchdog
   2 use the local APIC for the NMI watchdog using a performance counter. Note
-  This will use one performance counter.
+  This will use one performance counter and the local APIC's performance
+  counter vector.
 
 Idle loop
 
   idle=poll
   Don't do power saving in the idle loop using HLT, but poll for rescheduling 
-  event. This will make the CPUs eat a lot more power, but may be useful 
+  events. This will make the CPUs burn a lot more power, but may be useful 
   to get slightly better performance in multiprocessor benchmarks. It also
   makes some profiling using performance counters more accurate.
 
@@ -145,7 +146,7 @@
    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.
-   noforce don't force IOMMU usage. Should be fastest.
-   force  Force IOMMU and turn on unmap debugging.  
+   noforce don't force IOMMU usage. Default.
+   force  Force IOMMU for all devices.
 
 
diff -urN linux-2.4.22-bk25/Makefile linux-2.4.22-bk26/Makefile
--- linux-2.4.22-bk25/Makefile	2003-09-29 02:49:35.000000000 -0700
+++ linux-2.4.22-bk26/Makefile	2003-09-29 02:49:40.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 22
-EXTRAVERSION = -bk25
+EXTRAVERSION = -bk26
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.22-bk25/arch/ppc/8xx_io/Config.in linux-2.4.22-bk26/arch/ppc/8xx_io/Config.in
--- linux-2.4.22-bk25/arch/ppc/8xx_io/Config.in	2001-10-15 13:35:26.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/8xx_io/Config.in	2003-09-29 02:49:40.000000000 -0700
@@ -2,8 +2,14 @@
 # MPC8xx Communication options
 #
 mainmenu_option next_comment
-comment 'MPC8xx CPM Options'
+comment 'MPC8xx Options'
 
+comment 'Generic MPC8xx Options'
+bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK
+bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6
+bool 'I2C/SPI Microcode Patch' CONFIG_UCODE_PATCH
+
+comment 'MPC8xx CPM Options'
 if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
   bool 'CPM SCC Ethernet' CONFIG_SCC_ENET
   if [ "$CONFIG_SCC_ENET" = "y" ]; then
@@ -12,25 +18,28 @@
 	 SCC2	CONFIG_SCC2_ENET	\
 	 SCC3	CONFIG_SCC3_ENET"	SCC1
   fi
-  bool '860T FEC Ethernet' CONFIG_FEC_ENET
+  bool '8xxT FEC Ethernet' CONFIG_FEC_ENET
   if [ "$CONFIG_FEC_ENET" = "y" ]; then
     bool 'Use MDIO for PHY configuration' CONFIG_USE_MDIO
   fi
   bool 'Use Big CPM Ethernet Buffers' CONFIG_ENET_BIG_BUFFERS
 fi
+if [ "$CONFIG_SCC3_ENET" != "y" ]; then
+  bool 'Use SMC1 for UART' CONFIG_8xx_SMC1
+fi
 bool 'Use SMC2 for UART' CONFIG_SMC2_UART
 if [ "$CONFIG_SMC2_UART" = "y" ]; then
   bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_ALTSMC2
   bool 'Use SMC2 for Console' CONFIG_CONS_SMC2
 fi
-bool 'Enable SCC2 and SCC3 for UART' CONFIG_USE_SCC_IO
-
-# This doesn't really belong here, but it is convenient to ask
-# 8xx specific questions.
-
-comment 'Generic MPC8xx Options'
-bool 'Copy-Back Data Cache (else Writethrough)' CONFIG_8xx_COPYBACK
-bool 'CPU6 Silicon Errata (860 Pre Rev. C)' CONFIG_8xx_CPU6
-bool 'I2C/SPI Microcode Patch' CONFIG_UCODE_PATCH
-
+if [ "$CONFIG_SCC1_ENET" != "y" ]; then
+  bool 'Use SCC1 for UART' CONFIG_8xx_SCC1 
+fi
+if [ "$CONFIG_SCC2_ENET" != "y" ]; then
+  bool 'Use SCC2 for UART' CONFIG_8xx_SCC2
+fi
+if [ "$CONFIG_SCC3_ENET" != "y" ]; then
+  bool 'Use SCC3 for UART' CONFIG_8xx_SCC3
+fi
+bool 'Use SCC4 for UART' CONFIG_8xx_SCC4
 endmenu
diff -urN linux-2.4.22-bk25/arch/ppc/8xx_io/commproc.c linux-2.4.22-bk26/arch/ppc/8xx_io/commproc.c
--- linux-2.4.22-bk25/arch/ppc/8xx_io/commproc.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/8xx_io/commproc.c	2003-09-29 02:49:40.000000000 -0700
@@ -54,6 +54,7 @@
 static	struct	cpm_action cpm_vecs[CPMVEC_NR];
 static	void	cpm_interrupt(int irq, void * dev, struct pt_regs * regs);
 static	void	cpm_error_interrupt(int irq, void *, struct pt_regs * regs);
+static	void	alloc_host_memory(void);
 
 /* Define a table of names to identify CPM interrupt handlers in
  * /proc/interrupts.
@@ -104,7 +105,7 @@
 };
 
 void
-m8xx_cpm_reset(uint host_page_addr)
+m8xx_cpm_reset()
 {
 	volatile immap_t	 *imp;
 	volatile cpm8xx_t	*commproc;
@@ -130,7 +131,7 @@
 	 * this is what we realy want for some applications, but the
 	 * manual recommends it.
 	 * Bit 25, FAM can also be set to use FEC aggressive mode (860T).
-	*/
+	 */
 	imp->im_siu_conf.sc_sdcr = 1;
 
 	/* Reclaim the DP memory for our use.
@@ -138,25 +139,23 @@
 	dp_alloc_base = CPM_DATAONLY_BASE;
 	dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE;
 
-	/* Set the host page for allocation.
+	/* Tell everyone where the comm processor resides.
 	*/
-	host_buffer = host_page_addr;	/* Host virtual page address */
-	host_end = host_page_addr + PAGE_SIZE;
+	cpmp = (cpm8xx_t *)commproc;
+}
 
-	/* We need to get this page early, so I have to do it the
-	 * hard way.
-	 */
-	if (get_pteptr(&init_mm, host_page_addr, &pte)) {
-		pte_val(*pte) |= _PAGE_NO_CACHE;
-		flush_tlb_page(init_mm.mmap, host_buffer);
-	}
-	else {
-		panic("Huh?  No CPM host page?");
-	}
+/* We used to do this earlier, but have to postpone as long as possible
+ * to ensure the kernel VM is now running.
+ */
+static void
+alloc_host_memory()
+{
+	uint	physaddr;
 
-	/* Tell everyone where the comm processor resides.
+	/* Set the host page for allocation.
 	*/
-	cpmp = (cpm8xx_t *)commproc;
+	host_buffer = (uint)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &physaddr);
+	host_end = host_buffer + PAGE_SIZE;
 }
 
 /* This is called during init_IRQ.  We used to do it above, but this
@@ -321,6 +320,9 @@
 {
 	uint	retloc;
 
+	if (host_buffer == 0)
+		alloc_host_memory();
+
 	if ((host_buffer + size) >= host_end)
 		return(0);
 
diff -urN linux-2.4.22-bk25/arch/ppc/8xx_io/enet.c linux-2.4.22-bk26/arch/ppc/8xx_io/enet.c
--- linux-2.4.22-bk25/arch/ppc/8xx_io/enet.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/8xx_io/enet.c	2003-09-29 02:49:40.000000000 -0700
@@ -137,6 +137,11 @@
 	cbd_t	*cur_rx, *cur_tx;		/* The next free ring entry */
 	cbd_t	*dirty_tx;	/* The ring entries to be free()ed. */
 	scc_t	*sccp;
+
+	/* Virtual addresses for the receive buffers because we can't
+	 * do a __va() on them anymore.
+	 */
+	unsigned char *rx_vaddr[RX_RING_SIZE];
 	struct	net_device_stats stats;
 	uint	tx_free;
 	spinlock_t lock;
@@ -498,7 +503,7 @@
 			skb->dev = dev;
 			skb_put(skb,pkt_len-4);	/* Make room */
 			eth_copy_and_sum(skb,
-				(unsigned char *)__va(bdp->cbd_bufaddr),
+				cep->rx_vaddr[bdp - cep->rx_bd_base],
 				pkt_len-4, 0);
 			skb->protocol=eth_type_trans(skb,dev);
 			netif_rx(skb);
@@ -632,10 +637,9 @@
 {
 	struct net_device *dev;
 	struct scc_enet_private *cep;
-	int i, j;
-	unsigned char	*eap;
-	unsigned long	mem_addr;
-	pte_t		*pte;
+	int i, j, k;
+	unsigned char	*eap, *ba;
+	dma_addr_t	mem_addr;
 	bd_t		*bd;
 	volatile	cbd_t		*bdp;
 	volatile	cpm8xx_t	*cp;
@@ -826,24 +830,21 @@
 	bdp->cbd_sc |= BD_SC_WRAP;
 
 	bdp = cep->rx_bd_base;
+	k = 0;
 	for (i=0; i<CPM_ENET_RX_PAGES; i++) {
 
 		/* Allocate a page.
 		*/
-		mem_addr = __get_free_page(GFP_KERNEL);
-
-		/* Make it uncached.
-		*/
-		pte = va_to_pte(mem_addr);
-		pte_val(*pte) |= _PAGE_NO_CACHE;
-		flush_tlb_page(init_mm.mmap, mem_addr);
+		ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
 
 		/* Initialize the BD for every fragment in the page.
 		*/
 		for (j=0; j<CPM_ENET_RX_FRPPG; j++) {
 			bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
-			bdp->cbd_bufaddr = __pa(mem_addr);
+			bdp->cbd_bufaddr = mem_addr;
+			cep->rx_vaddr[k++] = ba;
 			mem_addr += CPM_ENET_RX_FRSIZE;
+			ba += CPM_ENET_RX_FRSIZE;
 			bdp++;
 		}
 	}
diff -urN linux-2.4.22-bk25/arch/ppc/8xx_io/fec.c linux-2.4.22-bk26/arch/ppc/8xx_io/fec.c
--- linux-2.4.22-bk25/arch/ppc/8xx_io/fec.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/8xx_io/fec.c	2003-09-29 02:49:40.000000000 -0700
@@ -161,7 +161,12 @@
 	cbd_t	*tx_bd_base;
 	cbd_t	*cur_rx, *cur_tx;		/* The next free ring entry */
 	cbd_t	*dirty_tx;	/* The ring entries to be free()ed. */
-	scc_t	*sccp;
+
+	/* Virtual addresses for the receive buffers because we can't
+	 * do a __va() on them anymore.
+	 */
+	unsigned char *rx_vaddr[RX_RING_SIZE];
+
 	struct	net_device_stats stats;
 	uint	tx_free;
 	spinlock_t lock;
@@ -587,7 +592,7 @@
 	fep->stats.rx_packets++;
 	pkt_len = bdp->cbd_datlen;
 	fep->stats.rx_bytes += pkt_len;
-	data = (__u8*)__va(bdp->cbd_bufaddr);
+	data = fep->rx_vaddr[bdp - fep->rx_bd_base];
 
 	/* This does 16 byte alignment, exactly what we need.
 	 * The packet length includes FCS, but we don't want to
@@ -602,9 +607,7 @@
 	} else {
 		skb->dev = dev;
 		skb_put(skb,pkt_len-4);	/* Make room */
-		eth_copy_and_sum(skb,
-				 (unsigned char *)__va(bdp->cbd_bufaddr),
-				 pkt_len-4, 0);
+		eth_copy_and_sum(skb, data, pkt_len-4, 0);
 		skb->protocol=eth_type_trans(skb,dev);
 		netif_rx(skb);
 	}
@@ -1700,10 +1703,9 @@
 {
 	struct net_device *dev;
 	struct fec_enet_private *fep;
-	int i, j;
-	unsigned char	*eap, *iap;
-	unsigned long	mem_addr;
-	pte_t		*pte;
+	int i, j, k;
+	unsigned char	*eap, *iap, *ba;
+	dma_addr_t	mem_addr;
 	volatile	cbd_t	*bdp;
 	cbd_t		*cbd_base;
 	volatile	immap_t	*immap;
@@ -1774,14 +1776,7 @@
 		printk("FEC initialization failed.\n");
 		return 1;
 	}
-	mem_addr = __get_free_page(GFP_KERNEL);
-	cbd_base = (cbd_t *)mem_addr;
-
-	/* Make it uncached.
-	*/
-	pte = va_to_pte(mem_addr);
-	pte_val(*pte) |= _PAGE_NO_CACHE;
-	flush_tlb_page(init_mm.mmap, mem_addr);
+	cbd_base = (cbd_t *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
 
 	/* Set receive and transmit descriptor base.
 	*/
@@ -1793,24 +1788,21 @@
 	/* Initialize the receive buffer descriptors.
 	*/
 	bdp = fep->rx_bd_base;
+	k = 0;
 	for (i=0; i<FEC_ENET_RX_PAGES; i++) {
 
 		/* Allocate a page.
 		*/
-		mem_addr = __get_free_page(GFP_KERNEL);
-
-		/* Make it uncached.
-		*/
-		pte = va_to_pte(mem_addr);
-		pte_val(*pte) |= _PAGE_NO_CACHE;
-		flush_tlb_page(init_mm.mmap, mem_addr);
+		ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
 
 		/* Initialize the BD for every fragment in the page.
 		*/
 		for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
 			bdp->cbd_sc = BD_ENET_RX_EMPTY;
-			bdp->cbd_bufaddr = __pa(mem_addr);
+			bdp->cbd_bufaddr = mem_addr;
+			fep->rx_vaddr[k++] = ba;
 			mem_addr += FEC_ENET_RX_FRSIZE;
+			ba += FEC_ENET_RX_FRSIZE;
 			bdp++;
 		}
 	}
@@ -1974,8 +1966,8 @@
 
 	/* Set receive and transmit descriptor base.
 	*/
-	fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
-	fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+	fecp->fec_r_des_start = iopa((uint)(fep->rx_bd_base));
+	fecp->fec_x_des_start = iopa((uint)(fep->tx_bd_base));
 
 	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
 	fep->tx_free = TX_RING_SIZE;
diff -urN linux-2.4.22-bk25/arch/ppc/8xx_io/uart.c linux-2.4.22-bk26/arch/ppc/8xx_io/uart.c
--- linux-2.4.22-bk25/arch/ppc/8xx_io/uart.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/8xx_io/uart.c	2003-09-29 02:49:40.000000000 -0700
@@ -126,10 +126,27 @@
  * type of SMC or SCC.
  * The SMCs do not support any modem control signals.
  */
-#define smc_scc_num	hub6
-#define NUM_IS_SCC	((int)0x00010000)
-#define PORT_NUM(P)	((P) & 0x0000ffff)
-#define PORT_IS_SCC(P)	((P) & NUM_IS_SCC)
+#define smc_scc_num	     hub6
+#define NUM_IS_SCC	     ((int)0x000100000)
+#define NUM_BRG              ((int)0x0000FF00)
+#define NUM_BRG_SHIFT        8
+#define NUM                  ((int)0x000000FF)
+#define NUM_SHIFT            0
+#define PORT_NUM(P)	     ((P) & NUM)
+#define PORT_NUM_SET(N)      (((N)-1) << NUM_SHIFT)
+#define PORT_IS_SCC(P)	     ((P) & NUM_IS_SCC)
+#define PORT_BRG(P)          (((P) & NUM_BRG) >> NUM_BRG_SHIFT)
+#define PORT_BRG_SET(P,B)    (P) = (((P) & ~NUM_BRG) | ((B) << NUM_BRG_SHIFT))
+
+/* Short names for the ports
+*/
+#define QUICC_CPM_SMC1  (PORT_NUM_SET(1))
+#define QUICC_CPM_SMC2  (PORT_NUM_SET(2))
+#define QUICC_CPM_SCC1  (PORT_NUM_SET(1)|NUM_IS_SCC)
+#define QUICC_CPM_SCC2  (PORT_NUM_SET(2)|NUM_IS_SCC)
+#define QUICC_CPM_SCC3  (PORT_NUM_SET(3)|NUM_IS_SCC)
+#define QUICC_CPM_SCC4  (PORT_NUM_SET(4)|NUM_IS_SCC)
+#define QUICC_MAX_BRG   3  /* BRG1..BRG4 */
 
 /* The serial port to use for KGDB. */
 #ifdef CONFIG_KGDB_TTYS1
@@ -151,22 +168,24 @@
  */
 static struct serial_state rs_table[] = {
 	/* UART CLK   PORT          IRQ      FLAGS  NUM   */
-#ifndef CONFIG_SCC3_ENET	/* SMC1 not usable with Ethernet on SCC3 */
-  	{ 0,     0, PROFF_SMC1, CPMVEC_SMC1,   0,    0 },    /* SMC1 ttyS0 */
+#ifdef CONFIG_8xx_SMC1
+  	{ 0,     0, PROFF_SMC1, CPMVEC_SMC1,   0,    QUICC_CPM_SMC1 },    /* SMC1 ttySx */
+#endif
+#ifdef CONFIG_8xx_SMC2
+  	{ 0,     0, PROFF_SMC2, CPMVEC_SMC2,   0,    QUICC_CPM_SMC2 },    /* SMC2 ttySx */
+#endif
+#ifdef CONFIG_8xx_SCC1
+  	{ 0,     0, PROFF_SCC1, CPMVEC_SCC1,   0,    QUICC_CPM_SCC1 },    /* SCC1 ttySx */
+#endif
+#ifdef CONFIG_8xx_SCC2
+  	{ 0,     0, PROFF_SCC2, CPMVEC_SCC2,   0,    QUICC_CPM_SCC2 },    /* SCC2 ttySx */
+#endif
+#ifdef CONFIG_8xx_SCC3
+  	{ 0,     0, PROFF_SCC3, CPMVEC_SCC3,   0,    QUICC_CPM_SCC3 },    /* SCC3 ttySx */
+#endif
+#ifdef CONFIG_8xx_SCC4
+  	{ 0,     0, PROFF_SCC4, CPMVEC_SCC4,   0,    QUICC_CPM_SCC4 },    /* SCC4 ttySx */
 #endif
-#if !defined(CONFIG_USB_MPC8xx) && !defined(CONFIG_USB_CLIENT_MPC8xx)
-# ifdef CONFIG_SMC2_UART
-  	{ 0,     0, PROFF_SMC2, CPMVEC_SMC2,   0,    1 },    /* SMC2 ttyS1 */
-# endif
-# ifdef CONFIG_USE_SCC_IO
-  	{ 0,     0, PROFF_SCC2, CPMVEC_SCC2,   0,    (NUM_IS_SCC | 1) },    /* SCC2 ttyS2 */
-  	{ 0,     0, PROFF_SCC3, CPMVEC_SCC3,   0,    (NUM_IS_SCC | 2) },    /* SCC3 ttyS3 */
-# endif
-  #else /* CONFIG_USB_xxx */
-# ifdef CONFIG_USE_SCC_IO
-  	{ 0,     0, PROFF_SCC3, CPMVEC_SCC3,   0,    (NUM_IS_SCC | 2) },    /* SCC3 ttyS3 */
-# endif
-#endif	/* CONFIG_USB_xxx */
 };
 
 #define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
@@ -218,6 +237,12 @@
 	cbd_t			*rx_cur;
 	cbd_t			*tx_bd_base;
 	cbd_t			*tx_cur;
+
+	/* Virtual addresses for the FIFOs because we can't __va() a
+	 * physical address anymore.
+	 */
+	 unsigned char		*rx_va_base;
+	 unsigned char		*tx_va_base;
 } ser_info_t;
 
 static struct console sercons = {
@@ -394,13 +419,13 @@
 		/* Get the number of characters and the buffer pointer.
 		*/
 		i = bdp->cbd_datlen;
-		cp = (unsigned char *)__va(bdp->cbd_bufaddr);
+		cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE);
 		status = bdp->cbd_sc;
 
 #ifdef CONFIG_KGDB
-		if (info->state->smc_scc_num == KGDB_SER_IDX) {
-			if (*cp == 0x03 || *cp == '$')
-				breakpoint();
+		if (info->state->smc_scc_num == KGDB_SER_IDX &&
+				(*cp == 0x03 || *cp == '$')) {
+			breakpoint();
 			return;
 		}
 #endif
@@ -420,7 +445,7 @@
 			icount->rx++;
 
 #ifdef SERIAL_DEBUG_INTR
-			printk("DR%02x:%02x...", ch, status);
+                        printk("DR%02x:%02x...", ch, status);
 #endif
 			*tty->flip.flag_buf_ptr = 0;
 			if (status & (BD_SC_BR | BD_SC_FR |
@@ -1033,7 +1058,7 @@
 			smcp->smc_smcmr = new_mode;
 	}
 
-	m8xx_cpm_setbrg((state - rs_table), baud_rate);
+	m8xx_cpm_setbrg(PORT_BRG(state->smc_scc_num), baud_rate);
 
 	restore_flags(flags);
 }
@@ -1042,6 +1067,7 @@
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 	volatile cbd_t	*bdp;
+	unsigned char *cp;
 
 	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
 		return;
@@ -1052,7 +1078,8 @@
 	bdp = info->tx_cur;
 	while (bdp->cbd_sc & BD_SC_READY);
 
-	*((char *)__va(bdp->cbd_bufaddr)) = ch;
+	cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
+	*cp = ch;
 	bdp->cbd_datlen = 1;
 	bdp->cbd_sc |= BD_SC_READY;
 
@@ -1064,7 +1091,6 @@
 		bdp++;
 
 	info->tx_cur = (cbd_t *)bdp;
-
 }
 
 static int rs_8xx_write(struct tty_struct * tty, int from_user,
@@ -1073,6 +1099,7 @@
 	int	c, ret = 0;
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 	volatile cbd_t *bdp;
+	unsigned char	*cp;
 
 #ifdef CONFIG_KGDB_CONSOLE
         /* Try to let stub handle output. Returns true if it did. */
@@ -1099,14 +1126,15 @@
 			break;
 		}
 
+		cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
 		if (from_user) {
-			if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
+			if (copy_from_user((void *)cp, buf, c)) {
 				if (!ret)
 					ret = -EFAULT;
 				break;
 			}
 		} else {
-			memcpy(__va(bdp->cbd_bufaddr), buf, c);
+			memcpy((void *)cp, buf, c);
 		}
 
 		bdp->cbd_datlen = c;
@@ -1181,6 +1209,7 @@
 static void rs_8xx_send_xchar(struct tty_struct *tty, char ch)
 {
 	volatile cbd_t	*bdp;
+	unsigned char	*cp;
 
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 
@@ -1190,7 +1219,8 @@
 	bdp = info->tx_cur;
 	while (bdp->cbd_sc & BD_SC_READY);
 
-	*((char *)__va(bdp->cbd_bufaddr)) = ch;
+	cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
+	*cp = ch;
 	bdp->cbd_datlen = 1;
 	bdp->cbd_sc |= BD_SC_READY;
 
@@ -2217,6 +2247,11 @@
 
 #ifdef CONFIG_SERIAL_CONSOLE
 
+/* I need this just so I can store the virtual addresses and have
+ * common functions for the early console printing.
+ */
+static ser_info_t consinfo;
+
 /*
  * Print a string to the serial port trying not to disturb any possible
  * real use of the port...
@@ -2249,6 +2284,8 @@
 		/* Get the address of the host memory buffer.
 		 */
 		bdp = bdbase = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
+		
+		info = &consinfo;
 	}
 
 	/*
@@ -2276,7 +2313,7 @@
 		if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
 			cp = (u_char *)(bdp->cbd_bufaddr);
 		else
-			cp = __va(bdp->cbd_bufaddr);
+			cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
 		*cp = *s;
 
 		bdp->cbd_datlen = 1;
@@ -2290,7 +2327,18 @@
 		/* if a LF, also do CR... */
 		if (*s == 10) {
 			while (bdp->cbd_sc & BD_SC_READY);
-			cp = __va(bdp->cbd_bufaddr);
+			/* This 'if' below will never be true, but a few
+			 * people argued with me that it was a "bug by
+			 * inspection" that is was easier to add the code
+			 * than continue the discussion.  The only time
+			 * the buffer address is in DPRAM is during early
+			 * use by kgdb/xmon, which format their own packets
+			 * and we never get here. -- Dan
+			 */
+			if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
+				cp = (u_char *)(bdp->cbd_bufaddr);
+			else
+				cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
 			*cp = 13;
 			bdp->cbd_datlen = 1;
 			bdp->cbd_sc |= BD_SC_READY;
@@ -2358,10 +2406,13 @@
 	 * If the port has been initialized for general use, we must
 	 * use information from the port structure.
 	 */
-	if ((info = (ser_info_t *)ser->info))
+	if ((info = (ser_info_t *)ser->info)) {
 		bdp = info->rx_cur;
-	else
+	}
+	else {
 		bdp = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+		info = &consinfo;
+	}
 
 	/*
 	 * We need to gracefully shut down the receiver, disable
@@ -2383,7 +2434,7 @@
 	if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
 		cp = (u_char *)(bdp->cbd_bufaddr);
 	else
-		cp = __va(bdp->cbd_bufaddr);
+		cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE);
 
 	if (obuf) {
 		i = c = bdp->cbd_datlen;
@@ -2522,6 +2573,43 @@
 /*
  * The serial driver boot-time initialization code!
  */
+
+int __init rs_8xx_alloc_brg(int port)
+{
+    static int brg = 0;
+    volatile cpm8xx_t *cp = cpmp;
+    int res = brg;
+
+    /* "Wire" the BRG to the specified port
+    */
+    switch (port) {
+    case QUICC_CPM_SMC1:
+        cp->cp_simode = (cp->cp_simode & ~(0x07<<12)) | (brg<<12);
+        break;
+    case QUICC_CPM_SMC2:
+        cp->cp_simode = (cp->cp_simode & ~(0x07<<28)) | (brg<<28);
+        break;
+    case QUICC_CPM_SCC1:
+        cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<0)) | (((brg<<3)|(brg<<0))<<0);
+        break;
+    case QUICC_CPM_SCC2:
+        cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<8)) | (((brg<<3)|(brg<<0))<<8);
+        break;
+    case QUICC_CPM_SCC3:
+        cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<16)) | (((brg<<3)|(brg<<0))<<16);
+        break;
+    case QUICC_CPM_SCC4:
+        cp->cp_sicr = (cp->cp_sicr & ~(0xFF<<24)) | (((brg<<3)|(brg<<0))<<24);
+        break;
+    }
+    /* Consume this BRG - Note: the last BRG will be reused if this
+    */
+    /* function is called too many times!
+    */
+    if (brg < QUICC_MAX_BRG) brg++;
+    return res;
+}
+
 int __init rs_8xx_init(void)
 {
 	struct serial_state * state;
@@ -2668,9 +2756,12 @@
 		state->icount.rx = state->icount.tx = 0;
 		state->icount.frame = state->icount.parity = 0;
 		state->icount.overrun = state->icount.brk = 0;
-		printk(KERN_INFO "ttyS%02d at 0x%04x is a %s\n",
+                PORT_BRG_SET(state->smc_scc_num, rs_8xx_alloc_brg(state->smc_scc_num));
+		printk(KERN_INFO "ttyS%d at 0x%04x is on %s%d using BRG%d\n",
 		       i, (unsigned int)(state->port),
-		       PORT_IS_SCC(state->smc_scc_num) ? "SCC" : "SMC");
+		       PORT_IS_SCC(state->smc_scc_num) ? "SCC" : "SMC",
+                       PORT_NUM(state->smc_scc_num)+1,
+                       PORT_BRG(state->smc_scc_num)+1);
 #ifdef CONFIG_SERIAL_CONSOLE
 		/* If we just printed the message on the console port, and
 		 * we are about to initialize it for general use, we have
@@ -2704,6 +2795,7 @@
 			/* Allocate space for FIFOs in the host memory.
 			*/
 			mem_addr = m8xx_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE);
+			info->rx_va_base = (unsigned char *)mem_addr;
 
 			/* Set the physical address of the host memory
 			 * buffers in the buffer descriptors, and the
@@ -2713,12 +2805,12 @@
 			info->rx_cur = info->rx_bd_base = (cbd_t *)bdp;
 
 			for (j=0; j<(RX_NUM_FIFO-1); j++) {
-				bdp->cbd_bufaddr = __pa(mem_addr);
+				bdp->cbd_bufaddr = iopa(mem_addr);
 				bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
 				mem_addr += RX_BUF_SIZE;
 				bdp++;
 			}
-			bdp->cbd_bufaddr = __pa(mem_addr);
+			bdp->cbd_bufaddr = iopa(mem_addr);
 			bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
 
 			idx = PORT_NUM(info->state->smc_scc_num);
@@ -2738,6 +2830,7 @@
 			/* Allocate space for FIFOs in the host memory.
 			*/
 			mem_addr = m8xx_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE);
+			info->tx_va_base = (unsigned char *)mem_addr;
 
 			/* Set the physical address of the host memory
 			 * buffers in the buffer descriptors, and the
@@ -2747,12 +2840,12 @@
 			info->tx_cur = info->tx_bd_base = (cbd_t *)bdp;
 
 			for (j=0; j<(TX_NUM_FIFO-1); j++) {
-				bdp->cbd_bufaddr = __pa(mem_addr);
+				bdp->cbd_bufaddr = iopa(mem_addr);
 				bdp->cbd_sc = BD_SC_INTRPT;
 				mem_addr += TX_BUF_SIZE;
 				bdp++;
 			}
-			bdp->cbd_bufaddr = __pa(mem_addr);
+			bdp->cbd_bufaddr = iopa(mem_addr);
 			bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
 
 			if (PORT_IS_SCC(info->state->smc_scc_num)) {
@@ -2846,12 +2939,14 @@
 				}
 #endif /* CONFIG_ALTSMC2 */
 
+#if 0
 				/* Connect the baud rate generator to the
 				 * SMC based upon index in rs_table.  Also
 				 * make sure it is connected to NMSI.
 				 */
 				cp->cp_simode &= ~(0xffff << (idx * 16));
 				cp->cp_simode |= (i << ((idx * 16) + 12));
+#endif
 
 				up->smc_tbase = dp_addr;
 
@@ -2903,7 +2998,7 @@
 
 			/* Set up the baud rate generator.
 			*/
-			m8xx_cpm_setbrg(i, baud_table[baud_idx]);
+                        m8xx_cpm_setbrg(PORT_BRG(state->smc_scc_num), baud_table[baud_idx]);
 
 		}
 	}
@@ -2959,20 +3054,28 @@
 	 * from dual port ram, and a character buffer area from host mem.
 	 */
 
+	/* Allocate space for two FIFOs.  We can't allocate from host
+	 * memory yet because vm allocator isn't initialized
+	 * during this early console init.
+	 */
+	dp_addr = m8xx_cpm_dpalloc(8);
+	mem_addr = (uint)(&cpmp->cp_dpmem[dp_addr]);
+
 	/* Allocate space for two buffer descriptors in the DP ram.
 	*/
 	dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2);
 
-	/* Allocate space for two 2 byte FIFOs in the host memory.
-	*/
-	mem_addr = m8xx_cpm_hostalloc(8);
-
 	/* Set the physical address of the host memory buffers in
 	 * the buffer descriptors.
 	 */
 	bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
-	bdp->cbd_bufaddr = __pa(mem_addr);
-	(bdp+1)->cbd_bufaddr = __pa(mem_addr+4);
+	bdp->cbd_bufaddr = iopa(mem_addr);
+	(bdp+1)->cbd_bufaddr = iopa(mem_addr+4);
+
+	consinfo.rx_va_base = mem_addr;
+	consinfo.rx_bd_base = bdp;
+	consinfo.tx_va_base = mem_addr + 4;
+	consinfo.tx_bd_base = bdp+1;
 
 	/* For the receive, set empty and wrap.
 	 * For transmit, set wrap.
diff -urN linux-2.4.22-bk25/arch/ppc/Makefile linux-2.4.22-bk26/arch/ppc/Makefile
--- linux-2.4.22-bk25/arch/ppc/Makefile	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/Makefile	2003-09-29 02:49:40.000000000 -0700
@@ -14,7 +14,7 @@
 #
 
 # Be sure to change PAGE_OFFSET in include/asm-ppc/page.h to match
-KERNELLOAD	=0xc0000000
+KERNELLOAD	=$(CONFIG_KERNEL_START)
 
 LINKFLAGS	= -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic
 CPPFLAGS	:= $(CPPFLAGS) -I$(TOPDIR)/arch/$(ARCH)
diff -urN linux-2.4.22-bk25/arch/ppc/boot/simple/embed_config.c linux-2.4.22-bk26/arch/ppc/boot/simple/embed_config.c
--- linux-2.4.22-bk25/arch/ppc/boot/simple/embed_config.c	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/boot/simple/embed_config.c	2003-09-29 02:49:40.000000000 -0700
@@ -753,4 +753,3 @@
 	timebase_period_ns = 1000000000 / bd->bi_tbfreq;
 }
 #endif
-
diff -urN linux-2.4.22-bk25/arch/ppc/boot/simple/misc-embedded.c linux-2.4.22-bk26/arch/ppc/boot/simple/misc-embedded.c
--- linux-2.4.22-bk25/arch/ppc/boot/simple/misc-embedded.c	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/boot/simple/misc-embedded.c	2003-09-29 02:49:40.000000000 -0700
@@ -79,6 +79,14 @@
 extern void gunzip(void *, int, unsigned char *, int *);
 extern void embed_config(bd_t **bp);
 
+/* Weak function for boards which don't need to build the
+ * board info struct because they are using PPCBoot/U-Boot.
+ */
+void __attribute__ ((weak))
+embed_config(bd_t **bdp)
+{
+}
+
 unsigned long
 load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
 		bd_t *bp)
diff -urN linux-2.4.22-bk25/arch/ppc/config.in linux-2.4.22-bk26/arch/ppc/config.in
--- linux-2.4.22-bk25/arch/ppc/config.in	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/config.in	2003-09-29 02:49:40.000000000 -0700
@@ -12,6 +12,7 @@
 mainmenu_option next_comment
 comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+bool 'Prompt for advanced kernel configuration options' CONFIG_ADVANCED_OPTIONS
 endmenu
 
 mainmenu_option next_comment
@@ -80,6 +81,7 @@
 	 RPX-Classic	CONFIG_RPXCLASSIC	\
 	 BSE-IP		CONFIG_BSEIP		\
 	 FADS		CONFIG_FADS		\
+	 D-Box2		CONFIG_DBOX2		\
 	 TQM823L	CONFIG_TQM823L		\
 	 TQM850L	CONFIG_TQM850L		\
 	 TQM855L	CONFIG_TQM855L		\
@@ -248,8 +250,49 @@
 comment 'General setup'
 
 bool 'High memory support (experimental)' CONFIG_HIGHMEM
+if [ "$CONFIG_ADVANCED_OPTIONS" = "y" ]; then
+  if [ "$CONFIG_HIGHMEM" = "y" ]; then
+    bool "  Set high memory pool address" CONFIG_HIGHMEM_START_BOOL
+    if [ "$CONFIG_HIGHMEM_START_BOOL" = "y" ]; then
+      hex "    Virtual start address of high memory pool" CONFIG_HIGHMEM_START 0xfe000000
+    fi
+  fi
+  bool "  Set maximum low memory" CONFIG_LOWMEM_SIZE_BOOL
+  if [ "$CONFIG_LOWMEM_SIZE_BOOL" = "y" ]; then
+    hex "    Maximum low memory size (in bytes)" CONFIG_LOWMEM_SIZE 0x20000000
+  fi
+
+  bool "Set custom kernel base address" CONFIG_KERNEL_START_BOOL
+  if [ "$CONFIG_KERNEL_START_BOOL" = "y" ]; then
+    hex "  Virtual address of kernel base" CONFIG_KERNEL_START 0xc0000000
+  fi
+  bool "Set custom user task size" CONFIG_TASK_SIZE_BOOL
+  if [ "$CONFIG_TASK_SIZE_BOOL" = "y" ]; then
+    hex "  Size of user task space" CONFIG_TASK_SIZE 0x80000000
+  fi
+fi
+
+if [ "$CONFIG_HIGHMEM_START_BOOL" != "y" ]; then
+  define_hex CONFIG_HIGHMEM_START 0xfe000000
+fi
 
-define_bool CONFIG_ISA n
+if [ "$CONFIG_LOWMEM_SIZE_BOOL" != "y" ]; then
+  define_hex CONFIG_LOWMEM_SIZE 0x30000000
+fi
+
+if [ "$CONFIG_KERNEL_START_BOOL" != "y" ]; then
+  define_hex CONFIG_KERNEL_START 0xc0000000
+fi
+
+if [ "$CONFIG_TASK_SIZE_BOOL" != "y" ]; then
+  define_hex CONFIG_TASK_SIZE 0x80000000
+fi
+
+if [ "$CONFIG_ALL_PPC" = "y" ]; then
+  bool 'Support for ISA-bus hardware' CONFIG_ISA
+else
+  define_bool CONFIG_ISA n
+fi
 define_bool CONFIG_EISA n
 define_bool CONFIG_SBUS n
 
diff -urN linux-2.4.22-bk25/arch/ppc/configs/IVMS8_defconfig linux-2.4.22-bk26/arch/ppc/configs/IVMS8_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/IVMS8_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/IVMS8_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -506,14 +506,8 @@
 # CONFIG_SOUND is not set
 
 #
-# MPC8xx CPM Options
+# MPC8xx Options
 #
-# CONFIG_SCC_ENET is not set
-CONFIG_FEC_ENET=y
-CONFIG_USE_MDIO=y
-CONFIG_ENET_BIG_BUFFERS=y
-# CONFIG_SMC2_UART is not set
-# CONFIG_USE_SCC_IO is not set
 
 #
 # Generic MPC8xx Options
@@ -523,6 +517,27 @@
 # CONFIG_UCODE_PATCH is not set
 
 #
+# MPC8xx CPM Options
+#
+# CONFIG_SCC_ENET is not set
+CONFIG_FEC_ENET=y
+CONFIG_USE_MDIO=y
+# CONFIG_FEC_GENERIC_PHY is not set
+# CONFIG_FEC_AM79C874 is not set
+# CONFIG_FEC_LXT970 is not set
+# CONFIG_FEC_QS6612 is not set
+# CONFIG_FEC_LXT970 is not set
+CONFIG_FEC_DP83843=y
+# CONFIG_FEC_DP83846A is not set
+CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xx_SMC1=y
+# CONFIG_SMC2_UART is not set
+# CONFIG_8xx_SCC1 is not set
+# CONFIG_8xx_SCC2 is not set
+# CONFIG_8xx_SCC3 is not set
+# CONFIG_8xx_SCC4 is not set
+
+#
 # USB support
 #
 # CONFIG_USB is not set
diff -urN linux-2.4.22-bk25/arch/ppc/configs/SM850_defconfig linux-2.4.22-bk26/arch/ppc/configs/SM850_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/SM850_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/SM850_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -470,6 +470,17 @@
 # CONFIG_SOUND is not set
 
 #
+# MPC8xx Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+CONFIG_8xx_CPU6=y
+# CONFIG_UCODE_PATCH is not set
+
+#
 # MPC8xx CPM Options
 #
 CONFIG_SCC_ENET=y
@@ -481,14 +492,9 @@
 CONFIG_SMC2_UART=y
 CONFIG_ALTSMC2=y
 CONFIG_CONS_SMC2=y
-# CONFIG_USE_SCC_IO is not set
-
-#
-# Generic MPC8xx Options
-#
-CONFIG_8xx_COPYBACK=y
-CONFIG_8xx_CPU6=y
-# CONFIG_UCODE_PATCH is not set
+# CONFIG_8xx_SCC1 is not set
+# CONFIG_8xx_SCC2 is not set
+# CONFIG_8xx_SCC4 is not set
 
 #
 # USB support
diff -urN linux-2.4.22-bk25/arch/ppc/configs/SPD823TS_defconfig linux-2.4.22-bk26/arch/ppc/configs/SPD823TS_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/SPD823TS_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/SPD823TS_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -469,6 +469,17 @@
 # CONFIG_SOUND is not set
 
 #
+# MPC8xx Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+# CONFIG_UCODE_PATCH is not set
+
+#
 # MPC8xx CPM Options
 #
 CONFIG_SCC_ENET=y
@@ -477,17 +488,13 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xx_SMC1=y
 CONFIG_SMC2_UART=y
 CONFIG_ALTSMC2=y
 # CONFIG_CONS_SMC2 is not set
-# CONFIG_USE_SCC_IO is not set
-
-#
-# Generic MPC8xx Options
-#
-CONFIG_8xx_COPYBACK=y
-# CONFIG_8xx_CPU6 is not set
-# CONFIG_UCODE_PATCH is not set
+# CONFIG_8xx_SCC1 is not set
+# CONFIG_8xx_SCC3 is not set
+# CONFIG_8xx_SCC4 is not set
 
 #
 # USB support
diff -urN linux-2.4.22-bk25/arch/ppc/configs/TQM823L_defconfig linux-2.4.22-bk26/arch/ppc/configs/TQM823L_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/TQM823L_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/TQM823L_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -470,6 +470,17 @@
 # CONFIG_SOUND is not set
 
 #
+# MPC8xx Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+# CONFIG_UCODE_PATCH is not set
+
+#
 # MPC8xx CPM Options
 #
 CONFIG_SCC_ENET=y
@@ -478,17 +489,13 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xx_SMC1=y
 CONFIG_SMC2_UART=y
 CONFIG_ALTSMC2=y
 # CONFIG_CONS_SMC2 is not set
-# CONFIG_USE_SCC_IO is not set
-
-#
-# Generic MPC8xx Options
-#
-CONFIG_8xx_COPYBACK=y
-# CONFIG_8xx_CPU6 is not set
-# CONFIG_UCODE_PATCH is not set
+# CONFIG_8xx_SCC1 is not set
+# CONFIG_8xx_SCC3 is not set
+# CONFIG_8xx_SCC4 is not set
 
 #
 # USB support
diff -urN linux-2.4.22-bk25/arch/ppc/configs/TQM850L_defconfig linux-2.4.22-bk26/arch/ppc/configs/TQM850L_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/TQM850L_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/TQM850L_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -470,6 +470,17 @@
 # CONFIG_SOUND is not set
 
 #
+# MPC8xx Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+# CONFIG_UCODE_PATCH is not set
+
+#
 # MPC8xx CPM Options
 #
 CONFIG_SCC_ENET=y
diff -urN linux-2.4.22-bk25/arch/ppc/configs/TQM860L_defconfig linux-2.4.22-bk26/arch/ppc/configs/TQM860L_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/TQM860L_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/TQM860L_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -511,6 +511,17 @@
 # CONFIG_SOUND is not set
 
 #
+# MPC8xx Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+# CONFIG_UCODE_PATCH is not set
+
+#
 # MPC8xx CPM Options
 #
 CONFIG_SCC_ENET=y
@@ -519,17 +530,13 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xx_SMC1=y
 CONFIG_SMC2_UART=y
 # CONFIG_ALTSMC2 is not set
 # CONFIG_CONS_SMC2 is not set
-# CONFIG_USE_SCC_IO is not set
-
-#
-# Generic MPC8xx Options
-#
-CONFIG_8xx_COPYBACK=y
-# CONFIG_8xx_CPU6 is not set
-# CONFIG_UCODE_PATCH is not set
+# CONFIG_8xx_SCC2 is not set
+# CONFIG_8xx_SCC3 is not set
+# CONFIG_8xx_SCC4 is not set
 
 #
 # USB support
diff -urN linux-2.4.22-bk25/arch/ppc/configs/bseip_defconfig linux-2.4.22-bk26/arch/ppc/configs/bseip_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/bseip_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/bseip_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -469,6 +469,17 @@
 # CONFIG_SOUND is not set
 
 #
+# MPC8xx Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+# CONFIG_UCODE_PATCH is not set
+
+#
 # MPC8xx CPM Options
 #
 CONFIG_SCC_ENET=y
@@ -477,17 +488,13 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 # CONFIG_ENET_BIG_BUFFERS is not set
+CONFIG_8xx_SMC1=y
 CONFIG_SMC2_UART=y
 # CONFIG_ALTSMC2 is not set
 # CONFIG_CONS_SMC2 is not set
-# CONFIG_USE_SCC_IO is not set
-
-#
-# Generic MPC8xx Options
-#
-CONFIG_8xx_COPYBACK=y
-# CONFIG_8xx_CPU6 is not set
-# CONFIG_UCODE_PATCH is not set
+# CONFIG_8xx_SCC1 is not set
+# CONFIG_8xx_SCC3 is not set
+# CONFIG_8xx_SCC4 is not set
 
 #
 # USB support
diff -urN linux-2.4.22-bk25/arch/ppc/configs/mbx_defconfig linux-2.4.22-bk26/arch/ppc/configs/mbx_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/mbx_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/mbx_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -465,6 +465,17 @@
 # CONFIG_SOUND is not set
 
 #
+# MPC8xx Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+CONFIG_8xx_CPU6=y
+# CONFIG_UCODE_PATCH is not set
+
+#
 # MPC8xx CPM Options
 #
 CONFIG_SCC_ENET=y
@@ -473,17 +484,13 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xx_SMC1=y
 CONFIG_SMC2_UART=y
 # CONFIG_ALTSMC2 is not set
 # CONFIG_CONS_SMC2 is not set
-CONFIG_USE_SCC_IO=y
-
-#
-# Generic MPC8xx Options
-#
-CONFIG_8xx_COPYBACK=y
-CONFIG_8xx_CPU6=y
-# CONFIG_UCODE_PATCH is not set
+# CONFIG_8xx_SCC2 is not set
+# CONFIG_8xx_SCC3 is not set
+# CONFIG_8xx_SCC4 is not set
 
 #
 # USB support
diff -urN linux-2.4.22-bk25/arch/ppc/configs/rpxcllf_defconfig linux-2.4.22-bk26/arch/ppc/configs/rpxcllf_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/rpxcllf_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/rpxcllf_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -504,6 +504,17 @@
 # CONFIG_SOUND is not set
 
 #
+# MPC8xx Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+# CONFIG_UCODE_PATCH is not set
+
+#
 # MPC8xx CPM Options
 #
 CONFIG_SCC_ENET=y
@@ -513,17 +524,13 @@
 CONFIG_FEC_ENET=y
 # CONFIG_USE_MDIO is not set
 CONFIG_ENET_BIG_BUFFERS=y
+CONFIG_8xx_SMC1=y
 CONFIG_SMC2_UART=y
 # CONFIG_ALTSMC2 is not set
 # CONFIG_CONS_SMC2 is not set
-CONFIG_USE_SCC_IO=y
-
-#
-# Generic MPC8xx Options
-#
-CONFIG_8xx_COPYBACK=y
-# CONFIG_8xx_CPU6 is not set
-# CONFIG_UCODE_PATCH is not set
+# CONFIG_8xx_SCC2 is not set
+# CONFIG_8xx_SCC3 is not set
+# CONFIG_8xx_SCC4 is not set
 
 #
 # USB support
diff -urN linux-2.4.22-bk25/arch/ppc/configs/rpxlite_defconfig linux-2.4.22-bk26/arch/ppc/configs/rpxlite_defconfig
--- linux-2.4.22-bk25/arch/ppc/configs/rpxlite_defconfig	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/configs/rpxlite_defconfig	2003-09-29 02:49:40.000000000 -0700
@@ -504,6 +504,17 @@
 # CONFIG_SOUND is not set
 
 #
+# MPC8xx Options
+#
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+# CONFIG_8xx_CPU6 is not set
+# CONFIG_UCODE_PATCH is not set
+
+#
 # MPC8xx CPM Options
 #
 CONFIG_SCC_ENET=y
@@ -512,15 +523,11 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 # CONFIG_ENET_BIG_BUFFERS is not set
+CONFIG_8xx_SMC1=y
 # CONFIG_SMC2_UART is not set
-# CONFIG_USE_SCC_IO is not set
-
-#
-# Generic MPC8xx Options
-#
-CONFIG_8xx_COPYBACK=y
-# CONFIG_8xx_CPU6 is not set
-# CONFIG_UCODE_PATCH is not set
+# CONFIG_8xx_SCC1 is not set
+# CONFIG_8xx_SCC3 is not set
+# CONFIG_8xx_SCC4 is not set
 
 #
 # USB support
diff -urN linux-2.4.22-bk25/arch/ppc/kernel/head_8xx.S linux-2.4.22-bk26/arch/ppc/kernel/head_8xx.S
--- linux-2.4.22-bk25/arch/ppc/kernel/head_8xx.S	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/kernel/head_8xx.S	2003-09-29 02:49:41.000000000 -0700
@@ -21,9 +21,9 @@
  *
  */
 
+#include <linux/config.h>
 #include <asm/processor.h>
 #include <asm/page.h>
-#include <linux/config.h>
 #include <asm/mmu.h>
 #include <asm/cache.h>
 #include <asm/pgtable.h>
@@ -817,16 +817,31 @@
  * kernel initialization.  This maps the first 8 MBytes of memory 1:1
  * virtual to physical.  Also, set the cache mode since that is defined
  * by TLB entries and perform any additional mapping (like of the IMMR).
+ * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
+ * 24 Mbytes of data, and the 8M IMMR space.  Anything not covered by
+ * these mappings is mapped by page tables.
  */
 initial_mmu:
 	tlbia			/* Invalidate all TLB entries */
+#ifdef CONFIG_PIN_TLB
+	lis	r8, MI_RSV4I@h
+	ori	r8, r8, 0x1c00
+#else
 	li	r8, 0
-	mtspr	MI_CTR, r8	/* Set instruction control to zero */
-	lis	r8, MD_RESETVAL@h
+#endif
+	mtspr	MI_CTR, r8	/* Set instruction MMU control */
+
+#ifdef CONFIG_PIN_TLB
+	lis	r10, (MD_RSV4I | MD_RESETVAL)@h
+	ori	r10, r10, 0x1c00
+	mr	r8, r10
+#else
+	lis	r10, MD_RESETVAL@h
+#endif
 #ifndef CONFIG_8xx_COPYBACK
-	oris	r8, r8, MD_WTDEF@h
+	oris	r10, r10, MD_WTDEF@h
 #endif
-	mtspr	MD_CTR, r8	/* Set data TLB control */
+	mtspr	MD_CTR, r10	/* Set data TLB control */
 
 	/* Now map the lower 8 Meg into the TLBs.  For this quick hack,
 	 * we can load the instruction and data TLB registers with the
@@ -850,6 +865,10 @@
 	/* Map another 8 MByte at the IMMR to get the processor
 	 * internal registers (among other things).
 	 */
+#ifdef CONFIG_PIN_TLB
+	addi	r10, r10, 0x0100
+	mtspr	MD_CTR, r10
+#endif
 	mfspr	r9, 638			/* Get current IMMR */
 	andis.	r9, r9, 0xff80		/* Get 8Mbyte boundary */
 
@@ -863,6 +882,30 @@
 	ori	r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
 	mtspr	MD_RPN, r8
 
+#ifdef CONFIG_PIN_TLB
+	/* Map two more 8M kernel data pages.
+	*/
+	addi	r10, r10, 0x0100
+	mtspr	MD_CTR, r10
+
+	lis	r8, KERNELBASE@h	/* Create vaddr for TLB */
+	addis	r8, r8, 0x0080		/* Add 8M */
+	ori	r8, r8, MI_EVALID	/* Mark it valid */
+	mtspr	MD_EPN, r8
+	li	r9, MI_PS8MEG		/* Set 8M byte page */
+	ori	r9, r9, MI_SVALID	/* Make it valid */
+	mtspr	MD_TWC, r9
+	li	r11, MI_BOOTINIT	/* Create RPN for address 0 */
+	addis	r11, r11, 0x0080	/* Add 8M */
+	mtspr	MD_RPN, r8
+
+	addis	r8, r8, 0x0080		/* Add 8M */
+	mtspr	MD_EPN, r8
+	mtspr	MD_TWC, r9
+	addis	r11, r11, 0x0080	/* Add 8M */
+	mtspr	MD_RPN, r8
+#endif
+
 	/* Since the cache is enabled according to the information we
 	 * just loaded into the TLB, invalidate and enable the caches here.
 	 * We should probably check/set other modes....later.
diff -urN linux-2.4.22-bk25/arch/ppc/kernel/indirect_pci.c linux-2.4.22-bk26/arch/ppc/kernel/indirect_pci.c
--- linux-2.4.22-bk25/arch/ppc/kernel/indirect_pci.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/kernel/indirect_pci.c	2003-09-29 02:49:41.000000000 -0700
@@ -24,6 +24,12 @@
 #define cfg_read(val, addr, type, op)	*val = op((type)(addr))
 #define cfg_write(val, addr, type, op)	op((type *)(addr), (val))
 
+#ifdef CONFIG_PPC_INDIRECT_PCI_BE
+#define PCI_CFG_OUT out_be32
+#else
+#define PCI_CFG_OUT out_le32
+#endif
+
 #define INDIRECT_PCI_OP(rw, size, type, op, mask)			 \
 static int								 \
 indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
@@ -39,9 +45,9 @@
 		if (dev->bus->number != hose->first_busno)		 \
 			cfg_type = 1;					 \
 									 \
-	out_be32(hose->cfg_addr, 					 \
-		 (((offset & 0xfc) | cfg_type) << 24) | (dev->devfn << 16) \
-		 | ((dev->bus->number - hose->bus_offset) << 8) | 0x80); \
+	PCI_CFG_OUT(hose->cfg_addr, 					 \
+		 (0x80000000 | ((dev->bus->number - hose->bus_offset) << 16) \
+		  | (dev->devfn << 8) | ((offset & 0xfc) | cfg_type)));	 \
 	cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);	 \
 	return PCIBIOS_SUCCESSFUL;    					 \
 }
diff -urN linux-2.4.22-bk25/arch/ppc/kernel/irq.c linux-2.4.22-bk26/arch/ppc/kernel/irq.c
--- linux-2.4.22-bk25/arch/ppc/kernel/irq.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/kernel/irq.c	2003-09-29 02:49:41.000000000 -0700
@@ -429,7 +429,7 @@
 	int status;
 	struct irqaction *action;
 	int cpu = smp_processor_id();
-	irq_desc_t *desc = irq_desc + irq;
+	irq_desc_t *desc = &irq_desc[irq];
 
 	kstat.irqs[cpu][irq]++;
 	spin_lock(&desc->lock);
@@ -501,12 +501,25 @@
 	 * The ->end() handler has to deal with interrupts which got
 	 * disabled while the handler was running.
 	 */
-	if (irq_desc[irq].handler) {
-		if (irq_desc[irq].handler->end)
-			irq_desc[irq].handler->end(irq);
-		else if (irq_desc[irq].handler->enable)
-			irq_desc[irq].handler->enable(irq);
+	if (desc->handler) {
+		if (desc->handler->end)
+			desc->handler->end(irq);
+		else if (desc->handler->enable)
+			desc->handler->enable(irq);
 	}
+
+#ifdef CONFIG_DBOX2
+	/*
+	 * Interrupts marked as oneshot are level
+	 * triggered. We disable them here for onboard
+	 * hardware which can not be configured to
+	 * generate edge triggered interrupts due to
+	 * lack of documentation.
+	 */
+	if ((action) && (action->flags & SA_ONESHOT))
+		disable_irq_nosync(irq);
+#endif
+
 	spin_unlock(&desc->lock);
 }
 
diff -urN linux-2.4.22-bk25/arch/ppc/kernel/ppc_ksyms.c linux-2.4.22-bk26/arch/ppc/kernel/ppc_ksyms.c
--- linux-2.4.22-bk25/arch/ppc/kernel/ppc_ksyms.c	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/kernel/ppc_ksyms.c	2003-09-29 02:49:41.000000000 -0700
@@ -162,7 +162,7 @@
 EXPORT_SYMBOL(iopa);
 EXPORT_SYMBOL(mm_ptov);
 EXPORT_SYMBOL(ioremap);
-#ifdef CONFIG_44x
+#ifdef CONFIG_PTE_64BIT
 EXPORT_SYMBOL(ioremap64);
 #endif
 EXPORT_SYMBOL(__ioremap);
@@ -356,6 +356,7 @@
 EXPORT_SYMBOL(cpm_install_handler);
 EXPORT_SYMBOL(cpm_free_handler);
 EXPORT_SYMBOL(m8xx_cpm_hostalloc);
+EXPORT_SYMBOL(m8xx_cpm_dpalloc);
 #endif /* CONFIG_8xx */
 
 /* Those should really be inline */
diff -urN linux-2.4.22-bk25/arch/ppc/mm/pgtable.c linux-2.4.22-bk26/arch/ppc/mm/pgtable.c
--- linux-2.4.22-bk25/arch/ppc/mm/pgtable.c	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/ppc/mm/pgtable.c	2003-09-29 02:49:41.000000000 -0700
@@ -37,10 +37,11 @@
 unsigned long ioremap_bot;
 int io_bat_index;
 
-/* Maximum 768Mb of lowmem. On SMP, this value will be
- * trimmed down to whatever can be covered by BATs though.
+/* The maximum lowmem defaults to 768Mb, but this can be configured to
+ * another value.  On SMP, this value will be trimmed down to whatever
+ * can be covered by BATs.
  */
-#define MAX_LOW_MEM	0x30000000
+#define MAX_LOW_MEM	CONFIG_LOWMEM_SIZE
 
 #ifndef CONFIG_SMP
 struct pgtable_cache_struct quicklists;
@@ -67,7 +68,7 @@
 #define p_mapped_by_bats(x)	(0UL)
 #endif /* HAVE_BATS */
 
-#ifdef CONFIG_44x
+#ifdef CONFIG_PTE_64BIT
 void *
 ioremap(phys_addr_t addr, unsigned long size)
 {
@@ -82,14 +83,14 @@
 	return __ioremap(addr, size, _PAGE_NO_CACHE);
 }
 
-#else /* CONFIG_44x */
+#else /* !CONFIG_PTE_64BIT */
 
 void *
 ioremap(phys_addr_t addr, unsigned long size)
 {
 	return __ioremap(addr, size, _PAGE_NO_CACHE);
 }
-#endif /* CONFIG_44x */
+#endif /* CONFIG_PTE_64BIT */
 
 void *
 __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
diff -urN linux-2.4.22-bk25/arch/ppc/platforms/dbox2.h linux-2.4.22-bk26/arch/ppc/platforms/dbox2.h
--- linux-2.4.22-bk25/arch/ppc/platforms/dbox2.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.22-bk26/arch/ppc/platforms/dbox2.h	2003-09-29 02:49:41.000000000 -0700
@@ -0,0 +1,24 @@
+/*
+ * D-BOX2 board specific definitions
+ * 
+ * Copyright (c) 2001-2002 Florian Schirmer (jolt@tuxbox.org)
+ */
+
+#ifndef __MACH_DBOX2_H
+#define __MACH_DBOX2_H
+
+#include <linux/config.h>
+ 
+#include <asm/ppcboot.h>
+
+#define	DBOX2_IMMR_BASE	0xFF000000	/* phys. addr of IMMR */
+#define	DBOX2_IMAP_SIZE	(64 * 1024)	/* size of mapped area */
+
+#define	IMAP_ADDR	DBOX2_IMMR_BASE	/* physical base address of IMMR area */
+#define IMAP_SIZE	DBOX2_IMAP_SIZE	/* mapped size of IMMR area */
+
+/* We don't use the 8259.
+*/
+#define NR_8259_INTS	0
+
+#endif	/* __MACH_DBOX2_H */
diff -urN linux-2.4.22-bk25/arch/x86_64/Makefile linux-2.4.22-bk26/arch/x86_64/Makefile
--- linux-2.4.22-bk25/arch/x86_64/Makefile	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/Makefile	2003-09-29 02:49:41.000000000 -0700
@@ -19,7 +19,7 @@
 # 20010105  Andi Kleen, add IA32 compiler.
 #           ....and later removed it again....
 #
-# $Id: Makefile,v 1.33 2003/05/12 14:36:34 ak Exp $
+# $Id: Makefile,v 1.34 2003/09/25 02:50:05 ak Exp $
 
 #
 # early bootup linking needs 32bit. You can either use real 32bit tools
@@ -38,6 +38,8 @@
 LDFLAGS=-e stext
 LINKFLAGS =-T $(TOPDIR)/arch/x86_64/vmlinux.lds $(LDFLAGS)
 
+check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1 ; then echo "$(1)"; else echo "$(2)"; fi)
+
 CFLAGS += -mno-red-zone
 CFLAGS += -mcmodel=kernel
 CFLAGS += -pipe
@@ -51,9 +53,7 @@
 ifneq ($(CONFIG_X86_REMOTE_DEBUG),y)
 CFLAGS += -fno-asynchronous-unwind-tables
 endif
-
-# prevent gcc from keeping the stack 16 byte aligned (FIXME)
-#CFLAGS += -mpreferred-stack-boundary=2
+CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
 
 HEAD := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
 
diff -urN linux-2.4.22-bk25/arch/x86_64/boot/setup.S linux-2.4.22-bk26/arch/x86_64/boot/setup.S
--- linux-2.4.22-bk25/arch/x86_64/boot/setup.S	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/boot/setup.S	2003-09-29 02:49:41.000000000 -0700
@@ -524,7 +524,7 @@
 	cmpw	$0, %cs:realmode_swtch
 	jz	rmodeswtch_normal
 
-	lcall	%cs:realmode_swtch
+	lcall	*%cs:realmode_swtch
 
 	jmp	rmodeswtch_end
 
diff -urN linux-2.4.22-bk25/arch/x86_64/config.in linux-2.4.22-bk26/arch/x86_64/config.in
--- linux-2.4.22-bk25/arch/x86_64/config.in	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/config.in	2003-09-29 02:49:41.000000000 -0700
@@ -66,7 +66,7 @@
    define_bool CONFIG_X86_UP_IOAPIC y
 else
    define_bool CONFIG_HAVE_DEC_LOCK y
-   int  'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32
+   int  'Maximum number of CPUs (2-8)' CONFIG_NR_CPUS 4
 fi
 
 bool 'Machine check support' CONFIG_MCE
diff -urN linux-2.4.22-bk25/arch/x86_64/defconfig linux-2.4.22-bk26/arch/x86_64/defconfig
--- linux-2.4.22-bk25/arch/x86_64/defconfig	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/defconfig	2003-09-29 02:49:41.000000000 -0700
@@ -40,13 +40,15 @@
 CONFIG_X86_IO_APIC=y
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_MTRR=y
-# CONFIG_SMP is not set
-CONFIG_NR_CPUS=32
+CONFIG_SMP=y
 CONFIG_HPET_TIMER=y
 CONFIG_GART_IOMMU=y
-CONFIG_X86_UP_IOAPIC=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_NR_CPUS=4
 CONFIG_MCE=y
-# CONFIG_K8_NUMA is not set
+CONFIG_K8_NUMA=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_NUMA=y
 
 #
 # General setup
@@ -89,6 +91,7 @@
 # CONFIG_ACPI_ASUS is not set
 # CONFIG_ACPI_TOSHIBA is not set
 CONFIG_ACPI_DEBUG=y
+# CONFIG_ACPI_RELAXED_AML is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -109,6 +112,7 @@
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -307,6 +311,9 @@
 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_AIC7XXX_PROBE_EISA_VL is not set
 # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -351,8 +358,9 @@
 #
 # Fusion MPT device support
 #
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_BOOT is not set
+CONFIG_FUSION=y
+CONFIG_FUSION_BOOT=y
+CONFIG_FUSION_MAX_SGE=40
 # CONFIG_FUSION_ISENSE is not set
 # CONFIG_FUSION_CTL is not set
 # CONFIG_FUSION_LAN is not set
@@ -517,6 +525,7 @@
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_RNG is not set
 # CONFIG_INTEL_RNG is not set
+CONFIG_HW_RANDOM=y
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
@@ -529,7 +538,7 @@
 #
 # CONFIG_FTAPE is not set
 CONFIG_AGP=y
-CONFIG_AGP_AMD_8151=y
+CONFIG_AGP_AMD_K8=y
 CONFIG_AGP_INTEL=y
 CONFIG_AGP_I810=y
 CONFIG_AGP_VIA=y
@@ -537,6 +546,12 @@
 CONFIG_AGP_SIS=y
 CONFIG_AGP_ALI=y
 CONFIG_AGP_SWORKS=y
+CONFIG_AGP_NVIDIA=y
+# CONFIG_AGP_ATI is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
 # CONFIG_DRM is not set
 # CONFIG_MWAVE is not set
 
@@ -549,6 +564,7 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_REISERFS_FS=y
@@ -558,6 +574,7 @@
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BEFS_DEBUG is not set
 # CONFIG_BFS_FS is not set
@@ -599,6 +616,7 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_SIMICSFS is not set
 
 #
 # Network File Systems
@@ -607,6 +625,7 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
@@ -704,17 +723,23 @@
 # CONFIG_BLUEZ is not set
 
 #
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
 # Kernel hacking
 #
 CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_SLAB=y
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_CHECKING is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_CHECKING=y
 # CONFIG_INIT_DEBUG is not set
-# CONFIG_IOMMU_DEBUG is not set
+CONFIG_IOMMU_DEBUG=y
 CONFIG_IOMMU_LEAK=y
 # CONFIG_DEBUG_STACKOVERFLOW is not set
+CONFIG_LOG_BUF_SHIFT=17
 
 #
 # Library routines
diff -urN linux-2.4.22-bk25/arch/x86_64/ia32/ia32_binfmt.c linux-2.4.22-bk26/arch/x86_64/ia32/ia32_binfmt.c
--- linux-2.4.22-bk25/arch/x86_64/ia32/ia32_binfmt.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/ia32/ia32_binfmt.c	2003-09-29 02:49:41.000000000 -0700
@@ -28,7 +28,6 @@
 
 #define ELF_NAME "elf/i386"
 
-#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
 #define IA32_STACK_TOP IA32_PAGE_OFFSET
 #define ELF_ET_DYN_BASE		(IA32_PAGE_OFFSET/3 + 0x1000000)
 
diff -urN linux-2.4.22-bk25/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.22-bk26/arch/x86_64/ia32/ia32_ioctl.c
--- linux-2.4.22-bk25/arch/x86_64/ia32/ia32_ioctl.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/ia32/ia32_ioctl.c	2003-09-29 02:49:41.000000000 -0700
@@ -1,4 +1,4 @@
-/* $Id: ia32_ioctl.c,v 1.34 2003/05/08 06:34:01 ak Exp $
+/* $Id: ia32_ioctl.c,v 1.37 2003/08/20 11:00:23 ak Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -2472,6 +2472,9 @@
 	mm_segment_t old_fs;
 	void *karg = &u;
 
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
 	switch (cmd) {
 	case VG_STATUS:
 		v = kmalloc(sizeof(vg_t), GFP_KERNEL);
@@ -3535,6 +3538,7 @@
 COMPATIBLE_IOCTL(TIOCGPTN)
 COMPATIBLE_IOCTL(TIOCSPTLCK)
 COMPATIBLE_IOCTL(TIOCSERGETLSR)
+COMPATIBLE_IOCTL(FIOQSIZE)
 /* Big F */
 COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO)
 COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
@@ -4416,6 +4420,9 @@
 	struct ioctl_trans *t;
 	unsigned long hash = ioctl32_hash(cmd);
 
+	if (handler == NULL)
+		handler = (void *)sys_ioctl; 
+
 	lock_kernel(); 
 	for (t = (struct ioctl_trans *)ioctl32_hash_table[hash];
 	     t;
@@ -4555,7 +4562,7 @@
 			       "cmd(%08x){%s} arg(%08x) on %s\n",
 			       current->comm, current->pid,
 			       (int)fd, (unsigned int)cmd, buf, (unsigned int)arg,
-			       IS_ERR(fn) ? "???" : fn);
+			       fn);
 			if (path) 
 				free_page((unsigned long)path); 
 		}
diff -urN linux-2.4.22-bk25/arch/x86_64/ia32/ia32_signal.c linux-2.4.22-bk26/arch/x86_64/ia32/ia32_signal.c
--- linux-2.4.22-bk25/arch/x86_64/ia32/ia32_signal.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/ia32/ia32_signal.c	2003-09-29 02:49:41.000000000 -0700
@@ -7,7 +7,7 @@
  *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
  *  2000-12-*   x86-64 compatibility mode signal handling by Andi Kleen
  * 
- *  $Id: ia32_signal.c,v 1.31 2003/03/12 08:22:12 ak Exp $
+ *  $Id: ia32_signal.c,v 1.32 2003/09/06 18:10:44 ak Exp $
  */
 
 #include <linux/sched.h>
@@ -78,6 +78,10 @@
 		default:
 			err |= __put_user(from->si_uid, &to->si_uid);
 			break;
+		case __SI_POLL >> 16:
+			err |= __put_user(from->si_band, &to->si_band); 
+			err |= __put_user(from->si_fd, &to->si_fd); 
+			break;
 		/* case __SI_RT: This is not generated by the kernel as of now.  */
 		}
 		return err;
diff -urN linux-2.4.22-bk25/arch/x86_64/ia32/ia32entry.S linux-2.4.22-bk26/arch/x86_64/ia32/ia32entry.S
--- linux-2.4.22-bk25/arch/x86_64/ia32/ia32entry.S	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/ia32/ia32entry.S	2003-09-29 02:49:41.000000000 -0700
@@ -3,7 +3,7 @@
  * 		
  * Copyright 2000,2001 Andi Kleen, SuSE Labs.
  * 
- * $Id: ia32entry.S,v 1.40 2003/04/03 09:46:54 ak Exp $ 		
+ * $Id: ia32entry.S,v 1.41 2003/09/22 04:25:53 ak Exp $ 		
  */		 
 
 #include <asm/calling.h>
@@ -256,10 +256,10 @@
 	.quad sys32_adjtimex
 	.quad sys32_mprotect		/* 125 */
 	.quad sys32_sigprocmask
-	.quad sys32_module_warning	/* create_module */
-	.quad sys32_module_warning	/* init_module */
-	.quad sys32_module_warning	/* delete module */
-	.quad sys32_module_warning	/* 130  get_kernel_syms */
+	.quad sys32_create_module
+	.quad sys32_init_module
+	.quad sys32_delete_module
+	.quad sys32_get_kernel_syms 	/* 130 */
 	.quad ni_syscall	/* quotactl */ 
 	.quad sys_getpgid
 	.quad sys_fchdir
@@ -296,7 +296,7 @@
 	.quad sys_setresuid16
 	.quad sys_getresuid16	/* 165 */
 	.quad sys32_vm86_warning	/* vm86 */ 
-	.quad quiet_ni_syscall	/* query_module */
+	.quad sys32_query_module
 	.quad sys_poll
 	.quad sys32_nfsservctl
 	.quad sys_setresgid16	/* 170 */
diff -urN linux-2.4.22-bk25/arch/x86_64/ia32/ipc32.c linux-2.4.22-bk26/arch/x86_64/ia32/ipc32.c
--- linux-2.4.22-bk25/arch/x86_64/ia32/ipc32.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/ia32/ipc32.c	2003-09-29 02:49:41.000000000 -0700
@@ -16,6 +16,8 @@
 
 #include <asm/ia32.h>
 
+extern int sem_ctls[];
+
 /*
  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
  *
@@ -163,6 +165,7 @@
 #define SEMOP		 1
 #define SEMGET		 2
 #define SEMCTL		 3
+#define SEMTIMEDOP       4
 #define MSGSND		11
 #define MSGRCV		12
 #define MSGGET		13
@@ -638,7 +641,27 @@
 	switch (call) {
 	      case SEMOP:
 		/* struct sembuf is the same on 32 and 64bit :)) */
-		return sys_semop(first, (struct sembuf *)AA(ptr), second);
+		return sys_semtimedop(first, (struct sembuf *)AA(ptr), second, NULL);
+	      case SEMTIMEDOP: { 
+		int err;
+		mm_segment_t oldfs = get_fs();
+		struct timespec32 *ts32 = (struct timespec32 *)AA(fifth);
+		struct timespec ts;
+		if ((unsigned)second > sem_ctls[2])
+			return -EINVAL;		
+		if (ts32) { 
+			if (get_user(ts.tv_sec, &ts32->tv_sec) ||
+				__get_user(ts.tv_nsec, &ts32->tv_nsec) ||
+				verify_area(VERIFY_READ, (void *)AA(ptr), 
+								second*sizeof(struct sembuf)))
+					return -EFAULT; 
+		} 			
+		set_fs(KERNEL_DS); 
+	 	err = sys_semtimedop(first, (struct sembuf *)AA(ptr), second,
+					ts32 ? &ts : NULL); 
+		set_fs(oldfs);
+		return err; 			
+	      }	
 	      case SEMGET:
 		return sys_semget(first, second, third);
 	      case SEMCTL:
@@ -663,9 +686,7 @@
 	      case SHMCTL:
 		return shmctl32(first, second, (void *)AA(ptr));
 
-	      default:
-		return -EINVAL;
 	}
-	return -EINVAL;
+	return -ENOSYS;
 }
 
diff -urN linux-2.4.22-bk25/arch/x86_64/ia32/socket32.c linux-2.4.22-bk26/arch/x86_64/ia32/socket32.c
--- linux-2.4.22-bk25/arch/x86_64/ia32/socket32.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/ia32/socket32.c	2003-09-29 02:49:41.000000000 -0700
@@ -503,7 +503,6 @@
 		__u32 filter;
 	} *fprog32 = (struct sock_fprog32 *)optval;
 	struct sock_fprog kfprog;
-	unsigned int fsize;
 	mm_segment_t old_fs;
 	__u32 uptr;
 	int ret;
diff -urN linux-2.4.22-bk25/arch/x86_64/ia32/sys_ia32.c linux-2.4.22-bk26/arch/x86_64/ia32/sys_ia32.c
--- linux-2.4.22-bk25/arch/x86_64/ia32/sys_ia32.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/ia32/sys_ia32.c	2003-09-29 02:49:41.000000000 -0700
@@ -16,7 +16,7 @@
  *
  * This file assumes that there is a hole at the end of user address space.
  *
- * $Id: sys_ia32.c,v 1.58 2003/05/09 17:21:17 ak Exp $
+ * $Id: sys_ia32.c,v 1.62 2003/09/22 04:25:53 ak Exp $
  */
 
 #include <linux/config.h>
@@ -475,7 +475,13 @@
 	    __put_user (kbuf->f_ffree, &ubuf->f_ffree) ||
 	    __put_user (kbuf->f_namelen, &ubuf->f_namelen) ||
 	    __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
-	    __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]))
+	    __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) ||
+	    __put_user (0, &ubuf->f_spare[0]) ||
+	    __put_user (0, &ubuf->f_spare[1]) ||
+	    __put_user (0, &ubuf->f_spare[2]) ||
+	    __put_user (0, &ubuf->f_spare[3]) ||
+	    __put_user (0, &ubuf->f_spare[4]) ||
+	    __put_user (0, &ubuf->f_spare[5]))
 		return -EFAULT;
 	return 0;
 }
@@ -925,11 +931,6 @@
 			    (struct timeval32 *)A(a.tvp));
 }
 
-struct timespec32 {
-	int 	tv_sec;
-	int	tv_nsec;
-};
-
 extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp); 
 
 asmlinkage long
@@ -1517,10 +1518,30 @@
 	struct sysinfo s;
 	int ret;
 	mm_segment_t old_fs = get_fs ();
+	int bitcount = 0;
 	
 	set_fs (KERNEL_DS);
 	ret = sys_sysinfo(&s);
 	set_fs (old_fs);
+
+        /* Check to see if any memory value is too large for 32-bit and scale
+	 *  down if needed
+	 */
+	if ((s.totalram >> 32) || (s.totalswap >> 32)) {
+		while (s.mem_unit < PAGE_SIZE) {
+			s.mem_unit <<= 1;
+			bitcount++;
+		}
+		s.totalram >>= bitcount;
+		s.freeram >>= bitcount;
+		s.sharedram >>= bitcount;
+		s.bufferram >>= bitcount;
+		s.totalswap >>= bitcount;
+		s.freeswap >>= bitcount;
+		s.totalhigh >>= bitcount;
+		s.freehigh >>= bitcount;
+	}
+
 	if (verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo32)) ||
 	    __put_user (s.uptime, &info->uptime) ||
 	    __put_user (s.loads[0], &info->loads[0]) ||
@@ -2534,17 +2555,422 @@
 }
 #endif
 
-long sys32_module_warning(void)
+#ifdef CONFIG_MODULES
+
+extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
+
+asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
 { 
-	static long warn_time = -(60*HZ); 
-	if (time_before(warn_time + 60*HZ,jiffies) && strcmp(current->comm,"klogd")) { 
-		printk(KERN_INFO "%s: 32bit modutils not supported on 64bit kernel\n",
-		       current->comm);
-		warn_time = jiffies;
+	return sys_create_module(name_user, (size_t)size);
+}
+
+extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
+
+/* Hey, when you're trying to init module, take time and prepare us a nice 64bit
+ * module structure, even if from 32bit modutils... Why to pollute kernel... :))
+ */
+asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
+{
+	return sys_init_module(name_user, mod_user);
+}
+
+extern asmlinkage int sys_delete_module(const char *name_user);
+
+asmlinkage int sys32_delete_module(const char *name_user)
+{
+	return sys_delete_module(name_user);
+}
+
+struct module_info32 {
+	u32 addr;
+	u32 size;
+	u32 flags;
+	s32 usecount;
+};
+
+/* Query various bits about modules.  */
+
+static inline long
+get_mod_name(const char *user_name, char **buf)
+{
+	unsigned long page;
+	long retval;
+
+	if ((unsigned long)user_name >= TASK_SIZE
+	    && !segment_eq(get_fs (), KERNEL_DS))
+		return -EFAULT;
+
+	page = __get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
+	if (retval > 0) {
+		if (retval < PAGE_SIZE) {
+			*buf = (char *)page;
+			return retval;
 	} 
-	return -ENOSYS ;
+		retval = -ENAMETOOLONG;
+	} else if (!retval)
+		retval = -EINVAL;
+
+	free_page(page);
+	return retval;
+}
+
+static inline void
+put_mod_name(char *buf)
+{
+	free_page((unsigned long)buf);
 } 
 
+static __inline__ struct module *find_module(const char *name)
+{
+	struct module *mod;
+
+	for (mod = module_list; mod ; mod = mod->next) {
+		if (mod->flags & MOD_DELETED)
+			continue;
+		if (!strcmp(mod->name, name))
+			break;
+	}
+
+	return mod;
+}
+
+static int
+qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	struct module *mod;
+	size_t nmod, space, len;
+
+	nmod = space = 0;
+
+	for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
+		len = strlen(mod->name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+		if (copy_to_user(buf, mod->name, len))
+			return -EFAULT;
+		buf += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	if (put_user(nmod, ret))
+		return -EFAULT;
+	else
+		return 0;
+
+calc_space_needed:
+	space += len;
+	while ((mod = mod->next)->next != NULL)
+		space += strlen(mod->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static int
+qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	size_t i, space, len;
+
+	if (mod->next == NULL)
+		return -EINVAL;
+	if (!MOD_CAN_QUERY(mod))
+		return put_user(0, ret);
+
+	space = 0;
+	for (i = 0; i < mod->ndeps; ++i) {
+		const char *dep_name = mod->deps[i].dep->name;
+
+		len = strlen(dep_name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+		if (copy_to_user(buf, dep_name, len))
+			return -EFAULT;
+		buf += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	return put_user(i, ret);
+
+calc_space_needed:
+	space += len;
+	while (++i < mod->ndeps)
+		space += strlen(mod->deps[i].dep->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static int
+qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	size_t nrefs, space, len;
+	struct module_ref *ref;
+
+	if (mod->next == NULL)
+		return -EINVAL;
+	if (!MOD_CAN_QUERY(mod))
+		if (put_user(0, ret))
+			return -EFAULT;
+		else
+			return 0;
+
+	space = 0;
+	for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
+		const char *ref_name = ref->ref->name;
+
+		len = strlen(ref_name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+		if (copy_to_user(buf, ref_name, len))
+			return -EFAULT;
+		buf += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	if (put_user(nrefs, ret))
+		return -EFAULT;
+	else
+		return 0;
+
+calc_space_needed:
+	space += len;
+	while ((ref = ref->next_ref) != NULL)
+		space += strlen(ref->ref->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static inline int
+qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	size_t i, space, len;
+	struct module_symbol *s;
+	char *strings;
+	unsigned *vals;
+
+	if (!MOD_CAN_QUERY(mod))
+		if (put_user(0, ret))
+			return -EFAULT;
+		else
+			return 0;
+
+	space = mod->nsyms * 2*sizeof(u32);
+
+	i = len = 0;
+	s = mod->syms;
+
+	if (space > bufsize)
+		goto calc_space_needed;
+
+	if (!access_ok(VERIFY_WRITE, buf, space))
+		return -EFAULT;
+
+	bufsize -= space;
+	vals = (unsigned *)buf;
+	strings = buf+space;
+
+	for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
+		len = strlen(s->name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+
+		if (copy_to_user(strings, s->name, len)
+		    || __put_user(s->value, vals+0)
+		    || __put_user(space, vals+1))
+			return -EFAULT;
+
+		strings += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	if (put_user(i, ret))
+		return -EFAULT;
+	else
+		return 0;
+
+calc_space_needed:
+	for (; i < mod->nsyms; ++i, ++s)
+		space += strlen(s->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static inline int
+qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	int error = 0;
+
+	if (mod->next == NULL)
+		return -EINVAL;
+
+	if (sizeof(struct module_info32) <= bufsize) {
+		struct module_info32 info;
+		info.addr = (unsigned long)mod;
+		info.size = mod->size;
+		info.flags = mod->flags;
+		info.usecount =
+			((mod_member_present(mod, can_unload)
+			  && mod->can_unload)
+			 ? -1 : atomic_read(&mod->uc.usecount));
+
+		if (copy_to_user(buf, &info, sizeof(struct module_info32)))
+			return -EFAULT;
+	} else
+		error = -ENOSPC;
+
+	if (put_user(sizeof(struct module_info32), ret))
+		return -EFAULT;
+
+	return error;
+}
+
+asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
+{
+	struct module *mod;
+	int err;
+
+	lock_kernel();
+	if (name_user == 0) {
+		/* This finds "kernel_module" which is not exported. */
+		for(mod = module_list; mod->next != NULL; mod = mod->next)
+			;
+	} else {
+		long namelen;
+		char *name;
+
+		if ((namelen = get_mod_name(name_user, &name)) < 0) {
+			err = namelen;
+			goto out;
+		}
+		err = -ENOENT;
+		if (namelen == 0) {
+			/* This finds "kernel_module" which is not exported. */
+			for(mod = module_list; mod->next != NULL; mod = mod->next)
+				;
+		} else if ((mod = find_module(name)) == NULL) {
+			put_mod_name(name);
+			goto out;
+		}
+		put_mod_name(name);
+	}
+
+	switch (which)
+	{
+	case 0:
+		err = 0;
+		break;
+	case QM_MODULES:
+		err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_DEPS:
+		err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_REFS:
+		err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_SYMBOLS:
+		err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_INFO:
+		err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+out:
+	unlock_kernel();
+	return err;
+}
+
+struct kernel_sym32 {
+	u32 value;
+	char name[60];
+};
+		 
+extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
+
+asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
+{
+	int len, i;
+	struct kernel_sym *tbl;
+	mm_segment_t old_fs;
+	
+	len = sys_get_kernel_syms(NULL);
+	if (!table) return len;
+	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
+	if (!tbl) return -ENOMEM;
+	old_fs = get_fs();
+	set_fs (KERNEL_DS);
+	sys_get_kernel_syms(tbl);
+	set_fs (old_fs);
+	for (i = 0; i < len; i++, table++) {
+		if (put_user (tbl[i].value, &table->value) ||
+		    copy_to_user (table->name, tbl[i].name, 60))
+			break;
+	}
+	kfree (tbl);
+	return i;
+}
+
+#else /* CONFIG_MODULES */
+
+asmlinkage unsigned long
+sys32_create_module(const char *name_user, size_t size)
+{
+	return -ENOSYS;
+}
+
+asmlinkage int
+sys32_init_module(const char *name_user, struct module *mod_user)
+{
+	return -ENOSYS;
+}
+
+asmlinkage int
+sys32_delete_module(const char *name_user)
+{
+	return -ENOSYS;
+}
+
+asmlinkage int
+sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
+		 size_t *ret)
+{
+	/* Let the program know about the new interface.  Not that
+	   it'll do them much good.  */
+	if (which == 0)
+		return 0;
+
+	return -ENOSYS;
+}
+
+asmlinkage int
+sys32_get_kernel_syms(struct kernel_sym *table)
+{
+	return -ENOSYS;
+}
+
+#endif  /* CONFIG_MODULES */
+
 long sys32_vm86_warning(void)
 { 
 	static long warn_time = -(60*HZ); 
@@ -2565,7 +2991,7 @@
 
 static int __init ia32_init (void)
 {
-	printk("IA32 emulation $Id: sys_ia32.c,v 1.58 2003/05/09 17:21:17 ak Exp $\n");  
+	printk("IA32 emulation $Id: sys_ia32.c,v 1.62 2003/09/22 04:25:53 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.22-bk25/arch/x86_64/kernel/acpi.c linux-2.4.22-bk26/arch/x86_64/kernel/acpi.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/acpi.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/acpi.c	2003-09-29 02:49:41.000000000 -0700
@@ -44,6 +44,7 @@
 #include <asm/io_apic.h>
 #include <asm/proto.h>
 
+extern int acpi_disabled;
 
 #define PREFIX			"ACPI: "
 
@@ -352,6 +353,28 @@
 #ifdef CONFIG_X86_LOCAL_APIC
 
 	/* 
+	 * ACPI interpreter is required to complete interrupt setup,
+	 * so if it is off, don't enumerate the io-apics with ACPI.
+	 * If MPS is present, it will handle them,
+	 * otherwise the system will stay in PIC mode
+	 */
+	if (acpi_disabled) {
+		return 1;
+	}
+
+	if (!use_acpi_pci)
+		return 0; 
+
+	/* If "nolocalapic" is specified don't look further */
+	extern int apic_disabled;
+	if (apic_disabled) {
+		printk(KERN_INFO PREFIX "Skipping Local/IO-APIC probe due to \"nolocalapic\"\n");
+		return 0;	
+	}	
+	printk(KERN_INFO PREFIX "Parsing Local APIC info in MADT\n"); 
+	
+
+	/* 
 	 * MADT
 	 * ----
 	 * Parse the Multiple APIC Description Table (MADT), if exists.
@@ -412,6 +435,15 @@
 #ifdef CONFIG_X86_IO_APIC
 
 	/* 
+	 * if "noapic" boot option, don't look for IO-APICs
+	 */
+	if (ioapic_setup_disabled()) {
+		printk(KERN_INFO PREFIX "Skipping IOAPIC probe "
+			"due to 'noapic' option.\n");
+		return 1;
+        }
+
+	/* 
 	 * I/O APIC 
 	 * --------
 	 */
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/acpi_wakeup.S linux-2.4.22-bk26/arch/x86_64/kernel/acpi_wakeup.S
--- linux-2.4.22-bk25/arch/x86_64/kernel/acpi_wakeup.S	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/acpi_wakeup.S	2003-09-29 02:49:41.000000000 -0700
@@ -209,7 +209,7 @@
 
 	movw	$0x0e00 + '!', %ds:(0xb801a)
 	movq	saved_eip, %rax
-	jmp	%rax
+	jmp	*%rax
 
 .code32
 
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/bluesmoke.c linux-2.4.22-bk26/arch/x86_64/kernel/bluesmoke.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/bluesmoke.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/bluesmoke.c	2003-09-29 02:49:41.000000000 -0700
@@ -186,7 +186,7 @@
 	[0] = "err cpu1",
 };
 
-static void check_k8_nb(void)
+static void check_k8_nb(int header)
 {
 	struct pci_dev *nb;
 	nb = find_k8_nb(); 
@@ -198,6 +198,9 @@
 	pci_read_config_dword(nb, 0x4c, &statushigh);
 	if (!(statushigh & (1<<31)))
 		return;
+	if (header) 
+		printk(KERN_ERR "CPU %d: Silent Northbridge MCE\n", smp_processor_id());
+
 	printk(KERN_ERR "Northbridge status %08x%08x\n",
 	       statushigh,statuslow); 
 
@@ -257,9 +260,11 @@
 	rdmsrl(MSR_IA32_MCG_STATUS, status); 
 	if ((status & (1<<2)) == 0) { 
 		if (!regs) 
-			check_k8_nb();
+			check_k8_nb(1);
 		return; 
 	}
+	printk(KERN_EMERG "CPU %d: Machine Check Exception: %016Lx\n", smp_processor_id(), status);
+
 	if (status & 1)
 		printk(KERN_EMERG "MCG_STATUS: unrecoverable\n"); 
 
@@ -277,7 +282,7 @@
 	if (nbstatus & (1UL<57))
 		printk(KERN_EMERG "Unrecoverable condition\n"); 
 		
-	check_k8_nb();
+	check_k8_nb(0);
 
 	if (nbstatus & (1UL<<58)) { 
 		u64 adr;
@@ -338,7 +343,6 @@
 {
 	u64 cap;
 	int i;
-	struct pci_dev *nb; 
 
 	if (!test_bit(X86_FEATURE_MCE, &c->x86_capability) || 
 	    !test_bit(X86_FEATURE_MCA, &c->x86_capability))
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/e820.c linux-2.4.22-bk26/arch/x86_64/kernel/e820.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/e820.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/e820.c	2003-09-29 02:49:41.000000000 -0700
@@ -1,7 +1,7 @@
 /* 
  * Handle the memory map.
  * The functions here do the job until bootmem takes over.
- * $Id: e820.c,v 1.6 2002/10/15 09:35:16 ak Exp $
+ * $Id: e820.c,v 1.10 2003/09/25 03:22:05 ak Exp $
  */
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -12,6 +12,7 @@
 #include <asm/page.h>
 #include <asm/e820.h>
 #include <asm/proto.h>
+#include <asm/acpi.h>
 #include <asm/bootsetup.h>
 
 extern unsigned long table_start, table_end;
@@ -488,7 +489,6 @@
 			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);
@@ -500,7 +500,6 @@
 extern char command_line[], saved_command_line[];
 extern int fallback_aper_order;
 extern int iommu_setup(char *opt);
-extern int acpi_disabled;
 
 void __init parse_mem_cmdline (char ** cmdline_p)
 {
@@ -541,6 +540,22 @@
 #endif
  		else if (!memcmp(from, "acpi=off", 8))
   			acpi_disabled = 1;
+		else if (!memcmp(from,"maxcpus=0",9)) {
+			disable_ioapic_setup();
+			apic_disabled = 1;
+		}
+		
+		else if (!memcmp(from, "noapic", 6)) 
+			disable_ioapic_setup();
+		else if (!memcmp(from, "nolocalapic", 11) || !memcmp(from,"nolapic",7))
+			apic_disabled = 1;
+		else if (!memcmp(from, "pci=noacpi", 10))
+			use_acpi_pci = 0;
+		else if (!memcmp(from,"apic",4)) {
+			extern int ioapic_force;
+			ioapic_force = 1;
+			skip_ioapic_setup = 0;
+		}
 		
 	next:
 		c = *(from++);
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/head.S linux-2.4.22-bk26/arch/x86_64/kernel/head.S
--- linux-2.4.22-bk25/arch/x86_64/kernel/head.S	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/head.S	2003-09-29 02:49:41.000000000 -0700
@@ -6,7 +6,7 @@
  *  Copyright (C) 2000 Karsten Keil <kkeil@suse.de>
  *  Copyright (C) 2001,2002 Andi Kleen <ak@suse.de>
  *
- *  $Id: head.S,v 1.56 2003/05/12 14:38:43 ak Exp $
+ *  $Id: head.S,v 1.57 2003/07/11 15:58:46 ak Exp $
  */
 
 
@@ -312,7 +312,8 @@
 ENTRY(level3_physmem_pgt)
 	.quad	0x0000000000105007		/* -> level2_kernel_pgt (so that __va works even before pagetable_init) */
 
-.org 0xb000
+	.org 0xb000
+#ifdef CONFIG_ACPI_SLEEP
 ENTRY(wakeup_level4_pgt)
         .quad   0x0000000000102007              /* -> level3_ident_pgt */
         .fill   255,8,0
@@ -320,6 +321,7 @@
         .fill   254,8,0
         /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
         .quad   0x0000000000103007              /* -> level3_kernel_pgt */
+#endif
 
 .data
 
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/io_apic.c linux-2.4.22-bk26/arch/x86_64/kernel/io_apic.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/io_apic.c	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/io_apic.c	2003-09-29 02:49:41.000000000 -0700
@@ -165,6 +165,14 @@
 	struct IO_APIC_route_entry entry;
 	unsigned long flags;
 
+        /* Check delivery_mode to be sure we're not clearing an SMI pin */
+        spin_lock_irqsave(&ioapic_lock, flags);
+        *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
+        *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
+        spin_unlock_irqrestore(&ioapic_lock, flags);
+        if (entry.delivery_mode == dest_SMI)
+                return;
+
 	/*
 	 * Disable it in the IO-APIC irq-routing table:
 	 */
@@ -194,9 +202,11 @@
 int pirq_entries [MAX_PIRQS];
 int pirqs_enabled;
 int skip_ioapic_setup;
+int ioapic_force; 
 
 static int __init noioapic_setup(char *str)
 {
+	ioapic_force = 1;
 	skip_ioapic_setup = 1;
 	return 1;
 }
@@ -205,12 +215,66 @@
 
 static int __init ioapic_setup(char *str)
 {
+	ioapic_force = 1;
 	skip_ioapic_setup = 0;
 	return 1;
 }
 
 __setup("apic", ioapic_setup);
 
+#ifndef CONFIG_SMP
+#include <asm/pci-direct.h>
+#include <linux/pci_ids.h>
+#include <linux/pci.h>
+
+/* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC
+   off. Check for an Nvidia or VIA PCI bridge and turn it off.
+   Use pci direct infrastructure because this runs before the PCI subsystem. 
+
+   Can be overwritten with "apic" */
+void __init check_ioapic(void) 
+{ 
+	int num,slot,func; 
+	if (ioapic_force) 
+		return; 
+
+	/* Poor man's PCI discovery */
+	for (num = 0; num < 32; num++) { 
+		for (slot = 0; slot < 32; slot++) { 
+			for (func = 0; func < 8; func++) { 
+				u32 class;
+				u32 vendor;
+				class = read_pci_config(num,slot,func,
+							PCI_CLASS_REVISION);
+				if (class == 0xffffffff)
+					break; 
+
+		       		if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
+					continue; 
+
+				vendor = read_pci_config(num, slot, func, 
+							 PCI_VENDOR_ID);
+				vendor &= 0xffff;
+				switch (vendor) { 
+				case PCI_VENDOR_ID_NVIDIA: 
+				case PCI_VENDOR_ID_VIA:
+					printk(KERN_INFO 
+     "PCI bridge %02x:%02x from %x found. Setting \"noapic\". Overwrite with \"apic\"\n",
+					       num,slot,vendor); 
+					skip_ioapic_setup = 1;
+					return;
+				} 
+
+				/* No multi-function device? */
+				u8 type = read_pci_config_byte(num,slot,func,
+							       PCI_HEADER_TYPE);
+				if (!(type & 0x80))
+					break;
+			} 
+		}
+	}
+} 
+#endif
 
 static int __init ioapic_pirq_setup(char *str)
 {
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/ioport.c linux-2.4.22-bk26/arch/x86_64/kernel/ioport.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/ioport.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/ioport.c	2003-09-29 02:49:41.000000000 -0700
@@ -19,35 +19,13 @@
 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
 static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
 {
-	unsigned long mask;
-	unsigned long *bitmap_base = bitmap + base / sizeof(long);
-	unsigned low_index = base & (BITS_PER_LONG - 1);
-	int length = low_index + extent;
-
-	if (low_index != 0) {
-		mask = (~0UL << low_index);
-		if (length < 64)
-			mask &= ~(~0UL << length);
+	int i;
 		if (new_value)
-			*bitmap_base++ |= mask;
+		for (i = base; i < base + extent; i++) 
+			__set_bit(i, bitmap); 
 		else
-			*bitmap_base++ &= ~mask;
-		length -= 64;
-	}
-
-	mask = (new_value ? ~0UL : 0UL);
-	while (length >= 64) {
-		*bitmap_base++ = mask;
-		length -= 64;
-	}
-
-	if (length > 0) {
-		mask = ~(~0UL << length);
-		if (new_value)
-			*bitmap_base++ |= mask;
-		else
-			*bitmap_base++ &= ~mask;
-	}
+		for (i = base; i < base + extent; i++) 
+			clear_bit(i, bitmap); 
 }
 
 /*
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/mpparse.c linux-2.4.22-bk26/arch/x86_64/kernel/mpparse.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/mpparse.c	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/mpparse.c	2003-09-29 02:49:41.000000000 -0700
@@ -139,9 +139,12 @@
 	str[6] = 0;
 	Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
 
-	if (m->mpc_busid >= MAX_MP_BUSSES) {
+#if MAX_MP_BUSSES < 256
+	if ((long)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) {
+	} else 
+#endif	
+	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;
@@ -756,7 +759,7 @@
 	mp_ioapic_routing[idx].irq_end = irq_base + 
 		io_apic_get_redir_entries(idx);
 
-	printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
+	printk("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
 		"IRQ %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 
 		mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
 		mp_ioapic_routing[idx].irq_start,
@@ -883,8 +886,6 @@
 
 #ifndef CONFIG_ACPI_HT_ONLY
 
-/* Ensure the ACPI SCI interrupt level is active low, edge-triggered */
-
 extern FADT_DESCRIPTOR acpi_fadt;
 
 void __init mp_config_ioapic_for_sci(int irq)
@@ -893,6 +894,7 @@
 	int ioapic_pin;
 	struct acpi_table_madt* madt;
 	struct acpi_table_int_src_ovr *entry = NULL;
+	acpi_interrupt_flags flags;
 	void *madt_end;
 	acpi_status status;
 
@@ -911,23 +913,42 @@
 
 		while ((void *) entry < madt_end) {
                 	if (entry->header.type == ACPI_MADT_INT_SRC_OVR &&
-			    acpi_fadt.sci_int == entry->global_irq)
-                		return;
+ 			    acpi_fadt.sci_int == entry->bus_irq)
+ 				goto found;
 
                 	entry = (struct acpi_table_int_src_ovr *)
                 	        ((unsigned long) entry + entry->header.length);
         	}
 	}
+ 	/*
+ 	 * Although the ACPI spec says that the SCI should be level/low
+ 	 * don't reprogram it unless there is an explicit MADT OVR entry
+ 	 * instructing us to do so -- otherwise we break Tyan boards which
+ 	 * have the SCI wired edge/high but no MADT OVR.
+ 	 */
+ 	return;
+
+found:
+ 	/*
+ 	 * See the note at the end of ACPI 2.0b section
+ 	 * 5.2.10.8 for what this is about.
+ 	 */
+ 	flags = entry->flags;
+ 	acpi_fadt.sci_int = entry->global_irq;
+ 	irq = entry->global_irq;
 
 	ioapic = mp_find_ioapic(irq);
 
 	ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
 
-	io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 1, 1);
+ 	io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 
+ 				(flags.trigger >> 1) , (flags.polarity >> 1));
 }
 
 #endif /*CONFIG_ACPI_HT_ONLY*/
 
+int acpi_tolerant;
+
 #ifdef CONFIG_ACPI_PCI
 
 void __init mp_parse_prt (void)
@@ -961,6 +982,13 @@
 		}
 
 		irq = entry->link.index;
+
+  		/* Don't set up the ACPI SCI because it's already set up */
+                if (acpi_fadt.sci_int == irq) {
+                         entry->irq = irq; /*we still need to set entry's irq*/
+ 			continue;
+                }
+
 		ioapic = mp_find_ioapic(irq);
 		if (ioapic < 0)
 			continue;
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/nmi.c linux-2.4.22-bk26/arch/x86_64/kernel/nmi.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/nmi.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/nmi.c	2003-09-29 02:49:41.000000000 -0700
@@ -30,6 +30,7 @@
 unsigned int nmi_watchdog = NMI_LOCAL_APIC;
 static unsigned int nmi_hz = HZ;
 unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
+int panic_on_timeout;
 
 int nmi_watchdog_disabled; 
 
@@ -121,6 +122,13 @@
 {
 	int nmi;
 
+	if (!strncmp(str,"panic",5)) {
+		panic_on_timeout = 1;
+		str = strchr(str, ',');
+		if (!str) 
+			return 1; 
+		++str;	
+	}			
 	get_option(&str, &nmi);
 
 	if (nmi >= NMI_INVALID)
@@ -380,6 +388,8 @@
 			bust_spinlocks(1);
 			printk("NMI Watchdog detected LOCKUP on CPU%d, eip %16lx, registers:\n", cpu, regs->rip);
 			show_registers(regs);
+			if (panic_on_timeout)
+				panic("NMI lockup");
 			printk("console shuts up ...\n");
 			console_silent();
 			spin_unlock(&nmi_print_lock);
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/pci-gart.c linux-2.4.22-bk26/arch/x86_64/kernel/pci-gart.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/pci-gart.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/pci-gart.c	2003-09-29 02:49:41.000000000 -0700
@@ -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.27 2003/08/05 18:25:31 ak Exp $
+ * $Id: pci-gart.c,v 1.28 2003/09/19 07:01:58 ak Exp $
  */
 
 #include <linux/config.h>
@@ -588,9 +588,12 @@
 	    if (!memcmp(p, "memaper", 7)) { 
 		    fallback_aper_force = 1; 
 		    p += 7; 
-		    if (*p == '=' && get_option(&p, &arg))
+		    if (*p == '=') { 
+			    ++p;
+			    if (get_option(&p, &arg))
 			    fallback_aper_order = arg;
 	    } 
+	    } 
 #ifdef CONFIG_IOMMU_LEAK
 	    if (!memcmp(p,"leak", 4)) { 
 		    leak_trace = 1;
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/pci-pc.c linux-2.4.22-bk26/arch/x86_64/kernel/pci-pc.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/pci-pc.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/pci-pc.c	2003-09-29 02:49:41.000000000 -0700
@@ -23,9 +23,11 @@
 #include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/mpspec.h>
+#include <asm/proto.h>
 
 #include "pci-x86_64.h"
 
+int use_acpi_pci = 1;
 unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
 
 int pcibios_last_bus = -1;
@@ -588,7 +590,7 @@
 
 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
 #ifdef CONFIG_ACPI_PCI
- 	if (!acpi_pci_irq_init())
+ 	if (!acpi_disabled && use_acpi_pci && !acpi_pci_irq_init())
  		pci_using_acpi_prt = 1;
 #endif
  	if (!pci_using_acpi_prt) {
@@ -661,7 +663,7 @@
 		return err;
 
 #ifdef CONFIG_ACPI_PCI
-	if (pci_using_acpi_prt) {
+	if (use_acpi_pci && pci_using_acpi_prt) {
 		acpi_pci_irq_enable(dev);
 		return 0;
 	}
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/pci-x86_64.c linux-2.4.22-bk26/arch/x86_64/kernel/pci-x86_64.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/pci-x86_64.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/pci-x86_64.c	2003-09-29 02:49:41.000000000 -0700
@@ -294,6 +294,17 @@
 	}
 }
 
+void __init pcibios_set_cacheline_size(void)
+{
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+
+	pci_cache_line_size = 32 >> 2;
+	if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
+		pci_cache_line_size = 64 >> 2;	/* K7 & K8 */
+	else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL)
+		pci_cache_line_size = 128 >> 2;	/* P4 */
+}
+
 void __init pcibios_resource_survey(void)
 {
 	DBG("PCI: Allocating resources\n");
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/pci-x86_64.h linux-2.4.22-bk26/arch/x86_64/kernel/pci-x86_64.h
--- linux-2.4.22-bk25/arch/x86_64/kernel/pci-x86_64.h	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/pci-x86_64.h	2003-09-29 02:49:41.000000000 -0700
@@ -27,8 +27,10 @@
 /* pci-i386.c */
 
 extern unsigned int pcibios_max_latency;
+extern u8 pci_cache_line_size;
 
 void pcibios_resource_survey(void);
+void pcibios_set_cacheline_size(void);
 int pcibios_enable_resources(struct pci_dev *, int mask);
 
 /* pci-pc.c */
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/process.c linux-2.4.22-bk26/arch/x86_64/kernel/process.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/process.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/process.c	2003-09-29 02:49:41.000000000 -0700
@@ -9,7 +9,7 @@
  *  X86-64 port
  *	Andi Kleen.
  * 
- *  $Id: process.c,v 1.70 2003/06/09 05:18:21 ak Exp $
+ *  $Id: process.c,v 1.74 2003/08/13 13:43:16 ak Exp $
  */
 
 /*
@@ -168,7 +168,7 @@
 static int reboot_mode = 0; 
 
 /* reboot=b[ios] | t[riple] | k[bd] [, [w]arm | [c]old]
-   bios	  Use the CPU reboto vector for warm reset
+   bios	  Use the CPU reboot vector for warm reset
    warm   Don't set the cold reboot flag
    cold   Set the cold reboto flag
    triple Force a triple fault (init)
@@ -227,7 +227,7 @@
 		      [target] "b" (WARMBOOT_TRAMP));
 }
 
-static inline void kb_wait(void)
+static void kb_wait(void)
 {
 	int i;
 
@@ -252,6 +252,7 @@
 
 	/* AP calling this. Just halt */
 	if (cpuid != boot_cpu_id) { 
+		printk("CPU %d SMP halt\n", cpuid); 
 		for (;;)
 			asm("hlt");
 	}
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/setup.c linux-2.4.22-bk26/arch/x86_64/kernel/setup.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/setup.c	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/setup.c	2003-09-29 02:49:41.000000000 -0700
@@ -295,6 +295,11 @@
 #endif
 
 	paging_init();
+#if !defined(CONFIG_SMP) && defined(CONFIG_X86_IO_APIC)
+	extern void check_ioapic(void);
+	check_ioapic();
+#endif
+
 #ifdef CONFIG_ACPI_BOOT
 	/*
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
@@ -377,7 +382,10 @@
 		c->x86_cache_size=(ecx>>24)+(edx>>24);	
 		if (n >= 0x80000006) {
 			printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line/%d way)\n",
-			       ecx_2>>16, ecx_2&0xFF, (ecx_2>>12)&0xf);
+			       ecx_2>>16, ecx_2&0xFF, 
+			       /*  use bits[15:13] as power of 2 for # of ways */
+			       1 << ((ecx>>13) & 0x7) 
+			       /* Direct and Full associative L2 are very unlikely */);
 			c->x86_cache_size = ecx_2 >> 16;
 		c->x86_tlbsize = ((ebx>>16)&0xff) + ((ebx_2>>16)&0xfff) + 
 			(ebx&0xff) + ((ebx_2)&0xfff);
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/setup64.c linux-2.4.22-bk26/arch/x86_64/kernel/setup64.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/setup64.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/setup64.c	2003-09-29 02:49:41.000000000 -0700
@@ -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.23 2003/05/16 14:22:27 ak Exp $
+ * $Id: setup64.c,v 1.25 2003/07/11 15:58:47 ak Exp $
  */ 
 #include <linux/config.h>
 #include <linux/init.h>
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/signal.c linux-2.4.22-bk26/arch/x86_64/kernel/signal.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/signal.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/signal.c	2003-09-29 02:49:41.000000000 -0700
@@ -8,7 +8,7 @@
  *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
  *  2000-2001   x86-64 support by Andi Kleen
  * 
- *  $Id: signal.c,v 1.42 2003/02/24 21:06:02 ak Exp $
+ *  $Id: signal.c,v 1.43 2003/09/06 18:10:44 ak Exp $
  */
 
 #include <linux/sched.h>
@@ -71,6 +71,10 @@
 		default:
 			err |= __put_user(from->si_uid, &to->si_uid);
 			break;
+		case __SI_POLL >> 16:
+			err |= __put_user(from->si_band, &to->si_band); 
+			err |= __put_user(from->si_fd, &to->si_fd); 
+			break;
 		/* case __SI_RT: This is not generated by the kernel as of now.  */
 		}
 		return err;
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/smpboot.c linux-2.4.22-bk26/arch/x86_64/kernel/smpboot.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/smpboot.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/smpboot.c	2003-09-29 02:49:41.000000000 -0700
@@ -50,6 +50,7 @@
 #include <asm/kdebug.h>
 #include <asm/timex.h>
 #include <asm/proto.h>
+#include <asm/acpi.h>
 
 /* Setup configured maximum number of CPUs to activate */
 static int max_cpus = -1;
@@ -863,7 +864,7 @@
 	 * If we couldnt find an SMP configuration at boot time,
 	 * get out of here now!
 	 */
-	if (!smp_found_config) {
+	if (!smp_found_config && !acpi_lapic) {
 		printk(KERN_NOTICE "SMP motherboard not detected.\n");
 		io_apic_irqs = 0;
 		cpu_online_map = phys_cpu_present_map = 1;
@@ -907,10 +908,8 @@
 	if (!max_cpus) {
 		smp_found_config = 0;
 		printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
-		io_apic_irqs = 0;
 		cpu_online_map = phys_cpu_present_map = 1;
 		smp_num_cpus = 1;
-		apic_disabled = 1;
 		goto smp_done;
 	}
 
@@ -1012,6 +1011,9 @@
 	if (cpu_has_tsc && cpucount)
 		synchronize_tsc_bp();
 
+	if (nmi_watchdog != 0) 
+		check_nmi_watchdog(); 
+
 smp_done:
 	zap_low_mappings();
 	time_init_smp();
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/suspend.c linux-2.4.22-bk26/arch/x86_64/kernel/suspend.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/suspend.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/suspend.c	2003-09-29 02:49:41.000000000 -0700
@@ -5,6 +5,9 @@
  *
  * Copyright (c) 2002 Pavel Machek <pavel@suse.cz>
  * Copyright (c) 2001 Patrick Mochel <mochel@osdl.org>
+ * 
+ * AK currently useless for 24 because the core ACPI code doesn't support S3.
+ *    and most of the infrastructure is missing.
  */
 
 #include <linux/config.h>
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/sys_x86_64.c linux-2.4.22-bk26/arch/x86_64/kernel/sys_x86_64.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/sys_x86_64.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/sys_x86_64.c	2003-09-29 02:49:41.000000000 -0700
@@ -128,3 +128,17 @@
 	unsigned long raddr;
 	return sys_shmat(shmid,shmaddr,shmflg,&raddr) ?: raddr;
 } 
+
+asmlinkage long sys_time64(long * tloc)
+{
+	struct timeval now; 
+	int i; 
+
+	do_gettimeofday(&now);
+	i = now.tv_sec;
+	if (tloc) {
+		if (put_user(i,tloc))
+			i = -EFAULT;
+	}
+	return i;
+}
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/traps.c linux-2.4.22-bk26/arch/x86_64/kernel/traps.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/traps.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/traps.c	2003-09-29 02:49:41.000000000 -0700
@@ -7,7 +7,7 @@
  *  Pentium III FXSR, SSE support
  *	Gareth Hughes <gareth@valinux.com>, May 2000
  *
- *  $Id: traps.c,v 1.66 2003/06/09 05:18:21 ak Exp $
+ *  $Id: traps.c,v 1.69 2003/09/21 04:54:09 ak Exp $
  */
 
 /*
@@ -81,7 +81,7 @@
 
 struct notifier_block *die_chain;
 
-int kstack_depth_to_print = 40;
+int kstack_depth_to_print = 12;
 
 #ifdef CONFIG_KALLSYMS
 #include <linux/kallsyms.h> 
@@ -342,18 +342,25 @@
 spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 int die_owner = -1;
 
-void die(const char * str, struct pt_regs * regs, long err)
+void __die(const char * str, struct pt_regs * regs, long err)
+{
+	printk(KERN_EMERG "%s: %04lx\n", str, err & 0xffff);
+ 	notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
+	show_registers(regs);
+	/* Execute summary in case the oops scrolled away */
+	printk(KERN_EMERG "RIP "); 
+	printk_address(regs->rip); 
+	printk(" RSP <%016lx>\n", regs->rsp); 
+}
+
+void prepare_die(unsigned long *flags)
 {
-	unsigned long flags;
 	int cpu;
 	console_verbose();
 	bust_spinlocks(1);
-	handle_BUG(regs);		
-	printk(KERN_EMERG "%s: %04lx\n", str, err & 0xffff);
- 	notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
 	cpu = safe_smp_processor_id(); 
 	/* racy, but better than risking deadlock. */ 
-	__save_flags(flags); 
+	__save_flags(*flags); 
 	__cli();
 	if (!spin_trylock(&die_lock)) { 
 		if (cpu == die_owner) 
@@ -362,9 +369,23 @@
 			spin_lock(&die_lock); 
 	}
 	die_owner = cpu; 
-	show_registers(regs);
-	bust_spinlocks(0);
+} 
+
+void exit_die(unsigned long flags)
+{
+	die_owner = -1;
 	spin_unlock_irqrestore(&die_lock, flags);
+	__sti();	/* back scroll should work */
+	bust_spinlocks(0);
+}
+
+void die(const char * str, struct pt_regs * regs, long err)
+{
+	unsigned long flags;
+	prepare_die(&flags);
+	handle_BUG(regs);		
+	__die(str, regs, err);
+	exit_die(flags);
 	do_exit(SIGSEGV);
 }
 
diff -urN linux-2.4.22-bk25/arch/x86_64/kernel/x8664_ksyms.c linux-2.4.22-bk26/arch/x86_64/kernel/x8664_ksyms.c
--- linux-2.4.22-bk25/arch/x86_64/kernel/x8664_ksyms.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/kernel/x8664_ksyms.c	2003-09-29 02:49:41.000000000 -0700
@@ -13,6 +13,7 @@
 #include <linux/string.h>
 #include <linux/tty.h>
 #include <linux/string.h>
+#include <linux/nmi.h>
 
 #include <asm/semaphore.h>
 #include <asm/processor.h>
@@ -222,4 +223,6 @@
 #endif
 
 extern void int_ret_from_sys_call(void);
-EXPORT_SYMBOL(int_ret_from_sys_call); 
+EXPORT_SYMBOL_NOVERS(int_ret_from_sys_call); 
+
+EXPORT_SYMBOL(touch_nmi_watchdog);
diff -urN linux-2.4.22-bk25/arch/x86_64/lib/copy_page.S linux-2.4.22-bk26/arch/x86_64/lib/copy_page.S
--- linux-2.4.22-bk25/arch/x86_64/lib/copy_page.S	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/lib/copy_page.S	2003-09-29 02:49:41.000000000 -0700
@@ -10,14 +10,8 @@
 copy_page:
 	prefetch (%rsi) 
 	prefetch 1*64(%rsi)
-	prefetch 2*64(%rsi)
-	prefetch 3*64(%rsi)
-	prefetch 4*64(%rsi)
 	prefetchw (%rdi) 
 	prefetchw 1*64(%rdi) 
-	prefetchw 2*64(%rdi) 
-	prefetchw 3*64(%rdi)
-	prefetchw 4*64(%rdi)
 
 	subq	$3*8,%rsp
 	movq	%rbx,(%rsp)
diff -urN linux-2.4.22-bk25/arch/x86_64/lib/copy_user.S linux-2.4.22-bk26/arch/x86_64/lib/copy_user.S
--- linux-2.4.22-bk25/arch/x86_64/lib/copy_user.S	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/lib/copy_user.S	2003-09-29 02:49:41.000000000 -0700
@@ -4,7 +4,7 @@
  * Functions to copy from and to user space.		
  */		 
 
-#define FIX_ALIGNMENT 1
+/* #define FIX_ALIGNMENT 1 */
 
 	#include <asm/current.h>
 	#include <asm/offset.h>
@@ -59,9 +59,8 @@
 	.globl copy_user_generic	
 	.p2align 4
 copy_user_generic:	
-	/* Put the first cacheline into cache. This should handle
-	   the small movements in ioctls etc., but not penalize the bigger
-	   filesystem data copies too much. */
+	prefetch (%rsi)
+	prefetchw (%rdi)
 	pushq %rbx
 	xorl %eax,%eax		/*zero for the exception handler */
 
diff -urN linux-2.4.22-bk25/arch/x86_64/lib/csum-copy.S linux-2.4.22-bk26/arch/x86_64/lib/csum-copy.S
--- linux-2.4.22-bk25/arch/x86_64/lib/csum-copy.S	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/lib/csum-copy.S	2003-09-29 02:49:41.000000000 -0700
@@ -56,29 +56,18 @@
 	.globl csum_partial_copy_generic
 	.p2align 4
 csum_partial_copy_generic:
-	cmpl	 $3*64,%edx
+	cmpl	 $2*64,%edx
 	jle	 .Lignore
 
 	ignore
-	prefetch (%rdi)
-	ignore
 	prefetch 1*64(%rdi)
 	ignore
 	prefetch 2*64(%rdi)
 	ignore
-	prefetch 3*64(%rdi)
-	ignore
-	prefetch 4*64(%rdi)
-	ignore
 	prefetchw (%rsi)
 	ignore
 	prefetchw 1*64(%rsi)
 	ignore
-	prefetchw 2*64(%rsi)
-	ignore
-	prefetchw 3*64(%rsi)
-	ignore
-	prefetchw 4*64(%rsi)
 
 .Lignore:		
 	subq  $7*8,%rsp
@@ -126,9 +115,6 @@
 	source
 	movq  56(%rdi),%r13
 		
-	ignore 2f
-	prefetch 5*64(%rdi)
-2:							
 	adcq  %rbx,%rax
 	adcq  %r8,%rax
 	adcq  %r11,%rax
@@ -158,10 +144,6 @@
 	dest
 	movq %r13,56(%rsi)
 	
-	ignore 3f
-	prefetchw 5*64(%rsi)
-3:
-	
 	leaq 64(%rdi),%rdi
 	leaq 64(%rsi),%rsi
 
diff -urN linux-2.4.22-bk25/arch/x86_64/lib/usercopy.c linux-2.4.22-bk26/arch/x86_64/lib/usercopy.c
--- linux-2.4.22-bk25/arch/x86_64/lib/usercopy.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/lib/usercopy.c	2003-09-29 02:49:41.000000000 -0700
@@ -68,7 +68,7 @@
 	asm volatile(
 		"	testq  %[size8],%[size8]\n"
 		"	jz     4f\n"
-		"0:	movnti %[zero],(%[dst])\n"
+		"0:	movq %[zero],(%[dst])\n"
 		"	addq   %[eight],%[dst]\n"
 		"	decl %%ecx ; jnz   0b\n"
 		"4:	movq  %[size1],%%rcx\n"
@@ -77,7 +77,7 @@
 		"1:	movb   %b[zero],(%[dst])\n"
 		"	incq   %[dst]\n"
 		"	decl %%ecx ; jnz  1b\n"
-		"2:	sfence\n"
+		"2:\n"
 		".section .fixup,\"ax\"\n"
 		"3:	lea 0(%[size1],%[size8],8),%[size8]\n"
 		"	jmp 2b\n"
diff -urN linux-2.4.22-bk25/arch/x86_64/mm/fault.c linux-2.4.22-bk26/arch/x86_64/mm/fault.c
--- linux-2.4.22-bk25/arch/x86_64/mm/fault.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/mm/fault.c	2003-09-29 02:49:41.000000000 -0700
@@ -94,6 +94,85 @@
 	printk("BAD\n");
 }
 
+/* Sometimes the CPU reports invalid exceptions on prefetch.
+   Check that here and ignore.
+   Opcode checker based on code by Richard Brunner */
+static int is_prefetch(struct pt_regs *regs, unsigned long addr)
+{ 
+	unsigned char *instr = (unsigned char *)(regs->rip);
+	int scan_more = 1;
+	int prefetch = 0; 
+	unsigned char *max_instr = instr + 15;
+
+	/* Avoid recursive faults for this common case */
+	if (regs->rip == addr)
+		return 0; 
+
+	if (regs->cs & (1<<2))
+		return 0;
+
+	while (scan_more && instr < max_instr) { 
+		unsigned char opcode;
+		unsigned char instr_hi;
+		unsigned char instr_lo;
+
+		if (__get_user(opcode, instr))
+			break; 
+
+		instr_hi = opcode & 0xf0; 
+		instr_lo = opcode & 0x0f; 
+		instr++;
+
+		switch (instr_hi) { 
+		case 0x20:
+		case 0x30:
+			/* Values 0x26,0x2E,0x36,0x3E are valid x86
+			   prefixes.  In long mode, the CPU will signal
+			   invalid opcode if some of these prefixes are
+			   present so we will never get here anyway */
+			scan_more = ((instr_lo & 7) == 0x6);
+			break;
+			
+		case 0x40:
+			/* In AMD64 long mode, 0x40 to 0x4F are valid REX prefixes
+			   Need to figure out under what instruction mode the
+			   instruction was issued ... */
+			/* Could check the LDT for lm, but for now it's good
+			   enough to assume that long mode only uses well known
+			   segments or kernel. */
+			scan_more = ((regs->cs & 3) == 0) || (regs->cs == __USER_CS);
+			break;
+			
+		case 0x60:
+			/* 0x64 thru 0x67 are valid prefixes in all modes. */
+			scan_more = (instr_lo & 0xC) == 0x4;
+			break;		
+		case 0xF0:
+			/* 0xF0, 0xF2, and 0xF3 are valid prefixes in all modes. */
+			scan_more = !instr_lo || (instr_lo>>1) == 1;
+			break;			
+		case 0x00:
+			/* Prefetch instruction is 0x0F0D or 0x0F18 */
+			scan_more = 0;
+			if (__get_user(opcode, instr)) 
+				break;
+			prefetch = (instr_lo == 0xF) &&
+				(opcode == 0x0D || opcode == 0x18);
+			break;			
+		default:
+			scan_more = 0;
+			break;
+		} 
+	}
+
+#if 0
+	if (prefetch)
+		printk("%s: prefetch caused page fault at %lx/%lx\n", current->comm,
+		       regs->rip, addr);
+#endif
+	return prefetch;
+}
+
 int page_fault_trace; 
 int exception_trace = 1;
 
@@ -156,7 +235,7 @@
 	 * context, we must not take the fault..
 	 */
 	if (in_interrupt() || !mm)
-		goto no_context;
+		goto bad_area_nosemaphore;
 
 again:
 	down_read(&mm->mmap_sem);
@@ -226,9 +305,11 @@
 	up_read(&mm->mmap_sem);
 
 bad_area_nosemaphore:
-
 	/* User mode accesses just cause a SIGSEGV */
 	if (error_code & 4) {
+		if (is_prefetch(regs, address))
+			return;
+
 		if (exception_trace && !(tsk->ptrace & PT_PTRACED) && 
 		    (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_IGN ||
 		    (tsk->sig->action[SIGSEGV-1].sa.sa_handler == SIG_DFL)))
@@ -260,40 +341,27 @@
 		return;
 	}
 
+	if (is_prefetch(regs, address))
+		return;
+
 /*
  * Oops. The kernel tried to access some bad page. We'll have to
  * terminate things with extreme prejudice.
  */
 
-	console_verbose();
-	bust_spinlocks(1); 
-
-	int cpu = safe_smp_processor_id(); 
 	unsigned long flags; 
-	extern int die_owner; 
-	extern spinlock_t die_lock;
-	
-	__save_flags(flags); 
-	__cli(); 
-	if (!spin_trylock(&die_lock)) { 
-		if (cpu == die_owner) 
-			/* nested oops. should stop eventually */;
-		else
-			spin_lock(&die_lock); 
-	}
-	die_owner = cpu; 
-
+	prepare_die(&flags);
 	if (address < PAGE_SIZE)
 		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
 	else
 		printk(KERN_ALERT "Unable to handle kernel paging request");
-	printk(" at virtual address %016lx\n",address);
-	printk(" printing rip:\n");
-	printk("%016lx\n", regs->rip);
+	printk(KERN_ALERT " at %016lx RIP: ", address); 
+	printk_address(regs->rip);
 	dump_pagetable(address);
-	die("Oops", regs, error_code);
-	bust_spinlocks(0); 
-	spin_unlock_irqrestore(&die_lock, flags);
+	__die("Oops", regs, error_code);
+	/* Executive summary in case the oops scrolled away */
+	printk(KERN_EMERG "CR2: %016lx\n", address);
+	exit_die(flags);
 	do_exit(SIGKILL);
 
 /*
@@ -315,10 +383,13 @@
 do_sigbus:
 	up_read(&mm->mmap_sem);
 
-	/*
-	 * Send a sigbus, regardless of whether we were in kernel
-	 * or user mode.
-	 */
+	/* Kernel mode? Handle exceptions or die */
+	if (!(error_code & 4))
+		goto no_context;
+		
+	if (is_prefetch(regs, address))
+		return;
+
 	tsk->thread.cr2 = address;
 	tsk->thread.error_code = error_code;
 	tsk->thread.trap_no = 14;
@@ -327,10 +398,6 @@
 	info.si_code = BUS_ADRERR;
 	info.si_addr = (void *)address;
 	force_sig_info(SIGBUS, &info, tsk);
-
-	/* Kernel mode? Handle exceptions or die */
-	if (!(error_code & 4))
-		goto no_context;
 	return;
 
 
diff -urN linux-2.4.22-bk25/arch/x86_64/mm/ioremap.c linux-2.4.22-bk26/arch/x86_64/mm/ioremap.c
--- linux-2.4.22-bk25/arch/x86_64/mm/ioremap.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/mm/ioremap.c	2003-09-29 02:49:41.000000000 -0700
@@ -125,12 +125,12 @@
 	 */
 	if (phys_addr < virt_to_phys(high_memory)) {
 		char *t_addr, *t_end;
-		struct page *page;
 
 		t_addr = __va(phys_addr);
 		t_end = t_addr + (size - 1);
 	   
 #ifndef CONFIG_DISCONTIGMEM
+		struct page *page;
 		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
 			if(!PageReserved(page))
 				return NULL;
diff -urN linux-2.4.22-bk25/arch/x86_64/mm/k8topology.c linux-2.4.22-bk26/arch/x86_64/mm/k8topology.c
--- linux-2.4.22-bk25/arch/x86_64/mm/k8topology.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.22-bk26/arch/x86_64/mm/k8topology.c	2003-09-29 02:49:41.000000000 -0700
@@ -6,7 +6,7 @@
  * Instead the northbridge registers are read directly. 
  * 
  * Copyright 2002 Andi Kleen, SuSE Labs.
- * $Id: k8topology.c,v 1.7 2003/04/02 21:36:22 ak Exp $
+ * $Id: k8topology.c,v 1.11 2003/09/12 01:55:37 ak Exp $
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -20,6 +20,8 @@
 #include <asm/e820.h>
 #include <asm/pci-direct.h>
 
+#define Dprintk(x...)
+
 int memnode_shift;
 u8  memnodemap[NODEMAPSIZE];
 
@@ -110,6 +112,9 @@
 		limit = read_pci_config(0, nb, 1, 0x44 + i*8);
 
 		nodeid = limit & 3; 
+		if ((base & 3) == 0) { 
+			continue;
+		} 
 		if (!limit) { 
 			printk(KERN_INFO "Skipping node entry %d (base %lx)\n", i,			       base);
 			continue;
@@ -145,7 +150,7 @@
 		if (limit == base) 
 			continue; 
 		if (limit < base) { 
-			printk(KERN_INFO"Node %d bogus settings %lx-%lx. Ignored.\n",
+			Dprintk(KERN_INFO"Node %d bogus settings %lx-%lx. Ignored.\n",
 			       nodeid, base, limit); 			       
 			continue; 
 		} 
diff -urN linux-2.4.22-bk25/drivers/block/cciss.c linux-2.4.22-bk26/drivers/block/cciss.c
--- linux-2.4.22-bk25/drivers/block/cciss.c	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/drivers/block/cciss.c	2003-09-29 02:49:41.000000000 -0700
@@ -106,7 +106,15 @@
 
 #define READ_AHEAD 	 128
 #define NR_CMDS		 128 /* #commands that can be outstanding */
-#define MAX_CTLR 8
+#define MAX_CTLR	 32 
+
+/* No sense in giving up our preallocated major numbers */
+#if MAX_CTLR < 8
+#error"cciss.c: MAX_CTLR must be 8 or greater"
+#endif
+
+/* Originally cciss driver only supports 8 major number */
+#define MAX_CTLR_ORIG  COMPAQ_CISS_MAJOR7 - COMPAQ_CISS_MAJOR + 1
 
 #define CCISS_DMA_MASK 0xFFFFFFFFFFFFFFFF /* 64 bit DMA */
 
@@ -121,7 +129,7 @@
 #endif
 
 static ctlr_info_t *hba[MAX_CTLR];
-
+static int map_major_to_ctlr[MAX_BLKDEV] = {0}; /* gets ctlr num from maj num */
 static struct proc_dir_entry *proc_cciss;
 
 static void do_cciss_request(request_queue_t *q);
@@ -421,7 +429,7 @@
  */
 static int cciss_open(struct inode *inode, struct file *filep)
 {
-	int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
+ 	int ctlr = map_major_to_ctlr[MAJOR(inode->i_rdev)];
 	int dsk  = MINOR(inode->i_rdev) >> NWD_SHIFT;
 
 #ifdef CCISS_DEBUG
@@ -462,7 +470,7 @@
  */
 static int cciss_release(struct inode *inode, struct file *filep)
 {
-	int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
+	int ctlr = map_major_to_ctlr[MAJOR(inode->i_rdev)];
 	int dsk  = MINOR(inode->i_rdev) >> NWD_SHIFT;
 
 #ifdef CCISS_DEBUG
@@ -482,7 +490,7 @@
 static int cciss_ioctl(struct inode *inode, struct file *filep, 
 		unsigned int cmd, unsigned long arg)
 {
-	int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
+	int ctlr = map_major_to_ctlr[MAJOR(inode->i_rdev)];
 	int dsk  = MINOR(inode->i_rdev) >> NWD_SHIFT;
 
 #ifdef CCISS_DEBUG
@@ -1028,7 +1036,7 @@
         int i;
 
         target = MINOR(dev) >> NWD_SHIFT;
-        ctlr = MAJOR(dev) - MAJOR_NR;
+	ctlr = map_major_to_ctlr[MAJOR(dev)];
         gdev = &(hba[ctlr]->gendisk);
 
         spin_lock_irqsave(&io_request_lock, flags);
@@ -1047,12 +1055,12 @@
 
         for(i=max_p-1; i>=0; i--) {
                 int minor = start+i;
-                invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1);
+                invalidate_device(MKDEV(hba[ctlr]->major, minor), 1);
                 gdev->part[minor].start_sect = 0;
                 gdev->part[minor].nr_sects = 0;
 
                 /* reset the blocksize so we can read the partition table */
-                blksize_size[MAJOR_NR+ctlr][minor] = 1024;
+                blksize_size[hba[ctlr]->major][minor] = 1024;
         }
 	/* setup partitions per disk */
 	grok_partitions(gdev, target, MAX_PART, 
@@ -1093,7 +1101,7 @@
 	for (i=max_p-1; i>=0; i--) {
 		int minor = start+i;
 		/* printk("invalidating( %d %d)\n", ctlr, minor); */
-		invalidate_device(MKDEV(MAJOR_NR+ctlr, minor), 1);
+		invalidate_device(MKDEV(hba[ctlr]->major, minor), 1);
 		/* so open will now fail */
 		h->sizes[minor] = 0;
 		/* so it will no longer appear in /proc/partitions */
@@ -1581,12 +1589,12 @@
 
 	for(i=max_p-1; i>=0; i--) {
 		int minor = start+i;
-		invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1);
+		invalidate_device(MKDEV(hba[ctlr]->major, minor), 1);
 		gdev->part[minor].start_sect = 0;
 		gdev->part[minor].nr_sects = 0;
 
 		/* reset the blocksize so we can read the partition table */
-		blksize_size[MAJOR_NR+ctlr][minor] = block_size;
+		blksize_size[hba[ctlr]->major][minor] = block_size;
 		hba[ctlr]->hardsizes[minor] = block_size;
 	}
 
@@ -1700,12 +1708,12 @@
 
 	for (i=max_p-1; i>=0; i--) {
 		int minor = start+i;
-		invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1);
+		invalidate_device(MKDEV(hba[ctlr]->major, minor), 1);
 		gdev->part[minor].start_sect = 0;
 		gdev->part[minor].nr_sects = 0;
 
 		/* reset the blocksize so we can read the partition table */
-		blksize_size[MAJOR_NR+ctlr][minor] = 1024;
+		blksize_size[hba[ctlr]->major][minor] = block_size;
 		hba[ctlr]->hardsizes[minor] = block_size;
 	}
 
@@ -2269,7 +2277,7 @@
 	if (creq->nr_segments > MAXSGENTRIES)
                 BUG();
 
-        if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR ) {
+	if( h->ctlr != map_major_to_ctlr[MAJOR(creq->rq_dev)] ) {
                 printk(KERN_WARNING "doreq cmd for %d, %x at %p\n",
                                 h->ctlr, creq->rq_dev, creq);
                 blkdev_dequeue_request(creq);
@@ -2436,7 +2444,7 @@
 	/*
 	 * See if we can queue up some more IO
 	 */
-	do_cciss_request(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr));
+	do_cciss_request(BLK_DEFAULT_QUEUE(h->major));
 	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 /* 
@@ -2874,8 +2882,10 @@
 			return i;
 		}
 	}
-	printk(KERN_WARNING "cciss: This driver supports a maximum"
-		" of 8 controllers.\n");
+	printk(KERN_WARNING 
+		"cciss: This driver supports a maximum of %d controllers.\n"
+		"You can change this value in cciss.c and recompile.\n",
+		MAX_CTLR);
 	return -1;
 }
 
@@ -3063,6 +3073,7 @@
 	request_queue_t *q;
 	int i;
 	int j;
+	int rc;
 
 	printk(KERN_DEBUG "cciss: Device 0x%x has been found at"
 			" bus %d dev %d func %d\n",
@@ -3078,16 +3089,33 @@
 	}
 	sprintf(hba[i]->devname, "cciss%d", i);
 	hba[i]->ctlr = i;
+
+	/* register with the major number, or get a dynamic major number */
+	/* by passing 0 as argument */
+
+	if (i < MAX_CTLR_ORIG)
+		hba[i]->major = MAJOR_NR + i;
+
 	hba[i]->pdev = pdev;
 	ASSERT_CTLR_ALIVE(hba[i]);
 
-	if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops)) {
+	rc = (register_blkdev(hba[i]->major, hba[i]->devname, &cciss_fops));
+	if (rc < 0) {
 		printk(KERN_ERR "cciss:  Unable to get major number "
-			"%d for %s\n", MAJOR_NR+i, hba[i]->devname);
+			"%d for %s\n", hba[i]->major, hba[i]->devname);
 		release_io_mem(hba[i]);
 		free_hba(i);
 		return -1;
+	} else {
+		if (i < MAX_CTLR_ORIG) {
+			hba[i]->major = MAJOR_NR + i;
+			map_major_to_ctlr[MAJOR_NR + i] = i;
+		} else {
+			hba[i]->major = rc;
+			map_major_to_ctlr[rc] = i;
+		}
 	}
+
 	/* make sure the board interrupts are off */
 	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
 	if (request_irq(hba[i]->intr, do_cciss_intr, 
@@ -3096,7 +3124,8 @@
 
 		printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
 			hba[i]->intr, hba[i]->devname);
-		unregister_blkdev( MAJOR_NR+i, hba[i]->devname);
+		unregister_blkdev( hba[i]->major, hba[i]->devname);
+		map_major_to_ctlr[hba[i]->major] = 0;
 		release_io_mem(hba[i]);
 		free_hba(i);
 		return -1;
@@ -3125,7 +3154,8 @@
 				hba[i]->errinfo_pool, 
 				hba[i]->errinfo_pool_dhandle);
                 free_irq(hba[i]->intr, hba[i]);
-                unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+                unregister_blkdev(hba[i]->major, hba[i]->devname);
+		map_major_to_ctlr[hba[i]->major] = 0;
 		release_io_mem(hba[i]);
 		free_hba(i);
                 printk( KERN_ERR "cciss: out of memory");
@@ -3152,16 +3182,16 @@
 
 	cciss_procinit(i);
 
-	q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
+	q = BLK_DEFAULT_QUEUE(hba[i]->major);
 	q->queuedata = hba[i];
 	blk_init_queue(q, do_cciss_request);
 	blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
 	blk_queue_headactive(q, 0);		
 
 	/* fill in the other Kernel structs */
-	blksize_size[MAJOR_NR+i] = hba[i]->blocksizes;
-        hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes;
-        read_ahead[MAJOR_NR+i] = READ_AHEAD;
+	blksize_size[hba[i]->major] = hba[i]->blocksizes;
+        hardsect_size[hba[i]->major] = hba[i]->hardsizes;
+        read_ahead[hba[i]->major] = READ_AHEAD;
 
 	/* Set the pointers to queue functions */ 
 	q->back_merge_fn = cpq_back_merge_fn;
@@ -3170,7 +3200,7 @@
 
 
 	/* Fill in the gendisk data */ 	
-	hba[i]->gendisk.major = MAJOR_NR + i;
+	hba[i]->gendisk.major = hba[i]->major;
 	hba[i]->gendisk.major_name = "cciss";
 	hba[i]->gendisk.minor_shift = NWD_SHIFT;
 	hba[i]->gendisk.max_p = MAX_PART;
@@ -3185,7 +3215,7 @@
 	cciss_geninit(i);
 	for(j=0; j<NWD; j++)
 		register_disk(&(hba[i]->gendisk),
-			MKDEV(MAJOR_NR+i, j <<4), 
+			MKDEV(hba[i]->major, j <<4), 
 			MAX_PART, &cciss_fops, 
 			hba[i]->drv[j].nr_blocks);
 
@@ -3228,7 +3258,8 @@
 	pci_set_drvdata(pdev, NULL);
 	iounmap((void*)hba[i]->vaddr);
 	cciss_unregister_scsi(i);  /* unhook from SCSI subsystem */
-	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+	unregister_blkdev(hba[i]->major, hba[i]->devname);
+	map_major_to_ctlr[hba[i]->major] = 0;
 	remove_proc_entry(hba[i]->devname, proc_cciss);	
 	
 
diff -urN linux-2.4.22-bk25/drivers/block/cciss.h linux-2.4.22-bk26/drivers/block/cciss.h
--- linux-2.4.22-bk25/drivers/block/cciss.h	2003-09-29 02:49:36.000000000 -0700
+++ linux-2.4.22-bk26/drivers/block/cciss.h	2003-09-29 02:49:41.000000000 -0700
@@ -40,6 +40,7 @@
 struct ctlr_info 
 {
 	int	ctlr;
+	int	major;
 	char	devname[8];
 	char    *product_name;
 	char	firm_ver[4]; // Firmware version 
diff -urN linux-2.4.22-bk25/drivers/block/cciss_scsi.c linux-2.4.22-bk26/drivers/block/cciss_scsi.c
--- linux-2.4.22-bk25/drivers/block/cciss_scsi.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.22-bk26/drivers/block/cciss_scsi.c	2003-09-29 02:49:41.000000000 -0700
@@ -71,16 +71,7 @@
 #endif
 #endif
 
-static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = {
-	{ name: "cciss0", ndevices: 0 },
-	{ name: "cciss1", ndevices: 0 },
-	{ name: "cciss2", ndevices: 0 },
-	{ name: "cciss3", ndevices: 0 },
-	{ name: "cciss4", ndevices: 0 },
-	{ name: "cciss5", ndevices: 0 },
-	{ name: "cciss6", ndevices: 0 },
-	{ name: "cciss7", ndevices: 0 },
-};
+static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR];
 
 /* We need one Scsi_Host_Template *per controller* instead of
    the usual one Scsi_Host_Template per controller *type*. This
@@ -92,11 +83,7 @@
    (that's called from cciss.c:cciss_init_one()) */
 
 static
-Scsi_Host_Template driver_template[MAX_CTLR] =
-{
-	CCISS_SCSI, CCISS_SCSI, CCISS_SCSI, CCISS_SCSI,
-	CCISS_SCSI, CCISS_SCSI, CCISS_SCSI, CCISS_SCSI,
-};
+Scsi_Host_Template driver_template[MAX_CTLR];
 
 #pragma pack(1)
 struct cciss_scsi_cmd_stack_elem_t {
@@ -803,13 +790,7 @@
 
 	sh->this_id = SELF_SCSI_ID;
 
-	/* This is a bit kludgey, using the adapter name to figure out */
-	/* which scsi host template we've got, won't scale beyond 9 ctlrs. */
-	i = tpnt->name[5] - '0';
-
-#	if MAX_CTLR > 9
-#		error "cciss_scsi.c: MAX_CTLR > 9, code maintenance needed."
-#	endif
+	i = simple_strtol((char *)&tpnt->name[5], NULL, 10);
 
 	if (i<0 || i>=MAX_CTLR || hba[i] == NULL) {
 		/* we didn't find ourself... we shouldn't get here. */
@@ -1528,9 +1509,10 @@
 	unsigned long flags;
 
 	CPQ_TAPE_LOCK(ctlr, flags);
-	driver_template[ctlr].name = ccissscsi[ctlr].name;
-	driver_template[ctlr].proc_name = ccissscsi[ctlr].name;
-	driver_template[ctlr].module = THIS_MODULE;;
+
+	sprintf( ccissscsi[ctlr].name, "cciss%d", ctlr );
+	
+	init_driver_template(ctlr);
 
 	/* Since this is really a block driver, the SCSI core may not be
 	   initialized yet, in which case, calling scsi_register_module
diff -urN linux-2.4.22-bk25/drivers/block/cciss_scsi.h linux-2.4.22-bk26/drivers/block/cciss_scsi.h
--- linux-2.4.22-bk25/drivers/block/cciss_scsi.h	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.22-bk26/drivers/block/cciss_scsi.h	2003-09-29 02:49:41.000000000 -0700
@@ -89,7 +89,7 @@
 };
 
 struct cciss_scsi_hba_t {
-	char *name;
+	char name[32];
 	int ndevices;
 #define CCISS_MAX_SCSI_DEVS_PER_HBA 16
 	struct cciss_scsi_dev_t dev[CCISS_MAX_SCSI_DEVS_PER_HBA];
diff -urN linux-2.4.22-bk25/drivers/char/Config.in linux-2.4.22-bk26/drivers/char/Config.in
--- linux-2.4.22-bk25/drivers/char/Config.in	2003-09-29 02:49:37.000000000 -0700
+++ linux-2.4.22-bk26/drivers/char/Config.in	2003-09-29 02:49:41.000000000 -0700
@@ -308,7 +308,7 @@
 
 if [ "$CONFIG_GART_IOMMU" = "y" ]; then
 	bool '/dev/agpgart (AGP Support)' CONFIG_AGP
-	define_bool CONFIG_AGP_AMD_8151 y
+	define_bool CONFIG_AGP_AMD_K8 y
 else
 	tristate '/dev/agpgart (AGP Support)' CONFIG_AGP
 fi      
@@ -318,7 +318,7 @@
    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
+      bool '  AMD Opteron/Athlon64 on-CPU GART support' CONFIG_AGP_AMD_K8
    fi   
    bool '  Generic SiS support' CONFIG_AGP_SIS
    bool '  ALI chipset support' CONFIG_AGP_ALI
diff -urN linux-2.4.22-bk25/drivers/char/agp/agp.h linux-2.4.22-bk26/drivers/char/agp/agp.h
--- linux-2.4.22-bk25/drivers/char/agp/agp.h	2003-09-29 02:49:37.000000000 -0700
+++ linux-2.4.22-bk26/drivers/char/agp/agp.h	2003-09-29 02:49:41.000000000 -0700
@@ -172,6 +172,12 @@
 #ifndef PCI_DEVICE_ID_VIA_82C694X_0
 #define PCI_DEVICE_ID_VIA_82C694X_0      0x0605
 #endif
+#ifndef PCI_DEVICE_ID_VIA_8380_0
+#define PCI_DEVICE_ID_VIA_8380_0	0x0204
+#endif
+#ifndef PCI_DEVICE_ID_VIA_8385_0
+#define PCI_DEVICE_ID_VIA_8385_0	0x3188
+#endif 
 #ifndef PCI_DEVICE_ID_INTEL_810_0
 #define PCI_DEVICE_ID_INTEL_810_0       0x7120
 #endif
@@ -511,6 +517,14 @@
 #define NVIDIA_3_APBASE     0x50
 #define NVIDIA_3_APLIMIT    0x54
 
+/* NVIDIA x86-64 registers */
+#define NVIDIA_X86_64_0_APBASE		0x10
+#define NVIDIA_X86_64_1_APBASE1		0x50
+#define NVIDIA_X86_64_1_APLIMIT1	0x54
+#define NVIDIA_X86_64_1_APSIZE		0xa8
+#define NVIDIA_X86_64_1_APBASE2		0xd8
+#define NVIDIA_X86_64_1_APLIMIT2	0xdc
+
 /* HP ZX1 IOC registers */
 #define HP_ZX1_IBASE		0x300
 #define HP_ZX1_IMASK		0x308
diff -urN linux-2.4.22-bk25/drivers/char/agp/agpgart_be.c linux-2.4.22-bk26/drivers/char/agp/agpgart_be.c
--- linux-2.4.22-bk25/drivers/char/agp/agpgart_be.c	2003-09-29 02:49:37.000000000 -0700
+++ linux-2.4.22-bk26/drivers/char/agp/agpgart_be.c	2003-09-29 02:49:41.000000000 -0700
@@ -49,9 +49,7 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/page.h>
-#ifdef CONFIG_AGP_NVIDIA
-    #include <asm/msr.h>
-#endif
+#include <asm/msr.h>
 
 #include <linux/agp_backend.h>
 #include "agp.h"
@@ -3403,38 +3401,11 @@
 
 #endif /* CONFIG_AGP_AMD */
 
-#ifdef CONFIG_AGP_AMD_8151
+#ifdef CONFIG_AGP_AMD_K8
 
 /* 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);
-}
-
+/* This is misnamed. It is really a generic AMD K8 Northbridge AMD driver. */
 
 static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
 {
@@ -3442,7 +3413,6 @@
 	void *temp;
 	long tmp;
 	u32 pte;
-	u64 addr;
 
 	temp = agp_bridge.current_size;
 
@@ -3472,9 +3442,8 @@
 	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		addr = agp_bridge.mask_memory(mem->memory[i], mem->type);
+		tmp = agp_bridge.mask_memory(mem->memory[i], mem->type);
 
-		tmp = addr;
 		BUG_ON(tmp & 0xffffff0000000ffc);
 		pte = (tmp & 0x000000ff00000000) >> 28;
 		pte |=(tmp & 0x00000000fffff000);
@@ -3612,10 +3581,7 @@
 
 static int amd_8151_configure(void)
 {
-	struct pci_dev *dev, *hammer=NULL;
-	int current_size;
-	int tmp, tmp2, i;
-	u64 aperbar;
+	struct pci_dev *dev;
 	unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real);
 
 	/* Configure AGP regs in each x86-64 host bridge. */
@@ -3624,54 +3590,8 @@
 			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;
 }
 
@@ -3690,15 +3610,6 @@
 			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);
-		}
 	}
 }
 
@@ -3712,7 +3623,7 @@
 
 static gatt_mask amd_8151_masks[] =
 {
-	{0x00000001, 0}
+	{0, 0}
 };
 
 
@@ -3747,7 +3658,7 @@
 				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);
+				printk (KERN_INFO "AGP: Version %x AGP device found.\n", scratch);
 			}
 		}
 	}
@@ -3866,7 +3777,165 @@
 	(void) pdev; /* unused */
 }
 
-#endif /* CONFIG_AGP_AMD_8151 */
+/* NVIDIA x86-64 chipset support */
+ 
+
+static struct _nvidia_x86_64_private {
+	struct pci_dev *dev_1;
+} nvidia_x86_64_private;
+
+
+static aper_size_info_32 nvidia_x86_64_sizes[5] =
+{
+	{512,  131072, 7, 0x00000000 },
+	{256,  65536,  6, 0x00000008 },
+	{128,  32768,  5, 0x0000000C },
+	{64,   16384,  4, 0x0000000E },
+	{32,   8192,   3, 0x0000000F }
+};
+
+
+static int nvidia_x86_64_configure(void)
+{
+	struct pci_dev *dev, *hammer=NULL;
+	int i, current_size;
+	u32 tmp, apbase, apbar, aplimit;
+	unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real);
+
+	if (!agp_bridge.dev) 
+		return -ENODEV;
+
+	/* 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;
+		}
+	}
+	if (hammer == NULL)
+		return -ENODEV;
+
+	/* translate x86-64 aperture size to NVIDIA aperture size */
+	current_size = amd_x86_64_fetch_size();
+	for (i = 0 ; i < agp_bridge.num_aperture_sizes; i++) {
+		if (nvidia_x86_64_sizes[i].size == current_size)
+			break;
+	}
+	/* if x86-64 size does not match any NVIDIA size, exit here */
+	if (i == agp_bridge.num_aperture_sizes)
+		return -ENODEV;
+	pci_read_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APSIZE, &tmp);
+	tmp &= ~(0xf);
+	tmp |= nvidia_x86_64_sizes[i].size_value;
+	pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APSIZE, tmp);
+
+	/* shadow x86-64 registers into NVIDIA registers */
+	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &apbase);
+	/* if x86-64 aperture base is beyond 4G, exit here */
+	if ( (apbase & 0x7fff) >> (32 - 25) )
+		 return -ENODEV;
+	apbase = (apbase & 0x7fff) << 25;
+
+	/* AK: most likely the shadow into the primary device is not needed */
+
+	pci_read_config_dword(agp_bridge.dev, NVIDIA_X86_64_0_APBASE, &apbar);
+	apbar &= ~PCI_BASE_ADDRESS_MEM_MASK;
+	apbar |= apbase;
+	pci_write_config_dword(agp_bridge.dev, NVIDIA_X86_64_0_APBASE, apbar);
+
+	/* Shadow into secondary device looks dubious, but we keep it for now.
+	   If these two could be dropped then the NForce3 code path could
+	   be just folded into the generic functions above. */
+
+	aplimit = apbase + (current_size * 1024 * 1024) - 1;
+	pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APBASE1, apbase);
+	pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APLIMIT1, aplimit);
+	pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APBASE2, apbase);
+	pci_write_config_dword(nvidia_x86_64_private.dev_1, NVIDIA_X86_64_1_APLIMIT2, aplimit);
+
+	/* Original driver updated the IORR here, but AMD documentation
+	   explicitely discourages this for something already covered by the GART. */
+	
+	return 0;
+}
+
+
+static void nvidia_x86_64_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);
+		}
+	}
+}
+
+
+static unsigned long nvidia_x86_64_mask_memory(unsigned long addr, int type)
+{
+	return addr | agp_bridge.masks[0].mask;
+}
+
+
+static gatt_mask nvidia_x86_64_masks[] =
+{
+	{0x00000001, 0}
+};
+
+
+static int __init nvidia_x86_64_setup (struct pci_dev *pdev)
+{
+	nvidia_x86_64_private.dev_1 =
+		pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(11, 0));
+
+	if (nvidia_x86_64_private.dev_1 == NULL) {
+		printk(KERN_INFO PFX "agpgart: Detected an NVIDIA "
+			"nForce3 chipset, but could not find "
+			"the secondary device.\n");
+		agp_bridge.type = NOT_SUPPORTED;
+		return -ENODEV;
+	}
+
+	agp_bridge.masks = nvidia_x86_64_masks;
+	agp_bridge.aperture_sizes = (void *) nvidia_x86_64_sizes;
+	agp_bridge.size_type = U32_APER_SIZE;
+	agp_bridge.num_aperture_sizes = 5;
+	agp_bridge.dev_private_data = NULL;
+	agp_bridge.needs_scratch_page = FALSE;
+	agp_bridge.configure = nvidia_x86_64_configure;
+	agp_bridge.fetch_size = amd_x86_64_fetch_size;
+	agp_bridge.cleanup = nvidia_x86_64_cleanup;
+	agp_bridge.tlb_flush = amd_x86_64_tlbflush;
+	agp_bridge.mask_memory = nvidia_x86_64_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_K8 */
 
 #ifdef CONFIG_AGP_ALI
 
@@ -5938,6 +6007,20 @@
 		"AMD",
 		"761",
 		amd_irongate_setup },
+#endif
+#ifdef CONFIG_AGP_AMD_K8
+	{ PCI_DEVICE_ID_AMD_8151_0,
+		PCI_VENDOR_ID_AMD,
+		AMD_8151,
+		"AMD",
+		"On-CPU GART",
+		amd_8151_setup },
+
+	/* Note: when adding more PCI-IDs for 8151 compatible bridges
+	   add them to the end of their vendor lists, not here.
+	   This list has to be ordered by vendor. */
+#endif /* CONFIG_AGP_AMD */
+#ifdef CONFIG_AGP_AMD
 	{ 0,
 		PCI_VENDOR_ID_AMD,
 		AMD_GENERIC,
@@ -5946,15 +6029,6 @@
 		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,
@@ -6178,6 +6252,16 @@
 		"SiS",
                 "550",
 		sis_generic_setup },
+#endif
+#ifdef CONFIG_AGP_AMD_K8
+	{ PCI_DEVICE_ID_SI_755,
+		PCI_VENDOR_ID_SI,
+		AMD_8151,
+		"AMD",
+		"On-CPU GART",
+		amd_8151_setup },
+#endif
+#ifdef CONFIG_AGP_SIS
 	{ 0,
 		PCI_VENDOR_ID_SI,
 		SIS_GENERIC,
@@ -6265,6 +6349,24 @@
 		"Via",
 		"Apollo P4M266",
 		via_generic_setup },
+#endif
+#ifdef CONFIG_AGP_AMD_K8
+ 	{ PCI_DEVICE_ID_VIA_8380_0,
+ 		PCI_VENDOR_ID_VIA,
+ 		AMD_8151,
+ 		"AMD",
+ 		"On-CPU GART",
+ 		amd_8151_setup },
+
+ 	/* VIA K8T800 */
+ 	{ PCI_DEVICE_ID_VIA_8385_0,
+  		PCI_VENDOR_ID_VIA,
+  		AMD_8151,
+  		"AMD",
+  		"On-CPU GART",
+ 		amd_8151_setup },		
+#endif
+#ifdef CONFIG_AGP_VIA
 	{ 0,
 		PCI_VENDOR_ID_VIA,
 		VIA_GENERIC,
@@ -6286,6 +6388,16 @@
 		"NVIDIA",
 		"nForce2",
 		nvidia_generic_setup },
+#endif
+#ifdef CONFIG_AGP_AMD_K8
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE3,
+		PCI_VENDOR_ID_NVIDIA,
+		NVIDIA_NFORCE3,
+		"NVIDIA",
+		"nForce3/K8 On-CPU GART",
+		nvidia_x86_64_setup },
+#endif
+#ifdef CONFIG_AGP_NVIDIA
 	{ 0,
 		PCI_VENDOR_ID_NVIDIA,
 		NVIDIA_GENERIC,
@@ -6412,7 +6524,11 @@
 	}
 
 	printk(KERN_ERR PFX "Unsupported %s chipset (device id: %04x),"
+#ifdef MODULE
 	       " you might want to try agp_try_unsupported=1.\n",
+#else
+	       " you might want to boot with agp=try_unsupported\n",
+#endif
 	       agp_bridge_info[i].vendor_name, pdev->device);
 	return -ENODEV;
 }
@@ -6435,6 +6551,31 @@
 
 	agp_bridge.dev = dev;
 
+#ifdef CONFIG_AGP_AMD_K8
+	/* If there is any K8 northbridge in the system always use the K8 driver */
+	if (agp_try_unsupported
+	    && pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, NULL)
+	    && !pci_find_device(PCI_VENDOR_ID_NVIDIA, 
+				PCI_DEVICE_ID_NVIDIA_NFORCE3,
+				NULL)) { 
+
+		/* find capndx */
+		cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
+		if (cap_ptr == 0x00)
+			return -ENODEV;
+		agp_bridge.capndx = cap_ptr;
+		
+		/* Fill in the mode register */
+		pci_read_config_dword(agp_bridge.dev,
+				      agp_bridge.capndx + 4,
+				      &agp_bridge.mode);
+		
+		printk(KERN_INFO PFX "Detected GART in AMD K8 Northbridge\n"); 
+		agp_bridge.type = AMD_8151; 
+		return amd_8151_setup(dev);
+	}					
+#endif
+
 	/* Need to test for I810 here */
 #ifdef CONFIG_AGP_I810
 	if (dev->vendor == PCI_VENDOR_ID_INTEL) {
@@ -6892,10 +7033,26 @@
 	&agp_copy_info
 };
 
+static int __initdata agp_off = 0; 
+int __init agp_setup(char *s) 
+{ 
+	if (!strcmp(s,"off"))
+		agp_off = 1;
+	if (!strcmp(s,"try_unsupported"))
+		agp_try_unsupported = 1;
+	return 0;		
+} 
+__setup("agp=", agp_setup); 
+
 int __init agp_init(void)
 {
 	int ret_val;
 
+	if (agp_off) { 
+		printk("AGP disabled\n"); 
+		return -1;
+	} 
+
 	printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Jeff Hartmann\n",
 	       AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
 
diff -urN linux-2.4.22-bk25/drivers/net/Config.in linux-2.4.22-bk26/drivers/net/Config.in
--- linux-2.4.22-bk25/drivers/net/Config.in	2003-09-29 02:49:38.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/Config.in	2003-09-29 02:49:41.000000000 -0700
@@ -269,17 +269,6 @@
 dep_tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN $CONFIG_PCI $CONFIG_EXPERIMENTAL
 dep_tristate 'Realtek 8169 Gigabit Ethernet support' CONFIG_R8169 $CONFIG_PCI
 dep_tristate 'Marvell Yukon Chipset / SysKonnect SK-98xx Support' CONFIG_SK98LIN $CONFIG_PCI
-if [ "$CONFIG_SK98LIN" != "n" ]; then
-   bool '  3Com 3C940/3C941 Gigabit Ethernet Adapter' CONFIG_SK98LIN_T1
-   bool '  Allied Telesyn AT-29xx Gigabit Ethernet Adapter' CONFIG_SK98LIN_T3
-   bool '  CNet N-Way Gigabit Ethernet Adapter' CONFIG_SK98LIN_T8
-   bool '  D-Link DGE-530T Gigabit Ethernet Adapter' CONFIG_SK98LIN_T6
-   bool '  Linksys EG10xx Ethernet Server Adapter' CONFIG_SK98LIN_T9
-   bool '  Marvell RDK-80xx Adapter' CONFIG_SK98LIN_T4
-   bool '  Marvell Yukon Gigabit Ethernet Adapter' CONFIG_SK98LIN_T7
-   bool '  SysKonnect SK-98xx Server Gigabit Adapter' CONFIG_SK98LIN_T2
-   bool '  SysKonnect SK-98xx V2.0 Gigabit Ethernet Adapter' CONFIG_SK98LIN_T5
-fi
 dep_tristate 'Broadcom Tigon3 support' CONFIG_TIGON3 $CONFIG_PCI
 
 if [ "$CONFIG_MOMENCO_OCELOT_C" = "y" -o "$CONFIG_MOMENCO_JAGUAR_ATX" = "y" ]; then
diff -urN linux-2.4.22-bk25/drivers/net/e1000/e1000.h linux-2.4.22-bk26/drivers/net/e1000/e1000.h
--- linux-2.4.22-bk25/drivers/net/e1000/e1000.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/e1000/e1000.h	2003-09-29 02:49:41.000000000 -0700
@@ -122,7 +122,12 @@
 #define E1000_RX_BUFFER_WRITE	16	/* Must be power of 2 */
 
 #define AUTO_ALL_MODES       0
-#define E1000_EEPROM_APME    4
+#define E1000_EEPROM_APME    0x0400
+
+#ifndef E1000_MASTER_SLAVE
+/* Switch to override PHY master/slave setting */
+#define E1000_MASTER_SLAVE	e1000_ms_hw_default
+#endif
 
 /* only works for sizes that are powers of 2 */
 #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
@@ -180,6 +185,7 @@
 	spinlock_t stats_lock;
 	atomic_t irq_sem;
 	struct tq_struct tx_timeout_task;
+     	uint8_t fc_autoneg;
 
 	struct timer_list blink_timer;
 	unsigned long led_status;
@@ -194,6 +200,7 @@
 	uint32_t tx_head_addr;
 	uint32_t tx_fifo_size;
 	atomic_t tx_fifo_stall;
+	boolean_t pcix_82544;
 
 	/* RX */
 	struct e1000_desc_ring rx_ring;
diff -urN linux-2.4.22-bk25/drivers/net/e1000/e1000_ethtool.c linux-2.4.22-bk26/drivers/net/e1000/e1000_ethtool.c
--- linux-2.4.22-bk25/drivers/net/e1000/e1000_ethtool.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/e1000/e1000_ethtool.c	2003-09-29 02:49:41.000000000 -0700
@@ -190,6 +190,55 @@
 	return 0;
 }
 
+static int
+e1000_ethtool_gpause(struct e1000_adapter *adapter,
+                     struct ethtool_pauseparam *epause)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	
+	epause->autoneg = 
+		(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
+	
+	if(hw->fc == e1000_fc_rx_pause)
+		epause->rx_pause = 1;
+	else if(hw->fc == e1000_fc_tx_pause)
+		epause->tx_pause = 1;
+	else if(hw->fc == e1000_fc_full) {
+		epause->rx_pause = 1;
+		epause->tx_pause = 1;
+	}
+	
+	return 0;
+}
+
+static int
+e1000_ethtool_spause(struct e1000_adapter *adapter,
+                     struct ethtool_pauseparam *epause)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	
+	adapter->fc_autoneg = epause->autoneg;
+
+	if(epause->rx_pause && epause->tx_pause)
+		hw->fc = e1000_fc_full;
+	else if(epause->rx_pause && !epause->tx_pause)
+		hw->fc = e1000_fc_rx_pause;
+	else if(!epause->rx_pause && epause->tx_pause)
+		hw->fc = e1000_fc_tx_pause;
+	else if(!epause->rx_pause && !epause->tx_pause)
+		hw->fc = e1000_fc_none;
+
+	hw->original_fc = hw->fc;
+
+	if(netif_running(adapter->netdev)) {
+		e1000_down(adapter);
+		e1000_up(adapter);
+	} else
+		e1000_reset(adapter);
+	
+	return 0;
+}
+
 static void
 e1000_ethtool_gdrvinfo(struct e1000_adapter *adapter,
                        struct ethtool_drvinfo *drvinfo)
@@ -197,7 +246,7 @@
 	strncpy(drvinfo->driver,  e1000_driver_name, 32);
 	strncpy(drvinfo->version, e1000_driver_version, 32);
 	strncpy(drvinfo->fw_version, "N/A", 32);
-	strncpy(drvinfo->bus_info, adapter->pdev->slot_name, 32);
+	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
 	drvinfo->n_stats = E1000_STATS_LEN;
 	drvinfo->testinfo_len = E1000_TEST_LEN;
 #define E1000_REGS_LEN 32
@@ -504,7 +553,7 @@
 	return *data;
 }
 
-static void
+static irqreturn_t
 e1000_test_intr(int irq,
 		void *data,
 		struct pt_regs *regs)
@@ -514,7 +563,7 @@
 
 	adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 static int
@@ -958,9 +1007,13 @@
 	case e1000_82544:
 	case e1000_82540:
 	case e1000_82545:
+	case e1000_82545_rev_3:
 	case e1000_82546:
+	case e1000_82546_rev_3:
 	case e1000_82541:
+	case e1000_82541_rev_2:
 	case e1000_82547:
+	case e1000_82547_rev_2:
 		return e1000_integrated_phy_loopback(adapter);
 		break;
 
@@ -983,9 +1036,12 @@
 {
 	uint32_t rctl;
 
-	if(adapter->hw.media_type == e1000_media_type_fiber) {
+	if(adapter->hw.media_type == e1000_media_type_fiber ||
+	   adapter->hw.media_type == e1000_media_type_internal_serdes) {
 		if(adapter->hw.mac_type == e1000_82545 ||
-		   adapter->hw.mac_type == e1000_82546)
+		   adapter->hw.mac_type == e1000_82546 ||
+		   adapter->hw.mac_type == e1000_82545_rev_3 ||
+		   adapter->hw.mac_type == e1000_82546_rev_3)
 			return e1000_set_phy_loopback(adapter);
 		else {
 			rctl = E1000_READ_REG(&adapter->hw, RCTL);
@@ -1010,9 +1066,12 @@
 	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
 
 	if(adapter->hw.media_type == e1000_media_type_copper ||
-	   (adapter->hw.media_type == e1000_media_type_fiber &&
+	   ((adapter->hw.media_type == e1000_media_type_fiber ||
+	     adapter->hw.media_type == e1000_media_type_internal_serdes) &&
 	    (adapter->hw.mac_type == e1000_82545 ||
-	     adapter->hw.mac_type == e1000_82546))) {
+	     adapter->hw.mac_type == e1000_82546 ||
+	     adapter->hw.mac_type == e1000_82545_rev_3 ||
+	     adapter->hw.mac_type == e1000_82546_rev_3))) {
 		adapter->hw.autoneg = TRUE;
 		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
 		if(phy_reg & MII_CR_LOOPBACK) {
@@ -1114,7 +1173,7 @@
 			e1000_down(adapter);
 		else
 			e1000_reset(adapter);
-		
+
 		if(e1000_reg_test(adapter, &data[0]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
@@ -1162,6 +1221,7 @@
 		return;
 
 	case E1000_DEV_ID_82546EB_FIBER:
+	case E1000_DEV_ID_82546GB_FIBER:
 		/* Wake events only supported on port A for dual fiber */
 		if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
 			wol->supported = 0;
@@ -1200,6 +1260,7 @@
 		return wol->wolopts ? -EOPNOTSUPP : 0;
 
 	case E1000_DEV_ID_82546EB_FIBER:
+	case E1000_DEV_ID_82546GB_FIBER:
 		/* Wake events only supported on port A for dual fiber */
 		if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
 			return wol->wolopts ? -EOPNOTSUPP : 0;
@@ -1437,6 +1498,19 @@
 		addr += offsetof(struct ethtool_eeprom, data);
 		return e1000_ethtool_seeprom(adapter, &eeprom, addr);
 	}
+	case ETHTOOL_GPAUSEPARAM: {
+		struct ethtool_pauseparam epause = {ETHTOOL_GPAUSEPARAM};
+		e1000_ethtool_gpause(adapter, &epause);
+		if(copy_to_user(addr, &epause, sizeof(epause)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SPAUSEPARAM: {
+		struct ethtool_pauseparam epause;
+		if(copy_from_user(&epause, addr, sizeof(epause)))
+			return -EFAULT;
+		return e1000_ethtool_spause(adapter, &epause);
+	}
 	case ETHTOOL_GSTATS: {
 		struct {
 			struct ethtool_stats eth_stats;
@@ -1475,6 +1549,107 @@
 			return -EFAULT;
 		return 0;
 	}
+	case ETHTOOL_GRXCSUM: {
+		struct ethtool_value edata = { ETHTOOL_GRXCSUM };
+
+		edata.data = adapter->rx_csum;
+		if (copy_to_user(addr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SRXCSUM: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, addr, sizeof(edata)))
+			return -EFAULT;
+		adapter->rx_csum = edata.data;
+		if(netif_running(netdev)) {
+			e1000_down(adapter);
+			e1000_up(adapter);
+		} else
+			e1000_reset(adapter);
+		return 0;
+	}
+	case ETHTOOL_GTXCSUM: {
+		struct ethtool_value edata = { ETHTOOL_GTXCSUM };
+
+		edata.data =
+			(netdev->features & NETIF_F_HW_CSUM) != 0;
+		if (copy_to_user(addr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_STXCSUM: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, addr, sizeof(edata)))
+			return -EFAULT;
+
+		if(adapter->hw.mac_type < e1000_82543) {
+			if (edata.data != 0)
+				return -EINVAL;
+			return 0;
+		}
+
+		if (edata.data)
+			netdev->features |= NETIF_F_HW_CSUM;
+		else
+			netdev->features &= ~NETIF_F_HW_CSUM;
+
+		return 0;
+	}
+	case ETHTOOL_GSG: {
+		struct ethtool_value edata = { ETHTOOL_GSG };
+
+		edata.data =
+			(netdev->features & NETIF_F_SG) != 0;
+		if (copy_to_user(addr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_SSG: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, addr, sizeof(edata)))
+			return -EFAULT;
+
+		if (edata.data)
+			netdev->features |= NETIF_F_SG;
+		else
+			netdev->features &= ~NETIF_F_SG;
+
+		return 0;
+	}
+#ifdef NETIF_F_TSO
+	case ETHTOOL_GTSO: {
+		struct ethtool_value edata = { ETHTOOL_GTSO };
+
+		edata.data = (netdev->features & NETIF_F_TSO) != 0;
+		if (copy_to_user(addr, &edata, sizeof(edata)))
+			return -EFAULT;
+		return 0;
+	}
+	case ETHTOOL_STSO: {
+		struct ethtool_value edata;
+
+		if (copy_from_user(&edata, addr, sizeof(edata)))
+			return -EFAULT;
+
+		if ((adapter->hw.mac_type < e1000_82544) ||
+		    (adapter->hw.mac_type == e1000_82547)) {
+			if (edata.data != 0)
+				return -EINVAL;
+			return 0;
+		}
+
+		if (edata.data)
+			netdev->features |= NETIF_F_TSO;
+		else
+			netdev->features &= ~NETIF_F_TSO;
+
+		return 0;
+	}
+#endif
 	default:
 		return -EOPNOTSUPP;
 	}
diff -urN linux-2.4.22-bk25/drivers/net/e1000/e1000_hw.c linux-2.4.22-bk26/drivers/net/e1000/e1000_hw.c
--- linux-2.4.22-bk25/drivers/net/e1000/e1000_hw.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/e1000/e1000_hw.c	2003-09-29 02:49:41.000000000 -0700
@@ -34,14 +34,15 @@
 
 static int32_t e1000_set_phy_type(struct e1000_hw *hw);
 static void e1000_phy_init_script(struct e1000_hw *hw);
-static int32_t e1000_setup_fiber_link(struct e1000_hw *hw);
 static int32_t e1000_setup_copper_link(struct e1000_hw *hw);
+static int32_t e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
+static int32_t e1000_adjust_serdes_amplitude(struct e1000_hw *hw);
 static int32_t e1000_phy_force_speed_duplex(struct e1000_hw *hw);
 static int32_t e1000_config_mac_to_phy(struct e1000_hw *hw);
-static int32_t e1000_force_mac_fc(struct e1000_hw *hw);
 static void e1000_raise_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);
 static void e1000_lower_mdi_clk(struct e1000_hw *hw, uint32_t *ctrl);
-static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data, uint16_t count);
+static void e1000_shift_out_mdi_bits(struct e1000_hw *hw, uint32_t data,
+                                     uint16_t count);
 static uint16_t e1000_shift_in_mdi_bits(struct e1000_hw *hw);
 static int32_t e1000_phy_reset_dsp(struct e1000_hw *hw);
 static int32_t e1000_write_eeprom_spi(struct e1000_hw *hw, uint16_t offset,
@@ -52,14 +53,31 @@
 static int32_t e1000_spi_eeprom_ready(struct e1000_hw *hw);
 static void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
 static void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
-static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count);
+static void e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data,
+                                    uint16_t count);
+static int32_t e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr,
+                                      uint16_t phy_data);
+static int32_t e1000_read_phy_reg_ex(struct e1000_hw *hw,uint32_t reg_addr,
+                                     uint16_t *phy_data);
 static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count);
 static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
 static void e1000_release_eeprom(struct e1000_hw *hw);
 static void e1000_standby_eeprom(struct e1000_hw *hw);
 static int32_t e1000_id_led_init(struct e1000_hw * hw);
+static int32_t e1000_set_vco_speed(struct e1000_hw *hw);
 
 
+/* IGP cable length table */
+static const
+uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
+    { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+      5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
+      25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
+      40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
+      60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
+      90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
+      100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+      110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
 
 /******************************************************************************
  * Set the phy type member in the hw struct.
@@ -100,50 +118,41 @@
     DEBUGFUNC("e1000_phy_init_script");
 
     if(hw->phy_init_script) {
-        msec_delay(10);
+        msec_delay(20);
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
         e1000_write_phy_reg(hw,0x0000,0x0140);
 
         msec_delay(5);
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F95);
-        e1000_write_phy_reg(hw,0x0015,0x0001);
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F71);
-        e1000_write_phy_reg(hw,0x0011,0xBD21);
+        if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
+            e1000_write_phy_reg(hw, 0x1F95, 0x0001);
+
+            e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F79);
-        e1000_write_phy_reg(hw,0x0019,0x0018);
+            e1000_write_phy_reg(hw, 0x1F79, 0x0018);
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F30);
-        e1000_write_phy_reg(hw,0x0010,0x1600);
+            e1000_write_phy_reg(hw, 0x1F30, 0x1600);
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F31);
-        e1000_write_phy_reg(hw,0x0011,0x0014);
+            e1000_write_phy_reg(hw, 0x1F31, 0x0014);
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F32);
-        e1000_write_phy_reg(hw,0x0012,0x161C);
+            e1000_write_phy_reg(hw, 0x1F32, 0x161C);
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F94);
-        e1000_write_phy_reg(hw,0x0014,0x0003);
+            e1000_write_phy_reg(hw, 0x1F94, 0x0003);
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x1F96);
-        e1000_write_phy_reg(hw,0x0016,0x003F);
+            e1000_write_phy_reg(hw, 0x1F96, 0x003F);
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x2010);
-        e1000_write_phy_reg(hw,0x0010,0x0008);
+            e1000_write_phy_reg(hw, 0x2010, 0x0008);
+        } else {
+            e1000_write_phy_reg(hw, 0x1F73, 0x0099);
+        }
 
-        e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000);
-        e1000_write_phy_reg(hw,0x0000,0x3300);
+        e1000_write_phy_reg(hw, 0x0000, 0x3300);
 
 
         if(hw->mac_type == e1000_82547) {
             uint16_t fused, fine, coarse;
 
             /* Move to analog registers page */
-            e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 
-                                IGP01E1000_ANALOG_REGS_PAGE);
-
             e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
 
             if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
@@ -158,17 +167,14 @@
                 } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
                     fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
 
-                fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) | 
-                        (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) | 
+                fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
+                        (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
                         (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);
 
                 e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
-                e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS, 
+                e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
                                     IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
             }
-            /* Return to first page of registers */
-            e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
-                                IGP01E1000_IEEE_REGS_PAGE);
         }
     }
 }
@@ -218,32 +224,89 @@
     case E1000_DEV_ID_82545EM_FIBER:
         hw->mac_type = e1000_82545;
         break;
+    case E1000_DEV_ID_82545GM_COPPER:
+    case E1000_DEV_ID_82545GM_FIBER:
+    case E1000_DEV_ID_82545GM_SERDES:
+        hw->mac_type = e1000_82545_rev_3;
+        break;
     case E1000_DEV_ID_82546EB_COPPER:
     case E1000_DEV_ID_82546EB_FIBER:
     case E1000_DEV_ID_82546EB_QUAD_COPPER:
         hw->mac_type = e1000_82546;
         break;
+    case E1000_DEV_ID_82546GB_COPPER:
+    case E1000_DEV_ID_82546GB_FIBER:
+    case E1000_DEV_ID_82546GB_SERDES:
+        hw->mac_type = e1000_82546_rev_3;
+        break;
     case E1000_DEV_ID_82541EI:
-    case E1000_DEV_ID_82541EP:
+    case E1000_DEV_ID_82541EI_MOBILE:
         hw->mac_type = e1000_82541;
         break;
+    case E1000_DEV_ID_82541ER:
+    case E1000_DEV_ID_82541GI:
+    case E1000_DEV_ID_82541GI_MOBILE:
+        hw->mac_type = e1000_82541_rev_2;
+        break;
     case E1000_DEV_ID_82547EI:
         hw->mac_type = e1000_82547;
         break;
+    case E1000_DEV_ID_82547GI:
+        hw->mac_type = e1000_82547_rev_2;
+        break;
     default:
         /* Should never have loaded on this device */
         return -E1000_ERR_MAC_TYPE;
     }
 
-
     return E1000_SUCCESS;
 }
+
+/*****************************************************************************
+ * Set media type and TBI compatibility.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * **************************************************************************/
+void
+e1000_set_media_type(struct e1000_hw *hw)
+{
+    uint32_t status;
+
+    DEBUGFUNC("e1000_set_media_type");
+
+    if(hw->mac_type != e1000_82543) {
+        /* tbi_compatibility is only valid on 82543 */
+        hw->tbi_compatibility_en = FALSE;
+    }
+
+    switch (hw->device_id) {
+    case E1000_DEV_ID_82545GM_SERDES:
+    case E1000_DEV_ID_82546GB_SERDES:
+        hw->media_type = e1000_media_type_internal_serdes;
+        break;
+    default:
+        if(hw->mac_type >= e1000_82543) {
+            status = E1000_READ_REG(hw, STATUS);
+            if(status & E1000_STATUS_TBIMODE) {
+                hw->media_type = e1000_media_type_fiber;
+                /* tbi_compatibility not valid on fiber */
+                hw->tbi_compatibility_en = FALSE;
+            } else {
+                hw->media_type = e1000_media_type_copper;
+            }
+        } else {
+            /* This is an 82542 (fiber only) */
+            hw->media_type = e1000_media_type_fiber;
+        }
+    }
+}
+
 /******************************************************************************
  * Reset the transmit and receive units; mask and clear all interrupts.
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+int32_t
 e1000_reset_hw(struct e1000_hw *hw)
 {
     uint32_t ctrl;
@@ -280,49 +343,75 @@
      */
     msec_delay(10);
 
-    /* Issue a global reset to the MAC.  This will reset the chip's
-     * transmit, receive, DMA, and link units.  It will not effect
-     * the current PCI configuration.  The global reset bit is self-
-     * clearing, and should clear within a microsecond.
-     */
-    DEBUGOUT("Issuing a global reset to MAC\n");
     ctrl = E1000_READ_REG(hw, CTRL);
 
     /* Must reset the PHY before resetting the MAC */
     if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
         E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
-	msec_delay(5);
+        msec_delay(5);
     }
 
+    /* Issue a global reset to the MAC.  This will reset the chip's
+     * transmit, receive, DMA, and link units.  It will not effect
+     * the current PCI configuration.  The global reset bit is self-
+     * clearing, and should clear within a microsecond.
+     */
+    DEBUGOUT("Issuing a global reset to MAC\n");
+
     switch(hw->mac_type) {
         case e1000_82544:
         case e1000_82540:
         case e1000_82545:
         case e1000_82546:
         case e1000_82541:
+        case e1000_82541_rev_2:
             /* These controllers can't ack the 64-bit write when issuing the
              * reset, so use IO-mapping as a workaround to issue the reset */
             E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
             break;
+        case e1000_82545_rev_3:
+        case e1000_82546_rev_3:
+            /* Reset is performed on a shadow of the control register */
+            E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
+            break;
         default:
             E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
             break;
     }
 
-    /* Force a reload from the EEPROM if necessary */
-    if(hw->mac_type < e1000_82540) {
-        /* Wait for reset to complete */
-        udelay(10);
-        ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-        ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-        E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-        E1000_WRITE_FLUSH(hw);
-        /* Wait for EEPROM reload */
-        msec_delay(2);
-    } else {
-        /* Wait for EEPROM reload (it happens automatically) */
-        msec_delay(5);
-        /* Dissable HW ARPs on ASF enabled adapters */
+    /* After MAC reset, force reload of EEPROM to restore power-on settings to
+     * device.  Later controllers reload the EEPROM automatically, so just wait
+     * for reload to complete.
+     */
+    switch(hw->mac_type) {
+        case e1000_82542_rev2_0:
+        case e1000_82542_rev2_1:
+        case e1000_82543:
+        case e1000_82544:
+            /* Wait for reset to complete */
+            udelay(10);
+            ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+            ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+            E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+            E1000_WRITE_FLUSH(hw);
+            /* Wait for EEPROM reload */
+            msec_delay(2);
+            break;
+        case e1000_82541:
+        case e1000_82541_rev_2:
+        case e1000_82547:
+        case e1000_82547_rev_2:
+            /* Wait for EEPROM reload */
+            msec_delay(20);
+            break;
+        default:
+            /* Wait for EEPROM reload (it happens automatically) */
+            msec_delay(5);
+            break;
+    }
+
+    /* Disable HW ARPs on ASF enabled adapters */
+    if(hw->mac_type >= e1000_82540) {
         manc = E1000_READ_REG(hw, MANC);
         manc &= ~(E1000_MANC_ARP_EN);
         E1000_WRITE_REG(hw, MANC, manc);
@@ -350,6 +439,8 @@
         if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
             e1000_pci_set_mwi(hw);
     }
+
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -366,7 +457,7 @@
 int32_t
 e1000_init_hw(struct e1000_hw *hw)
 {
-    uint32_t ctrl, status;
+    uint32_t ctrl;
     uint32_t i;
     int32_t ret_val;
     uint16_t pcix_cmd_word;
@@ -377,31 +468,13 @@
     DEBUGFUNC("e1000_init_hw");
 
     /* Initialize Identification LED */
-    ret_val = e1000_id_led_init(hw);
-    if(ret_val < 0) {
+    if((ret_val = e1000_id_led_init(hw))) {
         DEBUGOUT("Error Initializing Identification LED\n");
         return ret_val;
     }
 
-    /* Set the Media Type and exit with error if it is not valid. */
-    if(hw->mac_type != e1000_82543) {
-        /* tbi_compatibility is only valid on 82543 */
-        hw->tbi_compatibility_en = FALSE;
-    }
-
-    if(hw->mac_type >= e1000_82543) {
-        status = E1000_READ_REG(hw, STATUS);
-        if(status & E1000_STATUS_TBIMODE) {
-            hw->media_type = e1000_media_type_fiber;
-            /* tbi_compatibility not valid on fiber */
-            hw->tbi_compatibility_en = FALSE;
-        } else {
-            hw->media_type = e1000_media_type_copper;
-        }
-    } else {
-        /* This is an 82542 (fiber only) */
-        hw->media_type = e1000_media_type_fiber;
-    }
+    /* Set the media type and TBI compatibility */
+    e1000_set_media_type(hw);
 
     /* Disabling VLAN filtering. */
     DEBUGOUT("Initializing the IEEE VLAN\n");
@@ -446,21 +519,30 @@
         E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
     }
 
-    /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
-    if(hw->bus_type == e1000_bus_type_pcix) {
-        e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
-        e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word);
-        cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
-            PCIX_COMMAND_MMRBC_SHIFT;
-        stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
-            PCIX_STATUS_HI_MMRBC_SHIFT;
-        if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
-            stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
-        if(cmd_mmrbc > stat_mmrbc) {
-            pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
-            pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
-            e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
+    switch(hw->mac_type) {
+    case e1000_82545_rev_3:
+    case e1000_82546_rev_3:
+        break;
+    default:
+        /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
+        if(hw->bus_type == e1000_bus_type_pcix) {
+            e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
+            e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI,
+                &pcix_stat_hi_word);
+            cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
+                PCIX_COMMAND_MMRBC_SHIFT;
+            stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
+                PCIX_STATUS_HI_MMRBC_SHIFT;
+            if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
+                stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
+            if(cmd_mmrbc > stat_mmrbc) {
+                pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
+                pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
+                e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER,
+                    &pcix_cmd_word);
+            }
         }
+        break;
     }
 
     /* Call a subroutine to configure the link and setup flow control. */
@@ -484,6 +566,46 @@
 }
 
 /******************************************************************************
+ * Adjust SERDES output amplitude based on EEPROM setting.
+ *
+ * hw - Struct containing variables accessed by shared code.
+ *****************************************************************************/
+static int32_t
+e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
+{
+    uint16_t eeprom_data;
+    int32_t  ret_val;
+
+    DEBUGFUNC("e1000_adjust_serdes_amplitude");
+
+    if(hw->media_type != e1000_media_type_internal_serdes)
+        return E1000_SUCCESS;
+
+    switch(hw->mac_type) {
+    case e1000_82545_rev_3:
+    case e1000_82546_rev_3:
+        break;
+    default:
+        return E1000_SUCCESS;
+    }
+
+    if ((ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
+                                     &eeprom_data))) {
+        return ret_val;
+    }
+
+    if(eeprom_data != EEPROM_RESERVED_WORD) {
+        /* Adjust SERDES output amplitude only. */
+        eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK; 
+        if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL,
+                                          eeprom_data)))
+            return ret_val;
+    }
+
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
  * Configures flow control and link settings.
  *
  * hw - Struct containing variables accessed by shared code
@@ -554,9 +676,9 @@
     }
 
     /* Call the necessary subroutine to configure the link. */
-    ret_val = (hw->media_type == e1000_media_type_fiber) ?
-              e1000_setup_fiber_link(hw) :
-              e1000_setup_copper_link(hw);
+    ret_val = (hw->media_type == e1000_media_type_copper) ?
+              e1000_setup_copper_link(hw) :
+              e1000_setup_fiber_serdes_link(hw);
 
     /* Initialize the flow control address, type, and PAUSE timer
      * registers to their default values.  This is done even if flow
@@ -595,7 +717,7 @@
 }
 
 /******************************************************************************
- * Sets up link for a fiber based adapter
+ * Sets up link for a fiber based or serdes based adapter
  *
  * hw - Struct containing variables accessed by shared code
  *
@@ -604,28 +726,37 @@
  * and receiver are not enabled.
  *****************************************************************************/
 static int32_t
-e1000_setup_fiber_link(struct e1000_hw *hw)
+e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
 {
     uint32_t ctrl;
     uint32_t status;
     uint32_t txcw = 0;
     uint32_t i;
-    uint32_t signal;
+    uint32_t signal = 0;
     int32_t ret_val;
 
-    DEBUGFUNC("e1000_setup_fiber_link");
+    DEBUGFUNC("e1000_setup_fiber_serdes_link");
 
-    /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
+    /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
      * set when the optics detect a signal. On older adapters, it will be
-     * cleared when there is a signal
+     * cleared when there is a signal.  This applies to fiber media only.
+     * If we're on serdes media, adjust the output amplitude to value set in
+     * the EEPROM.
      */
     ctrl = E1000_READ_REG(hw, CTRL);
-    if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1;
-    else signal = 0;
+    if(hw->media_type == e1000_media_type_fiber)
+        signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
+
+    if((ret_val = e1000_adjust_serdes_amplitude(hw)))
+        return ret_val;
 
     /* Take the link out of reset */
     ctrl &= ~(E1000_CTRL_LRST);
 
+    /* Adjust VCO speed to improve BER performance */
+    if((ret_val = e1000_set_vco_speed(hw)))
+        return ret_val;
+
     e1000_config_collision_dist(hw);
 
     /* Check for a software override of the flow control settings, and setup
@@ -692,8 +823,10 @@
      * indication in the Device Status Register.  Time-out if a link isn't
      * seen in 500 milliseconds seconds (Auto-negotiation should complete in
      * less than 500 milliseconds even if the other end is doing it in SW).
+     * For internal serdes, we just assume a signal is present, then poll.
      */
-    if((E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
+    if(hw->media_type == e1000_media_type_internal_serdes ||
+       (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
         DEBUGOUT("Looking for Link\n");
         for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
             msec_delay(10);
@@ -701,19 +834,20 @@
             if(status & E1000_STATUS_LU) break;
         }
         if(i == (LINK_UP_TIMEOUT / 10)) {
-            /* AutoNeg failed to achieve a link, so we'll call
-             * e1000_check_for_link. This routine will force the link up if we
-             * detect a signal. This will allow us to communicate with
-             * non-autonegotiating link partners.
-             */
             DEBUGOUT("Never got a valid link from auto-neg!!!\n");
             hw->autoneg_failed = 1;
-            ret_val = e1000_check_for_link(hw);
-            if(ret_val < 0) {
-                DEBUGOUT("Error while checking for link\n");
-                return ret_val;
+            if(hw->media_type == e1000_media_type_fiber) {
+                /* AutoNeg failed to achieve a link, so we'll call
+                 * e1000_check_for_link. This routine will force the link up if
+                 * we detect a signal. This will allow us to communicate with
+                 * non-autonegotiating link partners.
+                 */
+                if((ret_val = e1000_check_for_link(hw))) {
+                    DEBUGOUT("Error while checking for link\n");
+                    return ret_val;
+                }
+                hw->autoneg_failed = 0;
             }
-            hw->autoneg_failed = 0;
         } else {
             hw->autoneg_failed = 0;
             DEBUGOUT("Valid Link Found\n");
@@ -721,7 +855,7 @@
     } else {
         DEBUGOUT("No Signal Detected\n");
     }
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -756,233 +890,281 @@
     }
 
     /* Make sure we have a valid PHY */
-    ret_val = e1000_detect_gig_phy(hw);
-    if(ret_val < 0) {
+    if((ret_val = e1000_detect_gig_phy(hw))) {
         DEBUGOUT("Error, did not detect valid phy.\n");
         return ret_val;
     }
     DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
 
-    if (hw->phy_type == e1000_phy_igp) {
-
-        ret_val = e1000_phy_reset(hw);
-        if(ret_val < 0) {
-            DEBUGOUT("Error Resetting the PHY\n");
-            return ret_val;
-        }
+    if(hw->mac_type <= e1000_82543 ||
+       hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
+       hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
+        hw->phy_reset_disable = FALSE;
 
-        /* Wait 10ms for MAC to configure PHY from eeprom settings */
-        msec_delay(15);
+    if(!hw->phy_reset_disable) {
+        if (hw->phy_type == e1000_phy_igp) {
 
-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
-            DEBUGOUT("PHY Write Error\n");
-            return -E1000_ERR_PHY;
-        }
+            if((ret_val = e1000_phy_reset(hw))) {
+                DEBUGOUT("Error Resetting the PHY\n");
+                return ret_val;
+            }
 
-        /* Configure activity LED after PHY reset */
-        led_ctrl = E1000_READ_REG(hw, LEDCTL);
-        led_ctrl &= IGP_ACTIVITY_LED_MASK;
-        led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-        E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+            /* Wait 10ms for MAC to configure PHY from eeprom settings */
+            msec_delay(15);
 
-        if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
-            /* Disable SmartSpeed */
-            if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-                                  &phy_data) < 0) {
-                DEBUGOUT("PHY Read Error\n");
-                return -E1000_ERR_PHY;
-            }
-            phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-                                   phy_data) < 0) {
-                DEBUGOUT("PHY Write Error\n");
-                return -E1000_ERR_PHY;
-            }
-            /* Set auto Master/Slave resolution process */
-            if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data) < 0) {
-                DEBUGOUT("PHY Read Error\n");
-                return -E1000_ERR_PHY;
+            /* Configure activity LED after PHY reset */
+            led_ctrl = E1000_READ_REG(hw, LEDCTL);
+            led_ctrl &= IGP_ACTIVITY_LED_MASK;
+            led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
+            E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
+
+            /* disable lplu d3 during driver init */
+            if((ret_val = e1000_set_d3_lplu_state(hw, FALSE))) {
+                DEBUGOUT("Error Disabling LPLU D3\n");
+                return ret_val;
             }
-            phy_data &= ~CR_1000T_MS_ENABLE;
-            if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data) < 0) {
-                DEBUGOUT("PHY Write Error\n");
-                return -E1000_ERR_PHY;
+
+            /* Configure mdi-mdix settings */
+            if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                             &phy_data)))
+                return ret_val;
+
+            if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+                hw->dsp_config_state = e1000_dsp_config_disabled;
+                /* Force MDI for IGP B-0 PHY */
+                phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
+                              IGP01E1000_PSCR_FORCE_MDI_MDIX);
+                hw->mdix = 1;
+
+            } else {
+                hw->dsp_config_state = e1000_dsp_config_enabled;
+                phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
+
+                switch (hw->mdix) {
+                case 1:
+                    phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
+                    break;
+                case 2:
+                    phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
+                    break;
+                case 0:
+                default:
+                    phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
+                    break;
+                }
             }
-        }
+            if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                              phy_data)))
+                return ret_val;
 
-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+            /* set auto-master slave resolution settings */
+            if(hw->autoneg) {
+                e1000_ms_type phy_ms_setting = hw->master_slave;
+
+                if(hw->ffe_config_state == e1000_ffe_config_active)
+                    hw->ffe_config_state = e1000_ffe_config_enabled;
+
+                if(hw->dsp_config_state == e1000_dsp_config_activated)
+                    hw->dsp_config_state = e1000_dsp_config_enabled;
+
+                /* when autonegotiation advertisment is only 1000Mbps then we
+                 * should disable SmartSpeed and enable Auto MasterSlave
+                 * resolution as hardware default. */
+                if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
+                    /* Disable SmartSpeed */
+                    if((ret_val = e1000_read_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    &phy_data)))
+                        return ret_val;
+                    phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+                    if((ret_val = e1000_write_phy_reg(hw,
+                                                     IGP01E1000_PHY_PORT_CONFIG,
+                                                     phy_data)))
+                        return ret_val;
+                    /* Set auto Master/Slave resolution process */
+                    if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
+                                                     &phy_data)))
+                        return ret_val;
+                    phy_data &= ~CR_1000T_MS_ENABLE;
+                    if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
+                                                      phy_data)))
+                        return ret_val;
+                }
 
-        /* Force MDI for IGP PHY */
-        phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
-                      IGP01E1000_PSCR_FORCE_MDI_MDIX);
+                if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
+                                                 &phy_data)))
+                    return ret_val;
 
-        hw->mdix = 1;
+                /* load defaults for future use */
+                hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
+                                            ((phy_data & CR_1000T_MS_VALUE) ?
+                                             e1000_ms_force_master :
+                                             e1000_ms_force_slave) :
+                                             e1000_ms_auto;
+
+                switch (phy_ms_setting) {
+                case e1000_ms_force_master:
+                    phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
+                    break;
+                case e1000_ms_force_slave:
+                    phy_data |= CR_1000T_MS_ENABLE;
+                    phy_data &= ~(CR_1000T_MS_VALUE);
+                    break;
+                case e1000_ms_auto:
+                    phy_data &= ~CR_1000T_MS_ENABLE;
+                default:
+                    break;
+                }
+                if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
+                                                  phy_data)))
+                    return ret_val;
+            }
+        } else {
+            /* Enable CRS on TX. This must be set for half-duplex operation. */
+            if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                             &phy_data)))
+                return ret_val;
 
-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
-            DEBUGOUT("PHY Write Error\n");
-            return -E1000_ERR_PHY;
-        }
+            phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
 
-    } else {
-        /* Enable CRS on TX. This must be set for half-duplex operation. */
-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
-        phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+            /* Options:
+             *   MDI/MDI-X = 0 (default)
+             *   0 - Auto for all speeds
+             *   1 - MDI mode
+             *   2 - MDI-X mode
+             *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+             */
+            phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
 
-        /* Options:
-         *   MDI/MDI-X = 0 (default)
-         *   0 - Auto for all speeds
-         *   1 - MDI mode
-         *   2 - MDI-X mode
-         *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
-         */
-        phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+            switch (hw->mdix) {
+            case 1:
+                phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+                break;
+            case 2:
+                phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+                break;
+            case 3:
+                phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+                break;
+            case 0:
+            default:
+                phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+                break;
+            }
 
-        switch (hw->mdix) {
-        case 1:
-            phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
-            break;
-        case 2:
-            phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
-            break;
-        case 3:
-            phy_data |= M88E1000_PSCR_AUTO_X_1000T;
-            break;
-        case 0:
-        default:
-            phy_data |= M88E1000_PSCR_AUTO_X_MODE;
-            break;
-        }
+            /* Options:
+             *   disable_polarity_correction = 0 (default)
+             *       Automatic Correction for Reversed Cable Polarity
+             *   0 - Disabled
+             *   1 - Enabled
+             */
+            phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+            if(hw->disable_polarity_correction == 1)
+                phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+            if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                              phy_data)))
+                return ret_val;
 
-        /* Options:
-         *   disable_polarity_correction = 0 (default)
-         *       Automatic Correction for Reversed Cable Polarity
-         *   0 - Disabled
-         *   1 - Enabled
-         */
-        phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
-        if(hw->disable_polarity_correction == 1)
-            phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-        if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
-            DEBUGOUT("PHY Write Error\n");
-            return -E1000_ERR_PHY;
-        }
+            /* Force TX_CLK in the Extended PHY Specific Control Register
+             * to 25MHz clock.
+             */
+            if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                             &phy_data)))
+                return ret_val;
 
-        /* Force TX_CLK in the Extended PHY Specific Control Register
-         * to 25MHz clock.
-         */
-        if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
-        phy_data |= M88E1000_EPSCR_TX_CLK_25;
+            phy_data |= M88E1000_EPSCR_TX_CLK_25;
 
-        if (hw->phy_revision < M88E1011_I_REV_4) {
-            /* Configure Master and Slave downshift values */
-            phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
-                          M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
-            phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
-                         M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
-            if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-                                   phy_data) < 0) {
-                DEBUGOUT("PHY Write Error\n");
-                return -E1000_ERR_PHY;
+            if (hw->phy_revision < M88E1011_I_REV_4) {
+                /* Configure Master and Slave downshift values */
+                phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
+                              M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
+                phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
+                             M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+                if((ret_val = e1000_write_phy_reg(hw,
+                                                  M88E1000_EXT_PHY_SPEC_CTRL,
+                                                  phy_data)))
+                    return ret_val;
             }
-        }
 
-        /* SW Reset the PHY so all changes take effect */
-        ret_val = e1000_phy_reset(hw);
-        if(ret_val < 0) {
-            DEBUGOUT("Error Resetting the PHY\n");
-            return ret_val;
+            /* SW Reset the PHY so all changes take effect */
+            if((ret_val = e1000_phy_reset(hw))) {
+                DEBUGOUT("Error Resetting the PHY\n");
+                return ret_val;
+            }
         }
-    }
 
-    /* Options:
-     *   autoneg = 1 (default)
-     *      PHY will advertise value(s) parsed from
-     *      autoneg_advertised and fc
-     *   autoneg = 0
-     *      PHY will be set to 10H, 10F, 100H, or 100F
-     *      depending on value parsed from forced_speed_duplex.
-     */
+        /* Options:
+         *   autoneg = 1 (default)
+         *      PHY will advertise value(s) parsed from
+         *      autoneg_advertised and fc
+         *   autoneg = 0
+         *      PHY will be set to 10H, 10F, 100H, or 100F
+         *      depending on value parsed from forced_speed_duplex.
+         */
+
+        /* Is autoneg enabled?  This is enabled by default or by software
+         * override.  If so, call e1000_phy_setup_autoneg routine to parse the
+         * autoneg_advertised and fc options. If autoneg is NOT enabled, then
+         * the user should have provided a speed/duplex override.  If so, then
+         * call e1000_phy_force_speed_duplex to parse and set this up.
+         */
+        if(hw->autoneg) {
+            /* Perform some bounds checking on the hw->autoneg_advertised
+             * parameter.  If this variable is zero, then set it to the default.
+             */
+            hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
 
-    /* Is autoneg enabled?  This is enabled by default or by software override.
-     * If so, call e1000_phy_setup_autoneg routine to parse the
-     * autoneg_advertised and fc options. If autoneg is NOT enabled, then the
-     * user should have provided a speed/duplex override.  If so, then call
-     * e1000_phy_force_speed_duplex to parse and set this up.
-     */
-    if(hw->autoneg) {
-        /* Perform some bounds checking on the hw->autoneg_advertised
-         * parameter.  If this variable is zero, then set it to the default.
-         */
-        hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
+            /* If autoneg_advertised is zero, we assume it was not defaulted
+             * by the calling code so we set to advertise full capability.
+             */
+            if(hw->autoneg_advertised == 0)
+                hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
 
-        /* If autoneg_advertised is zero, we assume it was not defaulted
-         * by the calling code so we set to advertise full capability.
-         */
-        if(hw->autoneg_advertised == 0)
-            hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+            DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
+            if((ret_val = e1000_phy_setup_autoneg(hw))) {
+                DEBUGOUT("Error Setting up Auto-Negotiation\n");
+                return ret_val;
+            }
+            DEBUGOUT("Restarting Auto-Neg\n");
 
-        DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
-        ret_val = e1000_phy_setup_autoneg(hw);
-        if(ret_val < 0) {
-            DEBUGOUT("Error Setting up Auto-Negotiation\n");
-            return ret_val;
-        }
-        DEBUGOUT("Restarting Auto-Neg\n");
+            /* Restart auto-negotiation by setting the Auto Neg Enable bit and
+             * the Auto Neg Restart bit in the PHY control register.
+             */
+            if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
+                return ret_val;
 
-        /* Restart auto-negotiation by setting the Auto Neg Enable bit and
-         * the Auto Neg Restart bit in the PHY control register.
-         */
-        if(e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
-        phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
-        if(e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
-            DEBUGOUT("PHY Write Error\n");
-            return -E1000_ERR_PHY;
-        }
+            phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
+            if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
+                return ret_val;
 
-        /* Does the user want to wait for Auto-Neg to complete here, or
-         * check at a later time (for example, callback routine).
-         */
-        if(hw->wait_autoneg_complete) {
-            ret_val = e1000_wait_autoneg(hw);
-            if(ret_val < 0) {
-                DEBUGOUT("Error while waiting for autoneg to complete\n");
+            /* Does the user want to wait for Auto-Neg to complete here, or
+             * check at a later time (for example, callback routine).
+             */
+            if(hw->wait_autoneg_complete) {
+                if((ret_val = e1000_wait_autoneg(hw))) {
+                    DEBUGOUT("Error while waiting for autoneg to complete\n");
+                    return ret_val;
+                }
+            }
+            hw->get_link_status = TRUE;
+        } else {
+            DEBUGOUT("Forcing speed and duplex\n");
+            if((ret_val = e1000_phy_force_speed_duplex(hw))) {
+                DEBUGOUT("Error Forcing Speed and Duplex\n");
                 return ret_val;
             }
         }
-        hw->get_link_status = TRUE;
-    } else {
-        DEBUGOUT("Forcing speed and duplex\n");
-        ret_val = e1000_phy_force_speed_duplex(hw);
-        if(ret_val < 0) {
-            DEBUGOUT("Error Forcing Speed and Duplex\n");
-            return ret_val;
-        }
-    }
+    } /* !hw->phy_reset_disable */
 
     /* Check link status. Wait up to 100 microseconds for link to become
      * valid.
      */
     for(i = 0; i < 10; i++) {
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+            return ret_val;
+        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+            return ret_val;
+
         if(phy_data & MII_SR_LINK_STATUS) {
             /* We have link, so we need to finish the config process:
              *   1) Set up the MAC to the current PHY speed/duplex
@@ -995,25 +1177,31 @@
             if(hw->mac_type >= e1000_82544) {
                 e1000_config_collision_dist(hw);
             } else {
-                ret_val = e1000_config_mac_to_phy(hw);
-                if(ret_val < 0) {
+                if((ret_val = e1000_config_mac_to_phy(hw))) {
                     DEBUGOUT("Error configuring MAC to PHY settings\n");
                     return ret_val;
-                  }
+                }
             }
-            ret_val = e1000_config_fc_after_link_up(hw);
-            if(ret_val < 0) {
+            if((ret_val = e1000_config_fc_after_link_up(hw))) {
                 DEBUGOUT("Error Configuring Flow Control\n");
                 return ret_val;
             }
             DEBUGOUT("Valid link established!!!\n");
-            return 0;
+
+            if(hw->phy_type == e1000_phy_igp) {
+                if((ret_val = e1000_config_dsp_after_link_change(hw, TRUE))) {
+                    DEBUGOUT("Error Configuring DSP after link up\n");
+                    return ret_val;
+                }
+            }
+            DEBUGOUT("Valid link established!!!\n");
+            return E1000_SUCCESS;
         }
         udelay(10);
     }
 
     DEBUGOUT("Unable to establish link!!!\n");
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -1024,22 +1212,20 @@
 int32_t
 e1000_phy_setup_autoneg(struct e1000_hw *hw)
 {
+    int32_t ret_val;
     uint16_t mii_autoneg_adv_reg;
     uint16_t mii_1000t_ctrl_reg;
 
     DEBUGFUNC("e1000_phy_setup_autoneg");
 
     /* Read the MII Auto-Neg Advertisement Register (Address 4). */
-    if(e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
+    if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
+                                     &mii_autoneg_adv_reg)))
+        return ret_val;
 
     /* Read the MII 1000Base-T Control Register (Address 9). */
-    if(e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
+    if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg)))
+        return ret_val;
 
     /* Need to parse both autoneg_advertised and fc and set up
      * the appropriate PHY registers.  First we will parse for
@@ -1145,18 +1331,16 @@
         return -E1000_ERR_CONFIG;
     }
 
-    if(e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg) < 0) {
-        DEBUGOUT("PHY Write Error\n");
-        return -E1000_ERR_PHY;
-    }
+    if((ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV,
+                                      mii_autoneg_adv_reg)))
+        return ret_val;
 
     DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
 
-    if(e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg) < 0) {
-        DEBUGOUT("PHY Write Error\n");
-        return -E1000_ERR_PHY;
-    }
-    return 0;
+    if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg)))
+        return ret_val;
+
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -1192,10 +1376,8 @@
     ctrl &= ~E1000_CTRL_ASDE;
 
     /* Read the MII Control Register. */
-    if(e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
+    if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg)))
+        return ret_val;
 
     /* We need to disable autoneg in order to force link and duplex. */
 
@@ -1241,19 +1423,18 @@
     E1000_WRITE_REG(hw, CTRL, ctrl);
 
     if (hw->phy_type == e1000_phy_m88) {
-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                         &phy_data)))
+            return ret_val;
 
         /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
          * forced whenever speed are duplex are forced.
          */
         phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-        if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
-            DEBUGOUT("PHY Write Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                          phy_data)))
+            return ret_val;
+
         DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
 
         /* Need to reset the PHY or these changes will be ignored */
@@ -1262,26 +1443,23 @@
         /* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
          * forced whenever speed or duplex are forced.
          */
-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                         &phy_data)))
+            return ret_val;
 
         phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
         phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
 
-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data) < 0) {
-            DEBUGOUT("PHY Write Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                          phy_data)))
+            return ret_val;
     }
 
     /* Write back the modified PHY MII control register. */
-    if(e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg) < 0) {
-        DEBUGOUT("PHY Write Error\n");
-        return -E1000_ERR_PHY;
-    }
     udelay(1);
+    if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg)))
+        return ret_val;
+
 
     /* The wait_autoneg_complete flag may be a little misleading here.
      * Since we are forcing speed and duplex, Auto-Neg is not enabled.
@@ -1300,22 +1478,18 @@
             /* Read the MII Status Register and wait for Auto-Neg Complete bit
              * to be set.
              */
-            if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
-                DEBUGOUT("PHY Read Error\n");
-                return -E1000_ERR_PHY;
-            }
-            if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
-                DEBUGOUT("PHY Read Error\n");
-                return -E1000_ERR_PHY;
-            }
+            if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+                return ret_val;
+
+            if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+                return ret_val;
+
             if(mii_status_reg & MII_SR_LINK_STATUS) break;
             msec_delay(100);
         }
         if(i == 0) { /* We didn't get link */
             /* Reset the DSP and wait again for link. */
-
-            ret_val = e1000_phy_reset_dsp(hw);
-            if(ret_val < 0) {
+            if((ret_val = e1000_phy_reset_dsp(hw))) {
                 DEBUGOUT("Error Resetting PHY DSP\n");
                 return ret_val;
             }
@@ -1327,14 +1501,11 @@
             /* Read the MII Status Register and wait for Auto-Neg Complete bit
              * to be set.
              */
-            if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
-                DEBUGOUT("PHY Read Error\n");
-                return -E1000_ERR_PHY;
-            }
-            if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
-                DEBUGOUT("PHY Read Error\n");
-                return -E1000_ERR_PHY;
-            }
+            if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+                return ret_val;
+
+            if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+                return ret_val;
         }
     }
 
@@ -1343,30 +1514,29 @@
          * Extended PHY Specific Control Register to 25MHz clock.  This value
          * defaults back to a 2.5MHz clock when the PHY is reset.
          */
-        if(e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                         &phy_data)))
+            return ret_val;
+
         phy_data |= M88E1000_EPSCR_TX_CLK_25;
-        if(e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) {
-            DEBUGOUT("PHY Write Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                          phy_data)))
+            return ret_val;
 
         /* In addition, because of the s/w reset above, we need to enable CRS on
          * TX.  This must be set for both full and half duplex operation.
          */
-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                         &phy_data)))
+            return ret_val;
+
         phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-        if(e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) {
-            DEBUGOUT("PHY Write Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                          phy_data)))
+            return ret_val;
+
     }
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -1406,6 +1576,7 @@
 e1000_config_mac_to_phy(struct e1000_hw *hw)
 {
     uint32_t ctrl;
+    int32_t ret_val;
     uint16_t phy_data;
 
     DEBUGFUNC("e1000_config_mac_to_phy");
@@ -1421,10 +1592,10 @@
      * registers depending on negotiated values.
      */
     if (hw->phy_type == e1000_phy_igp) {
-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
+                                         &phy_data)))
+            return ret_val;
+
         if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD;
         else ctrl &= ~E1000_CTRL_FD;
 
@@ -1440,10 +1611,10 @@
                 IGP01E1000_PSSR_SPEED_100MBPS)
             ctrl |= E1000_CTRL_SPD_100;
     } else {
-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                         &phy_data)))
+            return ret_val;
+
         if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
         else ctrl &= ~E1000_CTRL_FD;
 
@@ -1459,7 +1630,7 @@
     }
     /* Write the configured values back to the Device Control Reg. */
     E1000_WRITE_REG(hw, CTRL, ctrl);
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -1473,7 +1644,7 @@
  * by the PHY rather than the MAC. Software must also configure these
  * bits when link is forced on a fiber connection.
  *****************************************************************************/
-static int32_t
+int32_t
 e1000_force_mac_fc(struct e1000_hw *hw)
 {
     uint32_t ctrl;
@@ -1526,7 +1697,7 @@
         ctrl &= (~E1000_CTRL_TFCE);
 
     E1000_WRITE_REG(hw, CTRL, ctrl);
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -1557,9 +1728,9 @@
      * configuration of the MAC to match the "fc" parameter.
      */
     if(((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) ||
+       ((hw->media_type == e1000_media_type_internal_serdes) && (hw->autoneg_failed)) ||
        ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) {
-        ret_val = e1000_force_mac_fc(hw);
-        if(ret_val < 0) {
+        if((ret_val = e1000_force_mac_fc(hw))) {
             DEBUGOUT("Error forcing flow control settings\n");
             return ret_val;
         }
@@ -1575,14 +1746,10 @@
          * has completed.  We read this twice because this reg has
          * some "sticky" (latched) bits.
          */
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
-            DEBUGOUT("PHY Read Error \n");
-            return -E1000_ERR_PHY;
-        }
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
-            DEBUGOUT("PHY Read Error \n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+            return ret_val;
+        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
+            return ret_val;
 
         if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
             /* The AutoNeg process has completed, so we now need to
@@ -1591,14 +1758,12 @@
              * Register (Address 5) to determine how flow control was
              * negotiated.
              */
-            if(e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg) < 0) {
-                DEBUGOUT("PHY Read Error\n");
-                return -E1000_ERR_PHY;
-            }
-            if(e1000_read_phy_reg(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg) < 0) {
-                DEBUGOUT("PHY Read Error\n");
-                return -E1000_ERR_PHY;
-            }
+            if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
+                                             &mii_nway_adv_reg)))
+                return ret_val;
+            if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
+                                             &mii_nway_lp_ability_reg)))
+                return ret_val;
 
             /* Two bits in the Auto Negotiation Advertisement Register
              * (Address 4) and two bits in the Auto Negotiation Base
@@ -1704,7 +1869,7 @@
                     hw->original_fc == e1000_fc_tx_pause) {
                 hw->fc = e1000_fc_none;
                 DEBUGOUT("Flow Control = NONE.\r\n");
-            } else {
+            } else if(!hw->fc_strict_ieee) {
                 hw->fc = e1000_fc_rx_pause;
                 DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
             }
@@ -1713,7 +1878,10 @@
              * negotiated to HALF DUPLEX, flow control should not be
              * enabled per IEEE 802.3 spec.
              */
-            e1000_get_speed_and_duplex(hw, &speed, &duplex);
+            if((ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex))) {
+                DEBUGOUT("Error getting link speed and duplex\n");
+                return ret_val;
+            }
 
             if(duplex == HALF_DUPLEX)
                 hw->fc = e1000_fc_none;
@@ -1721,16 +1889,15 @@
             /* Now we call a subroutine to actually force the MAC
              * controller to use the correct flow control settings.
              */
-            ret_val = e1000_force_mac_fc(hw);
-            if(ret_val < 0) {
+            if((ret_val = e1000_force_mac_fc(hw))) {
                 DEBUGOUT("Error forcing flow control settings\n");
                 return ret_val;
-             }
+            }
         } else {
             DEBUGOUT("Copper PHY and Auto Neg has not completed.\r\n");
         }
     }
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -1747,19 +1914,19 @@
     uint32_t ctrl;
     uint32_t status;
     uint32_t rctl;
-    uint32_t signal;
+    uint32_t signal = 0;
     int32_t ret_val;
     uint16_t phy_data;
     uint16_t lp_capability;
 
     DEBUGFUNC("e1000_check_for_link");
 
-    /* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
+    /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
      * set when the optics detect a signal. On older adapters, it will be
-     * cleared when there is a signal
+     * cleared when there is a signal.  This applies to fiber media only.
      */
-    if(hw->mac_type > e1000_82544) signal = E1000_CTRL_SWDPIN1;
-    else signal = 0;
+    if(hw->media_type == e1000_media_type_fiber)
+        signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
 
     ctrl = E1000_READ_REG(hw, CTRL);
     status = E1000_READ_REG(hw, STATUS);
@@ -1777,14 +1944,10 @@
          * of the PHY.
          * Read the register twice since the link bit is sticky.
          */
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+            return ret_val;
+        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+            return ret_val;
 
         if(phy_data & MII_SR_LINK_STATUS) {
             hw->get_link_status = FALSE;
@@ -1794,6 +1957,7 @@
 
         } else {
             /* No link detected */
+            e1000_config_dsp_after_link_change(hw, FALSE);
             return 0;
         }
 
@@ -1802,6 +1966,9 @@
          */
         if(!hw->autoneg) return -E1000_ERR_CONFIG;
 
+        /* optimize the dsp settings for the igp phy */
+        e1000_config_dsp_after_link_change(hw, TRUE);
+
         /* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
          * have Si on board that is 82544 or newer, Auto
          * Speed Detection takes care of MAC speed/duplex
@@ -1813,8 +1980,7 @@
         if(hw->mac_type >= e1000_82544)
             e1000_config_collision_dist(hw);
         else {
-            ret_val = e1000_config_mac_to_phy(hw);
-            if(ret_val < 0) {
+            if((ret_val = e1000_config_mac_to_phy(hw))) {
                 DEBUGOUT("Error configuring MAC to PHY settings\n");
                 return ret_val;
             }
@@ -1824,8 +1990,7 @@
          * need to restore the desired flow control settings because we may
          * have had to re-autoneg with a different link partner.
          */
-        ret_val = e1000_config_fc_after_link_up(hw);
-        if(ret_val < 0) {
+        if((ret_val = e1000_config_fc_after_link_up(hw))) {
             DEBUGOUT("Error configuring flow control\n");
             return ret_val;
         }
@@ -1840,10 +2005,9 @@
          * partner is TBI-based, and we turn on TBI Compatibility.
          */
         if(hw->tbi_compatibility_en) {
-            if(e1000_read_phy_reg(hw, PHY_LP_ABILITY, &lp_capability) < 0) {
-                DEBUGOUT("PHY Read Error\n");
-                return -E1000_ERR_PHY;
-            }
+            if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
+                                             &lp_capability)))
+                return ret_val;
             if(lp_capability & (NWAY_LPAR_10T_HD_CAPS |
                                 NWAY_LPAR_10T_FD_CAPS |
                                 NWAY_LPAR_100TX_HD_CAPS |
@@ -1900,8 +2064,7 @@
         E1000_WRITE_REG(hw, CTRL, ctrl);
 
         /* Configure Flow Control after forcing link up. */
-        ret_val = e1000_config_fc_after_link_up(hw);
-        if(ret_val < 0) {
+        if((ret_val = e1000_config_fc_after_link_up(hw))) {
             DEBUGOUT("Error configuring flow control\n");
             return ret_val;
         }
@@ -1918,7 +2081,7 @@
         E1000_WRITE_REG(hw, TXCW, hw->txcw);
         E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
     }
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -1928,12 +2091,14 @@
  * speed - Speed of the connection
  * duplex - Duplex setting of the connection
  *****************************************************************************/
-void
+int32_t
 e1000_get_speed_and_duplex(struct e1000_hw *hw,
                            uint16_t *speed,
                            uint16_t *duplex)
 {
     uint32_t status;
+    int32_t ret_val;
+    uint16_t phy_data;
 
     DEBUGFUNC("e1000_get_speed_and_duplex");
 
@@ -1962,6 +2127,27 @@
         *speed = SPEED_1000;
         *duplex = FULL_DUPLEX;
     }
+
+    /* IGP01 PHY may advertise full duplex operation after speed downgrade even
+     * if it is operating at half duplex.  Here we set the duplex settings to
+     * match the duplex in the link partner's capabilities.
+     */
+    if(hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
+        if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data)))
+            return ret_val;
+
+        if(!(phy_data & NWAY_ER_LP_NWAY_CAPS))
+            *duplex = HALF_DUPLEX;
+        else {
+            if((ret_val == e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data)))
+                return ret_val;
+            if((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
+               (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
+                *duplex = HALF_DUPLEX;
+        }
+    }
+
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -1972,6 +2158,7 @@
 int32_t
 e1000_wait_autoneg(struct e1000_hw *hw)
 {
+    int32_t ret_val;
     uint16_t i;
     uint16_t phy_data;
 
@@ -1983,20 +2170,16 @@
         /* Read the MII Status Register and wait for Auto-Neg
          * Complete bit to be set.
          */
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
-        if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+            return ret_val;
+        if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+            return ret_val;
         if(phy_data & MII_SR_AUTONEG_COMPLETE) {
-            return 0;
+            return E1000_SUCCESS;
         }
         msec_delay(100);
     }
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -2010,11 +2193,11 @@
                     uint32_t *ctrl)
 {
     /* Raise the clock input to the Management Data Clock (by setting the MDC
-     * bit), and then delay 2 microseconds.
+     * bit), and then delay 10 microseconds.
      */
     E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
     E1000_WRITE_FLUSH(hw);
-    udelay(2);
+    udelay(10);
 }
 
 /******************************************************************************
@@ -2028,11 +2211,11 @@
                     uint32_t *ctrl)
 {
     /* Lower the clock input to the Management Data Clock (by clearing the MDC
-     * bit), and then delay 2 microseconds.
+     * bit), and then delay 10 microseconds.
      */
     E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
     E1000_WRITE_FLUSH(hw);
-    udelay(2);
+    udelay(10);
 }
 
 /******************************************************************************
@@ -2076,7 +2259,7 @@
         E1000_WRITE_REG(hw, CTRL, ctrl);
         E1000_WRITE_FLUSH(hw);
 
-        udelay(2);
+        udelay(10);
 
         e1000_raise_mdi_clk(hw, &ctrl);
         e1000_lower_mdi_clk(hw, &ctrl);
@@ -2138,8 +2321,8 @@
 }
 
 /*****************************************************************************
-* Reads the value from a PHY register
-*
+* Reads the value from a PHY register, if the value is on a specific non zero
+* page, sets the page first.
 * hw - Struct containing variables accessed by shared code
 * reg_addr - address of the PHY register to read
 ******************************************************************************/
@@ -2148,11 +2331,33 @@
                    uint32_t reg_addr,
                    uint16_t *phy_data)
 {
+    uint32_t ret_val;
+
+    DEBUGFUNC("e1000_read_phy_reg");
+
+    if(hw->phy_type == e1000_phy_igp &&
+       (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
+        if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                             (uint16_t)reg_addr)))
+            return ret_val;
+    }
+
+    ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
+                                    phy_data);
+
+    return ret_val;
+}
+
+int32_t
+e1000_read_phy_reg_ex(struct e1000_hw *hw,
+                      uint32_t reg_addr,
+                      uint16_t *phy_data)
+{
     uint32_t i;
     uint32_t mdic = 0;
     const uint32_t phy_addr = 1;
 
-    DEBUGFUNC("e1000_read_phy_reg");
+    DEBUGFUNC("e1000_read_phy_reg_ex");
 
     if(reg_addr > MAX_PHY_REG_ADDRESS) {
         DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
@@ -2172,7 +2377,7 @@
 
         /* Poll the ready bit to see if the MDI read completed */
         for(i = 0; i < 64; i++) {
-            udelay(10);
+            udelay(50);
             mdic = E1000_READ_REG(hw, MDIC);
             if(mdic & E1000_MDIC_READY) break;
         }
@@ -2214,7 +2419,7 @@
          */
         *phy_data = e1000_shift_in_mdi_bits(hw);
     }
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -2229,11 +2434,33 @@
                     uint32_t reg_addr,
                     uint16_t phy_data)
 {
+    uint32_t ret_val;
+
+    DEBUGFUNC("e1000_write_phy_reg");
+
+    if(hw->phy_type == e1000_phy_igp &&
+       (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
+        if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                             (uint16_t)reg_addr)))
+            return ret_val;
+    }
+
+    ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
+                                     phy_data);
+
+    return ret_val;
+}
+
+int32_t
+e1000_write_phy_reg_ex(struct e1000_hw *hw,
+                    uint32_t reg_addr,
+                    uint16_t phy_data)
+{
     uint32_t i;
     uint32_t mdic = 0;
     const uint32_t phy_addr = 1;
 
-    DEBUGFUNC("e1000_write_phy_reg");
+    DEBUGFUNC("e1000_write_phy_reg_ex");
 
     if(reg_addr > MAX_PHY_REG_ADDRESS) {
         DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
@@ -2254,7 +2481,7 @@
 
         /* Poll the ready bit to see if the MDI read completed */
         for(i = 0; i < 64; i++) {
-            udelay(10);
+            udelay(50);
             mdic = E1000_READ_REG(hw, MDIC);
             if(mdic & E1000_MDIC_READY) break;
         }
@@ -2284,7 +2511,7 @@
         e1000_shift_out_mdi_bits(hw, mdic, 32);
     }
 
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -2329,11 +2556,6 @@
     udelay(150);
 
     if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0000) < 0) {
-            DEBUGOUT("PHY Write Error\n");
-            return;
-        }
-
         /* Configure activity LED after PHY reset */
         led_ctrl = E1000_READ_REG(hw, LEDCTL);
         led_ctrl &= IGP_ACTIVITY_LED_MASK;
@@ -2352,24 +2574,26 @@
 int32_t
 e1000_phy_reset(struct e1000_hw *hw)
 {
+    int32_t ret_val;
     uint16_t phy_data;
 
     DEBUGFUNC("e1000_phy_reset");
 
-    if(e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
-    phy_data |= MII_CR_RESET;
-    if(e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) {
-        DEBUGOUT("PHY Write Error\n");
-        return -E1000_ERR_PHY;
-    }
-    udelay(1);
-    if (hw->phy_type == e1000_phy_igp) {
+    if(hw->mac_type != e1000_82541_rev_2) {
+        if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
+            return ret_val;
+
+        phy_data |= MII_CR_RESET;
+        if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
+            return ret_val;
+
+        udelay(1);
+    } else e1000_phy_hw_reset(hw);
+
+    if(hw->phy_type == e1000_phy_igp)
         e1000_phy_init_script(hw);
-    }
-    return 0;
+
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -2380,23 +2604,21 @@
 int32_t
 e1000_detect_gig_phy(struct e1000_hw *hw)
 {
+    int32_t phy_init_status, ret_val;
     uint16_t phy_id_high, phy_id_low;
     boolean_t match = FALSE;
-    int32_t phy_init_status;
 
     DEBUGFUNC("e1000_detect_gig_phy");
 
     /* Read the PHY ID Registers to identify which PHY is onboard. */
-    if(e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
+    if((ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high)))
+        return ret_val;
+
     hw->phy_id = (uint32_t) (phy_id_high << 16);
     udelay(20);
-    if(e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
+    if((ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low)))
+        return ret_val;
+
     hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
     hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
 
@@ -2409,11 +2631,15 @@
         break;
     case e1000_82540:
     case e1000_82545:
+    case e1000_82545_rev_3:
     case e1000_82546:
+    case e1000_82546_rev_3:
         if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
         break;
     case e1000_82541:
+    case e1000_82541_rev_2:
     case e1000_82547:
+    case e1000_82547_rev_2:
         if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
         break;
     default:
@@ -2424,7 +2650,7 @@
 
     if ((match) && (phy_init_status == E1000_SUCCESS)) {
         DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
-        return 0;
+        return E1000_SUCCESS;
     }
     DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
     return -E1000_ERR_PHY;
@@ -2438,17 +2664,16 @@
 static int32_t
 e1000_phy_reset_dsp(struct e1000_hw *hw)
 {
-    int32_t ret_val = -E1000_ERR_PHY;
+    int32_t ret_val;
     DEBUGFUNC("e1000_phy_reset_dsp");
 
     do {
-        if(e1000_write_phy_reg(hw, 29, 0x001d) < 0) break;
-        if(e1000_write_phy_reg(hw, 30, 0x00c1) < 0) break;
-        if(e1000_write_phy_reg(hw, 30, 0x0000) < 0) break;
-        ret_val = 0;
+        if((ret_val = e1000_write_phy_reg(hw, 29, 0x001d))) break;
+        if((ret_val = e1000_write_phy_reg(hw, 30, 0x00c1))) break;
+        if((ret_val = e1000_write_phy_reg(hw, 30, 0x0000))) break;
+        ret_val = E1000_SUCCESS;
     } while(0);
 
-    if(ret_val < 0) DEBUGOUT("PHY Write Error\n");
     return ret_val;
 }
 
@@ -2459,8 +2684,10 @@
 * phy_info - PHY information structure
 ******************************************************************************/
 int32_t
-e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
+e1000_phy_igp_get_info(struct e1000_hw *hw,
+                       struct e1000_phy_info *phy_info)
 {
+    int32_t ret_val;
     uint16_t phy_data, polarity, min_length, max_length, average;
 
     DEBUGFUNC("e1000_phy_igp_get_info");
@@ -2476,13 +2703,14 @@
     phy_info->polarity_correction = e1000_polarity_reversal_enabled;
 
     /* Check polarity status */
-    if(e1000_check_polarity(hw, &polarity) < 0)
-        return -E1000_ERR_PHY;
+    if((ret_val = e1000_check_polarity(hw, &polarity)))
+        return ret_val;
 
     phy_info->cable_polarity = polarity;
 
-    if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
-        return -E1000_ERR_PHY;
+    if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
+                                     &phy_data)))
+        return ret_val;
 
     phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
                           IGP01E1000_PSSR_MDIX_SHIFT;
@@ -2490,8 +2718,8 @@
     if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
        IGP01E1000_PSSR_SPEED_1000MBPS) {
         /* Local/Remote Receiver Information are only valid at 1000 Mbps */
-        if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
-            return -E1000_ERR_PHY;
+        if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data)))
+            return ret_val;
 
         phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
                              SR_1000T_LOCAL_RX_STATUS_SHIFT;
@@ -2499,8 +2727,8 @@
                               SR_1000T_REMOTE_RX_STATUS_SHIFT;
 
         /* Get cable length */
-        if(e1000_get_cable_length(hw, &min_length, &max_length) < 0)
-            return -E1000_ERR_PHY;
+        if((ret_val = e1000_get_cable_length(hw, &min_length, &max_length)))
+            return ret_val;
 
         /* transalte to old method */
         average = (max_length + min_length) / 2;
@@ -2527,8 +2755,10 @@
 * phy_info - PHY information structure
 ******************************************************************************/
 int32_t
-e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info)
+e1000_phy_m88_get_info(struct e1000_hw *hw,
+                       struct e1000_phy_info *phy_info)
 {
+    int32_t ret_val;
     uint16_t phy_data, polarity;
 
     DEBUGFUNC("e1000_phy_m88_get_info");
@@ -2537,8 +2767,8 @@
      * and it stored in the hw->speed_downgraded parameter. */
     phy_info->downshift = hw->speed_downgraded;
 
-    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0)
-        return -E1000_ERR_PHY;
+    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data)))
+        return ret_val;
 
     phy_info->extended_10bt_distance =
         (phy_data & M88E1000_PSCR_10BT_EXT_DIST_ENABLE) >>
@@ -2548,13 +2778,13 @@
         M88E1000_PSCR_POLARITY_REVERSAL_SHIFT;
 
     /* Check polarity status */
-    if(e1000_check_polarity(hw, &polarity) < 0)
-        return -E1000_ERR_PHY;
+    if((ret_val = e1000_check_polarity(hw, &polarity)))
+        return ret_val;
 
     phy_info->cable_polarity = polarity;
 
-    if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
-        return -E1000_ERR_PHY;
+    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data)))
+        return ret_val;
 
     phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
                           M88E1000_PSSR_MDIX_SHIFT;
@@ -2566,8 +2796,8 @@
         phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
                                   M88E1000_PSSR_CABLE_LENGTH_SHIFT);
 
-        if(e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data) < 0)
-            return -E1000_ERR_PHY;
+        if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data)))
+            return ret_val;
 
         phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
                              SR_1000T_LOCAL_RX_STATUS_SHIFT;
@@ -2589,6 +2819,7 @@
 e1000_phy_get_info(struct e1000_hw *hw,
                    struct e1000_phy_info *phy_info)
 {
+    int32_t ret_val;
     uint16_t phy_data;
 
     DEBUGFUNC("e1000_phy_get_info");
@@ -2607,20 +2838,18 @@
         return -E1000_ERR_CONFIG;
     }
 
-    if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
-    if(e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) {
-        DEBUGOUT("PHY Read Error\n");
-        return -E1000_ERR_PHY;
-    }
+    if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+        return ret_val;
+
+    if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+        return ret_val;
+
     if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
         DEBUGOUT("PHY info is only valid if link is up\n");
         return -E1000_ERR_CONFIG;
     }
 
-    if (hw->phy_type == e1000_phy_igp)
+    if(hw->phy_type == e1000_phy_igp)
         return e1000_phy_igp_get_info(hw, phy_info);
     else
         return e1000_phy_m88_get_info(hw, phy_info);
@@ -2636,7 +2865,7 @@
         hw->mdix = 1;
         return -E1000_ERR_CONFIG;
     }
-    return 0;
+    return E1000_SUCCESS;
 }
 
 
@@ -2668,7 +2897,9 @@
         break;
     case e1000_82540:
     case e1000_82545:
+    case e1000_82545_rev_3:
     case e1000_82546:
+    case e1000_82546_rev_3:
         eeprom->type = e1000_eeprom_microwire;
         eeprom->opcode_bits = 3;
         eeprom->delay_usec = 50;
@@ -2681,8 +2912,9 @@
         }
         break;
     case e1000_82541:
+    case e1000_82541_rev_2:
     case e1000_82547:
-    default:
+    case e1000_82547_rev_2:
         if (eecd & E1000_EECD_TYPE) {
             eeprom->type = e1000_eeprom_spi;
             eeprom->opcode_bits = 8;
@@ -2707,6 +2939,18 @@
             }
         }
         break;
+    default:
+        eeprom->type = e1000_eeprom_spi;
+        eeprom->opcode_bits = 8;
+        eeprom->delay_usec = 1;
+        if (eecd & E1000_EECD_ADDR_BITS) {
+            eeprom->page_size = 32;
+            eeprom->address_bits = 16;
+        } else {
+            eeprom->page_size = 8;
+            eeprom->address_bits = 8;
+        }
+        break;
     }
 
     if (eeprom->type == e1000_eeprom_spi) {
@@ -2715,28 +2959,28 @@
             eeprom_size &= EEPROM_SIZE_MASK;
 
             switch (eeprom_size) {
-                case EEPROM_SIZE_16KB:
-                    eeprom->word_size = 8192;
-                    break;
-                case EEPROM_SIZE_8KB:
-                    eeprom->word_size = 4096;
-                    break;
-                case EEPROM_SIZE_4KB:
-                    eeprom->word_size = 2048;
-                    break;
-                case EEPROM_SIZE_2KB:
-                    eeprom->word_size = 1024;
-                    break;
-                case EEPROM_SIZE_1KB:
-                    eeprom->word_size = 512;
-                    break;
-                case EEPROM_SIZE_512B:
-                    eeprom->word_size = 256;
-                    break;
-                case EEPROM_SIZE_128B:
-                default:
-                    eeprom->word_size = 64;
-                    break;
+            case EEPROM_SIZE_16KB:
+                eeprom->word_size = 8192;
+                break;
+            case EEPROM_SIZE_8KB:
+                eeprom->word_size = 4096;
+                break;
+            case EEPROM_SIZE_4KB:
+                eeprom->word_size = 2048;
+                break;
+            case EEPROM_SIZE_2KB:
+                eeprom->word_size = 1024;
+                break;
+            case EEPROM_SIZE_1KB:
+                eeprom->word_size = 512;
+                break;
+            case EEPROM_SIZE_512B:
+                eeprom->word_size = 256;
+                break;
+            case EEPROM_SIZE_128B:
+            default:
+                eeprom->word_size = 64;
+                break;
             }
         }
     }
@@ -2841,7 +3085,8 @@
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 static uint16_t
-e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count)
+e1000_shift_in_ee_bits(struct e1000_hw *hw,
+                       uint16_t count)
 {
     uint32_t eecd;
     uint32_t i;
@@ -3101,13 +3346,17 @@
     }
 
     /* Prepare the EEPROM for reading  */
-    if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+    if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
         return -E1000_ERR_EEPROM;
 
     if(eeprom->type == e1000_eeprom_spi) {
+        uint16_t word_in;
         uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
 
-        if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
+        if(e1000_spi_eeprom_ready(hw)) {
+            e1000_release_eeprom(hw);
+            return -E1000_ERR_EEPROM;
+        }
 
         e1000_standby_eeprom(hw);
 
@@ -3118,30 +3367,35 @@
         /* Send the READ command (opcode + addr)  */
         e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
         e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits);
-    }
-    else if(eeprom->type == e1000_eeprom_microwire) {
-        /* Send the READ command (opcode + addr)  */
-        e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
-                                eeprom->opcode_bits);
-        e1000_shift_out_ee_bits(hw, offset, eeprom->address_bits);
-    }
 
-    /* Read the data.  The address of the eeprom internally increments with
-     * each word (microwire) or byte (spi) being read, saving on the overhead
-     * of eeprom setup and tear-down.  The address counter will roll over if
-     * reading beyond the size of the eeprom, thus allowing the entire memory
-     * to be read starting from any offset. */
-    for (i = 0; i < words; i++) {
-        uint16_t word_in = e1000_shift_in_ee_bits(hw, 16);
-        if (eeprom->type == e1000_eeprom_spi)
-            word_in = (word_in >> 8) | (word_in << 8);
-        data[i] = word_in;
+        /* Read the data.  The address of the eeprom internally increments with
+         * each byte (spi) being read, saving on the overhead of eeprom setup
+         * and tear-down.  The address counter will roll over if reading beyond
+         * the size of the eeprom, thus allowing the entire memory to be read
+         * starting from any offset. */
+        for (i = 0; i < words; i++) {
+            word_in = e1000_shift_in_ee_bits(hw, 16);
+            data[i] = (word_in >> 8) | (word_in << 8);
+        }
+    } else if(eeprom->type == e1000_eeprom_microwire) {
+        for (i = 0; i < words; i++) {
+            /* Send the READ command (opcode + addr)  */
+            e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
+                                    eeprom->opcode_bits);
+            e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i),
+                                    eeprom->address_bits);
+
+            /* Read the data.  For microwire, each word requires the overhead
+             * of eeprom setup and tear-down. */
+            data[i] = e1000_shift_in_ee_bits(hw, 16);
+            e1000_standby_eeprom(hw);
+        }
     }
 
     /* End this read operation */
     e1000_release_eeprom(hw);
 
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -3169,9 +3423,9 @@
         checksum += eeprom_data;
     }
 
-    if(checksum == (uint16_t) EEPROM_SUM) {
-        return 0;
-    } else {
+    if(checksum == (uint16_t) EEPROM_SUM)
+        return E1000_SUCCESS;
+    else {
         DEBUGOUT("EEPROM Checksum Invalid\n");
         return -E1000_ERR_EEPROM;
     }
@@ -3205,7 +3459,7 @@
         DEBUGOUT("EEPROM Write Error\n");
         return -E1000_ERR_EEPROM;
     }
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -3403,7 +3657,7 @@
 
     e1000_shift_out_ee_bits(hw, 0, (uint16_t)(eeprom->address_bits - 2));
 
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -3437,7 +3691,7 @@
     /* Save word 1 in lower half of part_num */
     *part_num |= eeprom_data;
 
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -3463,7 +3717,7 @@
         hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
         hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
     }
-    if((hw->mac_type == e1000_82546) &&
+    if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
        (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
         if(hw->perm_mac_addr[5] & 0x01)
             hw->perm_mac_addr[5] &= ~(0x01);
@@ -3472,7 +3726,7 @@
     }
     for(i = 0; i < NODE_ADDRESS_SIZE; i++)
         hw->mac_addr[i] = hw->perm_mac_addr[i];
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -3748,7 +4002,7 @@
 
     if(hw->mac_type < e1000_82540) {
         /* Nothing to do */
-        return 0;
+        return E1000_SUCCESS;
     }
 
     ledctl = E1000_READ_REG(hw, LEDCTL);
@@ -3799,7 +4053,7 @@
             break;
         }
     }
-    return 0;
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -3811,49 +4065,48 @@
 e1000_setup_led(struct e1000_hw *hw)
 {
     uint32_t ledctl;
+    int32_t ret_val = E1000_SUCCESS;
 
     DEBUGFUNC("e1000_setup_led");
 
-    switch(hw->device_id) {
-    case E1000_DEV_ID_82542:
-    case E1000_DEV_ID_82543GC_FIBER:
-    case E1000_DEV_ID_82543GC_COPPER:
-    case E1000_DEV_ID_82544EI_COPPER:
-    case E1000_DEV_ID_82544EI_FIBER:
-    case E1000_DEV_ID_82544GC_COPPER:
-    case E1000_DEV_ID_82544GC_LOM:
+    switch(hw->mac_type) {
+    case e1000_82542_rev2_0:
+    case e1000_82542_rev2_1:
+    case e1000_82543:
+    case e1000_82544:
         /* No setup necessary */
         break;
-    case E1000_DEV_ID_82545EM_FIBER:
-    case E1000_DEV_ID_82546EB_FIBER:
-        ledctl = E1000_READ_REG(hw, LEDCTL);
-        /* Save current LEDCTL settings */
-        hw->ledctl_default = ledctl;
-        /* Turn off LED0 */
-        ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
-                    E1000_LEDCTL_LED0_BLINK |
-                    E1000_LEDCTL_LED0_MODE_MASK);
-        ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT);
-        E1000_WRITE_REG(hw, LEDCTL, ledctl);
-        break;
-    case E1000_DEV_ID_82540EP:
-    case E1000_DEV_ID_82540EP_LOM:
-    case E1000_DEV_ID_82540EP_LP:
-    case E1000_DEV_ID_82540EM:
-    case E1000_DEV_ID_82540EM_LOM:
-    case E1000_DEV_ID_82545EM_COPPER:
-    case E1000_DEV_ID_82546EB_COPPER:
-    case E1000_DEV_ID_82546EB_QUAD_COPPER:
-    case E1000_DEV_ID_82541EI:
-    case E1000_DEV_ID_82541EP:
-    case E1000_DEV_ID_82547EI:
-        E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
-        break;
+    case e1000_82541:
+    case e1000_82547:
+    case e1000_82541_rev_2:
+    case e1000_82547_rev_2:
+        /* Turn off PHY Smart Power Down (if enabled) */
+        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
+                                         &hw->phy_spd_default)))
+            return ret_val;
+        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
+                                          (uint16_t)(hw->phy_spd_default &
+                                          ~IGP01E1000_GMII_SPD))))
+            return ret_val;
+        /* Fall Through */
     default:
-        DEBUGOUT("Invalid device ID\n");
-        return -E1000_ERR_CONFIG;
+        if(hw->media_type == e1000_media_type_fiber) {
+            ledctl = E1000_READ_REG(hw, LEDCTL);
+            /* Save current LEDCTL settings */
+            hw->ledctl_default = ledctl;
+            /* Turn off LED0 */
+            ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
+                        E1000_LEDCTL_LED0_BLINK |
+                        E1000_LEDCTL_LED0_MODE_MASK);
+            ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
+                       E1000_LEDCTL_LED0_MODE_SHIFT);
+            E1000_WRITE_REG(hw, LEDCTL, ledctl);
+        } else if(hw->media_type == e1000_media_type_copper)
+            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
+        break;
     }
-    return 0;
+
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -3864,39 +4117,33 @@
 int32_t
 e1000_cleanup_led(struct e1000_hw *hw)
 {
+    int32_t ret_val = E1000_SUCCESS;
+
     DEBUGFUNC("e1000_cleanup_led");
 
-    switch(hw->device_id) {
-    case E1000_DEV_ID_82542:
-    case E1000_DEV_ID_82543GC_FIBER:
-    case E1000_DEV_ID_82543GC_COPPER:
-    case E1000_DEV_ID_82544EI_COPPER:
-    case E1000_DEV_ID_82544EI_FIBER:
-    case E1000_DEV_ID_82544GC_COPPER:
-    case E1000_DEV_ID_82544GC_LOM:
+    switch(hw->mac_type) {
+    case e1000_82542_rev2_0:
+    case e1000_82542_rev2_1:
+    case e1000_82543:
+    case e1000_82544:
         /* No cleanup necessary */
         break;
-    case E1000_DEV_ID_82540EP:
-    case E1000_DEV_ID_82540EP_LOM:
-    case E1000_DEV_ID_82540EP_LP:
-    case E1000_DEV_ID_82540EM:
-    case E1000_DEV_ID_82540EM_LOM:
-    case E1000_DEV_ID_82545EM_COPPER:
-    case E1000_DEV_ID_82545EM_FIBER:
-    case E1000_DEV_ID_82546EB_COPPER:
-    case E1000_DEV_ID_82546EB_FIBER:
-    case E1000_DEV_ID_82546EB_QUAD_COPPER:
-    case E1000_DEV_ID_82541EI:
-    case E1000_DEV_ID_82541EP:
-    case E1000_DEV_ID_82547EI:
+    case e1000_82541:
+    case e1000_82547:
+    case e1000_82541_rev_2:
+    case e1000_82547_rev_2:
+        /* Turn on PHY Smart Power Down (if previously enabled) */
+        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
+                                          hw->phy_spd_default)))
+            return ret_val;
+        /* Fall Through */
+    default:
         /* Restore LEDCTL settings */
         E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
         break;
-    default:
-        DEBUGOUT("Invalid device ID\n");
-        return -E1000_ERR_CONFIG;
     }
-    return 0;
+
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -3907,50 +4154,44 @@
 int32_t
 e1000_led_on(struct e1000_hw *hw)
 {
-    uint32_t ctrl;
+    uint32_t ctrl = E1000_READ_REG(hw, CTRL);
 
     DEBUGFUNC("e1000_led_on");
 
-    switch(hw->device_id) {
-    case E1000_DEV_ID_82542:
-    case E1000_DEV_ID_82543GC_FIBER:
-    case E1000_DEV_ID_82543GC_COPPER:
-    case E1000_DEV_ID_82544EI_FIBER:
-        ctrl = E1000_READ_REG(hw, CTRL);
+    switch(hw->mac_type) {
+    case e1000_82542_rev2_0:
+    case e1000_82542_rev2_1:
+    case e1000_82543:
         /* Set SW Defineable Pin 0 to turn on the LED */
         ctrl |= E1000_CTRL_SWDPIN0;
         ctrl |= E1000_CTRL_SWDPIO0;
-        E1000_WRITE_REG(hw, CTRL, ctrl);
         break;
-    case E1000_DEV_ID_82544EI_COPPER:
-    case E1000_DEV_ID_82544GC_COPPER:
-    case E1000_DEV_ID_82544GC_LOM:
-    case E1000_DEV_ID_82545EM_FIBER:
-    case E1000_DEV_ID_82546EB_FIBER:
-        ctrl = E1000_READ_REG(hw, CTRL);
-        /* Clear SW Defineable Pin 0 to turn on the LED */
-        ctrl &= ~E1000_CTRL_SWDPIN0;
-        ctrl |= E1000_CTRL_SWDPIO0;
-        E1000_WRITE_REG(hw, CTRL, ctrl);
-        break;
-    case E1000_DEV_ID_82540EP:
-    case E1000_DEV_ID_82540EP_LOM:
-    case E1000_DEV_ID_82540EP_LP:
-    case E1000_DEV_ID_82540EM:
-    case E1000_DEV_ID_82540EM_LOM:
-    case E1000_DEV_ID_82545EM_COPPER:
-    case E1000_DEV_ID_82546EB_COPPER:
-    case E1000_DEV_ID_82546EB_QUAD_COPPER:
-    case E1000_DEV_ID_82541EI:
-    case E1000_DEV_ID_82541EP:
-    case E1000_DEV_ID_82547EI:
-        E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
+    case e1000_82544:
+        if(hw->media_type == e1000_media_type_fiber) {
+            /* Set SW Defineable Pin 0 to turn on the LED */
+            ctrl |= E1000_CTRL_SWDPIN0;
+            ctrl |= E1000_CTRL_SWDPIO0;
+        } else {
+            /* Clear SW Defineable Pin 0 to turn on the LED */
+            ctrl &= ~E1000_CTRL_SWDPIN0;
+            ctrl |= E1000_CTRL_SWDPIO0;
+        }
         break;
     default:
-        DEBUGOUT("Invalid device ID\n");
-        return -E1000_ERR_CONFIG;
+        if(hw->media_type == e1000_media_type_fiber) {
+            /* Clear SW Defineable Pin 0 to turn on the LED */
+            ctrl &= ~E1000_CTRL_SWDPIN0;
+            ctrl |= E1000_CTRL_SWDPIO0;
+        } else if(hw->media_type == e1000_media_type_copper) {
+            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
+            return E1000_SUCCESS;
+        }
+        break;
     }
-    return 0;
+
+    E1000_WRITE_REG(hw, CTRL, ctrl);
+
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -3961,50 +4202,44 @@
 int32_t
 e1000_led_off(struct e1000_hw *hw)
 {
-    uint32_t ctrl;
+    uint32_t ctrl = E1000_READ_REG(hw, CTRL);
 
     DEBUGFUNC("e1000_led_off");
 
-    switch(hw->device_id) {
-    case E1000_DEV_ID_82542:
-    case E1000_DEV_ID_82543GC_FIBER:
-    case E1000_DEV_ID_82543GC_COPPER:
-    case E1000_DEV_ID_82544EI_FIBER:
-        ctrl = E1000_READ_REG(hw, CTRL);
+    switch(hw->mac_type) {
+    case e1000_82542_rev2_0:
+    case e1000_82542_rev2_1:
+    case e1000_82543:
         /* Clear SW Defineable Pin 0 to turn off the LED */
         ctrl &= ~E1000_CTRL_SWDPIN0;
         ctrl |= E1000_CTRL_SWDPIO0;
-        E1000_WRITE_REG(hw, CTRL, ctrl);
         break;
-    case E1000_DEV_ID_82544EI_COPPER:
-    case E1000_DEV_ID_82544GC_COPPER:
-    case E1000_DEV_ID_82544GC_LOM:
-    case E1000_DEV_ID_82545EM_FIBER:
-    case E1000_DEV_ID_82546EB_FIBER:
-        ctrl = E1000_READ_REG(hw, CTRL);
-        /* Set SW Defineable Pin 0 to turn off the LED */
-        ctrl |= E1000_CTRL_SWDPIN0;
-        ctrl |= E1000_CTRL_SWDPIO0;
-        E1000_WRITE_REG(hw, CTRL, ctrl);
-        break;
-    case E1000_DEV_ID_82540EP:
-    case E1000_DEV_ID_82540EP_LOM:
-    case E1000_DEV_ID_82540EP_LP:
-    case E1000_DEV_ID_82540EM:
-    case E1000_DEV_ID_82540EM_LOM:
-    case E1000_DEV_ID_82545EM_COPPER:
-    case E1000_DEV_ID_82546EB_COPPER:
-    case E1000_DEV_ID_82546EB_QUAD_COPPER:
-    case E1000_DEV_ID_82541EI:
-    case E1000_DEV_ID_82541EP:
-    case E1000_DEV_ID_82547EI:
-        E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
+    case e1000_82544:
+        if(hw->media_type == e1000_media_type_fiber) {
+            /* Clear SW Defineable Pin 0 to turn off the LED */
+            ctrl &= ~E1000_CTRL_SWDPIN0;
+            ctrl |= E1000_CTRL_SWDPIO0;
+        } else {
+            /* Set SW Defineable Pin 0 to turn off the LED */
+            ctrl |= E1000_CTRL_SWDPIN0;
+            ctrl |= E1000_CTRL_SWDPIO0;
+        }
         break;
     default:
-        DEBUGOUT("Invalid device ID\n");
-        return -E1000_ERR_CONFIG;
+        if(hw->media_type == e1000_media_type_fiber) {
+            /* Set SW Defineable Pin 0 to turn off the LED */
+            ctrl |= E1000_CTRL_SWDPIN0;
+            ctrl |= E1000_CTRL_SWDPIO0;
+        } else if(hw->media_type == e1000_media_type_copper) {
+            E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
+            return E1000_SUCCESS;
+        }
+        break;
     }
-    return 0;
+
+    E1000_WRITE_REG(hw, CTRL, ctrl);
+
+    return E1000_SUCCESS;
 }
 
 /******************************************************************************
@@ -4127,8 +4362,7 @@
     DEBUGFUNC("e1000_update_adaptive");
 
     if(hw->adaptive_ifs) {
-        if((hw->collision_delta * hw->ifs_ratio) >
-           hw->tx_packet_delta) {
+        if((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) {
             if(hw->tx_packet_delta > MIN_NUM_XMITS) {
                 hw->in_ifs_mode = TRUE;
                 if(hw->current_ifs_val < hw->ifs_max_val) {
@@ -4140,8 +4374,7 @@
                 }
             }
         } else {
-            if((hw->in_ifs_mode == TRUE) &&
-               (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
+            if(hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
                 hw->current_ifs_val = 0;
                 hw->in_ifs_mode = FALSE;
                 E1000_WRITE_REG(hw, AIT, 0);
@@ -4324,7 +4557,8 @@
  * min_length - The estimated minimum length
  * max_length - The estimated maximum length
  *
- * returns: E1000_SUCCESS / -E1000_ERR_XXX
+ * returns: - E1000_ERR_XXX
+ *            E1000_SUCCESS
  *
  * This function always returns a ranged length (minimum & maximum).
  * So for M88 phy's, this function interprets the one value returned from the
@@ -4332,9 +4566,11 @@
  * For IGP phy's, the function calculates the range by the AGC registers.
  *****************************************************************************/
 int32_t
-e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length,
+e1000_get_cable_length(struct e1000_hw *hw,
+                       uint16_t *min_length,
                        uint16_t *max_length)
 {
+    int32_t ret_val;
     uint16_t agc_value = 0;
     uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
     uint16_t i, phy_data;
@@ -4345,8 +4581,9 @@
 
     /* Use old method for Phy older than IGP */
     if(hw->phy_type == e1000_phy_m88) {
-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
-            return -E1000_ERR_PHY;
+        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                         &phy_data)))
+            return ret_val;
 
         /* Convert the enum value to ranged values */
         switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
@@ -4376,19 +4613,16 @@
             break;
         }
     } else if(hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
-        uint16_t agc_reg_array[IGP01E1000_PHY_AGC_NUM] = {IGP01E1000_PHY_AGC_A,
+        uint16_t agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
+                                                         {IGP01E1000_PHY_AGC_A,
                                                           IGP01E1000_PHY_AGC_B,
                                                           IGP01E1000_PHY_AGC_C,
                                                           IGP01E1000_PHY_AGC_D};
         /* Read the AGC registers for all channels */
-        for(i = 0; i < IGP01E1000_PHY_AGC_NUM; i++) {
-            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
-                                   agc_reg_array[i]) != E1000_SUCCESS)
-                return -E1000_ERR_PHY;
-            if(e1000_read_phy_reg(hw, agc_reg_array[i] &
-                                  IGP01E1000_PHY_PAGE_SELECT, &phy_data) !=
-                                  E1000_SUCCESS)
-                return -E1000_ERR_PHY;
+        for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
+
+            if((ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data)))
+                return ret_val;
 
             cur_agc = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
 
@@ -4404,20 +4638,15 @@
                 min_agc = cur_agc;
         }
 
-        /* Return to page 0 */
-        if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
-           E1000_SUCCESS)
-            return -E1000_ERR_PHY;
-
         /* Remove the minimal AGC result for length < 50m */
-        if(agc_value < IGP01E1000_PHY_AGC_NUM * e1000_igp_cable_length_50) {
+        if(agc_value < IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
             agc_value -= min_agc;
 
             /* Get the average length of the remaining 3 channels */
-            agc_value /= (IGP01E1000_PHY_AGC_NUM - 1);
+            agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
         } else {
             /* Get the average length of all the 4 channels. */
-            agc_value /= IGP01E1000_PHY_AGC_NUM;
+            agc_value /= IGP01E1000_PHY_CHANNEL_NUM;
         }
 
         /* Set the range of the calculated length. */
@@ -4439,7 +4668,8 @@
  * polarity - output parameter : 0 - Polarity is not reversed
  *                               1 - Polarity is reversed.
  *
- * returns: E1000_SUCCESS / -E1000_ERR_XXX
+ * returns: - E1000_ERR_XXX
+ *            E1000_SUCCESS
  *
  * For phy's older then IGP, this function simply reads the polarity bit in the
  * Phy Status register.  For IGP phy's, this bit is valid only if link speed is
@@ -4448,22 +4678,26 @@
  * IGP01E1000_PHY_PCS_INIT_REG.
  *****************************************************************************/
 int32_t
-e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity)
+e1000_check_polarity(struct e1000_hw *hw,
+                     uint16_t *polarity)
 {
+    int32_t ret_val;
     uint16_t phy_data;
 
     DEBUGFUNC("e1000_check_polarity");
 
     if(hw->phy_type == e1000_phy_m88) {
         /* return the Polarity bit in the Status register. */
-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0)
-            return -E1000_ERR_PHY;
+        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                         &phy_data)))
+            return ret_val;
         *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
                     M88E1000_PSSR_REV_POLARITY_SHIFT;
     } else if(hw->phy_type == e1000_phy_igp) {
         /* Read the Status register to check the speed */
-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data) < 0)
-            return -E1000_ERR_PHY;
+        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
+                                         &phy_data)))
+            return ret_val;
 
         /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
          * find the polarity status */
@@ -4471,18 +4705,9 @@
            IGP01E1000_PSSR_SPEED_1000MBPS) {
 
             /* Read the GIG initialization PCS register (0x00B4) */
-            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
-                                   IGP01E1000_PHY_PCS_INIT_REG) < 0)
-                return -E1000_ERR_PHY;
-
-            if(e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG &
-                                  IGP01E1000_PHY_PAGE_SELECT, &phy_data) < 0)
-                return -E1000_ERR_PHY;
-
-            /* Return to page 0 */
-            if(e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0) !=
-               E1000_SUCCESS)
-                return -E1000_ERR_PHY;
+            if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
+                                             &phy_data)))
+                return ret_val;
 
             /* Check the polarity bits */
             *polarity = (phy_data & IGP01E1000_PHY_POLARITY_MASK) ? 1 : 0;
@@ -4502,7 +4727,8 @@
  * downshift - output parameter : 0 - No Downshift ocured.
  *                                1 - Downshift ocured.
  *
- * returns: E1000_SUCCESS / -E1000_ERR_XXX
+ * returns: - E1000_ERR_XXX
+ *            E1000_SUCCESS 
  *
  * For phy's older then IGP, this function reads the Downshift bit in the Phy
  * Specific Status register.  For IGP phy's, it reads the Downgrade bit in the
@@ -4512,25 +4738,287 @@
 int32_t
 e1000_check_downshift(struct e1000_hw *hw)
 {
+    int32_t ret_val;
     uint16_t phy_data;
 
     DEBUGFUNC("e1000_check_downshift");
 
     if(hw->phy_type == e1000_phy_igp) {
-        if(e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
+                                         &phy_data)))
+            return ret_val;
+
         hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
     }
     else if(hw->phy_type == e1000_phy_m88) {
-        if(e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data) < 0) {
-            DEBUGOUT("PHY Read Error\n");
-            return -E1000_ERR_PHY;
-        }
+        if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                         &phy_data)))
+            return ret_val;
+
         hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
-                                M88E1000_PSSR_DOWNSHIFT_SHIFT;
+                               M88E1000_PSSR_DOWNSHIFT_SHIFT;
     }
     return E1000_SUCCESS;
 }
 
+/*****************************************************************************
+ *
+ * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a
+ * gigabit link is achieved to improve link quality.
+ *
+ * hw: Struct containing variables accessed by shared code
+ *
+ * returns: - E1000_ERR_PHY if fail to read/write the PHY
+ *            E1000_SUCCESS at any other case.
+ *
+ ****************************************************************************/
+
+int32_t
+e1000_config_dsp_after_link_change(struct e1000_hw *hw,
+                                   boolean_t link_up)
+{
+    int32_t ret_val;
+    uint16_t phy_data, speed, duplex, i;
+    uint16_t dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
+                                        {IGP01E1000_PHY_AGC_PARAM_A,
+                                        IGP01E1000_PHY_AGC_PARAM_B,
+                                        IGP01E1000_PHY_AGC_PARAM_C,
+                                        IGP01E1000_PHY_AGC_PARAM_D};
+    uint16_t min_length, max_length;
+
+    DEBUGFUNC("e1000_config_dsp_after_link_change");
+
+    if(hw->phy_type != e1000_phy_igp)
+        return E1000_SUCCESS;
+
+    if(link_up) {
+        if((ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex))) {
+            DEBUGOUT("Error getting link speed and duplex\n");
+            return ret_val;
+        }
+
+        if(speed == SPEED_1000) {
+
+            e1000_get_cable_length(hw, &min_length, &max_length);
+
+            if((hw->dsp_config_state == e1000_dsp_config_enabled) &&
+                min_length >= e1000_igp_cable_length_50) {
+
+                for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
+                    if((ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
+                                                     &phy_data)))
+                        return ret_val;
+
+                    phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
+
+                    if((ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i],
+                                                      phy_data)))
+                        return ret_val;
+                }
+                hw->dsp_config_state = e1000_dsp_config_activated;
+            }
+
+            if((hw->ffe_config_state == e1000_ffe_config_enabled) &&
+               (min_length < e1000_igp_cable_length_50)) {
+
+                uint16_t ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
+                uint32_t idle_errs = 0;
+
+                /* clear previous idle error counts */
+                if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
+                                                 &phy_data)))
+                    return ret_val;
+
+                for(i = 0; i < ffe_idle_err_timeout; i++) {
+                    udelay(1000);
+                    if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
+                                                     &phy_data)))
+                        return ret_val;
+
+                    idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
+                    if(idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
+                        hw->ffe_config_state = e1000_ffe_config_active;
+
+                        if((ret_val = e1000_write_phy_reg(hw,
+                                    IGP01E1000_PHY_DSP_FFE,
+                                    IGP01E1000_PHY_DSP_FFE_CM_CP)))
+                            return ret_val;
+                        break;
+                    }
+
+                    if(idle_errs)
+                        ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_100;
+                }
+            }
+        }
+    } else {
+        if(hw->dsp_config_state == e1000_dsp_config_activated) {
+            if((ret_val = e1000_write_phy_reg(hw, 0x0000,
+                IGP01E1000_IEEE_FORCE_GIGA)))
+                return ret_val;
+            for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
+                if((ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
+                                                 &phy_data)))
+                    return ret_val;
+
+                phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
+                phy_data |=  IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
+
+                if((ret_val = e1000_write_phy_reg(hw,dsp_reg_array[i],
+                                                  phy_data)))
+                    return ret_val;
+            }
+
+            if((ret_val = e1000_write_phy_reg(hw, 0x0000,
+                                              IGP01E1000_IEEE_RESTART_AUTONEG)))
+                return ret_val;
+
+            hw->dsp_config_state = e1000_dsp_config_enabled;
+        }
+
+        if(hw->ffe_config_state == e1000_ffe_config_active) {
+            if((ret_val = e1000_write_phy_reg(hw, 0x0000,
+                                              IGP01E1000_IEEE_FORCE_GIGA)))
+                return ret_val;
+            if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
+                                              IGP01E1000_PHY_DSP_FFE_DEFAULT)))
+                return ret_val;
+
+            if((ret_val = e1000_write_phy_reg(hw, 0x0000,
+                                              IGP01E1000_IEEE_RESTART_AUTONEG)))
+                return ret_val;
+        hw->ffe_config_state = e1000_ffe_config_enabled;
+        }
+    }
+    return E1000_SUCCESS;
+}
+
+/*****************************************************************************
+ *
+ * This function sets the lplu state according to the active flag.  When
+ * activating lplu this function also disables smart speed and vise versa.
+ * lplu will not be activated unless the device autonegotiation advertisment
+ * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
+ * hw: Struct containing variables accessed by shared code
+ * active - true to enable lplu false to disable lplu.
+ *
+ * returns: - E1000_ERR_PHY if fail to read/write the PHY
+ *            E1000_SUCCESS at any other case.
+ *
+ ****************************************************************************/
+
+int32_t
+e1000_set_d3_lplu_state(struct e1000_hw *hw,
+                        boolean_t active)
+{
+    int32_t ret_val;
+    uint16_t phy_data;
+    DEBUGFUNC("e1000_set_d3_lplu_state");
+
+    if(!((hw->mac_type == e1000_82541_rev_2) ||
+         (hw->mac_type == e1000_82547_rev_2)))
+        return E1000_SUCCESS;
+
+    /* During driver activity LPLU should not be used or it will attain link
+     * from the lowest speeds starting from 10Mbps. The capability is used for
+     * Dx transitions and states */
+    if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data)))
+        return ret_val;
+
+    if(!active) {
+        phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
+        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data)))
+            return ret_val;
+
+        /* LPLU and SmartSpeed are mutually exclusive.  LPLU is used during
+         * Dx states where the power conservation is most important.  During
+         * driver activity we should enable SmartSpeed, so performance is
+         * maintained. */
+        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                         &phy_data)))
+            return ret_val;
+
+        phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
+        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                          phy_data)))
+            return ret_val;
+
+    } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
+              (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
+              (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
+
+        phy_data |= IGP01E1000_GMII_FLEX_SPD;
+        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data)))
+            return ret_val;
+
+        /* When LPLU is enabled we should disable SmartSpeed */
+        if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                         &phy_data)))
+            return ret_val;
+
+        phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+        if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+                                          phy_data)))
+            return ret_val;
+
+    }
+    return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Change VCO speed register to improve Bit Error Rate performance of SERDES.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int32_t
+e1000_set_vco_speed(struct e1000_hw *hw)
+{
+    int32_t  ret_val;
+    uint16_t default_page = 0;
+    uint16_t phy_data;
+
+    DEBUGFUNC("e1000_set_vco_speed");
+
+    switch(hw->mac_type) {
+    case e1000_82545_rev_3:
+    case e1000_82546_rev_3:
+       break;
+    default:
+        return E1000_SUCCESS;
+    }
+
+    /* Set PHY register 30, page 5, bit 8 to 0 */
+
+    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
+                                     &default_page)))
+        return ret_val;
+
+    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005)))
+        return ret_val;
+
+    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data)))
+        return ret_val;
+
+    phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
+    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data)))
+        return ret_val;
+
+    /* Set PHY register 30, page 4, bit 11 to 1 */
+
+    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004)))
+        return ret_val;
+
+    if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data)))
+        return ret_val;
+
+    phy_data |= M88E1000_PHY_VCO_REG_BIT11;
+    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data)))
+        return ret_val;
+
+    if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
+                                      default_page)))
+        return ret_val;
+
+    return E1000_SUCCESS;
+}
+
diff -urN linux-2.4.22-bk25/drivers/net/e1000/e1000_hw.h linux-2.4.22-bk26/drivers/net/e1000/e1000_hw.h
--- linux-2.4.22-bk25/drivers/net/e1000/e1000_hw.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/e1000/e1000_hw.h	2003-09-29 02:49:41.000000000 -0700
@@ -33,9 +33,9 @@
 #ifndef _E1000_HW_H_
 #define _E1000_HW_H_
 
-
 #include "e1000_osdep.h"
 
+
 /* Forward declarations of structures used by the shared code */
 struct e1000_hw;
 struct e1000_hw_stats;
@@ -50,9 +50,13 @@
     e1000_82544,
     e1000_82540,
     e1000_82545,
+    e1000_82545_rev_3,
     e1000_82546,
+    e1000_82546_rev_3,
     e1000_82541,
+    e1000_82541_rev_2,
     e1000_82547,
+    e1000_82547_rev_2,
     e1000_num_macs
 } e1000_mac_type;
 
@@ -67,6 +71,7 @@
 typedef enum {
     e1000_media_type_copper = 0,
     e1000_media_type_fiber = 1,
+    e1000_media_type_internal_serdes = 2,
     e1000_num_media_types
 } e1000_media_type;
 
@@ -90,7 +95,8 @@
 typedef enum {
     e1000_bus_type_unknown = 0,
     e1000_bus_type_pci,
-    e1000_bus_type_pcix
+    e1000_bus_type_pcix,
+    e1000_bus_type_reserved
 } e1000_bus_type;
 
 /* PCI bus speeds */
@@ -108,7 +114,8 @@
 typedef enum {
     e1000_bus_width_unknown = 0,
     e1000_bus_width_32,
-    e1000_bus_width_64
+    e1000_bus_width_64,
+    e1000_bus_width_reserved
 } e1000_bus_width;
 
 /* PHY status info structure and supporting enums */
@@ -186,6 +193,26 @@
     e1000_phy_undefined = 0xFF
 } e1000_phy_type;
 
+typedef enum {
+    e1000_ms_hw_default = 0,
+    e1000_ms_force_master,
+    e1000_ms_force_slave,
+    e1000_ms_auto
+} e1000_ms_type;
+
+typedef enum {
+    e1000_ffe_config_enabled = 0,
+    e1000_ffe_config_active,
+    e1000_ffe_config_blocked
+} e1000_ffe_config;
+
+typedef enum {
+    e1000_dsp_config_disabled = 0,
+    e1000_dsp_config_enabled,
+    e1000_dsp_config_activated,
+    e1000_dsp_config_undefined = 0xFF
+} e1000_dsp_config;
+
 struct e1000_phy_info {
     e1000_cable_length cable_length;
     e1000_10bt_ext_dist_enable extended_10bt_distance;
@@ -224,9 +251,10 @@
 
 /* Function prototypes */
 /* Initialization */
-void e1000_reset_hw(struct e1000_hw *hw);
+int32_t e1000_reset_hw(struct e1000_hw *hw);
 int32_t e1000_init_hw(struct e1000_hw *hw);
 int32_t e1000_set_mac_type(struct e1000_hw *hw);
+void e1000_set_media_type(struct e1000_hw *hw);
 
 /* Link Configuration */
 int32_t e1000_setup_link(struct e1000_hw *hw);
@@ -234,8 +262,9 @@
 void e1000_config_collision_dist(struct e1000_hw *hw);
 int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
 int32_t e1000_check_for_link(struct e1000_hw *hw);
-void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
+int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
 int32_t e1000_wait_autoneg(struct e1000_hw *hw);
+int32_t e1000_force_mac_fc(struct e1000_hw *hw);
 
 /* PHY */
 int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data);
@@ -292,6 +321,8 @@
 uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
 void e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value);
 void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
+int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
+int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
 
 #define E1000_READ_REG_IO(a, reg) \
     e1000_read_reg_io((a), E1000_##reg)
@@ -313,13 +344,22 @@
 #define E1000_DEV_ID_82540EP_LP          0x101E
 #define E1000_DEV_ID_82545EM_COPPER      0x100F
 #define E1000_DEV_ID_82545EM_FIBER       0x1011
+#define E1000_DEV_ID_82545GM_COPPER      0x1026
+#define E1000_DEV_ID_82545GM_FIBER       0x1027
+#define E1000_DEV_ID_82545GM_SERDES      0x1028
 #define E1000_DEV_ID_82546EB_COPPER      0x1010
 #define E1000_DEV_ID_82546EB_FIBER       0x1012
 #define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
 #define E1000_DEV_ID_82541EI             0x1013
-#define E1000_DEV_ID_82541EP             0x1018
+#define E1000_DEV_ID_82541EI_MOBILE      0x1018
+#define E1000_DEV_ID_82541ER             0x1078
+#define E1000_DEV_ID_82547GI             0x1075
+#define E1000_DEV_ID_82541GI             0x1076
+#define E1000_DEV_ID_82541GI_MOBILE      0x1077
+#define E1000_DEV_ID_82546GB_COPPER      0x1079
+#define E1000_DEV_ID_82546GB_FIBER       0x107A
+#define E1000_DEV_ID_82546GB_SERDES      0x107B
 #define E1000_DEV_ID_82547EI             0x1019
-#define NUM_DEV_IDS 20
 
 #define NODE_ADDRESS_SIZE 6
 #define ETH_LENGTH_OF_ADDRESS 6
@@ -385,7 +425,7 @@
     E1000_IMS_RXSEQ  |    \
     E1000_IMS_LSC)
 
-/* The number of high/low register pairs in the RAR. The RAR (Receive Address
+/* Number of high/low register pairs in the RAR. The RAR (Receive Address
  * Registers) holds the directed and multicast addresses that we monitor. We
  * reserve one of these spots for our directed address, allowing us room for
  * E1000_RAR_ENTRIES - 1 multicast addresses.
@@ -539,7 +579,7 @@
     volatile uint32_t high;     /* receive address high */
 };
 
-/* The number of entries in the Multicast Table Array (MTA). */
+/* Number of entries in the Multicast Table Array (MTA). */
 #define E1000_NUM_MTA_REGISTERS 128
 
 /* IPv4 Address Table Entry */
@@ -599,6 +639,7 @@
  * A - register array
  */
 #define E1000_CTRL     0x00000  /* Device Control - RW */
+#define E1000_CTRL_DUP 0x00004  /* Device Control Duplicate (Shadow) - RW */
 #define E1000_STATUS   0x00008  /* Device Status - RO */
 #define E1000_EECD     0x00010  /* EEPROM/Flash Control - RW */
 #define E1000_EERD     0x00014  /* EEPROM Read - RW */
@@ -934,6 +975,9 @@
     e1000_bus_width bus_width;
     e1000_bus_type bus_type;
     struct e1000_eeprom_info eeprom;
+    e1000_ms_type master_slave;
+    e1000_ms_type original_master_slave;
+    e1000_ffe_config ffe_config_state;
     uint32_t io_base;
     uint32_t phy_id;
     uint32_t phy_revision;
@@ -950,6 +994,8 @@
     uint32_t ledctl_default;
     uint32_t ledctl_mode1;
     uint32_t ledctl_mode2;
+    uint16_t phy_spd_default;
+    uint16_t dsp_reset_counter;
     uint16_t autoneg_advertised;
     uint16_t pci_cmd_word;
     uint16_t fc_high_water;
@@ -974,10 +1020,13 @@
     uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
     boolean_t disable_polarity_correction;
     boolean_t speed_downgraded;
+    e1000_dsp_config dsp_config_state;
     boolean_t get_link_status;
     boolean_t tbi_compatibility_en;
     boolean_t tbi_compatibility_on;
+    boolean_t phy_reset_disable;
     boolean_t fc_send_xon;
+    boolean_t fc_strict_ieee;
     boolean_t report_tx_early;
     boolean_t adaptive_ifs;
     boolean_t ifs_params_forced;
@@ -1059,7 +1108,7 @@
 #define E1000_EECD_PRES      0x00000100 /* EEPROM Present */
 #define E1000_EECD_SIZE      0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
 #define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
-					 * (0-small, 1-large) */
+                                         * (0-small, 1-large) */
 #define E1000_EECD_TYPE      0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
 #ifndef E1000_EEPROM_GRANT_ATTEMPTS
 #define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
@@ -1121,22 +1170,22 @@
 #define E1000_MDIC_ERROR     0x40000000
 
 /* LED Control */
-#define E1000_LEDCTL_LED0_MODE_MASK  0x0000000F
-#define E1000_LEDCTL_LED0_MODE_SHIFT 0
-#define E1000_LEDCTL_LED0_IVRT       0x00000040
-#define E1000_LEDCTL_LED0_BLINK      0x00000080
-#define E1000_LEDCTL_LED1_MODE_MASK  0x00000F00
-#define E1000_LEDCTL_LED1_MODE_SHIFT 8
-#define E1000_LEDCTL_LED1_IVRT       0x00004000
-#define E1000_LEDCTL_LED1_BLINK      0x00008000
-#define E1000_LEDCTL_LED2_MODE_MASK  0x000F0000
-#define E1000_LEDCTL_LED2_MODE_SHIFT 16
-#define E1000_LEDCTL_LED2_IVRT       0x00400000
-#define E1000_LEDCTL_LED2_BLINK      0x00800000
-#define E1000_LEDCTL_LED3_MODE_MASK  0x0F000000
-#define E1000_LEDCTL_LED3_MODE_SHIFT 24
-#define E1000_LEDCTL_LED3_IVRT       0x40000000
-#define E1000_LEDCTL_LED3_BLINK      0x80000000
+#define E1000_LEDCTL_LED0_MODE_MASK       0x0000000F
+#define E1000_LEDCTL_LED0_MODE_SHIFT      0
+#define E1000_LEDCTL_LED0_IVRT            0x00000040
+#define E1000_LEDCTL_LED0_BLINK           0x00000080
+#define E1000_LEDCTL_LED1_MODE_MASK       0x00000F00
+#define E1000_LEDCTL_LED1_MODE_SHIFT      8
+#define E1000_LEDCTL_LED1_IVRT            0x00004000
+#define E1000_LEDCTL_LED1_BLINK           0x00008000
+#define E1000_LEDCTL_LED2_MODE_MASK       0x000F0000
+#define E1000_LEDCTL_LED2_MODE_SHIFT      16
+#define E1000_LEDCTL_LED2_IVRT            0x00400000
+#define E1000_LEDCTL_LED2_BLINK           0x00800000
+#define E1000_LEDCTL_LED3_MODE_MASK       0x0F000000
+#define E1000_LEDCTL_LED3_MODE_SHIFT      24
+#define E1000_LEDCTL_LED3_IVRT            0x40000000
+#define E1000_LEDCTL_LED3_BLINK           0x80000000
 
 #define E1000_LEDCTL_MODE_LINK_10_1000  0x0
 #define E1000_LEDCTL_MODE_LINK_100_1000 0x1
@@ -1159,109 +1208,109 @@
 #define E1000_RAH_AV  0x80000000        /* Receive descriptor valid */
 
 /* Interrupt Cause Read */
-#define E1000_ICR_TXDW    0x00000001    /* Transmit desc written back */
-#define E1000_ICR_TXQE    0x00000002    /* Transmit Queue empty */
-#define E1000_ICR_LSC     0x00000004    /* Link Status Change */
-#define E1000_ICR_RXSEQ   0x00000008    /* rx sequence error */
-#define E1000_ICR_RXDMT0  0x00000010    /* rx desc min. threshold (0) */
-#define E1000_ICR_RXO     0x00000040    /* rx overrun */
-#define E1000_ICR_RXT0    0x00000080    /* rx timer intr (ring 0) */
-#define E1000_ICR_MDAC    0x00000200    /* MDIO access complete */
-#define E1000_ICR_RXCFG   0x00000400    /* RX /c/ ordered set */
-#define E1000_ICR_GPI_EN0 0x00000800    /* GP Int 0 */
-#define E1000_ICR_GPI_EN1 0x00001000    /* GP Int 1 */
-#define E1000_ICR_GPI_EN2 0x00002000    /* GP Int 2 */
-#define E1000_ICR_GPI_EN3 0x00004000    /* GP Int 3 */
-#define E1000_ICR_TXD_LOW 0x00008000
-#define E1000_ICR_SRPD    0x00010000
+#define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
+#define E1000_ICR_TXQE          0x00000002 /* Transmit Queue empty */
+#define E1000_ICR_LSC           0x00000004 /* Link Status Change */
+#define E1000_ICR_RXSEQ         0x00000008 /* rx sequence error */
+#define E1000_ICR_RXDMT0        0x00000010 /* rx desc min. threshold (0) */
+#define E1000_ICR_RXO           0x00000040 /* rx overrun */
+#define E1000_ICR_RXT0          0x00000080 /* rx timer intr (ring 0) */
+#define E1000_ICR_MDAC          0x00000200 /* MDIO access complete */
+#define E1000_ICR_RXCFG         0x00000400 /* RX /c/ ordered set */
+#define E1000_ICR_GPI_EN0       0x00000800 /* GP Int 0 */
+#define E1000_ICR_GPI_EN1       0x00001000 /* GP Int 1 */
+#define E1000_ICR_GPI_EN2       0x00002000 /* GP Int 2 */
+#define E1000_ICR_GPI_EN3       0x00004000 /* GP Int 3 */
+#define E1000_ICR_TXD_LOW       0x00008000
+#define E1000_ICR_SRPD          0x00010000
 
 /* Interrupt Cause Set */
-#define E1000_ICS_TXDW    E1000_ICR_TXDW        /* Transmit desc written back */
-#define E1000_ICS_TXQE    E1000_ICR_TXQE        /* Transmit Queue empty */
-#define E1000_ICS_LSC     E1000_ICR_LSC         /* Link Status Change */
-#define E1000_ICS_RXSEQ   E1000_ICR_RXSEQ       /* rx sequence error */
-#define E1000_ICS_RXDMT0  E1000_ICR_RXDMT0      /* rx desc min. threshold */
-#define E1000_ICS_RXO     E1000_ICR_RXO         /* rx overrun */
-#define E1000_ICS_RXT0    E1000_ICR_RXT0        /* rx timer intr */
-#define E1000_ICS_MDAC    E1000_ICR_MDAC        /* MDIO access complete */
-#define E1000_ICS_RXCFG   E1000_ICR_RXCFG       /* RX /c/ ordered set */
-#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0     /* GP Int 0 */
-#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1     /* GP Int 1 */
-#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2     /* GP Int 2 */
-#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3     /* GP Int 3 */
-#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_ICS_SRPD    E1000_ICR_SRPD
+#define E1000_ICS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
+#define E1000_ICS_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
+#define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
+#define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
+#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_ICS_RXO       E1000_ICR_RXO       /* rx overrun */
+#define E1000_ICS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
+#define E1000_ICS_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
+#define E1000_ICS_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
+#define E1000_ICS_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
+#define E1000_ICS_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
+#define E1000_ICS_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
+#define E1000_ICS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
+#define E1000_ICS_TXD_LOW   E1000_ICR_TXD_LOW
+#define E1000_ICS_SRPD      E1000_ICR_SRPD
 
 /* Interrupt Mask Set */
-#define E1000_IMS_TXDW    E1000_ICR_TXDW        /* Transmit desc written back */
-#define E1000_IMS_TXQE    E1000_ICR_TXQE        /* Transmit Queue empty */
-#define E1000_IMS_LSC     E1000_ICR_LSC         /* Link Status Change */
-#define E1000_IMS_RXSEQ   E1000_ICR_RXSEQ       /* rx sequence error */
-#define E1000_IMS_RXDMT0  E1000_ICR_RXDMT0      /* rx desc min. threshold */
-#define E1000_IMS_RXO     E1000_ICR_RXO         /* rx overrun */
-#define E1000_IMS_RXT0    E1000_ICR_RXT0        /* rx timer intr */
-#define E1000_IMS_MDAC    E1000_ICR_MDAC        /* MDIO access complete */
-#define E1000_IMS_RXCFG   E1000_ICR_RXCFG       /* RX /c/ ordered set */
-#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0     /* GP Int 0 */
-#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1     /* GP Int 1 */
-#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2     /* GP Int 2 */
-#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3     /* GP Int 3 */
-#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMS_SRPD    E1000_ICR_SRPD
+#define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
+#define E1000_IMS_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
+#define E1000_IMS_LSC       E1000_ICR_LSC       /* Link Status Change */
+#define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
+#define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_IMS_RXO       E1000_ICR_RXO       /* rx overrun */
+#define E1000_IMS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
+#define E1000_IMS_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
+#define E1000_IMS_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
+#define E1000_IMS_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
+#define E1000_IMS_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
+#define E1000_IMS_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
+#define E1000_IMS_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
+#define E1000_IMS_TXD_LOW   E1000_ICR_TXD_LOW
+#define E1000_IMS_SRPD      E1000_ICR_SRPD
 
 /* Interrupt Mask Clear */
-#define E1000_IMC_TXDW    E1000_ICR_TXDW        /* Transmit desc written back */
-#define E1000_IMC_TXQE    E1000_ICR_TXQE        /* Transmit Queue empty */
-#define E1000_IMC_LSC     E1000_ICR_LSC         /* Link Status Change */
-#define E1000_IMC_RXSEQ   E1000_ICR_RXSEQ       /* rx sequence error */
-#define E1000_IMC_RXDMT0  E1000_ICR_RXDMT0      /* rx desc min. threshold */
-#define E1000_IMC_RXO     E1000_ICR_RXO         /* rx overrun */
-#define E1000_IMC_RXT0    E1000_ICR_RXT0        /* rx timer intr */
-#define E1000_IMC_MDAC    E1000_ICR_MDAC        /* MDIO access complete */
-#define E1000_IMC_RXCFG   E1000_ICR_RXCFG       /* RX /c/ ordered set */
-#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0     /* GP Int 0 */
-#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1     /* GP Int 1 */
-#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2     /* GP Int 2 */
-#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3     /* GP Int 3 */
-#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
-#define E1000_IMC_SRPD    E1000_ICR_SRPD
+#define E1000_IMC_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
+#define E1000_IMC_TXQE      E1000_ICR_TXQE      /* Transmit Queue empty */
+#define E1000_IMC_LSC       E1000_ICR_LSC       /* Link Status Change */
+#define E1000_IMC_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
+#define E1000_IMC_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_IMC_RXO       E1000_ICR_RXO       /* rx overrun */
+#define E1000_IMC_RXT0      E1000_ICR_RXT0      /* rx timer intr */
+#define E1000_IMC_MDAC      E1000_ICR_MDAC      /* MDIO access complete */
+#define E1000_IMC_RXCFG     E1000_ICR_RXCFG     /* RX /c/ ordered set */
+#define E1000_IMC_GPI_EN0   E1000_ICR_GPI_EN0   /* GP Int 0 */
+#define E1000_IMC_GPI_EN1   E1000_ICR_GPI_EN1   /* GP Int 1 */
+#define E1000_IMC_GPI_EN2   E1000_ICR_GPI_EN2   /* GP Int 2 */
+#define E1000_IMC_GPI_EN3   E1000_ICR_GPI_EN3   /* GP Int 3 */
+#define E1000_IMC_TXD_LOW   E1000_ICR_TXD_LOW
+#define E1000_IMC_SRPD      E1000_ICR_SRPD
 
 /* Receive Control */
-#define E1000_RCTL_RST          0x00000001      /* Software reset */
-#define E1000_RCTL_EN           0x00000002      /* enable */
-#define E1000_RCTL_SBP          0x00000004      /* store bad packet */
-#define E1000_RCTL_UPE          0x00000008      /* unicast promiscuous enable */
-#define E1000_RCTL_MPE          0x00000010      /* multicast promiscuous enab */
-#define E1000_RCTL_LPE          0x00000020      /* long packet enable */
-#define E1000_RCTL_LBM_NO       0x00000000      /* no loopback mode */
-#define E1000_RCTL_LBM_MAC      0x00000040      /* MAC loopback mode */
-#define E1000_RCTL_LBM_SLP      0x00000080      /* serial link loopback mode */
-#define E1000_RCTL_LBM_TCVR     0x000000C0      /* tcvr loopback mode */
-#define E1000_RCTL_RDMTS_HALF   0x00000000      /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_QUAT   0x00000100      /* rx desc min threshold size */
-#define E1000_RCTL_RDMTS_EIGTH  0x00000200      /* rx desc min threshold size */
-#define E1000_RCTL_MO_SHIFT     12              /* multicast offset shift */
-#define E1000_RCTL_MO_0         0x00000000      /* multicast offset 11:0 */
-#define E1000_RCTL_MO_1         0x00001000      /* multicast offset 12:1 */
-#define E1000_RCTL_MO_2         0x00002000      /* multicast offset 13:2 */
-#define E1000_RCTL_MO_3         0x00003000      /* multicast offset 15:4 */
-#define E1000_RCTL_MDR          0x00004000      /* multicast desc ring 0 */
-#define E1000_RCTL_BAM          0x00008000      /* broadcast enable */
+#define E1000_RCTL_RST            0x00000001    /* Software reset */
+#define E1000_RCTL_EN             0x00000002    /* enable */
+#define E1000_RCTL_SBP            0x00000004    /* store bad packet */
+#define E1000_RCTL_UPE            0x00000008    /* unicast promiscuous enable */
+#define E1000_RCTL_MPE            0x00000010    /* multicast promiscuous enab */
+#define E1000_RCTL_LPE            0x00000020    /* long packet enable */
+#define E1000_RCTL_LBM_NO         0x00000000    /* no loopback mode */
+#define E1000_RCTL_LBM_MAC        0x00000040    /* MAC loopback mode */
+#define E1000_RCTL_LBM_SLP        0x00000080    /* serial link loopback mode */
+#define E1000_RCTL_LBM_TCVR       0x000000C0    /* tcvr loopback mode */
+#define E1000_RCTL_RDMTS_HALF     0x00000000    /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_QUAT     0x00000100    /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_EIGTH    0x00000200    /* rx desc min threshold size */
+#define E1000_RCTL_MO_SHIFT       12            /* multicast offset shift */
+#define E1000_RCTL_MO_0           0x00000000    /* multicast offset 11:0 */
+#define E1000_RCTL_MO_1           0x00001000    /* multicast offset 12:1 */
+#define E1000_RCTL_MO_2           0x00002000    /* multicast offset 13:2 */
+#define E1000_RCTL_MO_3           0x00003000    /* multicast offset 15:4 */
+#define E1000_RCTL_MDR            0x00004000    /* multicast desc ring 0 */
+#define E1000_RCTL_BAM            0x00008000    /* broadcast enable */
 /* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
-#define E1000_RCTL_SZ_2048      0x00000000      /* rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024      0x00010000      /* rx buffer size 1024 */
-#define E1000_RCTL_SZ_512       0x00020000      /* rx buffer size 512 */
-#define E1000_RCTL_SZ_256       0x00030000      /* rx buffer size 256 */
+#define E1000_RCTL_SZ_2048        0x00000000    /* rx buffer size 2048 */
+#define E1000_RCTL_SZ_1024        0x00010000    /* rx buffer size 1024 */
+#define E1000_RCTL_SZ_512         0x00020000    /* rx buffer size 512 */
+#define E1000_RCTL_SZ_256         0x00030000    /* rx buffer size 256 */
 /* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
-#define E1000_RCTL_SZ_16384     0x00010000      /* rx buffer size 16384 */
-#define E1000_RCTL_SZ_8192      0x00020000      /* rx buffer size 8192 */
-#define E1000_RCTL_SZ_4096      0x00030000      /* rx buffer size 4096 */
-#define E1000_RCTL_VFE          0x00040000      /* vlan filter enable */
-#define E1000_RCTL_CFIEN        0x00080000      /* canonical form enable */
-#define E1000_RCTL_CFI          0x00100000      /* canonical form indicator */
-#define E1000_RCTL_DPF          0x00400000      /* discard pause frames */
-#define E1000_RCTL_PMCF         0x00800000      /* pass MAC control frames */
-#define E1000_RCTL_BSEX         0x02000000      /* Buffer size extension */
+#define E1000_RCTL_SZ_16384       0x00010000    /* rx buffer size 16384 */
+#define E1000_RCTL_SZ_8192        0x00020000    /* rx buffer size 8192 */
+#define E1000_RCTL_SZ_4096        0x00030000    /* rx buffer size 4096 */
+#define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
+#define E1000_RCTL_CFIEN          0x00080000    /* canonical form enable */
+#define E1000_RCTL_CFI            0x00100000    /* canonical form indicator */
+#define E1000_RCTL_DPF            0x00400000    /* discard pause frames */
+#define E1000_RCTL_PMCF           0x00800000    /* pass MAC control frames */
+#define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
 
 /* Receive Descriptor */
 #define E1000_RDT_DELAY 0x0000ffff      /* Delay timer (1=1024us) */
@@ -1426,15 +1475,17 @@
 #define EEPROM_SIZE_128B        0x0000
 #define EEPROM_SIZE_MASK        0x1C00
 
-
 /* EEPROM Word Offsets */
-#define EEPROM_COMPAT              0x0003
-#define EEPROM_ID_LED_SETTINGS     0x0004
-#define EEPROM_INIT_CONTROL1_REG   0x000A
-#define EEPROM_INIT_CONTROL2_REG   0x000F
-#define EEPROM_CFG                 0x0012
-#define EEPROM_FLASH_VERSION       0x0032
-#define EEPROM_CHECKSUM_REG        0x003F
+#define EEPROM_COMPAT                 0x0003
+#define EEPROM_ID_LED_SETTINGS        0x0004
+#define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude adjustment. */
+#define EEPROM_INIT_CONTROL1_REG      0x000A
+#define EEPROM_INIT_CONTROL2_REG      0x000F
+#define EEPROM_INIT_CONTROL3_PORT_B   0x0014
+#define EEPROM_INIT_CONTROL3_PORT_A   0x0024
+#define EEPROM_CFG                    0x0012
+#define EEPROM_FLASH_VERSION          0x0032
+#define EEPROM_CHECKSUM_REG           0x003F
 
 /* Word definitions for ID LED Settings */
 #define ID_LED_RESERVED_0000 0x0000
@@ -1458,6 +1509,9 @@
 #define IGP_LED3_MODE           0x07000000
 
 
+/* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */
+#define EEPROM_SERDES_AMPLITUDE_MASK  0x000F
+
 /* Mask bits for fields in Word 0x0a of the EEPROM */
 #define EEPROM_WORD0A_ILOS   0x0010
 #define EEPROM_WORD0A_SWDPIO 0x01E0
@@ -1479,6 +1533,8 @@
 #define EEPROM_NODE_ADDRESS_BYTE_0 0
 #define EEPROM_PBA_BYTE_1          8
 
+#define EEPROM_RESERVED_WORD          0xFFFF
+
 /* EEPROM Map Sizes (Byte Counts) */
 #define PBA_SIZE 4
 
@@ -1490,7 +1546,7 @@
 #define E1000_HDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
 #define E1000_COLD_SHIFT                12
 
-/* The number of Transmit and Receive Descriptors must be a multiple of 8 */
+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
 #define REQ_TX_DESCRIPTOR_MULTIPLE  8
 #define REQ_RX_DESCRIPTOR_MULTIPLE  8
 
@@ -1557,35 +1613,30 @@
 #define PCIX_STATUS_HI_MMRBC_2K      0x2
 
 
-/* The number of bits that we need to shift right to move the "pause"
- * bits from the EEPROM (bits 13:12) to the "pause" (bits 8:7) field
- * in the TXCW register
+/* Number of bits required to shift right the "pause" bits from the
+ * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register.
  */
 #define PAUSE_SHIFT 5
 
-/* The number of bits that we need to shift left to move the "SWDPIO"
- * bits from the EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field
- * in the CTRL register
+/* Number of bits required to shift left the "SWDPIO" bits from the
+ * EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field in the CTRL register.
  */
 #define SWDPIO_SHIFT 17
 
-/* The number of bits that we need to shift left to move the "SWDPIO_EXT"
- * bits from the EEPROM word F (bits 7:4) to the bits 11:8 of The
- * Extended CTRL register.
- * in the CTRL register
+/* Number of bits required to shift left the "SWDPIO_EXT" bits from the
+ * EEPROM word F (bits 7:4) to the bits 11:8 of The Extended CTRL register.
  */
 #define SWDPIO__EXT_SHIFT 4
 
-/* The number of bits that we need to shift left to move the "ILOS"
- * bit from the EEPROM (bit 4) to the "ILOS" (bit 7) field
- * in the CTRL register
+/* Number of bits required to shift left the "ILOS" bit from the EEPROM
+ * (bit 4) to the "ILOS" (bit 7) field in the CTRL register.
  */
 #define ILOS_SHIFT  3
 
 
 #define RECEIVE_BUFFER_ALIGN_SIZE  (256)
 
-/* The number of milliseconds we wait for auto-negotiation to complete */
+/* Number of milliseconds we wait for auto-negotiation to complete */
 #define LINK_UP_TIMEOUT             500
 
 #define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
@@ -1668,7 +1719,16 @@
 #define M88E1000_EXT_PHY_SPEC_CTRL 0x14  /* Extended PHY Specific Control */
 #define M88E1000_RX_ERR_CNTR       0x15  /* Receive Error Counter */
 
+#define M88E1000_PHY_EXT_CTRL      0x1A  /* PHY extend control register */
+#define M88E1000_PHY_PAGE_SELECT   0x1D  /* Reg 29 for page number setting */
+#define M88E1000_PHY_GEN_CONTROL   0x1E  /* Its meaning depends on reg 29 */
+#define M88E1000_PHY_VCO_REG_BIT8  0x100 /* Bits 8 & 11 are adjusted for */
+#define M88E1000_PHY_VCO_REG_BIT11 0x800    /* improved BER performance */
+
 #define IGP01E1000_IEEE_REGS_PAGE  0x0000
+#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
+#define IGP01E1000_IEEE_FORCE_GIGA      0x0140
+
 /* IGP01E1000 Specific Registers */
 #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */
 #define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */
@@ -1684,17 +1744,35 @@
 #define IGP01E1000_PHY_AGC_C        0x1472
 #define IGP01E1000_PHY_AGC_D        0x1872
 
-/* Number of AGC registers */
-#define IGP01E1000_PHY_AGC_NUM     4
+/* IGP01E1000 DSP Reset Register */
+#define IGP01E1000_PHY_DSP_RESET   0x1F33
+#define IGP01E1000_PHY_DSP_SET     0x1F71
+#define IGP01E1000_PHY_DSP_FFE     0x1F35
+
+#define IGP01E1000_PHY_CHANNEL_NUM    4
+#define IGP01E1000_PHY_AGC_PARAM_A    0x1171
+#define IGP01E1000_PHY_AGC_PARAM_B    0x1271
+#define IGP01E1000_PHY_AGC_PARAM_C    0x1471
+#define IGP01E1000_PHY_AGC_PARAM_D    0x1871
+
+#define IGP01E1000_PHY_EDAC_MU_INDEX        0xC000
+#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000
+
+#define IGP01E1000_PHY_ANALOG_TX_STATE      0x2890
+#define IGP01E1000_PHY_ANALOG_CLASS_A       0x2000
+#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE  0x0004
+#define IGP01E1000_PHY_DSP_FFE_CM_CP        0x0069
 
+#define IGP01E1000_PHY_DSP_FFE_DEFAULT      0x002A
 /* IGP01E1000 PCS Initialization register - stores the polarity status when
  * speed = 1000 Mbps. */
 #define IGP01E1000_PHY_PCS_INIT_REG  0x00B4
+#define IGP01E1000_PHY_PCS_CTRL_REG  0x00B5
 
 #define IGP01E1000_ANALOG_REGS_PAGE  0x20C0
 
 #define MAX_PHY_REG_ADDRESS 0x1F        /* 5 bit address bus (0-0x1F) */
-
+#define MAX_PHY_MULTI_PAGE_REG  0xF     /*Registers that are equal on all pages*/
 /* PHY Control Register */
 #define MII_CR_SPEED_SELECT_MSB 0x0040  /* bits 6,13: 10=1000, 01=100, 00=10 */
 #define MII_CR_COLL_TEST_ENABLE 0x0080  /* Collision test enable */
@@ -1808,8 +1886,11 @@
 #define SR_1000T_LOCAL_RX_STATUS  0x2000 /* Local receiver OK */
 #define SR_1000T_MS_CONFIG_RES    0x4000 /* 1=Local TX is Master, 0=Slave */
 #define SR_1000T_MS_CONFIG_FAULT  0x8000 /* Master/Slave config fault */
-#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
-#define SR_1000T_LOCAL_RX_STATUS_SHIFT  13
+#define SR_1000T_REMOTE_RX_STATUS_SHIFT          12
+#define SR_1000T_LOCAL_RX_STATUS_SHIFT           13
+#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT    5
+#define FFE_IDLE_ERR_COUNT_TIMEOUT_20            20
+#define FFE_IDLE_ERR_COUNT_TIMEOUT_100           100
 
 /* Extended Status Register */
 #define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
@@ -1901,7 +1982,6 @@
 #define M88E1000_EPSCR_TX_CLK_25      0x0070 /* 25  MHz TX_CLK */
 #define M88E1000_EPSCR_TX_CLK_0       0x0000 /* NO  TX_CLK */
 
-
 /* IGP01E1000 Specific Port Config Register - R/W */
 #define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT  0x0010
 #define IGP01E1000_PSCFR_PRE_EN                0x0020
@@ -1952,6 +2032,11 @@
 #define IGP01E1000_MSE_CHANNEL_B        0x0F00
 #define IGP01E1000_MSE_CHANNEL_A        0xF000
 
+/* IGP01E1000 DSP reset macros */
+#define DSP_RESET_ENABLE     0x0
+#define DSP_RESET_DISABLE    0x2
+#define E1000_MAX_DSP_RESETS 10
+
 /* IGP01E1000 AGC Registers */
 
 #define IGP01E1000_AGC_LENGTH_SHIFT 7         /* Coarse - 13:11, Fine - 10:7 */
@@ -1962,18 +2047,6 @@
 /* The precision of the length is +/- 10 meters */
 #define IGP01E1000_AGC_RANGE    10
 
-/* IGP cable length table */
-static const
-uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] =
-    { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-      5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25,
-      25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40,
-      40, 50, 50, 50, 50, 50, 50, 50, 60, 60, 60, 60, 60, 60, 60, 60,
-      60, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 90, 90, 90,
-      90, 90, 90, 90, 90, 90, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
-      100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
-      110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
-
 /* IGP01E1000 PCS Initialization register */
 /* bits 3:6 in the PCS registers stores the channels polarity */
 #define IGP01E1000_PHY_POLARITY_MASK    0x0078
@@ -1982,11 +2055,12 @@
 #define IGP01E1000_GMII_FLEX_SPD               0x10 /* Enable flexible speed
                                                      * on Link-Up */
 #define IGP01E1000_GMII_SPD                    0x20 /* Enable SPD */
+
 /* IGP01E1000 Analog Register */
-#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS         0x0011
-#define IGP01E1000_ANALOG_FUSE_STATUS               0x0010
-#define IGP01E1000_ANALOG_FUSE_CONTROL              0x001C
-#define IGP01E1000_ANALOG_FUSE_BYPASS               0x001E
+#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS       0x20D1
+#define IGP01E1000_ANALOG_FUSE_STATUS             0x20D0
+#define IGP01E1000_ANALOG_FUSE_CONTROL            0x20DC
+#define IGP01E1000_ANALOG_FUSE_BYPASS             0x20DE
 
 #define IGP01E1000_ANALOG_FUSE_POLY_MASK            0xF000
 #define IGP01E1000_ANALOG_FUSE_FINE_MASK            0x0F80
@@ -2032,5 +2106,8 @@
 #define ADVERTISE_1000_HALF 0x0010
 #define ADVERTISE_1000_FULL 0x0020
 #define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F  /* Everything but 1000-Half */
+#define AUTONEG_ADVERTISE_10_100_ALL    0x000F /* All 10/100 speeds*/
+#define AUTONEG_ADVERTISE_10_ALL        0x0003 /* 10Mbps Full & Half speeds*/
+
 
 #endif /* _E1000_HW_H_ */
diff -urN linux-2.4.22-bk25/drivers/net/e1000/e1000_main.c linux-2.4.22-bk26/drivers/net/e1000/e1000_main.c
--- linux-2.4.22-bk25/drivers/net/e1000/e1000_main.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/e1000/e1000_main.c	2003-09-29 02:49:41.000000000 -0700
@@ -30,6 +30,22 @@
 
 /* Change Log
  *
+ * 5.2.16	8/8/03
+ *   o Added support for new controllers: 82545GM, 82546GB, 82541/7_B1
+ *   o Bug fix: reset h/w before first EEPROM read because we don't know
+ *     who may have been messing with the device before we got there.
+ *     [Dave Johnson (ddj -a-t- cascv.brown.edu)]
+ *   o Bug fix: read the correct work from EEPROM to detect programmed
+ *     WoL settings.
+ *   o Bug fix: TSO would hang if space left in FIFO was being miscalculated
+ *     when mss dropped without a correspoding drop in the DMA buffer size.
+ *   o ASF for Fiber nics isn't supported.
+ *   o Bug fix: Workaround added for potential hang with 82544 running in
+ *     PCI-X if send buffer terminates within an evenly-aligned dword.
+ *   o Feature: Add support for ethtool flow control setting.
+ *   o Feature: Add support for ethtool TSO setting.
+ *   o Feature: Increase default Tx Descriptor count to 1024 for >= 82544.
+ *   
  * 5.1.13	5/28/03
  *   o Bug fix: request_irq() failure resulted in freeing resources twice!
  *     [Don Fry (brazilnut@us.ibm.com)]
@@ -39,18 +55,11 @@
  *   o Cleanup: s/int/unsigned int/ for descriptor ring indexes.
  *   
  * 5.1.11	5/6/03
- *   o Feature: Added support for 82546EB (Quad-port) hardware.
- *   o Feature: Added support for Diagnostics through Ethtool.
- *   o Cleanup: Removed /proc support.
- *   o Cleanup: Removed proprietary IDIAG interface.
- *   o Bug fix: TSO bug fixes.
- *
- * 5.0.42	3/5/03
  */
 
 char e1000_driver_name[] = "e1000";
 char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-char e1000_driver_version[] = "5.1.13-k1";
+char e1000_driver_version[] = "5.2.16-k1";
 char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
@@ -61,7 +70,7 @@
  * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
  *   Class, Class Mask, private data (not used) }
  */
-static struct pci_device_id e1000_pci_tbl[] __devinitdata = {
+static struct pci_device_id e1000_pci_tbl[] = {
 	{0x8086, 0x1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -71,15 +80,28 @@
 	{0x8086, 0x100D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x100E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x100F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x1010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1075, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1076, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1077, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x1079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x107A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x8086, 0x107B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	/* required last entry */
 	{0,}
 };
@@ -120,7 +142,7 @@
 static void e1000_update_stats(struct e1000_adapter *adapter);
 static inline void e1000_irq_disable(struct e1000_adapter *adapter);
 static inline void e1000_irq_enable(struct e1000_adapter *adapter);
-static void e1000_intr(int irq, void *data, struct pt_regs *regs);
+static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
 static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
 #ifdef CONFIG_E1000_NAPI
 static int e1000_clean(struct net_device *netdev, int *budget);
@@ -425,6 +447,11 @@
 	if(pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
+	/* before reading the EEPROM, reset the controller to 
+	 * put the device in a known good starting state */
+	
+	e1000_reset_hw(&adapter->hw);
+
 	/* make sure the EEPROM is good */
 
 	if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
@@ -475,12 +502,28 @@
 	 * enable the ACPI Magic Packet filter
 	 */
 
-	e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL2_REG,1, &eeprom_data);
-	if((adapter->hw.mac_type >= e1000_82544) &&
-	   (eeprom_data & E1000_EEPROM_APME))
+	switch(adapter->hw.mac_type) {
+	case e1000_82542_rev2_0:
+	case e1000_82542_rev2_1:
+	case e1000_82543:
+		break;
+	case e1000_82546:
+	case e1000_82546_rev_3:
+		if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
+		   && (adapter->hw.media_type == e1000_media_type_copper)) {
+			e1000_read_eeprom(&adapter->hw,
+				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
+			break;
+		}
+		/* Fall Through */
+	default:
+		e1000_read_eeprom(&adapter->hw,
+			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+		break;
+	}
+	if(eeprom_data & E1000_EEPROM_APME)
 		adapter->wol |= E1000_WUFC_MAG;
 
-
 	/* reset the hardware with the new settings */
 
 	e1000_reset(adapter);
@@ -515,7 +558,8 @@
 	struct e1000_adapter *adapter = netdev->priv;
 	uint32_t manc;
 
-	if(adapter->hw.mac_type >= e1000_82540) {
+	if(adapter->hw.mac_type >= e1000_82540 &&
+	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		if(manc & E1000_MANC_SMBUS_EN) {
 			manc |= E1000_MANC_ARP_EN;
@@ -583,21 +627,13 @@
 	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
 	hw->fc_send_xon = 1;
 
-	if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547))
+	if((hw->mac_type == e1000_82541) ||
+	   (hw->mac_type == e1000_82547) ||
+	   (hw->mac_type == e1000_82541_rev_2) ||
+	   (hw->mac_type == e1000_82547_rev_2))
 		hw->phy_init_script = 1;
 
-	/* Media type - copper or fiber */
-
-	if(hw->mac_type >= e1000_82543) {
-		uint32_t status = E1000_READ_REG(hw, STATUS);
-
-		if(status & E1000_STATUS_TBIMODE)
-			hw->media_type = e1000_media_type_fiber;
-		else
-			hw->media_type = e1000_media_type_copper;
-	} else {
-		hw->media_type = e1000_media_type_fiber;
-	}
+	e1000_set_media_type(hw);
 
 	if(hw->mac_type < e1000_82543)
 		hw->report_tx_early = 0;
@@ -613,6 +649,7 @@
 	if(hw->media_type == e1000_media_type_copper) {
 		hw->mdix = AUTO_ALL_MODES;
 		hw->disable_polarity_correction = FALSE;
+		hw->master_slave = E1000_MASTER_SLAVE;
 	}
 
 	atomic_set(&adapter->irq_sem, 1);
@@ -762,7 +799,8 @@
 		tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
 		break;
 	default:
-		if(adapter->hw.media_type == e1000_media_type_fiber)
+		if(adapter->hw.media_type == e1000_media_type_fiber ||
+		   adapter->hw.media_type == e1000_media_type_internal_serdes)
 			tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
 		else
 			tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
@@ -797,6 +835,12 @@
 		adapter->txd_cmd |= E1000_TXD_CMD_RS;
 	else
 		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
+
+	/* Cache if we're 82544 running in PCI-X because we'll
+	 * need this to apply a workaround later in the send path. */
+	if(adapter->hw.mac_type == e1000_82544 &&
+	   adapter->hw.bus_type == e1000_bus_type_pcix)
+		adapter->pcix_82544 = 1;
 }
 
 /**
@@ -1489,11 +1533,18 @@
 {
 	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 	struct e1000_buffer *buffer_info;
-	int len = skb->len;
+	unsigned int len = skb->len, max_per_txd = E1000_MAX_DATA_PER_TXD;
 	unsigned int offset = 0, size, count = 0, i;
 
 #ifdef NETIF_F_TSO
-	unsigned int tso = skb_shinfo(skb)->tso_size;
+	unsigned int mss = skb_shinfo(skb)->tso_size;
+	/* The controller does a simple calculation to 
+	 * make sure there is enough room in the FIFO before
+	 * initiating the DMA for each buffer.  The calc is:
+	 * 4 = ceil(buffer len/mss).  To make sure we don't
+	 * overrun the FIFO, adjust the max buffer len if mss
+	 * drops. */
+	if(mss) max_per_txd = min(mss << 2, max_per_txd);
 #endif
 	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
 	unsigned int f;
@@ -1503,13 +1554,20 @@
 
 	while(len) {
 		buffer_info = &tx_ring->buffer_info[i];
-		size = min(len, E1000_MAX_DATA_PER_TXD);
+		size = min(len, max_per_txd);
 #ifdef NETIF_F_TSO
 		/* Workaround for premature desc write-backs
 		 * in TSO mode.  Append 4-byte sentinel desc */
-		if(tso && !nr_frags && size == len && size > 4)
+		if(mss && !nr_frags && size == len && size > 8)
 			size -= 4;
 #endif
+		/* Workaround for potential 82544 hang in PCI-X.  Avoid
+		 * terminating buffers within evenly-aligned dwords. */
+		if(adapter->pcix_82544 &&
+		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
+		   size > 4)
+			size -= 4;
+
 		buffer_info->length = size;
 		buffer_info->dma =
 			pci_map_single(adapter->pdev,
@@ -1529,22 +1587,30 @@
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = 0;
+		offset = frag->page_offset;
 
 		while(len) {
 			buffer_info = &tx_ring->buffer_info[i];
-			size = min(len, E1000_MAX_DATA_PER_TXD);
+			size = min(len, max_per_txd);
 #ifdef NETIF_F_TSO
 			/* Workaround for premature desc write-backs
 			 * in TSO mode.  Append 4-byte sentinel desc */
-			if(tso && f == (nr_frags-1) && size == len && size > 4)
+			if(mss && f == (nr_frags-1) && size == len && size > 8)
 				size -= 4;
 #endif
+			/* Workaround for potential 82544 hang in PCI-X.
+			 * Avoid terminating buffers within evenly-aligned
+			 * dwords. */
+			if(adapter->pcix_82544 &&
+			   !((unsigned long)(frag->page+offset+size-1) & 4) &&
+			   size > 4)
+				size -= 4;
+
 			buffer_info->length = size;
 			buffer_info->dma =
 				pci_map_page(adapter->pdev,
 					frag->page,
-					frag->page_offset + offset,
+					offset,
 					size,
 					PCI_DMA_TODEVICE);
 			buffer_info->time_stamp = jiffies;
@@ -1555,6 +1621,31 @@
 			if(++i == tx_ring->count) i = 0;
 		}
 	}
+
+	if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) {
+
+		/* There aren't enough descriptors available to queue up
+		 * this send, so undo the mapping and abort the send. 
+		 * We could have done the check before we mapped the skb,
+		 * but because of all the workarounds (above), it's too
+		 * difficult to predict how many we're going to need.*/
+		i = first;
+
+		while(count--) {
+			buffer_info = &tx_ring->buffer_info[i];
+			if(buffer_info->dma) {
+				pci_unmap_page(adapter->pdev,
+					       buffer_info->dma,
+					       buffer_info->length,
+					       PCI_DMA_TODEVICE);
+				buffer_info->dma = 0;
+			}
+			if(++i == tx_ring->count) i = 0;
+		}
+
+		return 0;
+	}
+
 	i = (i == 0) ? tx_ring->count - 1 : i - 1;
 	tx_ring->buffer_info[i].skb = skb;
 	tx_ring->buffer_info[first].next_to_watch = i;
@@ -1649,29 +1740,19 @@
 	return 0;
 }
 
-/* Tx Descriptors needed, worst case */
-#define TXD_USE_COUNT(S) (((S) >> E1000_MAX_TXD_PWR) + \
-			 (((S) & (E1000_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
-#define DESC_NEEDED TXD_USE_COUNT(MAX_JUMBO_FRAME_SIZE) + \
-	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
-
 static int
 e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev->priv;
 	unsigned int first;
 	unsigned int tx_flags = 0;
+	int count;
 
 	if(skb->len <= 0) {
 		dev_kfree_skb_any(skb);
 		return 0;
 	}
 
-	if(E1000_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED) {
-		netif_stop_queue(netdev);
-		return 1;
-	}
-
 	if(adapter->hw.mac_type == e1000_82547) {
 		if(e1000_82547_fifo_workaround(adapter, skb)) {
 			netif_stop_queue(netdev);
@@ -1692,7 +1773,12 @@
 	else if(e1000_tx_csum(adapter, skb))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
-	e1000_tx_queue(adapter, e1000_tx_map(adapter, skb, first), tx_flags);
+	if((count = e1000_tx_map(adapter, skb, first)))
+		e1000_tx_queue(adapter, count, tx_flags);
+	else {
+		netif_stop_queue(netdev);
+		return 1;
+	}
 
 	netdev->trans_start = jiffies;
 
@@ -1965,7 +2051,7 @@
  * @pt_regs: CPU registers structure
  **/
 
-static void
+static irqreturn_t
 e1000_intr(int irq, void *data, struct pt_regs *regs)
 {
 	struct net_device *netdev = data;
@@ -1976,7 +2062,7 @@
 #endif
 
 	if(!icr)
-		return;  /* Not our interrupt */
+		return IRQ_NONE;  /* Not our interrupt */
 
 	if(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
 		adapter->hw.get_link_status = 1;
@@ -2000,6 +2086,8 @@
 		   !e1000_clean_tx_irq(adapter))
 			break;
 #endif
+
+	return IRQ_HANDLED;
 }
 
 #ifdef CONFIG_E1000_NAPI
@@ -2385,7 +2473,7 @@
 	uint16_t mii_reg;
 	uint16_t spddplx;
 
-	if(adapter->hw.media_type == e1000_media_type_fiber)
+	if(adapter->hw.media_type != e1000_media_type_copper)
 		return -EOPNOTSUPP;
 
 	switch (cmd) {
@@ -2657,7 +2745,7 @@
 	case SYS_DOWN:
 	case SYS_HALT:
 	case SYS_POWER_OFF:
-		pci_for_each_dev(pdev) {
+		while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
 			if(pci_dev_driver(pdev) == &e1000_driver)
 				e1000_suspend(pdev, 3);
 		}
@@ -2704,7 +2792,8 @@
 			E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
 		}
 
-		if(adapter->hw.media_type == e1000_media_type_fiber) {
+		if(adapter->hw.media_type == e1000_media_type_fiber ||
+		   adapter->hw.media_type == e1000_media_type_internal_serdes) {
 			/* keep the laser running in D3 */
 			ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
 			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
@@ -2724,7 +2813,8 @@
 
 	pci_save_state(pdev, adapter->pci_state);
 
-	if(adapter->hw.mac_type >= e1000_82540) {
+	if(adapter->hw.mac_type >= e1000_82540 &&
+	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		if(manc & E1000_MANC_SMBUS_EN) {
 			manc |= E1000_MANC_ARP_EN;
@@ -2762,7 +2852,8 @@
 
 	netif_device_attach(netdev);
 
-	if(adapter->hw.mac_type >= e1000_82540) {
+	if(adapter->hw.mac_type >= e1000_82540 &&
+	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
 		manc &= ~(E1000_MANC_ARP_EN);
 		E1000_WRITE_REG(&adapter->hw, MANC, manc);
diff -urN linux-2.4.22-bk25/drivers/net/e1000/e1000_osdep.h linux-2.4.22-bk26/drivers/net/e1000/e1000_osdep.h
--- linux-2.4.22-bk25/drivers/net/e1000/e1000_osdep.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/e1000/e1000_osdep.h	2003-09-29 02:49:41.000000000 -0700
@@ -55,10 +55,13 @@
 #define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE
 
 typedef enum {
+#undef FALSE
     FALSE = 0,
+#undef TRUE
     TRUE = 1
 } boolean_t;
 
+#undef ASSERT
 #define ASSERT(x)	if(!(x)) BUG()
 #define MSGOUT(S, A, B)	printk(KERN_DEBUG S "\n", A, B)
 
diff -urN linux-2.4.22-bk25/drivers/net/e1000/e1000_param.c linux-2.4.22-bk26/drivers/net/e1000/e1000_param.c
--- linux-2.4.22-bk25/drivers/net/e1000/e1000_param.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/e1000/e1000_param.c	2003-09-29 02:49:41.000000000 -0700
@@ -140,7 +140,7 @@
  * Valid Range: 0, 1
  *  - 0 - disables all checksum offload
  *  - 1 - enables receive IP/TCP/UDP checksum offload
- *        on 82543 based NICs
+ *        on 82543 and newer -based NICs
  *
  * Default Value: 1
  */
@@ -458,6 +458,7 @@
 
 	switch(adapter->hw.media_type) {
 	case e1000_media_type_fiber:
+	case e1000_media_type_internal_serdes:
 		e1000_check_fiber_options(adapter);
 		break;
 	case e1000_media_type_copper:
@@ -601,7 +602,7 @@
 
 	switch (speed + dplx) {
 	case 0:
-		adapter->hw.autoneg = 1;
+		adapter->hw.autoneg = adapter->fc_autoneg = 1;
 		if(Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET)
 			printk(KERN_INFO
 			       "Speed and duplex autonegotiation enabled\n");
@@ -609,14 +610,14 @@
 	case HALF_DUPLEX:
 		printk(KERN_INFO "Half Duplex specified without Speed\n");
 		printk(KERN_INFO "Using Autonegotiation at Half Duplex only\n");
-		adapter->hw.autoneg = 1;
+		adapter->hw.autoneg = adapter->fc_autoneg = 1;
 		adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
 		                                 ADVERTISE_100_HALF;
 		break;
 	case FULL_DUPLEX:
 		printk(KERN_INFO "Full Duplex specified without Speed\n");
 		printk(KERN_INFO "Using Autonegotiation at Full Duplex only\n");
-		adapter->hw.autoneg = 1;
+		adapter->hw.autoneg = adapter->fc_autoneg = 1;
 		adapter->hw.autoneg_advertised = ADVERTISE_10_FULL |
 		                                 ADVERTISE_100_FULL |
 		                                 ADVERTISE_1000_FULL;
@@ -624,38 +625,38 @@
 	case SPEED_10:
 		printk(KERN_INFO "10 Mbps Speed specified without Duplex\n");
 		printk(KERN_INFO "Using Autonegotiation at 10 Mbps only\n");
-		adapter->hw.autoneg = 1;
+		adapter->hw.autoneg = adapter->fc_autoneg = 1;
 		adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
 		                                 ADVERTISE_10_FULL;
 		break;
 	case SPEED_10 + HALF_DUPLEX:
 		printk(KERN_INFO "Forcing to 10 Mbps Half Duplex\n");
-		adapter->hw.autoneg = 0;
+		adapter->hw.autoneg = adapter->fc_autoneg = 0;
 		adapter->hw.forced_speed_duplex = e1000_10_half;
 		adapter->hw.autoneg_advertised = 0;
 		break;
 	case SPEED_10 + FULL_DUPLEX:
 		printk(KERN_INFO "Forcing to 10 Mbps Full Duplex\n");
-		adapter->hw.autoneg = 0;
+		adapter->hw.autoneg = adapter->fc_autoneg = 0;
 		adapter->hw.forced_speed_duplex = e1000_10_full;
 		adapter->hw.autoneg_advertised = 0;
 		break;
 	case SPEED_100:
 		printk(KERN_INFO "100 Mbps Speed specified without Duplex\n");
 		printk(KERN_INFO "Using Autonegotiation at 100 Mbps only\n");
-		adapter->hw.autoneg = 1;
+		adapter->hw.autoneg = adapter->fc_autoneg = 1;
 		adapter->hw.autoneg_advertised = ADVERTISE_100_HALF |
 		                                 ADVERTISE_100_FULL;
 		break;
 	case SPEED_100 + HALF_DUPLEX:
 		printk(KERN_INFO "Forcing to 100 Mbps Half Duplex\n");
-		adapter->hw.autoneg = 0;
+		adapter->hw.autoneg = adapter->fc_autoneg = 0;
 		adapter->hw.forced_speed_duplex = e1000_100_half;
 		adapter->hw.autoneg_advertised = 0;
 		break;
 	case SPEED_100 + FULL_DUPLEX:
 		printk(KERN_INFO "Forcing to 100 Mbps Full Duplex\n");
-		adapter->hw.autoneg = 0;
+		adapter->hw.autoneg = adapter->fc_autoneg = 0;
 		adapter->hw.forced_speed_duplex = e1000_100_full;
 		adapter->hw.autoneg_advertised = 0;
 		break;
@@ -663,20 +664,20 @@
 		printk(KERN_INFO "1000 Mbps Speed specified without Duplex\n");
 		printk(KERN_INFO
 		       "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
-		adapter->hw.autoneg = 1;
+		adapter->hw.autoneg = adapter->fc_autoneg = 1;
 		adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
 		break;
 	case SPEED_1000 + HALF_DUPLEX:
 		printk(KERN_INFO "Half Duplex is not supported at 1000 Mbps\n");
 		printk(KERN_INFO
 		       "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
-		adapter->hw.autoneg = 1;
+		adapter->hw.autoneg = adapter->fc_autoneg = 1;
 		adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
 		break;
 	case SPEED_1000 + FULL_DUPLEX:
 		printk(KERN_INFO
 		       "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
-		adapter->hw.autoneg = 1;
+		adapter->hw.autoneg = adapter->fc_autoneg = 1;
 		adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
 		break;
 	default:
diff -urN linux-2.4.22-bk25/drivers/net/ibm_emac/ibm_emac.h linux-2.4.22-bk26/drivers/net/ibm_emac/ibm_emac.h
--- linux-2.4.22-bk25/drivers/net/ibm_emac/ibm_emac.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/ibm_emac/ibm_emac.h	2003-09-29 02:49:41.000000000 -0700
@@ -85,22 +85,52 @@
 #define EMAC_M1_IST			0x01000000
 #define EMAC_M1_MF_1000MBPS		0x00800000	/* 0's for 10MBPS */
 #define EMAC_M1_MF_100MBPS		0x00400000
+#define EMAC_M1_TR			0x00008000
+#ifdef CONFIG_IBM_EMAC4
+#define EMAC_M1_RFS_16K                 0x00280000	/* 000 for 512 byte */
+#define EMAC_M1_RFS_8K                  0x00200000
+#define EMAC_M1_RFS_4K                  0x00180000
+#define EMAC_M1_RFS_2K                  0x00100000
+#define EMAC_M1_RFS_1K                  0x00080000
+#define EMAC_M1_TX_FIFO_16K             0x00050000	/* 0's for 512 byte */
+#define EMAC_M1_TX_FIFO_8K              0x00040000
+#define EMAC_M1_TX_FIFO_4K              0x00030000
+#define EMAC_M1_TX_FIFO_2K              0x00020000
+#define EMAC_M1_TX_FIFO_1K              0x00010000
+#define EMAC_M1_TX_MWSW                 0x00001000	/* 0 wait for status */
+#define EMAC_M1_JUMBO_ENABLE            0x00000800	/* Upt to 9Kr status */
+#define EMAC_M1_OPB_CLK_66              0x00000010	/* 66Mhz */
+#define EMAC_M1_OPB_CLK_83              0x00000008	/* 83hz */
+#define EMAC_M1_OPB_CLK_100             0x00000018	/* 100Mhz */
+#define EMAC_M1_OPB_CLK_100P            0x00000020	/* 100Mhz+ */
+#else /* CONFIG_IBM_EMAC4 */
 #define EMAC_M1_RFS_4K			0x00300000	/* ~4k for 512 byte */
 #define EMAC_M1_RFS_2K			0x00200000
 #define EMAC_M1_RFS_1K			0x00100000
 #define EMAC_M1_TX_FIFO_2K		0x00080000	/* 0's for 512 byte */
 #define EMAC_M1_TX_FIFO_1K		0x00040000
 #define EMAC_M1_TR0_DEPEND		0x00010000	/* 0'x for single packet */
-#define EMAC_M1_TR0_MULTI		0x00008000
 #define EMAC_M1_TR1_DEPEND		0x00004000
 #define EMAC_M1_TR1_MULTI		0x00002000
 #define EMAC_M1_JUMBO_ENABLE		0x00001000
+#endif /* CONFIG_IBM_EMAC4 */
+#define EMAC_M1_BASE			(EMAC_M1_RFS_4K | \
+					EMAC_M1_TX_FIFO_2K | \
+					EMAC_M1_APP | \
+					EMAC_M1_TR)
 
 /* Transmit Mode Register 0 */
-#define EMAC_TXM0_GNP0			0x80000000
-#define EMAC_TXM0_GNP1			0x40000000
-#define EMAC_TXM0_GNPD			0x20000000
-#define EMAC_TXM0_FC			0x10000000
+#define EMAC_TMR0_GNP0			0x80000000
+#define EMAC_TMR0_GNP1			0x40000000
+#define EMAC_TMR0_GNPD			0x20000000
+#define EMAC_TMR0_FC			0x10000000
+#define EMAC_TMR0_TFAE_2_32		0x00000001
+#define EMAC_TMR0_TFAE_4_64		0x00000002
+#define EMAC_TMR0_TFAE_8_128		0x00000003
+#define EMAC_TMR0_TFAE_16_256		0x00000004
+#define EMAC_TMR0_TFAE_32_512		0x00000005
+#define EMAC_TMR0_TFAE_64_1024		0x00000006
+#define EMAC_TMR0_TFAE_128_2048		0x00000007
 
 /* Receive Mode Register */
 #define EMAC_RMR_SP			0x80000000
@@ -116,6 +146,14 @@
 #define EMAC_RMR_MIAE			0x00200000
 #define EMAC_RMR_BAE			0x00100000
 #define EMAC_RMR_MAE			0x00080000
+#define EMAC_RMR_RFAF_2_32		0x00000001
+#define EMAC_RMR_RFAF_4_64		0x00000002
+#define EMAC_RMR_RFAF_8_128		0x00000003
+#define EMAC_RMR_RFAF_16_256		0x00000004
+#define EMAC_RMR_RFAF_32_512		0x00000005
+#define EMAC_RMR_RFAF_64_1024		0x00000006
+#define EMAC_RMR_RFAF_128_2048		0x00000007
+#define EMAC_RMR_BASE			(EMAC_RMR_IAE | EMAC_RMR_BAE)
 
 /* Interrupt Status & enable Regs */
 #define EMAC_ISR_OVR			0x02000000
@@ -148,11 +186,11 @@
 #define EMAC_STACR_CLK_100MHZ		0x00000C00
 
 /* Transmit Request Threshold Register */
-#define EMAC_TRTR_256			0x18000000	/* 0's for 64 Bytes */
+#define EMAC_TRTR_1600			0x18000000	/* 0's for 64 Bytes */
+#define EMAC_TRTR_256			0x03000000
 #define EMAC_TRTR_192			0x10000000
 #define EMAC_TRTR_128			0x01000000
 
-
 #define EMAC_TX_CTRL_GFCS		0x0200
 #define EMAC_TX_CTRL_GP			0x0100
 #define EMAC_TX_CTRL_ISA		0x0080
@@ -176,8 +214,6 @@
 #define EMAC_TX_ST_UR			0x0002
 #define EMAC_TX_ST_SQE			0x0001
 
-#define EMAC_TX_ST_DEFAULT		0x03F3
-
 /* madmal receive status / Control bits */
 #define EMAC_RX_ST_OE			0x0200
 #define EMAC_RX_ST_PP			0x0100
@@ -191,5 +227,36 @@
 #define EMAC_RX_ST_IRE			0x0001
 #define EMAC_BAD_RX_PACKET		0x02ff
 
+/* Revision specific EMAC register defaults */
+#ifdef CONFIG_IBM_EMAC4
+#define EMAC_M1_DEFAULT			(EMAC_M1_BASE | \
+					EMAC_M1_OPB_CLK_66 | \
+					EMAC_M1_TX_MWSW)
+#define EMAC_RMR_DEFAULT		(EMAC_RMR_BASE | \
+					EMAC_RMR_RFAF_128_2048)
+#define EMAC_TMR0_XMIT			(EMAC_TMR0_GNP0 | \
+					EMAC_TMR0_TFAE_128_2048)
+#define EMAC_TRTR_DEFAULT		EMAC_TRTR_256
+#else /* !CONFIG_IBM_EMAC4 */
+#define EMAC_M1_DEFAULT			EMAC_M1_BASE
+#define EMAC_RMR_DEFAULT		EMAC_RMR_BASE
+#define EMAC_TMR0_XMIT			EMAC_TMR0_GNP0
+#define EMAC_TRTR_DEFAULT		EMAC_TRTR_1600
+#endif /* CONFIG_IBM_EMAC4 */
+
+/* SoC implementation specific EMAC register defaults */
+#if defined(CONFIG_440GP)
+#define EMAC_RWMR_DEFAULT		0x80009000
+#define EMAC_TMR0_DEFAULT		0x00000000
+#define EMAC_TMR1_DEFAULT		0xf8640000
+#elif defined(CONFIG_440GX)
+#define EMAC_RWMR_DEFAULT		0x1000a200
+#define EMAC_TMR0_DEFAULT		EMAC_TMR0_TFAE_128_2048
+#define EMAC_TMR1_DEFAULT		0x88810000
+#else
+#define EMAC_RWMR_DEFAULT		0x0f002000
+#define EMAC_TMR0_DEFAULT		0x00000000
+#define EMAC_TMR1_DEFAULT		0x380f0000
+#endif /* CONFIG_440GP */
 
 #endif
diff -urN linux-2.4.22-bk25/drivers/net/ibm_emac/ibm_ocp_enet.c linux-2.4.22-bk26/drivers/net/ibm_emac/ibm_ocp_enet.c
--- linux-2.4.22-bk25/drivers/net/ibm_emac/ibm_ocp_enet.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/ibm_emac/ibm_ocp_enet.c	2003-09-29 02:49:41.000000000 -0700
@@ -674,7 +674,7 @@
 	fep->tx_desc[fep->tx_slot].ctrl = ctrl;
 
 	/* Send the packet out. */
-	out_be32(&emacp->em0tmr0, EMAC_TXM0_GNP0);
+	out_be32(&emacp->em0tmr0, EMAC_TMR0_XMIT);
 
 	if (++fep->tx_slot == NUM_TX_BUFF)
 		fep->tx_slot = 0;
@@ -699,10 +699,9 @@
 	full_duplex = 0;
 	speed = SPEED_10;
 
-	/* set receive fifo to 4k and tx fifo to 2k */
-	mode_reg = EMAC_M1_RFS_4K | EMAC_M1_TX_FIFO_2K | EMAC_M1_APP |
-	    EMAC_M1_TR0_MULTI;
-       
+	/* set mode register 1 defaults */
+	mode_reg = EMAC_M1_DEFAULT;
+
 	/* Read link mode on PHY */
     	if (fep->phy_mii.def->ops->read_link(&fep->phy_mii) == 0) {
 	        /* If an error occurred, we don't deal with it yet */
@@ -871,26 +870,19 @@
 	if (netif_carrier_ok(fep->ndev))
 	    emac_adjust_to_link(fep);
 
-	/* enable broadcast and individual address */
-	out_be32(&emacp->em0rmr, EMAC_RMR_IAE | EMAC_RMR_BAE);
+	/* enable broadcast/individual address and RX FIFO defaults */
+	out_be32(&emacp->em0rmr, EMAC_RMR_DEFAULT);
 
+	/* set transmit request threshold register */
+	out_be32(&emacp->em0trtr, EMAC_TRTR_DEFAULT);
 
         /* Reconfigure multicast */
         __emac_set_multicast_list(fep->ndev);
 
-	/* set transmit request threshold register */
-	out_be32(&emacp->em0trtr, EMAC_TRTR_256);
-
-
-	/* set receive low/high water mark register */
-#ifdef CONFIG_440
-	/* 440GP has a 64 byte burst length */
-	out_be32(&emacp->em0rwmr, 0x80009000);
-	out_be32(&emacp->em0tmr1, 0xf8640000);
-#else
-	/* 405s have a 16 byte burst length */
-	out_be32(&emacp->em0rwmr, 0x0f002000);
-#endif				/* CONFIG_440 */
+	/* Set receiver/transmitter defaults */
+	out_be32(&emacp->em0rwmr, EMAC_RWMR_DEFAULT);
+	out_be32(&emacp->em0tmr0, EMAC_TMR0_DEFAULT);
+	out_be32(&emacp->em0tmr1, EMAC_TMR1_DEFAULT);
 
 	/* set frame gap */
 	out_be32(&emacp->em0ipgvr, CONFIG_IBM_OCP_ENET_GAP);
@@ -989,7 +981,8 @@
                  * latency peaks caused by this code
                  */
                 emac_reset_configure(fep);
-                emac_kick(fep);
+		if (fep->opened)
+                	emac_kick(fep);
 	} else {
 	        fep->timer_ticks = 0;
 	        netif_carrier_off(fep->ndev);
diff -urN linux-2.4.22-bk25/drivers/net/ibm_emac/ibm_ocp_mal.c linux-2.4.22-bk26/drivers/net/ibm_emac/ibm_ocp_mal.c
--- linux-2.4.22-bk25/drivers/net/ibm_emac/ibm_ocp_mal.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/ibm_emac/ibm_ocp_mal.c	2003-09-29 02:49:41.000000000 -0700
@@ -103,17 +103,17 @@
 	case 0:
 		set_mal_dcrn(mal, DCRN_MALRCBS0, size);
 		break;
-#ifdef DCRN_RCBS1
+#ifdef DCRN_MALRCBS1
 	case 1:
 		set_mal_dcrn(mal, DCRN_MALRCBS1, size);
 		break;
 #endif
-#ifdef DCRN_RCBS2
+#ifdef DCRN_MALRCBS2
 	case 2:
 		set_mal_dcrn(mal, DCRN_MALRCBS2, size);
 		break;
 #endif
-#ifdef DCRN_RCBS3
+#ifdef DCRN_MALRCBS3
 	case 3:
 		set_mal_dcrn(mal, DCRN_MALRCBS3, size);
 		break;
diff -urN linux-2.4.22-bk25/drivers/net/tlan.c linux-2.4.22-bk26/drivers/net/tlan.c
--- linux-2.4.22-bk25/drivers/net/tlan.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/tlan.c	2003-09-29 02:49:41.000000000 -0700
@@ -881,7 +881,9 @@
 			err );
 	}
 	dev->addr_len = 6;
-	
+
+	netif_carrier_off(dev);
+
 	/* Device methods */
 	dev->open = &TLan_Open;
 	dev->hard_start_xmit = &TLan_StartTx;
@@ -2205,6 +2207,8 @@
 
 	priv->tlanFullDuplex = FALSE;
 	priv->phyOnline=0;
+	netif_carrier_off(dev);
+
 /*  1.	Assert reset bit. */
 
 	data = inl(dev->base_addr + TLAN_HOST_CMD);
@@ -2368,6 +2372,7 @@
 		}
 		outl( priv->rxListDMA, dev->base_addr + TLAN_CH_PARM );
 		outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
+		netif_carrier_on(dev);
 	} else {
 		printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name );
 		TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
diff -urN linux-2.4.22-bk25/drivers/net/wireless/airo.c linux-2.4.22-bk26/drivers/net/wireless/airo.c
--- linux-2.4.22-bk25/drivers/net/wireless/airo.c	2003-09-29 02:49:38.000000000 -0700
+++ linux-2.4.22-bk26/drivers/net/wireless/airo.c	2003-09-29 02:49:41.000000000 -0700
@@ -202,7 +202,7 @@
 #ifndef RUN_AT
 #define RUN_AT(x) (jiffies+(x))
 #endif
-#if LINUX_VERSION_CODE < 0x020500
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23)
 static inline struct proc_dir_entry *PDE(const struct inode *inode)
 {
 	return inode->u.generic_ip;
diff -urN linux-2.4.22-bk25/include/asm-ppc/commproc.h linux-2.4.22-bk26/include/asm-ppc/commproc.h
--- linux-2.4.22-bk25/include/asm-ppc/commproc.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-ppc/commproc.h	2003-09-29 02:49:41.000000000 -0700
@@ -466,6 +466,23 @@
 #define SICR_ENET_CLKRT	((uint)0x0000003d)
 #endif	/* CONFIG_RPXCLASSIC */
 
+/***  D-BOX2  ***********************************************/
+
+#ifdef CONFIG_DBOX2
+
+#define PA_ENET_RXD	((ushort)0x0004)
+#define PA_ENET_TXD	((ushort)0x0008)
+#define PA_ENET_RCLK	((ushort)0x0200)
+#define PA_ENET_TCLK	((ushort)0x0800)
+
+#define PC_ENET_TENA	((ushort)0x0002)
+#define PC_ENET_CLSN	((ushort)0x0040)
+#define PC_ENET_RENA	((ushort)0x0080)
+
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00003d00)
+#endif	/* CONFIG_DBOX2 */
+
 /***  TQM823L, TQM850L  ***********************************************/
 
 #if defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L)
diff -urN linux-2.4.22-bk25/include/asm-ppc/highmem.h linux-2.4.22-bk26/include/asm-ppc/highmem.h
--- linux-2.4.22-bk25/include/asm-ppc/highmem.h	2003-09-29 02:49:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-ppc/highmem.h	2003-09-29 02:49:41.000000000 -0700
@@ -41,7 +41,7 @@
  * easily, subsequent pte tables have to be allocated in one physical
  * chunk of RAM.
  */
-#define PKMAP_BASE	(0xfe000000UL)
+#define PKMAP_BASE	CONFIG_HIGHMEM_START
 #define LAST_PKMAP	PTRS_PER_PTE
 #define LAST_PKMAP_MASK (LAST_PKMAP-1)
 #define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
diff -urN linux-2.4.22-bk25/include/asm-ppc/mpc8xx.h linux-2.4.22-bk26/include/asm-ppc/mpc8xx.h
--- linux-2.4.22-bk25/include/asm-ppc/mpc8xx.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-ppc/mpc8xx.h	2003-09-29 02:49:41.000000000 -0700
@@ -32,6 +32,10 @@
 #include <platforms/rpxclassic.h>
 #endif
 
+#ifdef CONFIG_DBOX2
+#include <platforms/dbox2.h>
+#endif
+
 #if defined(CONFIG_TQM8xxL)
 #include <platforms/tqm8xx.h>
 #endif
diff -urN linux-2.4.22-bk25/include/asm-ppc/page.h linux-2.4.22-bk26/include/asm-ppc/page.h
--- linux-2.4.22-bk25/include/asm-ppc/page.h	2003-09-29 02:49:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-ppc/page.h	2003-09-29 02:49:41.000000000 -0700
@@ -13,8 +13,7 @@
 #ifdef __KERNEL__
 #include <linux/config.h>
 
-/* Be sure to change arch/ppc/Makefile to match */
-#define PAGE_OFFSET	0xc0000000
+#define PAGE_OFFSET	CONFIG_KERNEL_START
 #define KERNELBASE	PAGE_OFFSET
 
 #ifndef __ASSEMBLY__
diff -urN linux-2.4.22-bk25/include/asm-ppc/pgtable.h linux-2.4.22-bk26/include/asm-ppc/pgtable.h
--- linux-2.4.22-bk25/include/asm-ppc/pgtable.h	2003-09-29 02:49:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-ppc/pgtable.h	2003-09-29 02:49:41.000000000 -0700
@@ -279,7 +279,7 @@
 #define	_PAGE_WRITETHRU	0x00000800		/* H: W bit */
 
 /* TODO: Add large page lowmem mapping support */
-#define _PMD_PRESENT	0
+#define _PMD_PRESENT	PAGE_MASK
 #define _PMD_PRESENT_MASK (PAGE_MASK)
 #define _PMD_BAD	(~PAGE_MASK)
 
diff -urN linux-2.4.22-bk25/include/asm-ppc/processor.h linux-2.4.22-bk26/include/asm-ppc/processor.h
--- linux-2.4.22-bk25/include/asm-ppc/processor.h	2003-09-29 02:49:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-ppc/processor.h	2003-09-29 02:49:41.000000000 -0700
@@ -797,7 +797,7 @@
  * as soon as I get around to remapping the io areas with the BATs
  * to match the mac we can raise this. -- Cort
  */
-#define TASK_SIZE	(0x80000000UL)
+#define TASK_SIZE	CONFIG_TASK_SIZE
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
diff -urN linux-2.4.22-bk25/include/asm-ppc/uaccess.h linux-2.4.22-bk26/include/asm-ppc/uaccess.h
--- linux-2.4.22-bk25/include/asm-ppc/uaccess.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-ppc/uaccess.h	2003-09-29 02:49:41.000000000 -0700
@@ -77,16 +77,28 @@
  * As we use the same address space for kernel and user data on the
  * PowerPC, we can just do these as direct assignments.  (Of course, the
  * exception handling means that it's no longer "just"...)
+ *
+ * The "user64" versions of the user access functions are versions that 
+ * allow access of 64-bit data. The "get_user" functions do not 
+ * properly handle 64-bit data because the value gets down cast to a long. 
+ * The "put_user" functions already handle 64-bit data properly but we add 
+ * "user64" versions for completeness
  */
 #define get_user(x,ptr) \
   __get_user_check((x),(ptr),sizeof(*(ptr)))
+#define get_user64(x,ptr) \
+  __get_user64_check((x),(ptr),sizeof(*(ptr)))
 #define put_user(x,ptr) \
   __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define put_user64(x,ptr) put_user(x,ptr)
 
 #define __get_user(x,ptr) \
   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __get_user64(x,ptr) \
+  __get_user64_nocheck((x),(ptr),sizeof(*(ptr)))
 #define __put_user(x,ptr) \
   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define __put_user64(x,ptr) __put_user(x,ptr)
 
 extern long __put_user_bad(void);
 
@@ -166,6 +178,15 @@
 	__gu_err;						\
 })
 
+#define __get_user64_nocheck(x,ptr,size)			\
+({								\
+	long __gu_err;						\
+	long long __gu_val;					\
+	__get_user_size64(__gu_val,(ptr),(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;			\
+	__gu_err;						\
+})
+
 #define __get_user_check(x,ptr,size)					\
 ({									\
 	long __gu_err = -EFAULT, __gu_val = 0;				\
@@ -176,6 +197,17 @@
 	__gu_err;							\
 })
 
+#define __get_user64_check(x,ptr,size)					\
+({									\
+	long __gu_err = -EFAULT;					\
+	long long __gu_val = 0;						\
+	const __typeof__(*(ptr)) *__gu_addr = (ptr);			\
+	if (access_ok(VERIFY_READ,__gu_addr,size))			\
+		__get_user_size64(__gu_val,__gu_addr,(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	__gu_err;							\
+})
+
 extern long __get_user_bad(void);
 
 #define __get_user_size(x,ptr,size,retval)			\
@@ -185,6 +217,17 @@
 	  case 1: __get_user_asm(x,ptr,retval,"lbz"); break;	\
 	  case 2: __get_user_asm(x,ptr,retval,"lhz"); break;	\
 	  case 4: __get_user_asm(x,ptr,retval,"lwz"); break;	\
+	  default: (x) = __get_user_bad();			\
+	}							\
+} while (0)
+
+#define __get_user_size64(x,ptr,size,retval)			\
+do {								\
+	retval = 0;						\
+	switch (size) {						\
+	  case 1: __get_user_asm(x,ptr,retval,"lbz"); break;	\
+	  case 2: __get_user_asm(x,ptr,retval,"lhz"); break;	\
+	  case 4: __get_user_asm(x,ptr,retval,"lwz"); break;	\
 	  case 8: __get_user_asm2(x, ptr, retval); break;	\
 	  default: (x) = __get_user_bad();			\
 	}							\
diff -urN linux-2.4.22-bk25/include/asm-x86_64/acpi.h linux-2.4.22-bk26/include/asm-x86_64/acpi.h
--- linux-2.4.22-bk25/include/asm-x86_64/acpi.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-x86_64/acpi.h	2003-09-29 02:49:42.000000000 -0700
@@ -115,7 +115,22 @@
 #endif
 #ifdef CONFIG_X86_IO_APIC
 extern int acpi_ioapic;
+extern int skip_ioapic_setup;
+
+static inline void disable_ioapic_setup(void)
+{
+	
+	skip_ioapic_setup = 1;
+}
+
+static inline int ioapic_setup_disabled(void)
+{
+	return skip_ioapic_setup;
+}
 #else
+static inline void disable_ioapic_setup(void)
+{ }
+
 #define acpi_ioapic 0
 #endif
 
@@ -142,6 +157,8 @@
 
 extern void mp_config_ioapic_for_sci(int irq);
 
+extern int use_acpi_pci;
+
 #endif /*__KERNEL__*/
 
 #endif /*_ASM_ACPI_H*/
diff -urN linux-2.4.22-bk25/include/asm-x86_64/calling.h linux-2.4.22-bk26/include/asm-x86_64/calling.h
--- linux-2.4.22-bk25/include/asm-x86_64/calling.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-bk26/include/asm-x86_64/calling.h	2003-09-29 02:49:42.000000000 -0700
@@ -8,7 +8,7 @@
 #define R14 8
 #define R13 16
 #define R12 24
-#define RBP 36
+#define RBP 32
 #define RBX 40
 /* arguments: interrupts/non tracing syscalls only save upto here*/
 #define R11 48
diff -urN linux-2.4.22-bk25/include/asm-x86_64/cpufeature.h linux-2.4.22-bk26/include/asm-x86_64/cpufeature.h
--- linux-2.4.22-bk25/include/asm-x86_64/cpufeature.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-bk26/include/asm-x86_64/cpufeature.h	2003-09-29 02:49:42.000000000 -0700
@@ -63,6 +63,26 @@
 #define X86_FEATURE_CYRIX_ARR	(3*32+ 2) /* Cyrix ARRs (= MTRRs) */
 #define X86_FEATURE_CENTAUR_MCR	(3*32+ 3) /* Centaur MCRs (= MTRRs) */
 
+#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
+#define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
+
+#define cpu_has_pge 1
+#define cpu_has_pse 1
+#define cpu_has_pae 1
+#define cpu_has_tsc 1
+#define cpu_has_de 1
+#define cpu_has_vme 1
+#define cpu_has_fxsr 1
+#define cpu_has_xmm 1
+#define cpu_has_apic 		boot_cpu_has(X86_FEATURE_APIC)
+#define cpu_has_ht 0 
+#define cpu_has_mp             boot_cpu_has(X86_FEATURE_MP)
+#define cpu_has_k6_mtrr 0
+#define cpu_has_cyrix_arr 0
+#define cpu_has_centaur_mcr 0
+#define cpu_has_mmx 0
+#define cpu_has_fpu 1
+
 #endif /* __ASM_X8664_CPUFEATURE_H */
 
 /* 
diff -urN linux-2.4.22-bk25/include/asm-x86_64/hardirq.h linux-2.4.22-bk26/include/asm-x86_64/hardirq.h
--- linux-2.4.22-bk25/include/asm-x86_64/hardirq.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-bk26/include/asm-x86_64/hardirq.h	2003-09-29 02:49:42.000000000 -0700
@@ -67,6 +67,8 @@
 {
 	++local_irq_count(cpu);
 
+	smp_mb();
+	
 	while (test_bit(0,&global_irq_lock)) {
 		cpu_relax();
 	}
diff -urN linux-2.4.22-bk25/include/asm-x86_64/ia32.h linux-2.4.22-bk26/include/asm-x86_64/ia32.h
--- linux-2.4.22-bk25/include/asm-x86_64/ia32.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-x86_64/ia32.h	2003-09-29 02:49:42.000000000 -0700
@@ -234,6 +234,11 @@
 	int iov_len; 
 };
 
+struct timespec32 {
+	int 	tv_sec;
+	int	tv_nsec;
+};
+
 #endif /* !CONFIG_IA32_SUPPORT */
  
 #endif 
diff -urN linux-2.4.22-bk25/include/asm-x86_64/kdebug.h linux-2.4.22-bk26/include/asm-x86_64/kdebug.h
--- linux-2.4.22-bk25/include/asm-x86_64/kdebug.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-x86_64/kdebug.h	2003-09-29 02:49:42.000000000 -0700
@@ -39,11 +39,13 @@
 	return notifier_call_chain(&die_chain, val, &args); 
 } 
 
-
 extern int printk_address(unsigned long address);
 extern void die(const char *,struct pt_regs *,long);
+extern void __die(const char *,struct pt_regs *,long);
 extern void show_stack(unsigned long* esp);
 extern void show_registers(struct pt_regs *regs);
 extern void dump_pagetable(unsigned long);
+extern void prepare_die(unsigned long *flags);
+extern void exit_die(unsigned long flags);
 
 #endif
diff -urN linux-2.4.22-bk25/include/asm-x86_64/pgalloc.h linux-2.4.22-bk26/include/asm-x86_64/pgalloc.h
--- linux-2.4.22-bk25/include/asm-x86_64/pgalloc.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-bk26/include/asm-x86_64/pgalloc.h	2003-09-29 02:49:42.000000000 -0700
@@ -204,7 +204,7 @@
 {
 	struct mm_struct *active_mm;
 	int state;
-};
+} ____cacheline_aligned;
 extern struct tlb_state cpu_tlbstate[NR_CPUS];
 
 
diff -urN linux-2.4.22-bk25/include/asm-x86_64/processor.h linux-2.4.22-bk26/include/asm-x86_64/processor.h
--- linux-2.4.22-bk25/include/asm-x86_64/processor.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-x86_64/processor.h	2003-09-29 02:49:42.000000000 -0700
@@ -17,6 +17,7 @@
 #include <asm/msr.h>
 #include <asm/current.h>
 #include <asm/system.h>
+#include <asm/cpufeature.h>
 
 #define TF_MASK		0x00000100
 #define IF_MASK		0x00000200
@@ -77,16 +78,6 @@
 #define current_cpu_data boot_cpu_data
 #endif
 
-#define cpu_has_pge 1
-#define cpu_has_pse 1
-#define cpu_has_pae 1
-#define cpu_has_tsc 1
-#define cpu_has_de 1
-#define cpu_has_vme 1
-#define cpu_has_fxsr 1
-#define cpu_has_xmm 1
-#define cpu_has_apic (test_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability))
-
 extern char ignore_irq13;
 
 extern void identify_cpu(struct cpuinfo_x86 *);
@@ -258,7 +249,9 @@
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_32 0xa0000000
+
+#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
+#define TASK_UNMAPPED_32 (IA32_PAGE_OFFSET / 3) 
 #define TASK_UNMAPPED_64 (TASK_SIZE/3) 
 #define TASK_UNMAPPED_BASE	\
 	((current->thread.flags & THREAD_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64)  
@@ -396,7 +389,7 @@
 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
 extern inline void rep_nop(void)
 {
-	__asm__ __volatile__("rep;nop");
+	__asm__ __volatile__("rep;nop":::"memory");
 }
 
 /* Avoid speculative execution by the CPU */
@@ -406,8 +399,6 @@
 	asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
 } 
 
-#define cpu_has_fpu 1
-
 #define ARCH_HAS_PREFETCH
 #define ARCH_HAS_PREFETCHW
 #define ARCH_HAS_SPINLOCK_PREFETCH
diff -urN linux-2.4.22-bk25/include/asm-x86_64/proto.h linux-2.4.22-bk26/include/asm-x86_64/proto.h
--- linux-2.4.22-bk25/include/asm-x86_64/proto.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-x86_64/proto.h	2003-09-29 02:49:42.000000000 -0700
@@ -43,6 +43,8 @@
 extern void __show_regs(struct pt_regs * regs);
 extern void show_regs(struct pt_regs * regs);
 
+extern int apic_disabled;
+extern int acpi_disabled;
 
 #define round_up(x,y) (((x) + (y) - 1) & ~((y)-1))
 #define round_down(x,y) ((x) & ~((y)-1))
diff -urN linux-2.4.22-bk25/include/asm-x86_64/ptrace.h linux-2.4.22-bk26/include/asm-x86_64/ptrace.h
--- linux-2.4.22-bk25/include/asm-x86_64/ptrace.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.22-bk26/include/asm-x86_64/ptrace.h	2003-09-29 02:49:42.000000000 -0700
@@ -6,7 +6,7 @@
 #define R14 8
 #define R13 16
 #define R12 24
-#define RBP 36
+#define RBP 32
 #define RBX 40
 /* arguments: interrupts/non tracing syscalls only save upto here*/
 #define R11 48
@@ -37,10 +37,6 @@
 /* options set using PTRACE_SETOPTIONS */
 #define PTRACE_O_TRACESYSGOOD     0x00000001
 
-/* Dummy values for ptrace */ 
-#define FS 1000 
-#define GS 1008
-
 #ifndef __ASSEMBLY__ 
 
 struct pt_regs {
diff -urN linux-2.4.22-bk25/include/asm-x86_64/system.h linux-2.4.22-bk26/include/asm-x86_64/system.h
--- linux-2.4.22-bk25/include/asm-x86_64/system.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-x86_64/system.h	2003-09-29 02:49:42.000000000 -0700
@@ -284,8 +284,8 @@
 #define sti() __global_sti()
 #define save_flags(x) ((x)=__global_save_flags())
 #define restore_flags(x) __global_restore_flags(x)
-#define save_and_cli(x) do { save_flags(x); cli(); } while(0);
-#define save_and_sti(x) do { save_flags(x); sti(); } while(0);
+#define save_and_cli(x) do { save_flags(x); cli(); } while(0)
+#define save_and_sti(x) do { save_flags(x); sti(); } while(0)
 
 #else
 
diff -urN linux-2.4.22-bk25/include/asm-x86_64/uaccess.h linux-2.4.22-bk26/include/asm-x86_64/uaccess.h
--- linux-2.4.22-bk25/include/asm-x86_64/uaccess.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-x86_64/uaccess.h	2003-09-29 02:49:42.000000000 -0700
@@ -254,12 +254,12 @@
 	case 10:
 	       	__get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
 		if (ret) return ret;
-		__get_user_asm(*(u16*)(8+dst),(u16*)(8+src),ret,"w","w","=r",2);
+		__get_user_asm(*(u16*)(8+(char*)dst),(u16*)(8+(char*)src),ret,"w","w","=r",2);
 		return ret; 
 	case 16:
 		__get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
 		if (ret) return ret;
-		__get_user_asm(*(u64*)(8+dst),(u64*)(8+src),ret,"q","","=r",8);
+		__get_user_asm(*(u64*)(8+(char*)dst),(u64*)(8+(char*)src),ret,"q","","=r",8);
 		return ret; 
 	default:
 		return copy_user_generic(dst,src,size); 
diff -urN linux-2.4.22-bk25/include/asm-x86_64/unistd.h linux-2.4.22-bk26/include/asm-x86_64/unistd.h
--- linux-2.4.22-bk25/include/asm-x86_64/unistd.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.22-bk26/include/asm-x86_64/unistd.h	2003-09-29 02:49:42.000000000 -0700
@@ -462,7 +462,7 @@
 #define __NR_tkill	200	/* 2.5 only */
 __SYSCALL(__NR_tkill, sys_ni_syscall) 
 #define __NR_time		201
-__SYSCALL(__NR_time, sys_time)
+__SYSCALL(__NR_time, sys_time64)
 #define __NR_futex		202 /* 2.5 only */
 __SYSCALL(__NR_futex, sys_ni_syscall)
 #define __NR_sched_setaffinity    203
@@ -495,8 +495,12 @@
 __SYSCALL(__NR_remap_file_pages, sys_ni_syscall)
 #define __NR_getdents64 217
 __SYSCALL(__NR_getdents64, sys_getdents64)
+#define __NR_restart_syscall	219
+__SYSCALL(__NR_restart_syscall, sys_ni_syscall)
+#define __NR_semtimedop		220
+__SYSCALL(__NR_semtimedop, sys_semtimedop)
 
-#define __NR_syscall_max __NR_getdents64
+#define __NR_syscall_max __NR_semtimedop
 
 #ifndef __NO_STUBS
 
diff -urN linux-2.4.22-bk25/include/linux/agp_backend.h linux-2.4.22-bk26/include/linux/agp_backend.h
--- linux-2.4.22-bk25/include/linux/agp_backend.h	2003-09-29 02:49:38.000000000 -0700
+++ linux-2.4.22-bk26/include/linux/agp_backend.h	2003-09-29 02:49:42.000000000 -0700
@@ -92,6 +92,7 @@
 	SVWRKS_GENERIC,
 	NVIDIA_NFORCE,
 	NVIDIA_NFORCE2,
+	NVIDIA_NFORCE3,
 	NVIDIA_GENERIC,
 	HP_ZX1,
 	ATI_RS100,
diff -urN linux-2.4.22-bk25/include/linux/pci_ids.h linux-2.4.22-bk26/include/linux/pci_ids.h
--- linux-2.4.22-bk25/include/linux/pci_ids.h	2003-09-29 02:49:38.000000000 -0700
+++ linux-2.4.22-bk26/include/linux/pci_ids.h	2003-09-29 02:49:42.000000000 -0700
@@ -559,6 +559,7 @@
 #define PCI_DEVICE_ID_SI_750		0x0750
 #define PCI_DEVICE_ID_SI_751		0x0751
 #define PCI_DEVICE_ID_SI_752		0x0752
+#define PCI_DEVICE_ID_SI_755            0x0755
 #define PCI_DEVICE_ID_SI_900		0x0900
 #define PCI_DEVICE_ID_SI_5107		0x5107
 #define PCI_DEVICE_ID_SI_5300		0x5300
@@ -967,6 +968,7 @@
 #define PCI_DEVICE_ID_NVIDIA_UVTNT2		0x002D
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE	0x0065
 #define PCI_DEVICE_ID_NVIDIA_ITNT2		0x00A0
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3		0x00d1
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR	0x0100
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR	0x0101
 #define PCI_DEVICE_ID_NVIDIA_QUADRO		0x0103
@@ -1091,6 +1093,7 @@
 #define PCI_DEVICE_ID_VIA_P4X333	0x3168
 #define PCI_DEVICE_ID_VIA_8235		0x3177
 #define PCI_DEVICE_ID_VIA_8377_0	0x3189
+#define PCI_DEVICE_ID_VIA_K8T400M_0	0x3188
 #define PCI_DEVICE_ID_VIA_8237		0x3227
 #define PCI_DEVICE_ID_VIA_86C100A	0x6100
 #define PCI_DEVICE_ID_VIA_8231		0x8231
