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

diff -urN linux-2.4.24-pre1/CREDITS linux-2.4.24-pre2/CREDITS
--- linux-2.4.24-pre1/CREDITS	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/CREDITS	2003-12-22 11:34:32.000000000 -0800
@@ -2597,9 +2597,9 @@
 S: USA
 
 N: Luca Risolia
-E: luca_ing@libero.it
-D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chip
-S: Via LibertÃ  41/a
+E: luca.risolia@studio.unibo.it
+D: V4L driver for W996[87]CF JPEG USB Dual Mode Camera Chips
+S: Via Liberta' 41-A
 S: Osio Sotto, 24046, Bergamo
 S: Italy
 
@@ -2668,6 +2668,7 @@
 N: Aristeu Sergio Rozanski Filho
 E: aris@conectiva.com.br
 D: Support for EtherExpress 10 ISA (i82595) in eepro driver
+D: User level driver support for input
 S: Conectiva S.A.
 S: R. Tocantins, 89 - Cristo Rei
 S: 80050-430 - Curitiba - Paraná
diff -urN linux-2.4.24-pre1/Documentation/Configure.help linux-2.4.24-pre2/Documentation/Configure.help
--- linux-2.4.24-pre1/Documentation/Configure.help	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/Documentation/Configure.help	2003-12-22 11:34:32.000000000 -0800
@@ -11351,6 +11351,27 @@
 
   If unsure, say N here.
 
+Cyclades-PC300 support
+CONFIG_PC300
+  This is a driver for the Cyclades-PC300 synchronous communication
+  boards. These boards provide synchronous serial interfaces to your
+  Linux box (interfaces currently available are RS-232/V.35, X.21 and
+  T1/E1). If you wish to support Multilink PPP, please select the
+  option below this one and read the file README.mlppp provided by PC300
+  package.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called pc300.o.
+
+  If you haven't heard about it, it's safe to say N.
+
+Cyclades-PC300 Sync TTY (to MLPPP) support
+CONFIG_PC300_MLPPP
+  Say 'Y' to this option if you are planning to use Multilink PPP over the
+  PC300 synchronous communication boards.
+
 SDL RISCom/N2 support
 CONFIG_N2
   This driver is for RISCom/N2 single or dual channel ISA cards
@@ -11745,9 +11766,11 @@
 	    - 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 (Albatron)
 	    - 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 (Foxconn)
 	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
 	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
 	    - Marvell RDK-8001 Adapter
@@ -14929,6 +14952,15 @@
   accessible under char device 13:64+ - /dev/input/eventX in a generic
   way.  This is the future ...
 
+CONFIG_INPUT_UINPUT
+  Say Y here if you want to support user level drivers for input
+  subsystem accessible under char device 10:223 - /dev/input/uinput.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called uinput.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.	    
+
 USB Scanner support
 CONFIG_USB_SCANNER
   Say Y here if you want to connect a USB scanner to your computer's
@@ -15361,19 +15393,18 @@
 
   This driver has an optional plugin, which is distributed as a
   separate module only (released under GPL). It contains code that 
-  allows you to use higher resolutions and framerates, and can't
-  be included into the official Linux kernel for performance 
-  purposes.
-  At the moment the driver needs a third-part module for the CMOS 
+  allows you to use higher resolutions and framerates, and cannot
+  be included in the official Linux kernel for performance purposes.
+  At the moment the driver needs a third-party module for the CMOS 
   sensors, which is available on internet: it is recommended to read
   <file:Documentation/usb/w9968cf.txt> for more informations and for
   a list of supported cameras.
 
   This driver uses the Video For Linux and the I2C APIs. 
-  You must say Y or M to both "Video For Linux" and 
-  "I2C Support" to use this driver.
-  Information on this API and pointers to "v4l" programs may be found
-  on the WWW at <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
+  You must say Y or M to both "Video For Linux" and "I2C Support" 
+  to use this driver. Information on this API and pointers to "v4l" 
+  programs may be found on the WWW at 
+  <http://roadrunner.swansea.uk.linux.org/v4l.shtml>.
 
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -22988,7 +23019,7 @@
   kernel or say M to compile it as module (hci_usb.o).
 
 HCI USB SCO (voice) support
-CONFIG_BLUEZ_USB_SCO
+CONFIG_BLUEZ_HCIUSB_SCO
   This option enables the SCO support in the HCI USB driver. You need this
   to transmit voice data with your Bluetooth USB device. And your device
   must also support sending SCO data over the HCI layer, because some of
@@ -22996,14 +23027,6 @@
  
   Say Y here to compile support for HCI SCO data.
  
-HCI USB zero packet support
-CONFIG_BLUEZ_USB_ZERO_PACKET
-  This option is provided only as a work around for buggy Bluetooth USB 
-  devices. Do NOT enable it unless you know for sure that your device 
-  requires zero packets.
- 
-  Most people should say N here.
-
 HCI VHCI Virtual HCI device driver
 CONFIG_BLUEZ_HCIVHCI
   Bluetooth Virtual HCI device driver.
diff -urN linux-2.4.24-pre1/Documentation/devices.txt linux-2.4.24-pre2/Documentation/devices.txt
--- linux-2.4.24-pre1/Documentation/devices.txt	2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.24-pre2/Documentation/devices.txt	2003-12-22 11:34:32.000000000 -0800
@@ -419,6 +419,7 @@
 		220 = /dev/mptctl	Message passing technology (MPT) control
 		221 = /dev/mvista/hssdsi	Montavista PICMG hot swap system driver
 		222 = /dev/mvista/hasi		Montavista PICMG high availability
+		223 = /dev/input/uinput		User level driver support for input
 		240-255			Reserved for local use
 
  11 char	Raw keyboard device
diff -urN linux-2.4.24-pre1/Documentation/i2c/dev-interface linux-2.4.24-pre2/Documentation/i2c/dev-interface
--- linux-2.4.24-pre1/Documentation/i2c/dev-interface	2001-10-11 08:05:47.000000000 -0700
+++ linux-2.4.24-pre2/Documentation/i2c/dev-interface	2003-12-22 11:34:32.000000000 -0800
@@ -87,7 +87,7 @@
 
 ioctl(file,I2C_TENBIT,long select)
   Selects ten bit addresses if select not equals 0, selects normal 7 bit
-  addresses if select equals 0.
+  addresses if select equals 0. Default 0.
 
 ioctl(file,I2C_FUNCS,unsigned long *funcs)
   Gets the adapter functionality and puts it in *funcs.
diff -urN linux-2.4.24-pre1/Documentation/i2c/i2c-protocol linux-2.4.24-pre2/Documentation/i2c/i2c-protocol
--- linux-2.4.24-pre1/Documentation/i2c/i2c-protocol	2000-07-28 12:50:51.000000000 -0700
+++ linux-2.4.24-pre2/Documentation/i2c/i2c-protocol	2003-12-22 11:34:32.000000000 -0800
@@ -52,10 +52,10 @@
 We have found some I2C devices that needs the following modifications:
 
   Flag I2C_M_NOSTART: 
-    In a combined transaction, no 'S Addr' is generated at some point.
-    For example, setting I2C_M_NOSTART on the second partial message
+    In a combined transaction, no 'S Addr Wr/Rd [A]' is generated at some
+    point. For example, setting I2C_M_NOSTART on the second partial message
     generates something like:
-      S Addr Rd [A] [Data] NA Wr [A] Data [A] P
+      S Addr Rd [A] [Data] NA Data [A] P
     If you set the I2C_M_NOSTART variable for the first partial message,
     we do not generate Addr, but we do generate the startbit S. This will
     probably confuse all other clients on your bus, so don't try this.
@@ -65,4 +65,3 @@
     need to emit an Rd instead of a Wr, or vice versa, you set this
     flag. For example:
       S Addr Rd [A] Data [A] Data [A] ... [A] Data [A] P
-                      
diff -urN linux-2.4.24-pre1/Documentation/i2c/smbus-protocol linux-2.4.24-pre2/Documentation/i2c/smbus-protocol
--- linux-2.4.24-pre1/Documentation/i2c/smbus-protocol	2001-02-16 15:53:08.000000000 -0800
+++ linux-2.4.24-pre2/Documentation/i2c/smbus-protocol	2003-12-22 11:34:32.000000000 -0800
@@ -1,3 +1,10 @@
+SMBus Protocol Summary
+======================
+The following is a summary of the SMBus protocol. It applies to
+all revisions of the protocol (1.0, 1.1, and 2.0).
+Certain protocol features which are not supported by
+this package are briefly described at the end of this document.
+
 Some adapters understand only the SMBus (System Management Bus) protocol,
 which is a subset from the I2C protocol. Fortunately, many devices use
 only the same subset, which makes it possible to put them on an SMBus.
@@ -6,7 +13,7 @@
 I2C protocol). This makes it possible to use the device driver on both
 SMBus adapters and I2C adapters (the SMBus command set is automatically
 translated to I2C on I2C adapters, but plain I2C commands can not be
-handled at all on a pure SMBus adapter).
+handled at all on most pure SMBus adapters).
 
 Below is a list of SMBus commands.
 
@@ -54,7 +61,7 @@
 This is the reverse of Read Byte: it sends a single byte to a device.
 See Read Byte for more information.
 
-S Addr Wr [A] Data NA P
+S Addr Wr [A] Data [A] P
 
 
 SMBus Read Byte Data
@@ -109,7 +116,7 @@
 SMBus Block Read
 ================
 
-This command reads a block of upto 32 bytes from a device, from a 
+This command reads a block of up to 32 bytes from a device, from a 
 designated register that is specified through the Comm byte. The amount
 of data is specified by the device in the Count byte.
 
@@ -120,8 +127,90 @@
 SMBus Block Write
 =================
 
-The opposite of the Block Read command, this writes upto 32 bytes to 
+The opposite of the Block Read command, this writes up to 32 bytes to 
 a device, to a designated register that is specified through the
 Comm byte. The amount of data is specified in the Count byte.
 
 S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
+
+
+SMBus Block Process Call
+========================
+
+SMBus Block Process Call was introduced in Revision 2.0 of the specification.
+
+This command selects a device register (through the Comm byte), sends
+1 to 31 bytes of data to it, and reads 1 to 31 bytes of data in return.
+
+S Addr Wr [A] Comm [A] Count [A] Data [A] ...
+                             S Addr Rd [A] [Count] A [Data] ... NA P
+
+
+SMBus Host Notify
+=================
+
+This command is sent from a SMBus device acting as a master to the
+SMBus host acting as a slave.
+It is the same form as Write Word, with the command code replaced by the
+alerting device's address.
+
+[S] [HostAddr] [Wr] A [DevAddr] A [DataLow] A [DataHigh] A [P]
+
+
+Packet Error Checking (PEC)
+===========================
+Packet Error Checking was introduced in Revision 1.1 of the specification.
+
+PEC adds a CRC-8 error-checking byte to all transfers.
+
+
+Address Resolution Protocol (ARP)
+=================================
+The Address Resolution Protocol was introduced in Revision 2.0 of
+the specification. It is a higher-layer protocol which uses the
+messages above.
+
+ARP adds device enumeration and dynamic address assignment to
+the protocol. All ARP communications use slave address 0x61 and
+require PEC checksums.
+
+
+I2C Block Transactions
+======================
+The following I2C block transactions are supported by the
+SMBus layer and are described here for completeness.
+I2C block transactions do not limit the number of bytes transferred
+but the SMBus layer places a limit of 32 bytes.
+
+
+I2C Block Read
+==============
+
+This command reads a block of bytes from a device, from a 
+designated register that is specified through the Comm byte.
+
+S Addr Wr [A] Comm [A] 
+           S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
+
+
+I2C Block Read (2 Comm bytes)
+=============================
+
+This command reads a block of bytes from a device, from a 
+designated register that is specified through the two Comm bytes.
+
+S Addr Wr [A] Comm1 [A] Comm2 [A] 
+           S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
+
+
+I2C Block Write
+===============
+
+The opposite of the Block Read command, this writes bytes to 
+a device, to a designated register that is specified through the
+Comm byte. Note that command lengths of 0, 2, or more bytes are
+supported as they are indistinguishable from data.
+
+S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
+
+
diff -urN linux-2.4.24-pre1/Documentation/i2c/summary linux-2.4.24-pre2/Documentation/i2c/summary
--- linux-2.4.24-pre1/Documentation/i2c/summary	2001-10-11 08:05:47.000000000 -0700
+++ linux-2.4.24-pre2/Documentation/i2c/summary	2003-12-22 11:34:32.000000000 -0800
@@ -4,7 +4,7 @@
 =============
 
 I2C (pronounce: I squared C) is a protocol developed by Philips. It is a 
-slow two-wire protocol (10-100 kHz), but it suffices for many types of 
+slow two-wire protocol (10-400 kHz), but it suffices for many types of 
 devices.
 
 SMBus (System Management Bus) is a subset of the I2C protocol. Many
@@ -43,15 +43,15 @@
 
 Included Bus Drivers
 ====================
-Note that not only stable drivers are patched into the kernel by 'mkpatch'.
+Note that only stable drivers are patched into the kernel by 'mkpatch'.
 
 
 Base modules
 ------------
 
-i2c-core: The basic I2C code, including the /proc interface
-i2c-dev:  The /dev interface
-i2c-proc: The /proc interface for device (client) drivers
+i2c-core: The basic I2C code, including the /proc/bus/i2c* interface
+i2c-dev:  The /dev/i2c-* interface
+i2c-proc: The /proc/sys/dev/sensors interface for device (client) drivers
 
 Algorithm drivers
 -----------------
diff -urN linux-2.4.24-pre1/Documentation/i2c/writing-clients linux-2.4.24-pre2/Documentation/i2c/writing-clients
--- linux-2.4.24-pre1/Documentation/i2c/writing-clients	2001-10-11 08:05:47.000000000 -0700
+++ linux-2.4.24-pre2/Documentation/i2c/writing-clients	2003-12-22 11:34:32.000000000 -0800
@@ -365,7 +365,7 @@
 
 The detect client function is called by i2c_probe or i2c_detect.
 The `kind' parameter contains 0 if this call is due to a `force'
-parameter, and 0 otherwise (for i2c_detect, it contains 0 if
+parameter, and -1 otherwise (for i2c_detect, it contains 0 if
 this call is due to the generic `force' parameter, and the chip type
 number if it is due to a specific `force' parameter).
 
@@ -448,9 +448,9 @@
     /* Note that we reserve some space for foo_data too. If you don't
        need it, remove it. We do it here to help to lessen memory
        fragmentation. */
-    if (! (new_client = kmalloc(sizeof(struct i2c_client)) + 
+    if (! (new_client = kmalloc(sizeof(struct i2c_client) + 
                                 sizeof(struct foo_data),
-                                GFP_KERNEL)) {
+                                GFP_KERNEL))) {
       err = -ENOMEM;
       goto ERROR0;
     }
diff -urN linux-2.4.24-pre1/Documentation/i386/zero-page.txt linux-2.4.24-pre2/Documentation/i386/zero-page.txt
--- linux-2.4.24-pre1/Documentation/i386/zero-page.txt	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/Documentation/i386/zero-page.txt	2003-12-22 11:34:32.000000000 -0800
@@ -66,10 +66,12 @@
 0x21c	unsigned long	INITRD_SIZE, size in bytes of ramdisk image
 0x220	4 bytes		(setup.S)
 0x224	unsigned short	setup.S heap end pointer
-0x228	4 bytes		DISK80_SIG_BUFFER (setup.S)
+0x228	4 bytes		unknown, but writing this in setup.S makes
+			kernel fail to decompress on some systems
+0x2cc	4 bytes		DISK80_SIG_BUFFER (setup.S)
 0x2d0 - 0x600		E820MAP
-0x600 - 0x800		EDDBUF (setup.S) for disk signature read sector
-0x600 - 0x7d4		EDDBUF (setup.S)
+0x600 - 0x7ff		EDDBUF (setup.S) for disk signature read sector
+0x600 - 0x7de		EDDBUF (setup.S)
 
 0x800	string, 2K max	COMMAND_LINE, the kernel commandline as
 			copied using CL_OFFSET.
diff -urN linux-2.4.24-pre1/Documentation/networking/sk98lin.txt linux-2.4.24-pre2/Documentation/networking/sk98lin.txt
--- linux-2.4.24-pre1/Documentation/networking/sk98lin.txt	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/Documentation/networking/sk98lin.txt	2003-12-22 11:34:32.000000000 -0800
@@ -2,9 +2,9 @@
 All rights reserved
 ===========================================================================
 
-sk98lin.txt created 23-Sep-2003
+sk98lin.txt created 15-Dec-2003
 
-Readme File for sk98lin v6.18
+Readme File for sk98lin v6.21
 Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
 
 This file contains
@@ -466,7 +466,7 @@
 Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad. 
 These features are only available after installation of open source 
 modules available on the Internet:
-For VLAN go to: http://scry.wanfear.com/~greear/vlan.html
+For VLAN go to: http://www.candelatech.com/~greear/vlan.html
 For Link Aggregation go to: http://www.st.rim.or.jp/~yumo
 
 NOTE: SysKonnect GmbH does not offer any support for these open source 
diff -urN linux-2.4.24-pre1/Documentation/usb/w9968cf.txt linux-2.4.24-pre2/Documentation/usb/w9968cf.txt
--- linux-2.4.24-pre1/Documentation/usb/w9968cf.txt	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/Documentation/usb/w9968cf.txt	2003-12-22 11:34:32.000000000 -0800
@@ -1,6 +1,7 @@
 
-         W996[87]CF JPEG USB Dual Mode Camera Chip driver for Linux 2.4
-         ==============================================================
+                   W996[87]CF JPEG USB Dual Mode Camera Chip
+                        Linux 2.4 driver (basic version)
+                   =========================================
 
                                - Documentation -
 
@@ -11,7 +12,7 @@
 2. License
 3. Overview
 4. Supported devices
-5. Kernel configuration and third-part module compilation
+5. Module dependencies
 6. Module loading
 7. Module paramaters
 8. Credits
@@ -19,7 +20,7 @@
 
 1. Copyright
 ============
-Copyright (C) 2002 2003 by Luca Risolia <luca_ing@libero.it>
+Copyright (C) 2002 2003 by Luca Risolia <luca.risolia@studio.unibo.it>
 
 
 2. License
@@ -45,20 +46,23 @@
 Winbond W9967CF and Winbond W9968CF JPEG USB Dual Mode Camera Chips, when they
 are being commanded by USB.
 
-The driver relies on the Video4Linux, USB and I2C core modules of the Linux
-kernel, version 2.4.19 or greater, and is not compatible in any way with
-previous versions. It has been designed to run properly on SMP systems
-as well. At the moment, an additional module, "ovcamchip", is mandatory; it
-provides support for some OmniVision CMOS sensors connected to the W996[87]CF
-chips.
-
-The driver is split into two modules: the basic one, "w9968cf", is needed for
-the supported devices to work; the second one, "w9968cf-vpp", is an optional
-module, which provides some useful video post-processing functions like video
-decoding, up-scaling and colour conversions (these routines can't be included
-into official kernels). Once the driver is installed, every time an application
-tries to open a recognized device, "w9968cf" checks the presence of the
-"w9968cf-vpp" module and loads it automatically by default.
+The full-featured driver is divided into two modules: the basic one, "w9968cf",
+is needed for the supported devices to work; the second one, "w9968cf-vpp",
+is an optional module, which provides some useful video post-processing
+functions like video decoding, up-scaling and colour conversions. Once the
+driver is installed, every time an application tries to open a recognized
+device, "w9968cf" checks the presence of the "w9968cf-vpp" module and loads it
+automatically by default.
+
+Please keep in mind that official kernels do NOT include the second module for
+performance purposes. However it is always recommended to download and install
+the latest and complete release of the driver, replacing the existing one, if
+present: it will be still even possible not to load the "w9968cf-vpp" module at
+all, if you ever want to. Another important missing feature of the version in
+the official Linux 2.4 kernels is the writeable /proc filesystem interface.
+
+The latest and full-featured version of the W996[87]CF driver can be found at:
+http://go.lamarinapunto.com/
 
 Up to 32 cameras can be handled at the same time. They can be connected and
 disconnected from the host many times without turning off the computer, if
@@ -67,15 +71,17 @@
 To change the default settings for each camera, many paramaters can be passed
 through command line when the module is loaded into memory.
 
-It is recommended to install the latest and full featured version of the 
-W996[87]CF driver, which can be found at:
-http://go.lamarinapunto.com/
+The driver relies on the Video4Linux, USB and I2C core modules of the official
+Linux kernels, version 2.4.19 or greater, and is not compatible in any way with
+previous versions. It has been designed to run properly on SMP systems as well.
+At the moment, an additional module, "ovcamchip", is mandatory; it provides
+support for some OmniVision CMOS sensors connected to the W996[87]CF chips.
 
-The "ovcamchip" module is part of the OV511 driver, version 2.25, which can be
+The "ovcamchip" module is part of the OV511 driver, version 2.27, which can be
 downloaded from internet:
 http://alpha.dyndns.org/ov511/
-To know how to patch, compile and load it, read the "Kernel configuration"
-paragraph.
+To know how to compile it, read the documentation included in the OV511 
+package.
 
 
 4. Supported devices
@@ -94,22 +100,21 @@
 The list above does NOT imply that all those devices work with this driver: up
 until now only webcams that have a CMOS sensor supported by the "ovcamchip"
 module work. 
-For a list of supported CMOS sensors, please visit the module author homepage:
-http://alpha.dyndns.org/ov511/
+For a list of supported CMOS sensors, please visit the the author's homepage on
+this module: http://alpha.dyndns.org/ov511/
 
 Possible external microcontrollers of those webcams are not supported: this
-means that still images can't be downloaded from the device memory.
+means that still images cannot be downloaded from the device memory.
 
 Furthermore, it's worth to note that I was only able to run tests on my
 "Creative Labs Video Blaster WebCam Go". Donations of other models, for
 additional testing and full support, would be much appreciated.
 
 
-5. Kernel configuration and third-part module compilation
-=========================================================
-As noted above, kernel 2.4.19 is the minimum for this driver; for it to work
-properly, the driver needs kernel support for Video4Linux, USB and I2C, and a
-third-part module for the CMOS sensor.
+5. Module dependencies
+======================
+The driver needs kernel support for Video4Linux, USB and I2C, and a third-party
+module for the CMOS sensor.
 
 The following options of the kernel configuration file must be enabled and
 corresponding modules must be compiled:
@@ -128,7 +133,7 @@
 	#
 	CONFIG_USB=m
 
-In addition, depending on the hardware being used, just one of the modules
+In addition, depending on the hardware being used, only one of the modules
 below is necessary:
 
 	# USB Host Controller Drivers
@@ -138,6 +143,12 @@
 	CONFIG_USB_UHCI_ALT=m
 	CONFIG_USB_OHCI=m
 
+And finally:
+
+	# USB Multimedia devices
+	#
+	CONFIG_USB_W9968CF=m
+
 Also, make sure "Enforce bandwidth allocation" is NOT enabled.
 
 The /proc filesystem can be optionally built into the kernel:
@@ -150,39 +161,18 @@
 	#
 	CONFIG_VIDEO_PROC_FS=y
 
-	# USB Multimedia devices
-	#
-	CONFIG_USB_W9968CF=m
-
 The last module we need is "ovcamchip.o". To obtain it, you have to download
-the OV511 driver, version 2.25 - don't use other versions - which is available
-at http://alpha.dyndns.org/ov511/ . Then you have to download the latest 
-version of the full featured W996[87]CF driver, which contains a patch for the
-"ovcamchip" module; it is available at http://go.lamarinapunto.com .
-Once you have obtained the packages, decompress, patch and compile the 
-"ovcamchip" module. In other words:
-
-	[user@localhost home]$ tar xvzf w9968cf-x.x.tar.gz
-	[user@localhost home]$ tar xvjf ov511-2.25.tar.bz2
-	[user@localhost home]$ cd ov511-2.25
-	[user@localhost ov511-2.25]$ patch -p1 <                              \
-	                             /path/to/w9968cf-x.x/ov511-2.25.patch
-	[user@localhost ov511-2.25]$ make
-
-It's worth to note that the full featured version of the W996[87]CF driver
-can also be installed overwriting the one in the kernel; in this case, read the
-documentation included in the package.
-
-If everything went well, the W996[87]CF driver can be immediatly used (see next
-paragraph).
+the OV511, version 2.27 - don't use other versions - and compile it according
+to its documentation. 
+The package is available at http://alpha.dyndns.org/ov511/ .
 
 
 6. Module loading
 =================
 To use the driver, it is necessary to load the "w9968cf" module into memory
-after every other module required; they are named, in order: "videodev",
-"usbcore", then "ehci-hcd", "usb-uhci", "uhci", "usb-ohci" (just one), and also
-"i2c-core" and "ovcamchip".
+after every other module required: for the 2.4 series of the kernel, they are
+named, in order: "videodev", "usbcore", then "ehci-hcd", "usb-uhci", "uhci",
+"usb-ohci" (just one), and also "i2c-core" and "ovcamchip".
 
 Loading can be done this way, from root:
 
@@ -213,11 +203,10 @@
 
 7. Module paramaters
 ====================
-
 Module paramaters are listed below:
 -------------------------------------------------------------------------------
 Name:           vppmod_load
-Type:           int
+Type:           bool
 Syntax:         <0|1>
 Description:    Automatic 'w9968cf-vpp' module loading: 0 disabled, 1 enabled.
                 If enabled, every time an application attempts to open a
@@ -258,22 +247,22 @@
 Name:           max_buffers
 Type:           int array (min = 0, max = 32)
 Syntax:         <n[,...]>
-Description:    Only for advanced users.
+Description:    For advanced users.
                 Specify the maximum number of video frame buffers to allocate
                 for each device, from 2 to 32.
 Default:        2
 -------------------------------------------------------------------------------
 Name:           double_buffer
-Type:           int array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]> 
 Description:    Hardware double buffering: 0 disabled, 1 enabled.
                 It should be enabled if you want smooth video output: if you
-                obtain out of sync. video, disable it at all, or try to
+                obtain out of sync. video, disable it, or try to
                 decrease the 'clockdiv' module paramater value.
 Default:        1 for every device.
 -------------------------------------------------------------------------------
 Name:           clamping
-Type:           int array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]> 
 Description:    Video data clamping: 0 disabled, 1 enabled.
 Default:        0 for every device.
@@ -288,13 +277,13 @@
 Default:        0 for every device.
 -------------------------------------------------------------------------------
 Name:           largeview
-Type:           int array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]> 
 Description:    Large view: 0 disabled, 1 enabled.
 Default:        1 for every device.
 -------------------------------------------------------------------------------
 Name:           upscaling
-Type:           int array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]> 
 Description:    Software scaling (for non-compressed video only):
                 0 disabled, 1 enabled.
@@ -316,9 +305,8 @@
                 YUV420P/YUV420 in any resolutions where width and height are
                 multiples of 16.
 Default:        2 for every device.
-Note:           If 'w9968cf-vpp' is not loaded, this paramater is set to,
-                forcing decompression is not allowed; in this case this 
-                paramater is set to 2.
+Note:           If 'w9968cf-vpp' is not loaded, forcing decompression is not
+                allowed; in this case this paramater is set to 2.
 -------------------------------------------------------------------------------
 Name:           force_palette
 Type:           int array (min = 0, max = 32)
@@ -342,7 +330,7 @@
 Note:           If 'w9968cf-vpp' is not loaded, this paramater is set to 9.
 -------------------------------------------------------------------------------
 Name:           force_rgb
-Type:           int array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]>
 Description:    Read RGB video data instead of BGR:
                 1 = use RGB component ordering.
@@ -351,28 +339,28 @@
 Default:        0 for every device.
 -------------------------------------------------------------------------------
 Name:           autobright
-Type:           long array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]>
 Description:    CMOS sensor automatically changes brightness:
                 0 = no, 1 = yes
 Default:        0 for every device.
 -------------------------------------------------------------------------------
 Name:           autoexp
-Type:           long array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]>
 Description:    CMOS sensor automatically changes exposure:
                 0 = no, 1 = yes
 Default:        1 for every device.
 -------------------------------------------------------------------------------
 Name:           lightfreq
-Type:           long array (min = 0, max = 32)
+Type:           int array (min = 0, max = 32)
 Syntax:         <50|60[,...]>
 Description:    Light frequency in Hz:
                 50 for European and Asian lighting, 60 for American lighting.
 Default:        50 for every device.
 -------------------------------------------------------------------------------
 Name:           bandingfilter
-Type:           long array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]> 
 Description:    Banding filter to reduce effects of fluorescent 
                 lighting:
@@ -382,7 +370,7 @@
 Default:        0 for every device.
 -------------------------------------------------------------------------------
 Name:           clockdiv
-Type:           long array (min = 0, max = 32)
+Type:           int array (min = 0, max = 32)
 Syntax:         <-1|n[,...]>
 Description:    Force pixel clock divisor to a specific value (for experts):
                 n may vary from 0 to 127.
@@ -391,21 +379,21 @@
 Default:        -1 for every device.
 -------------------------------------------------------------------------------
 Name:           backlight
-Type:           long array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]>
 Description:    Objects are lit from behind:
                 0 = no, 1 = yes
 Default:        0 for every device.
 -------------------------------------------------------------------------------
 Name:           mirror
-Type:           long array (min = 0, max = 32)
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]>
 Description:    Reverse image horizontally:
                 0 = no, 1 = yes
 Default:        0 for every device.
 -------------------------------------------------------------------------------
-Name:           sensor_mono
-Type:           long array (min = 0, max = 32)
+Name:           monochrome
+Type:           bool array (min = 0, max = 32)
 Syntax:         <0|1[,...]> 
 Description:    The CMOS sensor is monochrome:
                 0 = no, 1 = yes
@@ -446,7 +434,7 @@
 Type:           int
 Syntax:         <n> 
 Description:    Debugging information level, from 0 to 6:
-                0 = none (be cautious)
+                0 = none (use carefully)
                 1 = critical errors
                 2 = significant informations
                 3 = configuration or general messages
@@ -458,7 +446,7 @@
 Default:        2
 -------------------------------------------------------------------------------
 Name:           specific_debug
-Type:           int
+Type:           bool
 Syntax:         <0|1>
 Description:    Enable or disable specific debugging messages:
                 0 = print messages concerning every level <= 'debug' level.
@@ -479,8 +467,6 @@
 - memory management code has been copied from the bttv driver by Ralph Metzler,
   Marcus Metzler and Gerd Knorr;
 
-- the low-level I2C read function has been written by FrÃ©dÃ©ric Jouault, who
-  also gave me commented logs about sniffed USB traffic taken from another
-  driver for another system;
+- the low-level I2C read function has been written by Frederic Jouault;
 
-- the low-level I2C fast write function has been written by Piotr Czerczak;
+- the low-level I2C fast write function has been written by Piotr Czerczak.
diff -urN linux-2.4.24-pre1/MAINTAINERS linux-2.4.24-pre2/MAINTAINERS
--- linux-2.4.24-pre1/MAINTAINERS	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/MAINTAINERS	2003-12-22 11:34:32.000000000 -0800
@@ -2070,11 +2070,11 @@
 S:	Maintained
 
 USB W9968CF DRIVER
-P:      Luca Risolia
-M:      luca_ing@libero.it
-L:      linux-usb-devel@lists.sourceforge.net
-W:      http://go.lamarinapunto.com
-S:      Maintained
+P:	Luca Risolia
+M:	luca.risolia@studio.unibo.it
+L:	linux-usb-devel@lists.sourceforge.net
+W:	http://go.lamarinapunto.com
+S:	Maintained
 
 VFAT FILESYSTEM:
 P:	Gordon Chaffee
diff -urN linux-2.4.24-pre1/Makefile linux-2.4.24-pre2/Makefile
--- linux-2.4.24-pre1/Makefile	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/Makefile	2003-12-22 11:34:32.000000000 -0800
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 24
-EXTRAVERSION = -pre1
+EXTRAVERSION = -pre2
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.24-pre1/Rules.make linux-2.4.24-pre2/Rules.make
--- linux-2.4.24-pre1/Rules.make	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.24-pre2/Rules.make	2003-12-22 11:34:32.000000000 -0800
@@ -96,12 +96,12 @@
 $(O_TARGET): $(obj-y)
 	rm -f $@
     ifneq "$(strip $(obj-y))" ""
-	$(LD) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^)
+	$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^)
     else
 	$(AR) rcs $@
     endif
 	@ ( \
-	    echo 'ifeq ($(strip $(subst $(comma),:,$(EXTRA_LDFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(EXTRA_LDFLAGS) $$(obj-y))))' ; \
+	    echo 'ifeq ($(strip $(subst $(comma),:,$(LDFLAGS) $(EXTRA_LDFLAGS) $(obj-y))),$$(strip $$(subst $$(comma),:,$$(LDFLAGS) $$(EXTRA_LDFLAGS) $$(obj-y))))' ; \
 	    echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \
 	    echo 'endif' \
 	) > $(dir $@)/.$(notdir $@).flags
diff -urN linux-2.4.24-pre1/arch/cris/drivers/ds1302.c linux-2.4.24-pre2/arch/cris/drivers/ds1302.c
--- linux-2.4.24-pre1/arch/cris/drivers/ds1302.c	2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.24-pre2/arch/cris/drivers/ds1302.c	2003-12-22 11:34:32.000000000 -0800
@@ -346,6 +346,7 @@
 		{
 			struct rtc_time rtc_tm;
 						
+			memset(&rtc_tm, 0, sizeof (struct rtc_time));
 			get_rtc_time(&rtc_tm);						
 			if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
 				return -EFAULT;	
diff -urN linux-2.4.24-pre1/arch/cris/drivers/pcf8563.c linux-2.4.24-pre2/arch/cris/drivers/pcf8563.c
--- linux-2.4.24-pre1/arch/cris/drivers/pcf8563.c	2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.24-pre2/arch/cris/drivers/pcf8563.c	2003-12-22 11:34:32.000000000 -0800
@@ -220,6 +220,7 @@
 		{
 			struct rtc_time tm;
 
+			memset(&tm, 0, sizeof (struct rtc_time));
 			get_rtc_time(&tm);
 
 			if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) {
diff -urN linux-2.4.24-pre1/arch/i386/kernel/acpi.c linux-2.4.24-pre2/arch/i386/kernel/acpi.c
--- linux-2.4.24-pre1/arch/i386/kernel/acpi.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/i386/kernel/acpi.c	2003-12-22 11:34:33.000000000 -0800
@@ -333,8 +333,10 @@
 	 * Initialize the ACPI boot-time table parser.
 	 */
 	result = acpi_table_init();
-	if (result)
+	if (result) {
+		acpi_disabled = 1;
 		return result;
+	}
 
 	result = acpi_blacklisted();
 	if (result) {
diff -urN linux-2.4.24-pre1/arch/i386/kernel/mpparse.c linux-2.4.24-pre2/arch/i386/kernel/mpparse.c
--- linux-2.4.24-pre1/arch/i386/kernel/mpparse.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/i386/kernel/mpparse.c	2003-12-22 11:34:33.000000000 -0800
@@ -1280,8 +1280,14 @@
 
 	ioapic_pin = irq - mp_ioapic_routing[ioapic].irq_start;
 
+	/*
+	 * MPS INTI flags:
+	 *  trigger: 0=default, 1=edge, 3=level
+	 *  polarity: 0=default, 1=high, 3=low
+	 * Per ACPI spec, default for SCI means level/low.
+	 */
 	io_apic_set_pci_routing(ioapic, ioapic_pin, irq, 
-				(flags.trigger >> 1) , (flags.polarity >> 1));
+		(flags.trigger == 1 ? 0 : 1), (flags.polarity == 1 ? 0 : 1));
 }
 
 
diff -urN linux-2.4.24-pre1/arch/i386/kernel/smpboot.c linux-2.4.24-pre2/arch/i386/kernel/smpboot.c
--- linux-2.4.24-pre1/arch/i386/kernel/smpboot.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/i386/kernel/smpboot.c	2003-12-22 11:34:33.000000000 -0800
@@ -1106,7 +1106,7 @@
 	 */
 	Dprintk("CPU present map: %lx\n", phys_cpu_present_map);
 
-	for (bit = 0; bit < BITS_PER_LONG; bit++) {
+	for (bit = 0; bit < MAX_APICS; bit++) {
 		apicid = cpu_present_to_apicid(bit);
 		
 		/* don't try to boot BAD_APICID */
diff -urN linux-2.4.24-pre1/arch/m68k/bvme6000/rtc.c linux-2.4.24-pre2/arch/m68k/bvme6000/rtc.c
--- linux-2.4.24-pre1/arch/m68k/bvme6000/rtc.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.24-pre2/arch/m68k/bvme6000/rtc.c	2003-12-22 11:34:33.000000000 -0800
@@ -54,6 +54,7 @@
 		/* Ensure clock and real-time-mode-register are accessible */
 		msr = rtc->msr & 0xc0;
 		rtc->msr = 0x40;
+		memset(&wtime, 0, sizeof(struct rtc_time));
 		do {
 			wtime.tm_sec =  BCD2BIN(rtc->bcd_sec);
 			wtime.tm_min =  BCD2BIN(rtc->bcd_min);
diff -urN linux-2.4.24-pre1/arch/m68k/mvme16x/rtc.c linux-2.4.24-pre2/arch/m68k/mvme16x/rtc.c
--- linux-2.4.24-pre1/arch/m68k/mvme16x/rtc.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.24-pre2/arch/m68k/mvme16x/rtc.c	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 		cli();
 		/* Ensure clock and real-time-mode-register are accessible */
 		rtc->ctrl = RTC_READ;
+		memset(&wtime, 0, sizeof(struct rtc_time));
 		wtime.tm_sec =  BCD2BIN(rtc->bcd_sec);
 		wtime.tm_min =  BCD2BIN(rtc->bcd_min);
 		wtime.tm_hour = BCD2BIN(rtc->bcd_hr);
diff -urN linux-2.4.24-pre1/arch/mips/au1000/common/setup.c linux-2.4.24-pre2/arch/mips/au1000/common/setup.c
--- linux-2.4.24-pre1/arch/mips/au1000/common/setup.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/au1000/common/setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -46,11 +46,6 @@
 #include <asm/au1000.h>
 #include <asm/time.h>
 
-#if defined(CONFIG_AU1X00_SERIAL_CONSOLE)
-extern void console_setup(char *, int *);
-char serial_console[20];
-#endif
-
 #ifdef CONFIG_BLK_DEV_INITRD
 extern unsigned long initrd_start, initrd_end;
 extern void * __rd_start, * __rd_end;
diff -urN linux-2.4.24-pre1/arch/mips/config-shared.in linux-2.4.24-pre2/arch/mips/config-shared.in
--- linux-2.4.24-pre1/arch/mips/config-shared.in	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/config-shared.in	2003-12-22 11:34:33.000000000 -0800
@@ -74,7 +74,10 @@
 bool 'Support for Momentum Ocelot-G board' CONFIG_MOMENCO_OCELOT_G
 bool 'Support for Momentum Ocelot-C and -CS boards' CONFIG_MOMENCO_OCELOT_C
 bool 'Support for Momentum Jaguar-ATX boards' CONFIG_MOMENCO_JAGUAR_ATX
-
+bool 'Support PMC-Sierra Yosemite board' CONFIG_PMC_YOSEMITE
+if [ "$CONFIG_PMC_YOSEMITE" = "y" ]; then
+   bool '  Hypertransport Support for PMC-Sierra Yosemite'  CONFIG_HYPERTRANSPORT
+fi
 dep_bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 $CONFIG_EXPERIMENTAL
 bool 'Support for NEC DDB Vrc-5476' CONFIG_DDB5476
 bool 'Support for NEC DDB Vrc-5477' CONFIG_DDB5477
@@ -225,14 +228,6 @@
 bool 'Support for ZAO Networks Capcella' CONFIG_ZAO_CAPCELLA
 
 dep_bool 'High Memory Support' CONFIG_HIGHMEM $CONFIG_MIPS32
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   choice 'Kernel page size'					\
-	"4KB                    CONFIG_PAGE_SIZE_4KB		\
-	 16KB                   CONFIG_PAGE_SIZE_16KB		\
-	 64KB                   CONFIG_PAGE_SIZE_64KB" 4KB
-else
-   define_bool CONFIG_PAGE_SIZE_4KB y
-fi
 
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
@@ -252,7 +247,6 @@
 if [ "$CONFIG_CASIO_E55" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
    define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_VR41XX_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_ISA y
    define_bool CONFIG_DUMMY_KEYB y
@@ -433,7 +427,6 @@
 if [ "$CONFIG_IBM_WORKPAD" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
    define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_VR41XX_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_ISA y
    define_bool CONFIG_DUMMY_KEYB y
@@ -534,6 +527,18 @@
    define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_BOOT_ELF32 y
 fi
+
+if [ "$CONFIG_PMC_YOSEMITE" = "y" ]; then
+   define_bool CONFIG_PCI y
+   define_bool CONFIG_SWAP_IO_SPACE y
+   define_bool CONFIG_SWAP_IO_SPACE_W y
+   define_bool CONFIG_SWAP_IO_SPACE_L y
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_HIGHMEM y
+   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_NONCOHERENT_IO y
+fi
+
 if [ "$CONFIG_DDB5074" = "y" ]; then
    define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
    define_bool CONFIG_I8259 y
@@ -579,7 +584,6 @@
 if [ "$CONFIG_NEC_EAGLE" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
    define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_VR41XX_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PCI y
    define_bool CONFIG_NEW_PCI y
@@ -635,7 +639,6 @@
 if [ "$CONFIG_TANBAC_TB0226" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
    define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_VR41XX_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PCI y
    define_bool CONFIG_NEW_PCI y
@@ -646,7 +649,6 @@
 if [ "$CONFIG_TANBAC_TB0229" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
    define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_VR41XX_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PCI y
    define_bool CONFIG_NEW_PCI y
@@ -678,7 +680,6 @@
 if [ "$CONFIG_VICTOR_MPC30X" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
    define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_VR41XX_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PCI y
    define_bool CONFIG_NEW_PCI y
@@ -689,7 +690,6 @@
 if [ "$CONFIG_ZAO_CAPCELLA" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
    define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_VR41XX_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PCI y
    define_bool CONFIG_NEW_PCI y
@@ -725,6 +725,16 @@
 	 RM9000	CONFIG_CPU_RM9000 \
 	 SB1	CONFIG_CPU_SB1" R4x00
 
+if [ "$CONFIG_CPU_R3000" = "n" -a "$CONFIG_CPU_TX39XX" = "n" -a \
+     "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   choice 'Kernel page size'					\
+	"4KB                    CONFIG_PAGE_SIZE_4KB		\
+	 16KB                   CONFIG_PAGE_SIZE_16KB		\
+	 64KB                   CONFIG_PAGE_SIZE_64KB" 4KB
+else
+   define_bool CONFIG_PAGE_SIZE_4KB y
+fi
+
 if [ "$CONFIG_SMP_CAPABLE" = "y" ]; then
    bool '  Multi-Processing support' CONFIG_SMP
 fi
@@ -866,10 +876,6 @@
    fi
 fi
 
-if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
-   bool 'DS1742 BRAM/RTC support' CONFIG_RTC_DS1742
-fi
-
 if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
    bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX
 fi
@@ -936,6 +942,7 @@
 fi
 
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER
 
 if [ "$CONFIG_SOC_AU1X00" = "y" ]; then
    bool 'Power Management support' CONFIG_PM
diff -urN linux-2.4.24-pre1/arch/mips/ddb5xxx/ddb5074/setup.c linux-2.4.24-pre2/arch/mips/ddb5xxx/ddb5074/setup.c
--- linux-2.4.24-pre1/arch/mips/ddb5xxx/ddb5074/setup.c	2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/ddb5xxx/ddb5074/setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -36,10 +36,6 @@
 extern void breakpoint(void);
 #endif
 
-#if defined(CONFIG_SERIAL_CONSOLE)
-extern void console_setup(char *);
-#endif
-
 extern struct ide_ops std_ide_ops;
 extern struct kbd_ops std_kbd_ops;
 extern struct rtc_ops ddb_rtc_ops;
diff -urN linux-2.4.24-pre1/arch/mips/dec/setup.c linux-2.4.24-pre2/arch/mips/dec/setup.c
--- linux-2.4.24-pre1/arch/mips/dec/setup.c	2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/dec/setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -48,6 +48,11 @@
 
 extern asmlinkage void decstation_handle_int(void);
 
+#ifdef CONFIG_BLK_DEV_INITRD
+extern unsigned long initrd_start, initrd_end;
+extern void * __rd_start, * __rd_end;
+#endif
+
 spinlock_t ioasic_ssr_lock;
 
 volatile u32 *ioasic_base;
@@ -131,6 +136,11 @@
 
 void __init decstation_setup(void)
 {
+#ifdef CONFIG_BLK_DEV_INITRD
+       ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+       initrd_start = (unsigned long)&__rd_start;
+       initrd_end = (unsigned long)&__rd_end;
+#endif
 	board_be_init = dec_be_init;
 	board_time_init = dec_time_init;
 	board_timer_setup = dec_timer_setup;
diff -urN linux-2.4.24-pre1/arch/mips/defconfig linux-2.4.24-pre2/arch/mips/defconfig
--- linux-2.4.24-pre1/arch/mips/defconfig	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=y
@@ -108,6 +106,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -143,6 +144,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -508,7 +510,6 @@
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-CONFIG_INDYDOG=y
 # CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
@@ -588,6 +589,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-atlas linux-2.4.24-pre2/arch/mips/defconfig-atlas
--- linux-2.4.24-pre1/arch/mips/defconfig-atlas	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-atlas	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
@@ -140,6 +141,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -621,6 +623,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-bosporus linux-2.4.24-pre2/arch/mips/defconfig-bosporus
--- linux-2.4.24-pre1/arch/mips/defconfig-bosporus	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-bosporus	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -149,6 +150,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -790,6 +792,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-capcella linux-2.4.24-pre2/arch/mips/defconfig-capcella
--- linux-2.4.24-pre1/arch/mips/defconfig-capcella	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-capcella	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,14 +71,10 @@
 # CONFIG_VICTOR_MPC30X is not set
 CONFIG_ZAO_CAPCELLA=y
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
 CONFIG_NEW_TIME_C=y
-CONFIG_VR41XX_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_NEW_PCI=y
@@ -106,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -137,6 +137,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -519,7 +520,6 @@
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_INDYDOG is not set
 # CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
@@ -598,6 +598,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-cobalt linux-2.4.24-pre2/arch/mips/defconfig-cobalt
--- linux-2.4.24-pre1/arch/mips/defconfig-cobalt	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-cobalt	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
@@ -101,6 +99,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
@@ -132,6 +133,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -605,6 +607,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-csb250 linux-2.4.24-pre2/arch/mips/defconfig-csb250
--- linux-2.4.24-pre1/arch/mips/defconfig-csb250	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-csb250	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -139,7 +140,6 @@
 # CONFIG_PCMCIA_PB1X00 is not set
 CONFIG_PCMCIA_DB1X00=y
 # CONFIG_PCMCIA_XXS1500 is not set
-# CONFIG_PCMCIA_VRC4173 is not set
 
 #
 # PCI Hotplug Support
@@ -159,6 +159,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -689,6 +690,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-db1000 linux-2.4.24-pre2/arch/mips/defconfig-db1000
--- linux-2.4.24-pre1/arch/mips/defconfig-db1000	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-db1000	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -106,6 +104,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -139,7 +140,6 @@
 # CONFIG_PCMCIA_PB1X00 is not set
 CONFIG_PCMCIA_DB1X00=y
 # CONFIG_PCMCIA_XXS1500 is not set
-# CONFIG_PCMCIA_VRC4173 is not set
 
 #
 # PCI Hotplug Support
@@ -159,6 +159,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -766,6 +767,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-db1100 linux-2.4.24-pre2/arch/mips/defconfig-db1100
--- linux-2.4.24-pre1/arch/mips/defconfig-db1100	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-db1100	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -138,7 +139,6 @@
 # CONFIG_PCMCIA_PB1X00 is not set
 CONFIG_PCMCIA_DB1X00=y
 # CONFIG_PCMCIA_XXS1500 is not set
-# CONFIG_PCMCIA_VRC4173 is not set
 
 #
 # PCI Hotplug Support
@@ -158,6 +158,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -765,6 +766,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-db1500 linux-2.4.24-pre2/arch/mips/defconfig-db1500
--- linux-2.4.24-pre1/arch/mips/defconfig-db1500	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-db1500	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -138,7 +139,6 @@
 # CONFIG_PCMCIA_PB1X00 is not set
 CONFIG_PCMCIA_DB1X00=y
 # CONFIG_PCMCIA_XXS1500 is not set
-# CONFIG_PCMCIA_VRC4173 is not set
 
 #
 # PCI Hotplug Support
@@ -158,6 +158,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -688,6 +689,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-ddb5476 linux-2.4.24-pre2/arch/mips/defconfig-ddb5476
--- linux-2.4.24-pre1/arch/mips/defconfig-ddb5476	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-ddb5476	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 CONFIG_DDB5476=y
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ISA=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
@@ -135,6 +136,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -623,6 +625,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-ddb5477 linux-2.4.24-pre2/arch/mips/defconfig-ddb5477
--- linux-2.4.24-pre1/arch/mips/defconfig-ddb5477	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-ddb5477	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 CONFIG_DDB5477=y
@@ -69,9 +70,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_PCI=y
@@ -104,6 +102,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
@@ -135,6 +136,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -540,6 +542,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-decstation linux-2.4.24-pre2/arch/mips/defconfig-decstation
--- linux-2.4.24-pre1/arch/mips/defconfig-decstation	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-decstation	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
@@ -102,6 +100,7 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -133,6 +132,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -574,6 +574,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-e55 linux-2.4.24-pre2/arch/mips/defconfig-e55
--- linux-2.4.24-pre1/arch/mips/defconfig-e55	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-e55	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,14 +71,10 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
 CONFIG_NEW_TIME_C=y
-CONFIG_VR41XX_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_ISA=y
 CONFIG_DUMMY_KEYB=y
@@ -104,6 +101,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -134,6 +134,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -474,7 +475,6 @@
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_INDYDOG is not set
 # CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
@@ -553,6 +553,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-eagle linux-2.4.24-pre2/arch/mips/defconfig-eagle
--- linux-2.4.24-pre1/arch/mips/defconfig-eagle	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-eagle	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -71,14 +72,10 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
 CONFIG_NEW_TIME_C=y
-CONFIG_VR41XX_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_NEW_PCI=y
@@ -107,6 +104,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -153,6 +153,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -631,7 +632,6 @@
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_INDYDOG is not set
 # CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
@@ -719,6 +719,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-ev64120 linux-2.4.24-pre2/arch/mips/defconfig-ev64120
--- linux-2.4.24-pre1/arch/mips/defconfig-ev64120	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-ev64120	2003-12-22 11:34:33.000000000 -0800
@@ -56,6 +56,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -74,9 +75,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_PCI=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -138,6 +139,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -546,6 +548,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-ev96100 linux-2.4.24-pre2/arch/mips/defconfig-ev96100
--- linux-2.4.24-pre1/arch/mips/defconfig-ev96100	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-ev96100	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_PCI=y
@@ -105,6 +103,9 @@
 CONFIG_CPU_RM7000=y
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_BOARD_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_RM7000_CPU_SCACHE=y
@@ -141,6 +142,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -545,6 +547,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-hp-lj linux-2.4.24-pre2/arch/mips/defconfig-hp-lj
--- linux-2.4.24-pre1/arch/mips/defconfig-hp-lj	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-hp-lj	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
@@ -102,6 +100,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -134,6 +135,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -697,6 +699,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-hydrogen3 linux-2.4.24-pre2/arch/mips/defconfig-hydrogen3
--- linux-2.4.24-pre1/arch/mips/defconfig-hydrogen3	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-hydrogen3	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -138,7 +139,6 @@
 # CONFIG_PCMCIA_PB1X00 is not set
 CONFIG_PCMCIA_DB1X00=y
 # CONFIG_PCMCIA_XXS1500 is not set
-# CONFIG_PCMCIA_VRC4173 is not set
 
 #
 # PCI Hotplug Support
@@ -158,6 +158,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -765,6 +766,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-ip22 linux-2.4.24-pre2/arch/mips/defconfig-ip22
--- linux-2.4.24-pre1/arch/mips/defconfig-ip22	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-ip22	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=y
@@ -108,6 +106,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -143,6 +144,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -508,7 +510,6 @@
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-CONFIG_INDYDOG=y
 # CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
@@ -588,6 +589,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-jmr3927 linux-2.4.24-pre2/arch/mips/defconfig-jmr3927
--- linux-2.4.24-pre1/arch/mips/defconfig-jmr3927	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-jmr3927	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_TOSHIBA_BOARDS=y
@@ -104,6 +102,7 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -114,7 +113,6 @@
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
-CONFIG_RTC_DS1742=y
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
 # CONFIG_PCI_NAMES is not set
@@ -137,6 +135,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -562,6 +561,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-lasat linux-2.4.24-pre2/arch/mips/defconfig-lasat
--- linux-2.4.24-pre1/arch/mips/defconfig-lasat	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-lasat	2003-12-22 11:34:33.000000000 -0800
@@ -56,6 +56,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -74,9 +75,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOARD_SCACHE=y
@@ -108,6 +106,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -140,6 +141,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -680,6 +682,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-malta linux-2.4.24-pre2/arch/mips/defconfig-malta
--- linux-2.4.24-pre1/arch/mips/defconfig-malta	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-malta	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
@@ -110,6 +108,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
@@ -144,6 +145,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -617,6 +619,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-mirage linux-2.4.24-pre2/arch/mips/defconfig-mirage
--- linux-2.4.24-pre1/arch/mips/defconfig-mirage	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-mirage	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -149,6 +150,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -597,6 +599,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-mpc30x linux-2.4.24-pre2/arch/mips/defconfig-mpc30x
--- linux-2.4.24-pre1/arch/mips/defconfig-mpc30x	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-mpc30x	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -71,14 +72,10 @@
 CONFIG_VRC4173=y
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
 CONFIG_NEW_TIME_C=y
-CONFIG_VR41XX_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_NEW_PCI=y
@@ -107,6 +104,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -138,6 +138,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -509,6 +510,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-mtx-1 linux-2.4.24-pre2/arch/mips/defconfig-mtx-1
--- linux-2.4.24-pre1/arch/mips/defconfig-mtx-1	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-mtx-1	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -104,6 +102,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -138,6 +139,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -623,6 +625,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-nino linux-2.4.24-pre2/arch/mips/defconfig-nino
--- linux-2.4.24-pre1/arch/mips/defconfig-nino	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-nino	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -73,9 +74,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_NEW_TIME_C=y
@@ -103,6 +101,7 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -134,6 +133,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -447,6 +447,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-ocelot linux-2.4.24-pre2/arch/mips/defconfig-ocelot
--- linux-2.4.24-pre1/arch/mips/defconfig-ocelot	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-ocelot	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_PCI=y
@@ -101,6 +99,9 @@
 CONFIG_CPU_RM7000=y
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_BOARD_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_RM7000_CPU_SCACHE=y
@@ -137,6 +138,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -613,6 +615,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-osprey linux-2.4.24-pre2/arch/mips/defconfig-osprey
--- linux-2.4.24-pre1/arch/mips/defconfig-osprey	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-osprey	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_VR4181=y
@@ -103,6 +101,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -134,6 +135,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -493,6 +495,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-pb1000 linux-2.4.24-pre2/arch/mips/defconfig-pb1000
--- linux-2.4.24-pre1/arch/mips/defconfig-pb1000	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-pb1000	2003-12-22 11:34:33.000000000 -0800
@@ -53,6 +53,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -71,9 +72,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -107,6 +105,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -140,7 +141,6 @@
 CONFIG_PCMCIA_PB1X00=y
 # CONFIG_PCMCIA_DB1X00 is not set
 # CONFIG_PCMCIA_XXS1500 is not set
-# CONFIG_PCMCIA_VRC4173 is not set
 
 #
 # PCI Hotplug Support
@@ -160,6 +160,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -753,6 +754,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-pb1100 linux-2.4.24-pre2/arch/mips/defconfig-pb1100
--- linux-2.4.24-pre1/arch/mips/defconfig-pb1100	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-pb1100	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -107,6 +105,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -141,6 +142,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -740,6 +742,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-pb1500 linux-2.4.24-pre2/arch/mips/defconfig-pb1500
--- linux-2.4.24-pre1/arch/mips/defconfig-pb1500	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-pb1500	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -138,7 +139,6 @@
 CONFIG_PCMCIA_PB1X00=y
 # CONFIG_PCMCIA_DB1X00 is not set
 # CONFIG_PCMCIA_XXS1500 is not set
-# CONFIG_PCMCIA_VRC4173 is not set
 
 #
 # PCI Hotplug Support
@@ -158,6 +158,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -807,6 +808,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-rbtx4927 linux-2.4.24-pre2/arch/mips/defconfig-rbtx4927
--- linux-2.4.24-pre1/arch/mips/defconfig-rbtx4927	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-rbtx4927	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_NEW_TIME_C=y
@@ -103,6 +101,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_ADVANCED=y
 CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_LLDSCD=y
@@ -133,6 +134,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -571,6 +573,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-rm200 linux-2.4.24-pre2/arch/mips/defconfig-rm200
--- linux-2.4.24-pre1/arch/mips/defconfig-rm200	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-rm200	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=y
@@ -106,6 +104,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -139,6 +140,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -444,6 +446,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-sb1250-swarm linux-2.4.24-pre2/arch/mips/defconfig-sb1250-swarm
--- linux-2.4.24-pre1/arch/mips/defconfig-sb1250-swarm	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-sb1250-swarm	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -94,9 +95,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_NEW_TIME_C=y
@@ -126,6 +124,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 CONFIG_CPU_SB1=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_SMP=y
 # CONFIG_SIBYTE_DMA_PAGEOPS is not set
 CONFIG_SB1_PASS_1_WORKAROUNDS=y
@@ -164,6 +165,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -572,6 +574,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-sead linux-2.4.24-pre2/arch/mips/defconfig-sead
--- linux-2.4.24-pre1/arch/mips/defconfig-sead	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-sead	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
@@ -100,6 +98,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
@@ -134,6 +135,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -350,6 +352,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_ZISOFS_FS is not set
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-tb0226 linux-2.4.24-pre2/arch/mips/defconfig-tb0226
--- linux-2.4.24-pre1/arch/mips/defconfig-tb0226	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-tb0226	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,14 +71,10 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
 CONFIG_NEW_TIME_C=y
-CONFIG_VR41XX_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_NEW_PCI=y
@@ -106,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -137,6 +137,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -557,7 +558,6 @@
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_INDYDOG is not set
 # CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
@@ -636,6 +636,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-tb0229 linux-2.4.24-pre2/arch/mips/defconfig-tb0229
--- linux-2.4.24-pre1/arch/mips/defconfig-tb0229	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-tb0229	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -71,14 +72,10 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
 CONFIG_NEW_TIME_C=y
-CONFIG_VR41XX_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PCI=y
 CONFIG_NEW_PCI=y
@@ -107,6 +104,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -138,6 +138,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -495,7 +496,6 @@
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_INDYDOG is not set
 # CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
@@ -574,6 +574,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-ti1500 linux-2.4.24-pre2/arch/mips/defconfig-ti1500
--- linux-2.4.24-pre1/arch/mips/defconfig-ti1500	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-ti1500	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -138,7 +139,6 @@
 # CONFIG_PCMCIA_PB1X00 is not set
 # CONFIG_PCMCIA_DB1X00 is not set
 CONFIG_PCMCIA_XXS1500=y
-# CONFIG_PCMCIA_VRC4173 is not set
 
 #
 # PCI Hotplug Support
@@ -158,6 +158,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -596,7 +597,6 @@
 CONFIG_I2C=m
 # CONFIG_I2C_ALGOBIT is not set
 # CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGO_SGI is not set
 CONFIG_I2C_CHARDEV=m
 CONFIG_I2C_PROC=m
 
@@ -736,6 +736,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-workpad linux-2.4.24-pre2/arch/mips/defconfig-workpad
--- linux-2.4.24-pre1/arch/mips/defconfig-workpad	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-workpad	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,14 +71,10 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
 CONFIG_NEW_TIME_C=y
-CONFIG_VR41XX_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_ISA=y
 CONFIG_DUMMY_KEYB=y
@@ -104,6 +101,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_CPU_ADVANCED is not set
 # CONFIG_CPU_HAS_LLSC is not set
 # CONFIG_CPU_HAS_LLDSCD is not set
@@ -134,6 +134,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -474,7 +475,6 @@
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_INDYDOG is not set
 # CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
@@ -553,6 +553,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-xxs1500 linux-2.4.24-pre2/arch/mips/defconfig-xxs1500
--- linux-2.4.24-pre1/arch/mips/defconfig-xxs1500	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-xxs1500	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 # CONFIG_VTAG_ICACHE is not set
 CONFIG_64BIT_PHYS_ADDR=y
@@ -138,7 +139,6 @@
 # CONFIG_PCMCIA_PB1X00 is not set
 # CONFIG_PCMCIA_DB1X00 is not set
 CONFIG_PCMCIA_XXS1500=y
-# CONFIG_PCMCIA_VRC4173 is not set
 
 #
 # PCI Hotplug Support
@@ -158,6 +158,7 @@
 # CONFIG_MIPS32_N32 is not set
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 # CONFIG_PM is not set
 
 #
@@ -778,6 +779,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips/defconfig-yosemite linux-2.4.24-pre2/arch/mips/defconfig-yosemite
--- linux-2.4.24-pre1/arch/mips/defconfig-yosemite	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/defconfig-yosemite	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,662 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_COGENT_CSB250 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_TANBAC_TB0229 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+CONFIG_CPU_RM9000=y
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_RM7000_CPU_SCACHE=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BINFMT_IRIX is not set
+CONFIG_NET=y
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_MIPS32_O32 is not set
+# CONFIG_MIPS32_N32 is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# 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
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IPV6_SCTP__=y
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_BOOT is not set
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+# CONFIG_SERIAL_TXX9 is not set
+# CONFIG_SERIAL_TXX9_CONSOLE is not set
+# CONFIG_TXX927_SERIAL is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DS1742 is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# 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
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_KGDB is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
+CONFIG_LOG_BUF_SHIFT=0
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -urN linux-2.4.24-pre1/arch/mips/galileo-boards/ev96100/setup.c linux-2.4.24-pre2/arch/mips/galileo-boards/ev96100/setup.c
--- linux-2.4.24-pre1/arch/mips/galileo-boards/ev96100/setup.c	2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/galileo-boards/ev96100/setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -50,11 +50,6 @@
 #include <asm/galileo-boards/ev96100int.h>
 
 
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
-extern void console_setup(char *, int *);
-char serial_console[20];
-#endif
-
 extern char * __init prom_getcmdline(void);
 
 extern void mips_reboot_setup(void);
diff -urN linux-2.4.24-pre1/arch/mips/kernel/cpu-probe.c linux-2.4.24-pre2/arch/mips/kernel/cpu-probe.c
--- linux-2.4.24-pre1/arch/mips/kernel/cpu-probe.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/kernel/cpu-probe.c	2003-12-22 11:34:33.000000000 -0800
@@ -160,7 +160,7 @@
 }
 
 #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
-		| MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
+		| MIPS_CPU_COUNTER)
 
 static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
 {
diff -urN linux-2.4.24-pre1/arch/mips/kernel/irixsig.c linux-2.4.24-pre2/arch/mips/kernel/irixsig.c
--- linux-2.4.24-pre1/arch/mips/kernel/irixsig.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/kernel/irixsig.c	2003-12-22 11:34:33.000000000 -0800
@@ -676,49 +676,53 @@
 			continue;
 		flag = 1;
 		switch (p->state) {
-			case TASK_STOPPED:
-				if (!p->exit_code)
-					continue;
-				if (!(options & (W_TRAPPED|W_STOPPED)) &&
-				    !(p->ptrace & PT_PTRACED))
-					continue;
-				if (ru != NULL)
-					getrusage(p, RUSAGE_BOTH, ru);
-				__put_user(SIGCHLD, &info->sig);
-				__put_user(0, &info->code);
-				__put_user(p->pid, &info->stuff.procinfo.pid);
-				__put_user((p->exit_code >> 8) & 0xff,
-				           &info->stuff.procinfo.procdata.child.status);
-				__put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime);
-				__put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime);
-				p->exit_code = 0;
-				retval = 0;
-				goto end_waitsys;
-			case TASK_ZOMBIE:
-				current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime;
-				current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime;
-				if (ru != NULL)
-					getrusage(p, RUSAGE_BOTH, ru);
-				__put_user(SIGCHLD, &info->sig);
-				__put_user(1, &info->code);      /* CLD_EXITED */
-				__put_user(p->pid, &info->stuff.procinfo.pid);
-				__put_user((p->exit_code >> 8) & 0xff,
-				           &info->stuff.procinfo.procdata.child.status);
-				__put_user(p->times.tms_utime,
-				           &info->stuff.procinfo.procdata.child.utime);
-				__put_user(p->times.tms_stime,
-				           &info->stuff.procinfo.procdata.child.stime);
-				retval = 0;
-				if (p->p_opptr != p->p_pptr) {
-					REMOVE_LINKS(p);
-					p->p_pptr = p->p_opptr;
-					SET_LINKS(p);
-					notify_parent(p, SIGCHLD);
-				} else
-					release_task(p);
-				goto end_waitsys;
-			default:
+		case TASK_STOPPED:
+			if (!p->exit_code)
 				continue;
+			if (!(options & (W_TRAPPED|W_STOPPED)) &&
+			    !(p->ptrace & PT_PTRACED))
+				continue;
+			read_unlock(&tasklist_lock);
+			if (ru != NULL)
+				getrusage(p, RUSAGE_BOTH, ru);
+			__put_user(SIGCHLD, &info->sig);
+			__put_user(0, &info->code);
+			__put_user(p->pid, &info->stuff.procinfo.pid);
+			__put_user((p->exit_code >> 8) & 0xff,
+			           &info->stuff.procinfo.procdata.child.status);
+			__put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime);
+			__put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime);
+			p->exit_code = 0;
+			retval = 0;
+			goto end_waitsys;
+		case TASK_ZOMBIE:
+			current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime;
+			current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime;
+			read_unlock(&tasklist_lock);
+			if (ru != NULL)
+				getrusage(p, RUSAGE_BOTH, ru);
+			__put_user(SIGCHLD, &info->sig);
+			__put_user(1, &info->code);      /* CLD_EXITED */
+			__put_user(p->pid, &info->stuff.procinfo.pid);
+			__put_user((p->exit_code >> 8) & 0xff,
+			           &info->stuff.procinfo.procdata.child.status);
+			__put_user(p->times.tms_utime,
+			           &info->stuff.procinfo.procdata.child.utime);
+			__put_user(p->times.tms_stime,
+			           &info->stuff.procinfo.procdata.child.stime);
+			retval = 0;
+			if (p->p_opptr != p->p_pptr) {
+				write_lock_irq(&tasklist_lock);
+				REMOVE_LINKS(p);
+				p->p_pptr = p->p_opptr;
+				SET_LINKS(p);
+				notify_parent(p, SIGCHLD);
+				write_unlock_irq(&tasklist_lock);
+			} else
+				release_task(p);
+			goto end_waitsys;
+		default:
+			continue;
 		}
 	}
 	read_unlock(&tasklist_lock);
diff -urN linux-2.4.24-pre1/arch/mips/kernel/mips_ksyms.c linux-2.4.24-pre2/arch/mips/kernel/mips_ksyms.c
--- linux-2.4.24-pre1/arch/mips/kernel/mips_ksyms.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/kernel/mips_ksyms.c	2003-12-22 11:34:33.000000000 -0800
@@ -62,7 +62,7 @@
 EXPORT_SYMBOL_NOVERS(strstr);
 EXPORT_SYMBOL_NOVERS(strtok);
 
-EXPORT_SYMBOL(_clear_page);
+EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(kernel_thread);
 
 /*
diff -urN linux-2.4.24-pre1/arch/mips/kernel/setup.c linux-2.4.24-pre2/arch/mips/kernel/setup.c
--- linux-2.4.24-pre1/arch/mips/kernel/setup.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/kernel/setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -687,6 +687,11 @@
                 hp_setup();
                 break;
 #endif
+#ifdef  CONFIG_PMC_YOSEMITE
+        case MACH_GROUP_TITAN:
+                pmc_yosemite_setup();
+                break;
+#endif
 	default:
 		panic("Unsupported architecture");
 	}
diff -urN linux-2.4.24-pre1/arch/mips/kernel/smp.c linux-2.4.24-pre2/arch/mips/kernel/smp.c
--- linux-2.4.24-pre1/arch/mips/kernel/smp.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/kernel/smp.c	2003-12-22 11:34:33.000000000 -0800
@@ -61,26 +61,6 @@
  */
 void core_send_ipi(int cpu, unsigned int action);
 
-/*
- * Clear all undefined state in the cpu, set up sp and gp to the passed
- * values, and kick the cpu into smp_bootstrap();
- */
-void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
-
-/*
- *  After we've done initial boot, this function is called to allow the
- *  board code to clean up state, if needed
- */
-void prom_init_secondary(void);
-
-/*
- * Do whatever setup needs to be done for SMP at the board level.  Return
- * the number of cpus in the system, including this one
- */
-int prom_setup_smp(void);
-
-void prom_smp_finish(void);
-
 void __init smp_callin(void)
 {
 #if 0
@@ -89,34 +69,6 @@
 #endif
 }
 
-#ifndef CONFIG_SGI_IP27
-/*
- * Hook for doing final board-specific setup after the generic smp setup
- * is done
- */
-asmlinkage void start_secondary(void)
-{
-	unsigned int cpu = smp_processor_id();
-
-	cpu_probe();
-	prom_init_secondary();
-	per_cpu_trap_init();
-
-	/*
-	 * XXX parity protection should be folded in here when it's converted
-	 * to an option instead of something based on .cputype
-	 */
-	pgd_current[cpu] = init_mm.pgd;
-	cpu_data[cpu].udelay_val = loops_per_jiffy;
-	prom_smp_finish();
-	printk("Slave cpu booted successfully\n");
-	CPUMASK_SETB(cpu_online_map, cpu);
-	atomic_inc(&cpus_booted);
-	while (!atomic_read(&smp_commenced));
-	cpu_idle();
-}
-#endif /* CONFIG_SGI_IP27 */
-
 void __init smp_commence(void)
 {
 	wmb();
diff -urN linux-2.4.24-pre1/arch/mips/kernel/traps.c linux-2.4.24-pre2/arch/mips/kernel/traps.c
--- linux-2.4.24-pre1/arch/mips/kernel/traps.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/kernel/traps.c	2003-12-22 11:34:33.000000000 -0800
@@ -63,7 +63,7 @@
 
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
-void (*board_nmi_handler_setup)(void) = NULL;
+void (*board_nmi_handler_setup)(void);
 
 int kstack_depth_to_print = 24;
 
@@ -235,9 +235,10 @@
 	/*
 	 * Saved cp0 registers
 	 */
-	printk("epc  : %08lx    %s\nStatus: %08lx\nCause : %08lx\n",
-	       regs->cp0_epc, print_tainted(), regs->cp0_status,
-	       regs->cp0_cause);
+	printk("epc   : %08lx    %s\n", regs->cp0_epc, print_tainted());
+	printk("Status: %08lx\n", regs->cp0_status);
+	printk("epc   : %08lx\n", regs->cp0_cause);
+	printk("PrId  : %08x\n", read_c0_prid());
 }
 
 void show_registers(struct pt_regs *regs)
diff -urN linux-2.4.24-pre1/arch/mips/mips-boards/atlas/atlas_setup.c linux-2.4.24-pre2/arch/mips/mips-boards/atlas/atlas_setup.c
--- linux-2.4.24-pre1/arch/mips/mips-boards/atlas/atlas_setup.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/mips-boards/atlas/atlas_setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -22,6 +22,7 @@
 #include <linux/sched.h>
 #include <linux/mc146818rtc.h>
 #include <linux/ioport.h>
+#include <linux/console.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -33,11 +34,6 @@
 #include <asm/time.h>
 #include <asm/traps.h>
 
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
-extern void console_setup(char *, int *);
-char serial_console[20];
-#endif
-
 #ifdef CONFIG_KGDB
 extern void rs_kgdb_hook(int);
 extern void saa9730_kgdb_hook(void);
@@ -75,14 +71,20 @@
 #ifdef CONFIG_SERIAL_CONSOLE
 	argptr = prom_getcmdline();
 	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
-		int i = 0;
+		struct console_cmdline *c = &console_cmdline[0];
 		char *s = prom_getenv("modetty0");
-		while(s[i] >= '0' && s[i] <= '9')
+		int i = 0;
+		static char options[8];
+		while (s && s[i] >= '0' && s[i] <= '9') {
+			options[i] = s[i];
 			i++;
-		strcpy(serial_console, "ttyS0,");
-		strncpy(serial_console + 6, s, i);
-		prom_printf("Config serial console: %s\n", serial_console);
-		console_setup(serial_console, NULL);
+		}
+		options[i] = 0;
+		strcpy(c->name, "ttyS");
+		c->options = s ? options : NULL;
+		c->index = 0;
+		prom_printf("Serial console: %s%d %s\n",
+			    c->name, c->index, options);
 	}
 #endif
 
diff -urN linux-2.4.24-pre1/arch/mips/mips-boards/malta/malta_setup.c linux-2.4.24-pre2/arch/mips/mips-boards/malta/malta_setup.c
--- linux-2.4.24-pre1/arch/mips/mips-boards/malta/malta_setup.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/mips-boards/malta/malta_setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -45,11 +45,6 @@
 #include <linux/console.h>
 #endif
 
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
-extern void console_setup(char *, int *);
-char serial_console[20];
-#endif
-
 #ifdef CONFIG_KGDB
 extern void rs_kgdb_hook(int);
 int remote_debug = 0;
diff -urN linux-2.4.24-pre1/arch/mips/mips-boards/sead/sead_setup.c linux-2.4.24-pre2/arch/mips/mips-boards/sead/sead_setup.c
--- linux-2.4.24-pre1/arch/mips/mips-boards/sead/sead_setup.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/mips-boards/sead/sead_setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -22,6 +22,7 @@
 #include <linux/sched.h>
 #include <linux/mc146818rtc.h>
 #include <linux/ioport.h>
+#include <linux/console.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -31,11 +32,6 @@
 #include <asm/mips-boards/seadint.h>
 #include <asm/time.h>
 
-#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE)
-extern void console_setup(char *, int *);
-char serial_console[20];
-#endif
-
 extern void mips_reboot_setup(void);
 extern void mips_time_init(void);
 extern void mips_timer_setup(struct irqaction *irq);
@@ -54,14 +50,20 @@
 #ifdef CONFIG_SERIAL_CONSOLE
 	argptr = prom_getcmdline();
 	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
-		int i = 0;
+		struct console_cmdline *c = &console_cmdline[0];
 		char *s = prom_getenv("modetty0");
-		while(s[i] >= '0' && s[i] <= '9')
+		int i = 0;
+		static char options[8];
+		while (s && s[i] >= '0' && s[i] <= '9') {
+			options[i] = s[i];
 			i++;
-		strcpy(serial_console, "ttyS0,");
-		strncpy(serial_console + 6, s, i);
-		prom_printf("Config serial console: %s\n", serial_console);
-		console_setup(serial_console, NULL);
+		}
+		options[i] = 0;
+		strcpy(c->name, "ttyS");
+		c->options = s ? options : NULL;
+		c->index = 0;
+		prom_printf("Serial console: %s%d %s\n",
+			    c->name, c->index, options);
 	}
 #endif
 
diff -urN linux-2.4.24-pre1/arch/mips/mm/Makefile linux-2.4.24-pre2/arch/mips/mm/Makefile
--- linux-2.4.24-pre1/arch/mips/mm/Makefile	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/mm/Makefile	2003-12-22 11:34:33.000000000 -0800
@@ -14,8 +14,8 @@
 obj-y				+= cache.o extable.o init.o ioremap.o fault.o \
 				   loadmmu.o
 
-obj-$(CONFIG_CPU_R3000)		+= pg-r3k.o c-r3k.o tlb-r3k.o tlbex-r3k.o
-obj-$(CONFIG_CPU_TX39XX)	+= pg-r3k.o c-tx39.o tlb-r3k.o tlbex-r3k.o
+obj-$(CONFIG_CPU_R3000)		+= pg-r4k.o c-r3k.o tlb-r3k.o tlbex-r3k.o
+obj-$(CONFIG_CPU_TX39XX)	+= pg-r4k.o c-tx39.o tlb-r3k.o tlbex-r3k.o
 obj-$(CONFIG_CPU_TX49XX)	+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
 obj-$(CONFIG_CPU_R4300)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
 obj-$(CONFIG_CPU_R4X00)		+= pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o
diff -urN linux-2.4.24-pre1/arch/mips/mm/c-r3k.c linux-2.4.24-pre2/arch/mips/mm/c-r3k.c
--- linux-2.4.24-pre1/arch/mips/mm/c-r3k.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/mm/c-r3k.c	2003-12-22 11:34:33.000000000 -0800
@@ -23,9 +23,6 @@
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
 
-void r3k_clear_page(void * page);
-void r3k_copy_page(void * to, void * from);
-
 static unsigned long icache_size, dcache_size;		/* Size in bytes */
 static unsigned long icache_lsize, dcache_lsize;	/* Size in bytes */
 
@@ -320,11 +317,10 @@
 
 void __init ld_mmu_r23000(void)
 {
+	extern void build_clear_page(void);
+	extern void build_copy_page(void);
 	unsigned long config;
 
-	_clear_page = r3k_clear_page;
-	_copy_page = r3k_copy_page;
-
 	r3k_probe_cache();
 
 	_flush_cache_all = r3k_flush_cache_all;
@@ -344,4 +340,7 @@
 		icache_size >> 10, icache_lsize);
 	printk("Primary data cache %ldkB, linesize %ld bytes.\n",
 		dcache_size >> 10, dcache_lsize);
+
+	build_clear_page();
+	build_copy_page();
 }
diff -urN linux-2.4.24-pre1/arch/mips/mm/c-r4k.c linux-2.4.24-pre2/arch/mips/mm/c-r4k.c
--- linux-2.4.24-pre1/arch/mips/mm/c-r4k.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/mm/c-r4k.c	2003-12-22 11:34:33.000000000 -0800
@@ -28,27 +28,6 @@
 
 static unsigned long icache_size, dcache_size, scache_size;
 
-extern void andes_clear_page(void * page);
-extern void r4k_clear_page32_d16(void * page);
-extern void r4k_clear_page32_d32(void * page);
-extern void r4k_clear_page_d16(void * page);
-extern void r4k_clear_page_d32(void * page);
-extern void r4k_clear_page_r4600_v1(void * page);
-extern void r4k_clear_page_r4600_v2(void * page);
-extern void r4k_clear_page_s16(void * page);
-extern void r4k_clear_page_s32(void * page);
-extern void r4k_clear_page_s64(void * page);
-extern void r4k_clear_page_s128(void * page);
-extern void andes_copy_page(void * to, void * from);
-extern void r4k_copy_page_d16(void * to, void * from);
-extern void r4k_copy_page_d32(void * to, void * from);
-extern void r4k_copy_page_r4600_v1(void * to, void * from);
-extern void r4k_copy_page_r4600_v2(void * to, void * from);
-extern void r4k_copy_page_s16(void * to, void * from);
-extern void r4k_copy_page_s32(void * to, void * from);
-extern void r4k_copy_page_s64(void * to, void * from);
-extern void r4k_copy_page_s128(void * to, void * from);
-
 /*
  * Dummy cache handling routines for machines without boardcaches
  */
@@ -775,6 +754,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 2;
 		c->dcache.waybit= ffs(dcache_size/2) - 1;
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_R5432:
@@ -788,6 +769,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 2;
 		c->dcache.waybit = 0;
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_TX49XX:
@@ -800,6 +783,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 4;
 		c->dcache.waybit = 0;
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_R4000PC:
@@ -818,6 +803,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 1;
 		c->dcache.waybit = 0;	/* does not matter */
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_R10000:
@@ -831,6 +818,8 @@
 		c->dcache.linesz = 32;
 		c->dcache.ways = 2;
 		c->dcache.waybit = 0;
+
+		c->options |= MIPS_CPU_PREFETCH;
 		break;
 
 	case CPU_VR4133:
@@ -845,6 +834,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 2;
 		c->dcache.waybit = ffs(dcache_size/2) - 1;
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_VR41XX:
@@ -862,6 +853,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 1;
 		c->dcache.waybit = 0;	/* does not matter */
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_RM7000:
@@ -877,6 +870,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 4;
 		c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1;
+
+		c->options |= MIPS_CPU_CACHE_CDEX | MIPS_CPU_PREFETCH;
 		break;
 
 	default:
@@ -920,6 +915,8 @@
 		              c->dcache.ways *
 		              c->dcache.linesz;
 		c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1;
+
+		c->options |= MIPS_CPU_PREFETCH;
 		break;
 	}
 
@@ -1040,71 +1037,6 @@
 	return 1;
 }
 
-static void __init setup_noscache_funcs(void)
-{
-	unsigned int prid;
-
-	switch (current_cpu_data.dcache.linesz) {
-	case 16:
-		if (cpu_has_64bits)
-			_clear_page = r4k_clear_page_d16;
-		else
-			_clear_page = r4k_clear_page32_d16;
-		_copy_page = r4k_copy_page_d16;
-
-		break;
-	case 32:
-		prid = read_c0_prid() & 0xfff0;
-		if (prid == 0x2010) {			/* R4600 V1.7 */
-			_clear_page = r4k_clear_page_r4600_v1;
-			_copy_page = r4k_copy_page_r4600_v1;
-		} else if (prid == 0x2020) {		/* R4600 V2.0 */
-			_clear_page = r4k_clear_page_r4600_v2;
-			_copy_page = r4k_copy_page_r4600_v2;
-		} else {
-			if (cpu_has_64bits)
-				_clear_page = r4k_clear_page_d32;
-			else
-				_clear_page = r4k_clear_page32_d32;
-			_copy_page = r4k_copy_page_d32;
-		}
-		break;
-	}
-}
-
-static void __init setup_scache_funcs(void)
-{
-	struct cpuinfo_mips *c = &current_cpu_data;
-
-	if (c->dcache.linesz > c->scache.linesz)
-		panic("Invalid primary cache configuration detected");
-
-	if (c->cputype == CPU_R10000 || c->cputype == CPU_R12000) {
-		_clear_page = andes_clear_page;
-		_copy_page = andes_copy_page;
-		return;
-	}
-
-	switch (c->scache.linesz) {
-	case 16:
-		_clear_page = r4k_clear_page_s16;
-		_copy_page = r4k_copy_page_s16;
-		break;
-	case 32:
-		_clear_page = r4k_clear_page_s32;
-		_copy_page = r4k_copy_page_s32;
-		break;
-	case 64:
-		_clear_page = r4k_clear_page_s64;
-		_copy_page = r4k_copy_page_s64;
-		break;
-	case 128:
-		_clear_page = r4k_clear_page_s128;
-		_copy_page = r4k_copy_page_s128;
-		break;
-	}
-}
-
 typedef int (*probe_func_t)(unsigned long);
 extern int r5k_sc_init(void);
 extern int rm7k_sc_init(void);
@@ -1143,7 +1075,6 @@
 
 	case CPU_R5000:
 	case CPU_NEVADA:
-		setup_noscache_funcs();
 #ifdef CONFIG_R5000_CPU_SCACHE
 		r5k_sc_init();
 #endif
@@ -1151,7 +1082,6 @@
 
 	case CPU_RM7000:
 	case CPU_RM9000:
-		setup_noscache_funcs();
 #ifdef CONFIG_RM7000_CPU_SCACHE
 		rm7k_sc_init();
 #endif
@@ -1161,10 +1091,8 @@
 		sc_present = 0;
 	}
 
-	if (!sc_present) {
-		setup_noscache_funcs();
+	if (!sc_present)
 		return;
-	}
 
 	if ((c->isa_level == MIPS_CPU_ISA_M32 ||
 	     c->isa_level == MIPS_CPU_ISA_M64) &&
@@ -1180,7 +1108,6 @@
 	       scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
 
 	c->options |= MIPS_CPU_SUBSET_CACHES;
-        setup_scache_funcs();
 }
 
 static inline void coherency_setup(void)
@@ -1209,6 +1136,8 @@
 
 void __init ld_mmu_r4xx0(void)
 {
+	extern void build_clear_page(void);
+	extern void build_copy_page(void);
 	extern char except_vec2_generic;
 	struct cpuinfo_mips *c = &current_cpu_data;
 
@@ -1251,4 +1180,7 @@
 #endif
 
 	__flush_cache_all();
+
+	build_clear_page();
+	build_copy_page();
 }
diff -urN linux-2.4.24-pre1/arch/mips/mm/c-sb1.c linux-2.4.24-pre2/arch/mips/mm/c-sb1.c
--- linux-2.4.24-pre1/arch/mips/mm/c-sb1.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/mm/c-sb1.c	2003-12-22 11:34:33.000000000 -0800
@@ -25,14 +25,7 @@
 #include <asm/cpu.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
 extern void sb1_dma_init(void);
-extern void sb1_clear_page_dma(void * page);
-extern void sb1_copy_page_dma(void * to, void * from);
-#else
-extern void sb1_clear_page(void * page);
-extern void sb1_copy_page(void * to, void * from);
-#endif
 
 /* These are probed at ld_mmu time */
 static unsigned long icache_size;
@@ -53,23 +46,6 @@
 static unsigned int icache_range_cutoff;
 static unsigned int dcache_range_cutoff;
 
-void pgd_init(unsigned long page)
-{
-	unsigned long *p = (unsigned long *) page;
-	int i;
-
-	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
-		p[i + 0] = (unsigned long) invalid_pte_table;
-		p[i + 1] = (unsigned long) invalid_pte_table;
-		p[i + 2] = (unsigned long) invalid_pte_table;
-		p[i + 3] = (unsigned long) invalid_pte_table;
-		p[i + 4] = (unsigned long) invalid_pte_table;
-		p[i + 5] = (unsigned long) invalid_pte_table;
-		p[i + 6] = (unsigned long) invalid_pte_table;
-		p[i + 7] = (unsigned long) invalid_pte_table;
-	}
-}
-
 /*
  * The dcache is fully coherent to the system, with one
  * big caveat:  the instruction stream.  In other words,
@@ -582,12 +558,7 @@
 	probe_cache_sizes();
 
 #ifdef CONFIG_SIBYTE_DMA_PAGEOPS
-	_clear_page = sb1_clear_page_dma;
-	_copy_page = sb1_copy_page_dma;
 	sb1_dma_init();
-#else
-	_clear_page = sb1_clear_page;
-	_copy_page = sb1_copy_page;
 #endif
 
 	/*
diff -urN linux-2.4.24-pre1/arch/mips/mm/c-tx39.c linux-2.4.24-pre2/arch/mips/mm/c-tx39.c
--- linux-2.4.24-pre1/arch/mips/mm/c-tx39.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/mm/c-tx39.c	2003-12-22 11:34:33.000000000 -0800
@@ -28,9 +28,6 @@
 
 #include <asm/r4kcache.h>
 
-extern void r3k_clear_page(void * page);
-extern void r3k_copy_page(void * to, void * from);
-
 extern int r3k_have_wired_reg;	/* in r3k-tlb.c */
 
 /* This sequence is required to ensure icache is disabled immediately */
@@ -409,11 +406,10 @@
 
 void __init ld_mmu_tx39(void)
 {
+	extern void build_clear_page(void);
+	extern void build_copy_page(void);
 	unsigned long config;
 
-	_clear_page = r3k_clear_page;
-	_copy_page = r3k_copy_page;
-
 	config = read_c0_conf();
 	config &= ~TX39_CONF_WBON;
 	write_c0_conf(config);
@@ -488,4 +484,7 @@
 		icache_size >> 10, current_cpu_data.icache.linesz);
 	printk("Primary data cache %ldkb, linesize %d bytes\n",
 		dcache_size >> 10, current_cpu_data.dcache.linesz);
+
+	build_clear_page();
+	build_copy_page();
 }
diff -urN linux-2.4.24-pre1/arch/mips/mm/init.c linux-2.4.24-pre2/arch/mips/mm/init.c
--- linux-2.4.24-pre1/arch/mips/mm/init.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/mm/init.c	2003-12-22 11:34:33.000000000 -0800
@@ -43,6 +43,23 @@
 static unsigned long totalram_pages;
 static unsigned long totalhigh_pages;
 
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for (i = 0; i < USER_PTRS_PER_PGD; i+=8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
+
 /*
  * We have upto 8 empty zeroed pages so we can map one of the right colour
  * when needed.  This is necessary only on R4000 / R4400 SC and MC versions
diff -urN linux-2.4.24-pre1/arch/mips/mm/loadmmu.c linux-2.4.24-pre2/arch/mips/mm/loadmmu.c
--- linux-2.4.24-pre1/arch/mips/mm/loadmmu.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/mm/loadmmu.c	2003-12-22 11:34:33.000000000 -0800
@@ -22,10 +22,6 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
-/* memory functions */
-void (*_clear_page)(void * page);
-void (*_copy_page)(void * to, void * from);
-
 /* Cache operations. */
 void (*_flush_cache_all)(void);
 void (*___flush_cache_all)(void);
diff -urN linux-2.4.24-pre1/arch/mips/mm/pg-r3k.c linux-2.4.24-pre2/arch/mips/mm/pg-r3k.c
--- linux-2.4.24-pre1/arch/mips/mm/pg-r3k.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/mm/pg-r3k.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-/* page functions */
-void r3k_clear_page(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"addiu\t$1,%0,%2\n"
-		"1:\tsw\t$0,(%0)\n\t"
-		"sw\t$0,4(%0)\n\t"
-		"sw\t$0,8(%0)\n\t"
-		"sw\t$0,12(%0)\n\t"
-		"addiu\t%0,32\n\t"
-		"sw\t$0,-16(%0)\n\t"
-		"sw\t$0,-12(%0)\n\t"
-		"sw\t$0,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t$0,-4(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE)
-		: "memory");
-}
-
-void r3k_copy_page(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"addiu\t$1,%0,%8\n"
-		"1:\tlw\t%2,(%1)\n\t"
-		"lw\t%3,4(%1)\n\t"
-		"lw\t%4,8(%1)\n\t"
-		"lw\t%5,12(%1)\n\t"
-		"sw\t%2,(%0)\n\t"
-		"sw\t%3,4(%0)\n\t"
-		"sw\t%4,8(%0)\n\t"
-		"sw\t%5,12(%0)\n\t"
-		"lw\t%2,16(%1)\n\t"
-		"lw\t%3,20(%1)\n\t"
-		"lw\t%4,24(%1)\n\t"
-		"lw\t%5,28(%1)\n\t"
-		"sw\t%2,16(%0)\n\t"
-		"sw\t%3,20(%0)\n\t"
-		"sw\t%4,24(%0)\n\t"
-		"sw\t%5,28(%0)\n\t"
-		"addiu\t%0,64\n\t"
-		"addiu\t%1,64\n\t"
-		"lw\t%2,-32(%1)\n\t"
-		"lw\t%3,-28(%1)\n\t"
-		"lw\t%4,-24(%1)\n\t"
-		"lw\t%5,-20(%1)\n\t"
-		"sw\t%2,-32(%0)\n\t"
-		"sw\t%3,-28(%0)\n\t"
-		"sw\t%4,-24(%0)\n\t"
-		"sw\t%5,-20(%0)\n\t"
-		"lw\t%2,-16(%1)\n\t"
-		"lw\t%3,-12(%1)\n\t"
-		"lw\t%4,-8(%1)\n\t"
-		"lw\t%5,-4(%1)\n\t"
-		"sw\t%2,-16(%0)\n\t"
-		"sw\t%3,-12(%0)\n\t"
-		"sw\t%4,-8(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sw\t%5,-4(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (dummy1), "=r" (dummy2),
-		  "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		: "0" (to), "1" (from),
-		  "I" (PAGE_SIZE));
-}
-
-/*
- * Initialize new page directory with pointers to invalid ptes
- */
-void pgd_init(unsigned long page)
-{
-	unsigned long dummy1, dummy2;
-
-	/*
-	 * The plain and boring version for the R3000.  No cache flushing
-	 * stuff is implemented since the R3000 has physical caches.
-	 */
-	__asm__ __volatile__(
-		".set\tnoreorder\n"
-		"1:\tsw\t%2, (%0)\n\t"
-		"sw\t%2, 4(%0)\n\t"
-		"sw\t%2, 8(%0)\n\t"
-		"sw\t%2, 12(%0)\n\t"
-		"sw\t%2, 16(%0)\n\t"
-		"sw\t%2, 20(%0)\n\t"
-		"sw\t%2, 24(%0)\n\t"
-		"sw\t%2, 28(%0)\n\t"
-		"subu\t%1, 1\n\t"
-		"bnez\t%1, 1b\n\t"
-		"addiu\t%0, 32\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2)
-		:"r" ((unsigned long) invalid_pte_table), "0" (page),
-		 "1" (USER_PTRS_PER_PGD / 8));
-}
diff -urN linux-2.4.24-pre1/arch/mips/mm/pg-r4k.S linux-2.4.24-pre2/arch/mips/mm/pg-r4k.S
--- linux-2.4.24-pre1/arch/mips/mm/pg-r4k.S	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/mm/pg-r4k.S	1969-12-31 16:00:00.000000000 -0800
@@ -1,803 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * r4xx0.c: R4000 processor variant specific MMU/Cache routines.
- *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997,  1998,  1999,  2000 Ralf Baechle ralf@gnu.org
- */
-#include <linux/config.h>
-#include <asm/addrspace.h>
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/cacheops.h>
-#include <asm/mipsregs.h>
-#include <asm/offset.h>
-
-#ifdef CONFIG_64BIT_PHYS_ADDR
-#define PGD_SIZE	0x2000
-#else
-#define PGD_SIZE	0x1000
-#endif
-
-	.text
-	.set	noat
-
-/*
- * Zero an entire page.  Basically a simple unrolled loop should do the
- * job but we want more performance by saving memory bus bandwidth.  We
- * have five flavours of the routine available for:
- *
- * - 16byte cachelines and no second level cache
- * - 32byte cachelines second level cache
- * - a version which handles the buggy R4600 v1.x
- * - a version which handles the buggy R4600 v2.0
- * - Finally a last version without fancy cache games for the SC and MC
- *   versions of R4000 and R4400.
- */
-
-LEAF(r4k_clear_page32_d16)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_D, (a0)
-	sw	zero, (a0)
-	sw	zero, 4(a0)
-	sw	zero, 8(a0)
-	sw	zero, 12(a0)
-	addiu	a0, 32
-	cache	Create_Dirty_Excl_D, -16(a0)
-	sw	zero, -16(a0)
-	sw	zero, -12(a0)
-	sw	zero, -8(a0)
-	sw	zero, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_clear_page32_d16)
-
-LEAF(r4k_clear_page32_d32)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_D, (a0)
-	sw	zero, (a0)
-	sw	zero, 4(a0)
-	sw	zero, 8(a0)
-	sw	zero, 12(a0)
-	addiu	a0, 32
-	sw	zero, -16(a0)
-	sw	zero, -12(a0)
-	sw	zero, -8(a0)
-	sw	zero, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_clear_page32_d32)
-
-LEAF(r4k_clear_page_d16)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_D, (a0)
-	sd	zero, (a0)
-	sd	zero, 8(a0)
-	cache	Create_Dirty_Excl_D, 16(a0)
-	sd	zero, 16(a0)
-	sd	zero, 24(a0)
-	addiu	a0, 64
-	cache	Create_Dirty_Excl_D, -32(a0)
-	sd	zero, -32(a0)
-	sd	zero, -24(a0)
-	cache	Create_Dirty_Excl_D, -16(a0)
-	sd	zero, -16(a0)
-	sd	zero, -8(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_clear_page_d16)
-
-LEAF(r4k_clear_page_d32)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_D, (a0)
-	sd	zero, (a0)
-	sd	zero, 8(a0)
-	sd	zero, 16(a0)
-	sd	zero, 24(a0)
-	addiu	a0, 64
-	cache	Create_Dirty_Excl_D, -32(a0)
-	sd	zero, -32(a0)
-	sd	zero, -24(a0)
-	sd	zero, -16(a0)
-	sd	zero, -8(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_clear_page_d32)
-
-/*
- * This flavour of r4k_clear_page is for the R4600 V1.x.  Cite from the
- * IDT R4600 V1.7 errata:
- *
- *  18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
- *      Hit_Invalidate_D and Create_Dirty_Excl_D should only be
- *      executed if there is no other dcache activity. If the dcache is
- *      accessed for another instruction immeidately preceding when these
- *      cache instructions are executing, it is possible that the dcache
- *      tag match outputs used by these cache instructions will be
- *      incorrect. These cache instructions should be preceded by at least
- *      four instructions that are not any kind of load or store
- *      instruction.
- *
- *      This is not allowed:    lw
- *                              nop
- *                              nop
- *                              nop
- *                              cache       Hit_Writeback_Invalidate_D
- *
- *      This is allowed:        lw
- *                              nop
- *                              nop
- *                              nop
- *                              nop
- *                              cache       Hit_Writeback_Invalidate_D
- */
-
-LEAF(r4k_clear_page_r4600_v1)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	nop
-	nop
-	nop
-	nop
-	cache	Create_Dirty_Excl_D, (a0)
-	sd	zero, (a0)
-	sd	zero, 8(a0)
-	sd	zero, 16(a0)
-	sd	zero, 24(a0)
-	addiu	a0, 64
-	nop
-	nop
-	nop
-	cache	Create_Dirty_Excl_D, -32(a0)
-	sd	zero, -32(a0)
-	sd	zero, -24(a0)
-	sd	zero, -16(a0)
-	sd	zero, -8(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_clear_page_r4600_v1)
-
-LEAF(r4k_clear_page_r4600_v2)
-	.set	mips3
-	mfc0	a1, CP0_STATUS
-	ori	AT, a1, 1
-	xori	AT, 1
-	mtc0	AT, CP0_STATUS
-	nop
-	nop
-	nop
-
-	.set	volatile
-	la	AT, KSEG1
-	lw	zero, (AT)
-	.set	novolatile
-
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_D, (a0)
-	sd	zero, (a0)
-	sd	zero, 8(a0)
-	sd	zero, 16(a0)
-	sd	zero, 24(a0)
-	addiu	a0, 64
-	cache	Create_Dirty_Excl_D, -32(a0)
-	sd	zero, -32(a0)
-	sd	zero, -24(a0)
-	sd	zero, -16(a0)
-	sd	zero, -8(a0)
-	bne	AT, a0, 1b
-
-	mfc0	AT, CP0_STATUS			# __restore_flags
-	andi	a1, 1
-	ori	AT, 1
-	xori	AT, 1
-	or	a1, AT
-	mtc0	a1, CP0_STATUS
-	nop
-	nop
-	nop
-
-	jr	ra
-	END(r4k_clear_page_r4600_v2)
-
-/*
- * The next 4 versions are optimized for all possible scache configurations
- * of the SC / MC versions of R4000 and R4400 ...
- *
- * Todo: For even better performance we should have a routine optimized for
- * every legal combination of dcache / scache linesize.  When I (Ralf) tried
- * this the kernel crashed shortly after mounting the root filesystem.  CPU
- * bug?  Weirdo cache instruction semantics?
- */
-
-LEAF(r4k_clear_page_s16)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_SD, (a0)
-	sd	zero, (a0)
-	sd	zero, 8(a0)
-	cache	Create_Dirty_Excl_SD, 16(a0)
-	sd	zero, 16(a0)
-	sd	zero, 24(a0)
-	addiu	a0, 64
-	cache	Create_Dirty_Excl_SD, -32(a0)
-	sd	zero, -32(a0)
-	sd	zero, -24(a0)
-	cache	Create_Dirty_Excl_SD, -16(a0)
-	sd	zero, -16(a0)
-	sd	zero, -8(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_clear_page_s16)
-
-LEAF(r4k_clear_page_s32)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_SD, (a0)
-	sd	zero, (a0)
-	sd	zero, 8(a0)
-	sd	zero, 16(a0)
-	sd	zero, 24(a0)
-	addiu	a0, 64
-	cache	Create_Dirty_Excl_SD, -32(a0)
-	sd	zero, -32(a0)
-	sd	zero, -24(a0)
-	sd	zero, -16(a0)
-	sd	zero, -8(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_clear_page_s32)
-
-LEAF(r4k_clear_page_s64)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_SD, (a0)
-	sd	zero, (a0)
-	sd	zero, 8(a0)
-	sd	zero, 16(a0)
-	sd	zero, 24(a0)
-	addiu	a0, 64
-	sd	zero, -32(a0)
-	sd	zero, -24(a0)
-	sd	zero, -16(a0)
-	sd	zero, -8(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_clear_page_s64)
-
-LEAF(r4k_clear_page_s128)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_SD, (a0)
-	sd	zero, (a0)
-	sd	zero, 8(a0)
-	sd	zero, 16(a0)
-	sd	zero, 24(a0)
-	sd	zero, 32(a0)
-	sd	zero, 40(a0)
-	sd	zero, 48(a0)
-	sd	zero, 56(a0)
-	addiu	a0, 128
-	sd	zero, -64(a0)
-	sd	zero, -56(a0)
-	sd	zero, -48(a0)
-	sd	zero, -40(a0)
-	sd	zero, -32(a0)
-	sd	zero, -24(a0)
-	sd	zero, -16(a0)
-	sd	zero, -8(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_clear_page_s128)
-
-/*
- * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
- * with 64-bit kernels.  The prefetch offsets have been experimentally tuned
- * an Origin 200.
- */
-LEAF(andes_clear_page)
-	.set		mips4
-	LONG_ADDIU	AT, a0, _PAGE_SIZE
-1:	pref		7, 512(a0)
-	sd		zero, 0*SZREG(a0)
-	sd		zero, 1*SZREG(a0)
-	sd		zero, 2*SZREG(a0)
-	sd		zero, 3*SZREG(a0)
-	LONG_ADDIU	a0, a0, 8*SZREG
-	sd		zero, -4*SZREG(a0)
-	sd		zero, -3*SZREG(a0)
-	sd		zero, -2*SZREG(a0)
-	sd		zero, -1*SZREG(a0)
-	bne		AT, a0, 1b
-	j		ra
-	END(andes_clear_page)
-	.set		mips0
-
-/*
- * This is still inefficient.  We only can do better if we know the
- * virtual address where the copy will be accessed.
- */
-
-LEAF(r4k_copy_page_d16)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_D, (a0)
-	lw	a3, (a1)
-	lw	a2, 4(a1)
-	lw	v1, 8(a1)
-	lw	v0, 12(a1)
-	sw	a3, (a0)
-	sw	a2, 4(a0)
-	sw	v1, 8(a0)
-	sw	v0, 12(a0)
-	cache	Create_Dirty_Excl_D, 16(a0)
-	lw	a3, 16(a1)
-	lw	a2, 20(a1)
-	lw	v1, 24(a1)
-	lw	v0, 28(a1)
-	sw	a3, 16(a0)
-	sw	a2, 20(a0)
-	sw	v1, 24(a0)
-	sw	v0, 28(a0)
-	cache	Create_Dirty_Excl_D, 32(a0)
-	addiu	a0, 64
-	addiu	a1, 64
-	lw	a3, -32(a1)
-	lw	a2, -28(a1)
-	lw	v1, -24(a1)
-	lw	v0, -20(a1)
-	sw	a3, -32(a0)
-	sw	a2, -28(a0)
-	sw	v1, -24(a0)
-	sw	v0, -20(a0)
-	cache	Create_Dirty_Excl_D, -16(a0)
-	lw	a3, -16(a1)
-	lw	a2, -12(a1)
-	lw	v1, -8(a1)
-	lw	v0, -4(a1)
-	sw	a3, -16(a0)
-	sw	a2, -12(a0)
-	sw	v1, -8(a0)
-	sw	v0, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_copy_page_d16)
-
-LEAF(r4k_copy_page_d32)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_D, (a0)
-	lw	a3, (a1)
-	lw	a2, 4(a1)
-	lw	v1, 8(a1)
-	lw	v0, 12(a1)
-	sw	a3, (a0)
-	sw	a2, 4(a0)
-	sw	v1, 8(a0)
-	sw	v0, 12(a0)
-	lw	a3, 16(a1)
-	lw	a2, 20(a1)
-	lw	v1, 24(a1)
-	lw	v0, 28(a1)
-	sw	a3, 16(a0)
-	sw	a2, 20(a0)
-	sw	v1, 24(a0)
-	sw	v0, 28(a0)
-	cache	Create_Dirty_Excl_D, 32(a0)
-	addiu	a0, 64
-	addiu	a1, 64
-	lw	a3, -32(a1)
-	lw	a2, -28(a1)
-	lw	v1, -24(a1)
-	lw	v0, -20(a1)
-	sw	a3, -32(a0)
-	sw	a2, -28(a0)
-	sw	v1, -24(a0)
-	sw	v0, -20(a0)
-	lw	a3, -16(a1)
-	lw	a2, -12(a1)
-	lw	v1, -8(a1)
-	lw	v0, -4(a1)
-	sw	a3, -16(a0)
-	sw	a2, -12(a0)
-	sw	v1, -8(a0)
-	sw	v0, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_copy_page_d32)
-
-/*
- * Again a special version for the R4600 V1.x
- */
-
-LEAF(r4k_copy_page_r4600_v1)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	nop
-	nop
-	nop
-	nop
-	cache	Create_Dirty_Excl_D, (a0)
-	lw	a3, (a1)
-	lw	a2, 4(a1)
-	lw	v1, 8(a1)
-	lw	v0, 12(a1)
-	sw	a3, (a0)
-	sw	a2, 4(a0)
-	sw	v1, 8(a0)
-	sw	v0, 12(a0)
-	lw	a3, 16(a1)
-	lw	a2, 20(a1)
-	lw	v1, 24(a1)
-	lw	v0, 28(a1)
-	sw	a3, 16(a0)
-	sw	a2, 20(a0)
-	sw	v1, 24(a0)
-	sw	v0, 28(a0)
-	nop
-	nop
-	nop
-	nop
-	cache	Create_Dirty_Excl_D, 32(a0)
-	addiu	a0, 64
-	addiu	a1, 64
-	lw	a3, -32(a1)
-	lw	a2, -28(a1)
-	lw	v1, -24(a1)
-	lw	v0, -20(a1)
-	sw	a3, -32(a0)
-	sw	a2, -28(a0)
-	sw	v1, -24(a0)
-	sw	v0, -20(a0)
-	lw	a3, -16(a1)
-	lw	a2, -12(a1)
-	lw	v1, -8(a1)
-	lw	v0, -4(a1)
-	sw	a3, -16(a0)
-	sw	a2, -12(a0)
-	sw	v1, -8(a0)
-	sw	v0, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_copy_page_r4600_v1)
-
-LEAF(r4k_copy_page_r4600_v2)
-	.set	mips3
-	mfc0	v1, CP0_STATUS
-	ori	AT, v1, 1
-	xori	AT, 1
-
-	mtc0	AT, CP0_STATUS
-	nop
-	nop
-	nop
-
-	addiu	AT, a0, _PAGE_SIZE
-1:	nop
-	nop
-	nop
-	nop
-	cache	Create_Dirty_Excl_D, (a0)
-	lw	t1, (a1)
-	lw	t0, 4(a1)
-	lw	a3, 8(a1)
-	lw	a2, 12(a1)
-	sw	t1, (a0)
-	sw	t0, 4(a0)
-	sw	a3, 8(a0)
-	sw	a2, 12(a0)
-	lw	t1, 16(a1)
-	lw	t0, 20(a1)
-	lw	a3, 24(a1)
-	lw	a2, 28(a1)
-	sw	t1, 16(a0)
-	sw	t0, 20(a0)
-	sw	a3, 24(a0)
-	sw	a2, 28(a0)
-	nop
-	nop
-	nop
-	nop
-	cache	Create_Dirty_Excl_D, 32(a0)
-	addiu	a0, 64
-	addiu	a1, 64
-	lw	t1, -32(a1)
-	lw	t0, -28(a1)
-	lw	a3, -24(a1)
-	lw	a2, -20(a1)
-	sw	t1, -32(a0)
-	sw	t0, -28(a0)
-	sw	a3, -24(a0)
-	sw	a2, -20(a0)
-	lw	t1, -16(a1)
-	lw	t0, -12(a1)
-	lw	a3, -8(a1)
-	lw	a2, -4(a1)
-	sw	t1, -16(a0)
-	sw	t0, -12(a0)
-	sw	a3, -8(a0)
-	sw	a2, -4(a0)
-	bne	AT, a0, 1b
-
-	mfc0	AT, CP0_STATUS			# __restore_flags
-	andi	v1, 1
-	ori	AT, 1
-	xori	AT, 1
-	or	v1, AT
-	mtc0	v1, CP0_STATUS
-	nop
-	nop
-	nop
-	jr	ra
-	END(r4k_copy_page_r4600_v2)
-
-/*
- * These are for R4000SC / R4400MC
- */
-
-LEAF(r4k_copy_page_s16)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_SD, (a0)
-	lw	a3, (a1)
-	lw	a2, 4(a1)
-	lw	v1, 8(a1)
-	lw	v0, 12(a1)
-	sw	a3, (a0)
-	sw	a2, 4(a0)
-	sw	v1, 8(a0)
-	sw	v0, 12(a0)
-	cache	Create_Dirty_Excl_SD, 16(a0)
-	lw	a3, 16(a1)
-	lw	a2, 20(a1)
-	lw	v1, 24(a1)
-	lw	v0, 28(a1)
-	sw	a3, 16(a0)
-	sw	a2, 20(a0)
-	sw	v1, 24(a0)
-	sw	v0, 28(a0)
-	cache	Create_Dirty_Excl_SD, 32(a0)
-	addiu	a0, 64
-	addiu	a1, 64
-	lw	a3, -32(a1)
-	lw	a2, -28(a1)
-	lw	v1, -24(a1)
-	lw	v0, -20(a1)
-	sw	a3, -32(a0)
-	sw	a2, -28(a0)
-	sw	v1, -24(a0)
-	sw	v0, -20(a0)
-	cache	Create_Dirty_Excl_SD, -16(a0)
-	lw	a3, -16(a1)
-	lw	a2, -12(a1)
-	lw	v1, -8(a1)
-	lw	v0, -4(a1)
-	sw	a3, -16(a0)
-	sw	a2, -12(a0)
-	sw	v1, -8(a0)
-	sw	v0, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_copy_page_s16)
-
-LEAF(r4k_copy_page_s32)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_SD, (a0)
-	lw	a3, (a1)
-	lw	a2, 4(a1)
-	lw	v1, 8(a1)
-	lw	v0, 12(a1)
-	sw	a3, (a0)
-	sw	a2, 4(a0)
-	sw	v1, 8(a0)
-	sw	v0, 12(a0)
-	lw	a3, 16(a1)
-	lw	a2, 20(a1)
-	lw	v1, 24(a1)
-	lw	v0, 28(a1)
-	sw	a3, 16(a0)
-	sw	a2, 20(a0)
-	sw	v1, 24(a0)
-	sw	v0, 28(a0)
-	cache	Create_Dirty_Excl_SD, 32(a0)
-	addiu	a0, 64
-	addiu	a1, 64
-	lw	a3, -32(a1)
-	lw	a2, -28(a1)
-	lw	v1, -24(a1)
-	lw	v0, -20(a1)
-	sw	a3, -32(a0)
-	sw	a2, -28(a0)
-	sw	v1, -24(a0)
-	sw	v0, -20(a0)
-	lw	a3, -16(a1)
-	lw	a2, -12(a1)
-	lw	v1, -8(a1)
-	lw	v0, -4(a1)
-	sw	a3, -16(a0)
-	sw	a2, -12(a0)
-	sw	v1, -8(a0)
-	sw	v0, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_copy_page_s32)
-
-LEAF(r4k_copy_page_s64)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_SD, (a0)
-	lw	a3, (a1)
-	lw	a2, 4(a1)
-	lw	v1, 8(a1)
-	lw	v0, 12(a1)
-	sw	a3, (a0)
-	sw	a2, 4(a0)
-	sw	v1, 8(a0)
-	sw	v0, 12(a0)
-	lw	a3, 16(a1)
-	lw	a2, 20(a1)
-	lw	v1, 24(a1)
-	lw	v0, 28(a1)
-	sw	a3, 16(a0)
-	sw	a2, 20(a0)
-	sw	v1, 24(a0)
-	sw	v0, 28(a0)
-	addiu	a0, 64
-	addiu	a1, 64
-	lw	a3, -32(a1)
-	lw	a2, -28(a1)
-	lw	v1, -24(a1)
-	lw	v0, -20(a1)
-	sw	a3, -32(a0)
-	sw	a2, -28(a0)
-	sw	v1, -24(a0)
-	sw	v0, -20(a0)
-	lw	a3, -16(a1)
-	lw	a2, -12(a1)
-	lw	v1, -8(a1)
-	lw	v0, -4(a1)
-	sw	a3, -16(a0)
-	sw	a2, -12(a0)
-	sw	v1, -8(a0)
-	sw	v0, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_copy_page_s64)
-
-LEAF(r4k_copy_page_s128)
-	.set	mips3
-	addiu	AT, a0, _PAGE_SIZE
-1:	cache	Create_Dirty_Excl_SD, (a0)
-	lw	a3, (a1)
-	lw	a2, 4(a1)
-	lw	v1, 8(a1)
-	lw	v0, 12(a1)
-	sw	a3, (a0)
-	sw	a2, 4(a0)
-	sw	v1, 8(a0)
-	sw	v0, 12(a0)
-	lw	a3, 16(a1)
-	lw	a2, 20(a1)
-	lw	v1, 24(a1)
-	lw	v0, 28(a1)
-	sw	a3, 16(a0)
-	sw	a2, 20(a0)
-	sw	v1, 24(a0)
-	sw	v0, 28(a0)
-	lw	a3, 32(a1)
-	lw	a2, 36(a1)
-	lw	v1, 40(a1)
-	lw	v0, 44(a1)
-	sw	a3, 32(a0)
-	sw	a2, 36(a0)
-	sw	v1, 40(a0)
-	sw	v0, 44(a0)
-	lw	a3, 48(a1)
-	lw	a2, 52(a1)
-	lw	v1, 56(a1)
-	lw	v0, 60(a1)
-	sw	a3, 48(a0)
-	sw	a2, 52(a0)
-	sw	v1, 56(a0)
-	sw	v0, 60(a0)
-	addiu	a0, 128
-	addiu	a1, 128
-	lw	a3, -64(a1)
-	lw	a2, -60(a1)
-	lw	v1, -56(a1)
-	lw	v0, -52(a1)
-	sw	a3, -64(a0)
-	sw	a2, -60(a0)
-	sw	v1, -56(a0)
-	sw	v0, -52(a0)
-	lw	a3, -48(a1)
-	lw	a2, -44(a1)
-	lw	v1, -40(a1)
-	lw	v0, -36(a1)
-	sw	a3, -48(a0)
-	sw	a2, -44(a0)
-	sw	v1, -40(a0)
-	sw	v0, -36(a0)
-	lw	a3, -32(a1)
-	lw	a2, -28(a1)
-	lw	v1, -24(a1)
-	lw	v0, -20(a1)
-	sw	a3, -32(a0)
-	sw	a2, -28(a0)
-	sw	v1, -24(a0)
-	sw	v0, -20(a0)
-	lw	a3, -16(a1)
-	lw	a2, -12(a1)
-	lw	v1, -8(a1)
-	lw	v0, -4(a1)
-	sw	a3, -16(a0)
-	sw	a2, -12(a0)
-	sw	v1, -8(a0)
-	sw	v0, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(r4k_copy_page_s128)
-
-
-	.text
-	.set	mips4
-	.set	noat
-
-
-/*
- * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
- * with 64-bit kernels.  The prefetch offsets have been experimentally tuned
- * an Origin 200.
- */
-LEAF(andes_copy_page)
-	.set		mips4
-	LONG_ADDIU	AT, a0, _PAGE_SIZE
-1:	pref		0, 2*128(a1)
-	pref		1, 2*128(a0)
-	LONG_L		a3, 0*SZREG(a1)
-	LONG_L		a2, 1*SZREG(a1)
-	LONG_L		v1, 2*SZREG(a1)
-	LONG_L		v0, 3*SZREG(a1)
-	LONG_S		a3, 0*SZREG(a0)
-	LONG_S		a2, 1*SZREG(a0)
-	LONG_S		v1, 2*SZREG(a0)
-	LONG_S		v0, 3*SZREG(a0)
-	LONG_ADDIU	a0, a0, 8*SZREG
-	LONG_ADDIU	a1, a1, 8*SZREG
-	LONG_L		a3, -4*SZREG(a1)
-	LONG_L		a2, -3*SZREG(a1)
-	LONG_L		v1, -2*SZREG(a1)
-	LONG_L		v0, -1*SZREG(a1)
-	LONG_S		a3, -4*SZREG(a0)
-	LONG_S		a2, -3*SZREG(a0)
-	LONG_S		v1, -2*SZREG(a0)
-	LONG_S		v0, -1*SZREG(a0)
-	bne		AT, a0,1b
-	j		ra
-	END(andes_copy_page)
-	.set		mips0
-
-/* This one still needs to receive cache optimizations  */
-LEAF(pgd_init)
-	.set	mips0
-	addiu	AT, a0, PGD_SIZE / 2
-	la	v0, invalid_pte_table
-1:	sw	v0, (a0)
-	sw	v0, 4(a0)
-	sw	v0, 8(a0)
-	sw	v0, 12(a0)
-	addiu	a0, 32
-	sw	v0, -16(a0)
-	sw	v0, -12(a0)
-	sw	v0, -8(a0)
-	sw	v0, -4(a0)
-	bne	AT, a0, 1b
-	jr	ra
-	END(pgd_init)
diff -urN linux-2.4.24-pre1/arch/mips/mm/pg-r4k.c linux-2.4.24-pre2/arch/mips/mm/pg-r4k.c
--- linux-2.4.24-pre1/arch/mips/mm/pg-r4k.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/mm/pg-r4k.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,470 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org)
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+
+#include <asm/cacheops.h>
+#include <asm/inst.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/prefetch.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+#include <asm/mmu_context.h>
+#include <asm/cpu.h>
+#include <asm/war.h>
+
+/*
+ * Maximum sizes:
+ *
+ * R4000 16 bytes D-cache, 128 bytes S-cache:		0x78 bytes
+ * R4600 v1.7:						0x5c bytes
+ * R4600 v2.0:						0x60 bytes
+ * With prefetching, 16 byte strides			0xa0 bytes
+ */
+
+static unsigned int clear_page_array[0xa0 / 4];
+
+void clear_page(void * page) __attribute__((alias("clear_page_array")));
+
+/*
+ * Maximum sizes:
+ *
+ * R4000 16 bytes D-cache, 128 bytes S-cache:		0xbc bytes
+ * R4600 v1.7:						0x80 bytes
+ * R4600 v2.0:						0x84 bytes
+ * With prefetching, 16 byte strides			0xb8 bytes
+ */
+static unsigned int copy_page_array[0xb8 / 4];
+
+void copy_page(void *to, void *from) __attribute__((alias("copy_page_array")));
+
+/*
+ * An address fits into a single register so it's safe to use 64-bit registers
+ * if we have 64-bit adresses.
+ */
+#define cpu_has_64bit_registers	cpu_has_64bit_addresses
+
+/*
+ * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
+ * with 64-bit kernels.  The prefetch offsets have been experimentally tuned
+ * an Origin 200.
+ */
+static int pref_offset_clear __initdata = 512;
+static int pref_offset_copy  __initdata = 256;
+
+static unsigned int pref_src_mode __initdata;
+static unsigned int pref_dst_mode __initdata;
+
+static int has_scache __initdata = 0;
+static int load_offset __initdata = 0;
+static int store_offset __initdata = 0;
+
+static unsigned int __initdata *dest, *epc;
+
+static inline void build_src_pref(int advance)
+{
+	if (!(load_offset & (cpu_dcache_line_size() - 1))) {
+		union mips_instruction mi;
+
+		mi.i_format.opcode     = pref_op;
+		mi.i_format.rs         = 5;		/* $a1 */
+		mi.i_format.rt         = pref_src_mode;
+		mi.i_format.simmediate = load_offset + advance;
+
+		*epc++ = mi.word;
+	}
+}
+
+static inline void __build_load_reg(int reg)
+{
+	union mips_instruction mi;
+
+	if (cpu_has_64bit_registers)
+		mi.i_format.opcode     = ld_op;
+	else
+		mi.i_format.opcode     = lw_op;
+	mi.i_format.rs         = 5;		/* $a1 */
+	mi.i_format.rt         = reg;		/* $zero */
+	mi.i_format.simmediate = load_offset;
+
+	load_offset += (cpu_has_64bit_registers ? 8 : 4);
+
+	*epc++ = mi.word;
+}
+
+static inline void build_load_reg(int reg)
+{
+	if (cpu_has_prefetch)
+		build_src_pref(pref_offset_copy);
+
+	__build_load_reg(reg);
+}
+
+static inline void build_dst_pref(int advance)
+{
+	if (!(store_offset & (cpu_dcache_line_size() - 1))) {
+		union mips_instruction mi;
+
+		mi.i_format.opcode     = pref_op;
+		mi.i_format.rs         = 4;		/* $a0 */
+		mi.i_format.rt         = pref_dst_mode;
+		mi.i_format.simmediate = store_offset + advance;
+
+		*epc++ = mi.word;
+	}
+}
+
+static inline void build_cdex(void)
+{
+	union mips_instruction mi;
+
+	if (has_scache && !(store_offset & (cpu_scache_line_size() - 1))) {
+
+		mi.c_format.opcode     = cache_op;
+		mi.c_format.rs         = 4;	/* $a0 */
+		mi.c_format.c_op       = 3;	/* Create Dirty Exclusive */
+		mi.c_format.cache      = 3;	/* Secondary Data Cache */
+		mi.c_format.simmediate = store_offset;
+
+		*epc++ = mi.word;
+	}
+
+	if (store_offset & (cpu_dcache_line_size() - 1))
+		return;
+
+	if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) {
+		*epc++ = 0;			/* nop */
+		*epc++ = 0;			/* nop */
+		*epc++ = 0;			/* nop */
+		*epc++ = 0;			/* nop */
+	}
+
+	mi.c_format.opcode     = cache_op;
+	mi.c_format.rs         = 4;		/* $a0 */
+	mi.c_format.c_op       = 3;		/* Create Dirty Exclusive */
+	mi.c_format.cache      = 1;		/* Data Cache */
+	mi.c_format.simmediate = store_offset;
+
+	*epc++ = mi.word;
+}
+
+static inline void __build_store_zero_reg(void)
+{
+	union mips_instruction mi;
+
+	if (cpu_has_64bits)
+		mi.i_format.opcode     = sd_op;
+	else
+		mi.i_format.opcode     = sw_op;
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = 0;		/* $zero */
+	mi.i_format.simmediate = store_offset;
+
+	store_offset += (cpu_has_64bits ? 8 : 4);
+
+	*epc++ = mi.word;
+}
+
+static inline void __build_store_reg(int reg)
+{
+	union mips_instruction mi;
+	int reg_size;
+
+#ifdef CONFIG_MIPS32
+	if (cpu_has_64bit_registers && reg == 0) {
+		mi.i_format.opcode     = sd_op;
+		reg_size               = 8;
+	} else {
+		mi.i_format.opcode     = sw_op;
+		reg_size               = 4;
+	}
+#endif
+#ifdef CONFIG_MIPS64
+	mi.i_format.opcode     = sd_op;
+	reg_size               = 8;
+#endif
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = reg;		/* $zero */
+	mi.i_format.simmediate = store_offset;
+
+	store_offset += reg_size;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_store_reg(int reg)
+{
+	if (cpu_has_prefetch)
+		if (reg)
+			build_dst_pref(pref_offset_copy);
+		else
+			build_dst_pref(pref_offset_clear);
+	else if (cpu_has_cache_cdex)
+		build_cdex();
+
+	__build_store_reg(reg);
+}
+
+static inline void build_addiu_at_a0(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = 1;		/* $at */
+	mi.i_format.simmediate = offset;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_addiu_a1(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 5;		/* $a1 */
+	mi.i_format.rt         = 5;		/* $a1 */
+	mi.i_format.simmediate = offset;
+
+	load_offset -= offset;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_addiu_a0(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = 4;		/* $a0 */
+	mi.i_format.simmediate = offset;
+
+	store_offset -= offset;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_bne(unsigned int *dest)
+{
+	union mips_instruction mi;
+
+	mi.i_format.opcode = bne_op;
+	mi.i_format.rs     = 1;			/* $at */
+	mi.i_format.rt     = 4;			/* $a0 */
+	mi.i_format.simmediate = dest - epc - 1;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_nop(void)
+{
+	*epc++ = 0;
+}
+
+static inline void build_jr_ra(void)
+{
+	union mips_instruction mi;
+
+	mi.r_format.opcode = spec_op;
+	mi.r_format.rs     = 31;
+	mi.r_format.rt     = 0;
+	mi.r_format.rd     = 0;
+	mi.r_format.re     = 0;
+	mi.r_format.func   = jr_op;
+
+	*epc++ = mi.word;
+}
+
+void __init build_clear_page(void)
+{
+	epc = (unsigned int *) &clear_page_array;
+
+	if (cpu_has_prefetch) {
+		switch (current_cpu_data.cputype) {
+		case CPU_R10000:
+		case CPU_R12000:
+			pref_src_mode = Pref_LoadStreamed;
+			pref_dst_mode = Pref_StoreRetained;
+			break;
+		default:
+			pref_src_mode = Pref_LoadStreamed;
+			pref_dst_mode = Pref_PrepareForStore;
+			break;
+		}
+	}
+
+	build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) {
+		*epc++ = 0x40026000;		/* mfc0    $v0, $12	*/
+		*epc++ = 0x34410001;		/* ori     $at, v0, 0x1	*/
+		*epc++ = 0x38210001;		/* xori    $at, at, 0x1	*/
+		*epc++ = 0x40816000;		/* mtc0    $at, $12	*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x3c01a000;		/* lui     $at, 0xa000  */
+		*epc++ = 0x8c200000;		/* lw      $zero, ($at) */
+	}
+
+dest = epc;
+	build_store_reg(0);
+	build_store_reg(0);
+	build_store_reg(0);
+	build_store_reg(0);
+	if (has_scache && cpu_scache_line_size() == 128) {
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+	}
+	build_addiu_a0(2 * store_offset);
+	build_store_reg(0);
+	build_store_reg(0);
+	if (has_scache && cpu_scache_line_size() == 128) {
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+	}
+	build_store_reg(0);
+	build_bne(dest);
+	 build_store_reg(0);
+
+	if (cpu_has_prefetch && pref_offset_clear) {
+		build_addiu_at_a0(pref_offset_clear);
+	dest = epc;
+		__build_store_reg(0);
+		__build_store_reg(0);
+		__build_store_reg(0);
+		__build_store_reg(0);
+		build_addiu_a0(2 * store_offset);
+		__build_store_reg(0);
+		__build_store_reg(0);
+		__build_store_reg(0);
+		build_bne(dest);
+		 __build_store_reg(0);
+	}
+
+	build_jr_ra();
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		*epc++ = 0x40826000;		/* mtc0    $v0, $12	*/
+	else
+		build_nop();
+
+	flush_icache_range((unsigned long)&clear_page_array,
+	                   (unsigned long) epc);
+
+	BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array));
+}
+
+void __init build_copy_page(void)
+{
+	epc = (unsigned int *) &copy_page_array;
+
+	build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) {
+		*epc++ = 0x40026000;		/* mfc0    $v0, $12	*/
+		*epc++ = 0x34410001;		/* ori     $at, v0, 0x1	*/
+		*epc++ = 0x38210001;		/* xori    $at, at, 0x1	*/
+		*epc++ = 0x40816000;		/* mtc0    $at, $12	*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x3c01a000;		/* lui     $at, 0xa000  */
+		*epc++ = 0x8c200000;		/* lw      $zero, ($at) */
+	}
+
+dest = epc;
+	build_load_reg( 8);
+	build_load_reg( 9);
+	build_load_reg(10);
+	build_load_reg(11);
+	build_store_reg( 8);
+	build_store_reg( 9);
+	build_store_reg(10);
+	build_store_reg(11);
+	if (has_scache && cpu_scache_line_size() == 128) {
+		build_load_reg( 8);
+		build_load_reg( 9);
+		build_load_reg(10);
+		build_load_reg(11);
+		build_store_reg( 8);
+		build_store_reg( 9);
+		build_store_reg(10);
+		build_store_reg(11);
+	}
+	build_addiu_a0(2 * store_offset);
+	build_addiu_a1(2 * load_offset);
+	build_load_reg( 8);
+	build_load_reg( 9);
+	build_load_reg(10);
+	build_load_reg(11);
+	build_store_reg( 8);
+	build_store_reg( 9);
+	build_store_reg(10);
+	if (has_scache && cpu_scache_line_size() == 128) {
+		build_store_reg(11);
+		build_load_reg( 8);
+		build_load_reg( 9);
+		build_load_reg(10);
+		build_load_reg(11);
+		build_store_reg( 8);
+		build_store_reg( 9);
+		build_store_reg(10);
+	}
+	build_bne(dest);
+	 build_store_reg(11);
+
+	if (cpu_has_prefetch && pref_offset_copy) {
+		build_addiu_at_a0(pref_offset_copy);
+	dest = epc;
+		__build_load_reg( 8);
+		__build_load_reg( 9);
+		__build_load_reg(10);
+		__build_load_reg(11);
+		__build_store_reg( 8);
+		__build_store_reg( 9);
+		__build_store_reg(10);
+		__build_store_reg(11);
+		build_addiu_a0(2 * store_offset);
+		build_addiu_a1(2 * load_offset);
+		__build_load_reg( 8);
+		__build_load_reg( 9);
+		__build_load_reg(10);
+		__build_load_reg(11);
+		__build_store_reg( 8);
+		__build_store_reg( 9);
+		__build_store_reg(10);
+		build_bne(dest);
+		 __build_store_reg(11);
+	}
+
+	build_jr_ra();
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		*epc++ = 0x40826000;		/* mtc0    $v0, $12	*/
+	else
+		build_nop();
+
+	BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
+}
diff -urN linux-2.4.24-pre1/arch/mips/mm/pg-sb1.c linux-2.4.24-pre2/arch/mips/mm/pg-sb1.c
--- linux-2.4.24-pre1/arch/mips/mm/pg-sb1.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/mm/pg-sb1.c	2003-12-22 11:34:33.000000000 -0800
@@ -2,6 +2,7 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 2000 SiByte, Inc.
+ * Copyright (C) 2002, 2003 Broadcom Corporation
  *
  * Written by Justin Carlson of SiByte, Inc.
  *         and Kip Walker of Broadcom Corp.
@@ -40,8 +41,11 @@
 #define SB1_PREF_STORE_STREAMED_HINT "5"
 #endif
 
-/* These are the functions hooked by the memory management function pointers */
-void sb1_clear_page(void *page)
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+static inline void clear_page_cpu(void *page)
+#else
+void clear_page(void *page)
+#endif
 {
 	/*
 	 * JDCXXX - This should be bottlenecked by the write buffer, but these
@@ -80,7 +84,11 @@
 
 }
 
-void sb1_copy_page(void *to, void *from)
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+static inline void copy_page_cpu(void *to, void *from)
+#else
+void copy_page(void *to, void *from)
+#endif
 {
 	/*
 	 * This should be optimized in assembly...can't use ld/sd, though,
@@ -168,13 +176,13 @@
 	      IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE));
 }
 
-void sb1_clear_page_dma(void *page)
+void clear_page(void *page)
 {
 	int cpu = smp_processor_id();
 
 	/* if the page is above Kseg0, use old way */
 	if (KSEGX(page) != K0BASE)
-		return sb1_clear_page(page);
+		return clear_page_cpu(page);
 
 	page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
 	page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
@@ -189,7 +197,7 @@
 	in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE));
 }
 
-void sb1_copy_page_dma(void *to, void *from)
+void copy_page(void *to, void *from)
 {
 	unsigned long from_phys = PHYSADDR(from);
 	unsigned long to_phys = PHYSADDR(to);
@@ -197,7 +205,7 @@
 
 	/* if either page is above Kseg0, use old way */
 	if ((KSEGX(to) != K0BASE) || (KSEGX(from) != K0BASE))
-		return sb1_copy_page(to, from);
+		return copy_page_cpu(to, from);
 
 	page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
 	page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
@@ -212,4 +220,4 @@
 	in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE));
 }
 
-#endif
+#endif /* CONFIG_SIBYTE_DMA_PAGEOPS */
diff -urN linux-2.4.24-pre1/arch/mips/mm/tlb-r3k.c linux-2.4.24-pre2/arch/mips/mm/tlb-r3k.c
--- linux-2.4.24-pre1/arch/mips/mm/tlb-r3k.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/mm/tlb-r3k.c	2003-08-25 04:44:40.000000000 -0700
@@ -246,7 +246,6 @@
 
 void __init r3k_tlb_init(void)
 {
-	write_c0_pagemask(PM_DEFAULT_MASK);
 	local_flush_tlb_all();
 	memcpy((void *)KSEG0, &except_vec0_r2300, 0x80);
 	flush_icache_range(KSEG0, KSEG0 + 0x80);
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/Makefile linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/Makefile
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/Makefile	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,18 @@
+#
+# Makefile for the PMC-Sierra Titan 
+#
+
+.S.s:
+	$(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+	$(CC) $(CFLAGS) -c $< -o $*.o
+
+O_TARGET:= titan.o
+
+obj-y    += irq-handler.o irq.o i2c-yosemite.o prom.o setup.o
+
+obj-$(CONFIG_PCI)		+= pci-irq.o pci.o
+obj-$(CONFIG_SMP)          	+= smp.o
+obj-$(CONFIG_HYPERTRANSPORT)	+= ht-irq.o ht.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,171 @@
+/*
+ *  arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
+ *
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Description:
+ *
+ * This code reads the ATMEL 24CXX EEPROM. The PMC-Sierra Yosemite board uses the ATMEL
+ * 24C32/24C64 which uses two byte addressing as compared to 24C16. Note that this program
+ * uses the serial port like /dev/ttyS0, to communicate with the EEPROM. Hence, you are 
+ * expected to have a connectivity from the EEPROM to the serial port. This program does
+ * __not__ communicate using the I2C protocol
+ */
+
+#include "atmel_read_eeprom.h"
+
+static void delay(int delay)
+{
+	while (delay--);
+}
+
+static void send_bit(unsigned char bit)
+{
+	scl_lo;
+	delay(TXX);
+	if (bit)
+		sda_hi;
+	else
+		sda_lo;
+
+	delay(TXX);
+	scl_hi;
+	delay(TXX);
+}
+
+static void send_ack(void)
+{
+	send_bit(0);
+}
+
+static void send_byte(unsigned char byte)
+{
+	int	i = 0;
+	
+	for (i = 7; i >= 0; i--) 
+		send_bit((byte >> i) & 0x01);
+}
+	
+static void send_start(void)
+{
+	sda_hi; 
+	delay(TXX);
+	scl_hi;
+	delay(TXX);
+	sda_lo;
+	delay(TXX);
+}
+
+static void send_stop(void)
+{
+	sda_lo;
+	delay(TXX);
+	scl_hi;
+	delay(TXX);
+	sda_hi;
+	delay(TXX);
+}
+
+static void do_idle(void)
+{
+	sda_hi;
+	scl_hi;
+	vcc_off;
+}
+
+static int recv_bit(void)
+{
+	int	status;
+
+	scl_lo;
+	delay(TXX);
+	sda_hi;
+	delay(TXX);
+	scl_hi;
+	delay(TXX);
+
+	return 1;
+}
+
+static unsigned char recv_byte(void) {
+        int i;
+        unsigned char byte=0;
+
+        for (i=7;i>=0;i--)                             
+                byte |= (recv_bit() << i);
+ 
+        return byte;
+}
+
+static int recv_ack(void)
+{
+	unsigned int	ack;
+
+	ack = (unsigned int)recv_bit();
+	scl_lo;
+
+	if (ack) {
+		do_idle();
+		printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM \n");
+		return -1;
+	}
+
+	return ack;
+}
+
+/*
+ * This function does the actual read of the EEPROM. It needs the buffer into which the
+ * read data is copied, the size of the EEPROM being read and the buffer size
+ */
+int read_eeprom(char *buffer, int eeprom_size, int size)
+{
+	int	i = 0, err;
+
+	send_start();
+	send_byte(W_HEADER);
+	recv_ack();
+
+	/* EEPROM with size of more then 2K need two byte addressing */
+	if (eeprom_size > 2048) {
+		send_byte(0x00);
+		recv_ack();
+	}
+
+	send_start();
+	send_byte(R_HEADER);
+	err = recv_ack();
+	if (err == -1)
+		return err;
+
+	for (i = 0; i < size; i++) {
+		*buffer++ = recv_byte();
+		send_ack();
+	}
+
+	/* Note : We should do some check if the buffer contains correct information */
+
+	send_stop();
+}
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,68 @@
+/*
+ *  arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
+ *
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Header file for atmel_read_eeprom.c 
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <linux/init.h>
+#include <asm/termios.h>
+#include <asm/ioctls.h>
+#include <linux/ioctl.h>
+#include <linux/fcntl.h>
+
+#define	DEFAULT_PORT 	"/dev/ttyS0"	/* Port to open */
+#define	TXX		0 		/* Dummy loop for spinning */
+
+#define	BLOCK_SEL	0x00		
+#define	SLAVE_ADDR	0xa0
+#define	READ_BIT	0x01
+#define	WRITE_BIT	0x00
+#define	R_HEADER	SLAVE_ADDR + BLOCK_SEL + READ_BIT
+#define	W_HEADER	SLAVE_ADDR + BLOCK_SEL + WRITE_BIT
+
+/*
+ * Clock, Voltages and Data
+ */
+#define	vcc_off		(ioctl(fd, TIOCSBRK, 0))
+#define	vcc_on		(ioctl(fd, TIOCCBRK, 0))
+#define	sda_hi		(ioctl(fd, TIOCMBIS, &dtr))
+#define	sda_lo		(ioctl(fd, TIOCMBIC, &dtr))
+#define	scl_lo		(ioctl(fd, TIOCMBIC, &rts))
+#define	scl_hi		(ioctl(fd, TIOCMBIS, &rts))
+
+const char rts = TIOCM_RTS;
+const char dtr = TIOCM_DTR;
+int fd;
+
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/ht-irq.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/ht-irq.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/ht-irq.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/ht-irq.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+/*
+ * HT Bus fixup for the Titan
+ * XXX IRQ values need to change based on the board layout
+ */
+void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus)
+{
+        struct pci_bus *current_bus = bus;
+        struct pci_dev *devices;
+        struct list_head *devices_link;
+
+	list_for_each(devices_link, &(current_bus->devices)) {
+                devices = pci_dev_b(devices_link);
+                if (devices == NULL)
+                        continue;
+	}
+
+	/*
+	 * PLX and SPKT related changes go here
+	 */
+
+}
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/ht.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/ht.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/ht.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/ht.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,458 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+
+#include <linux/init.h>
+#include <asm/titan_dep.h>
+
+#ifdef CONFIG_HYPERTRANSPORT
+
+
+/*
+ * This function check if the Hypertransport Link Initialization completed. If
+ * it did, then proceed further with scanning bus #2
+ */
+static __inline__ int check_titan_htlink(void)
+{
+        u32 val;
+
+        val = *(volatile u_int32_t *)(RM9000x2_HTLINK_REG);
+        if (val & 0x00000020)
+                /* HT Link Initialization completed */
+                return 1;
+        else
+                return 0;
+}
+
+static int titan_ht_config_read_dword(struct pci_dev *device,
+                                             int offset, u32* val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                                        0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        RM9K_WRITE(address_reg, address);
+        RM9K_READ(data_reg, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int titan_ht_config_read_word(struct pci_dev *device,
+                                             int offset, u16* val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                                0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        if ((offset & 0x3) == 0)
+                offset = 0x2;
+        else
+                offset = 0x0;
+
+        RM9K_WRITE(address_reg, address);
+        RM9K_READ_16(data_reg + offset, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+
+u32 longswap(unsigned long l)
+{
+        unsigned char b1,b2,b3,b4;
+
+        b1 = l&255;
+        b2 = (l>>8)&255;
+        b3 = (l>>16)&255;
+        b4 = (l>>24)&255;
+
+        return ((b1<<24) + (b2<<16) + (b3<<8) + b4);
+}
+
+
+static int titan_ht_config_read_byte(struct pci_dev *device,
+                                             int offset, u8* val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+        int offset1;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                                        0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        RM9K_WRITE(address_reg, address);
+
+        if ((offset & 0x3) == 0) {
+                offset1 = 0x3;
+        }
+        if ((offset & 0x3) == 1) {
+                offset1 = 0x2;
+        }
+        if ((offset & 0x3) == 2) {
+                offset1 = 0x1;
+        }
+        if ((offset & 0x3) == 3) {
+                offset1 = 0x0;
+        }
+        RM9K_READ_8(data_reg + offset1, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int titan_ht_config_write_dword(struct pci_dev *device,
+                                             int offset, u8 val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                                        0x80000000 | 0x1;
+        else
+              address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        RM9K_WRITE(address_reg, address);
+        RM9K_WRITE(data_reg, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write_word(struct pci_dev *device,
+                                             int offset, u8 val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        if ((offset & 0x3) == 0)
+                offset = 0x2;
+        else
+                offset = 0x0;
+
+        RM9K_WRITE(address_reg, address);
+        RM9K_WRITE_16(data_reg + offset, val);
+
+        return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write_byte(struct pci_dev *device,
+                                             int offset, u8 val)
+{
+        int dev, bus, func;
+        uint32_t address_reg, data_reg;
+        uint32_t address;
+        int offset1;
+
+        bus = device->bus->number;
+        dev = PCI_SLOT(device->devfn);
+        func = PCI_FUNC(device->devfn);
+
+	/* XXX Need to change the Bus # */
+        if (bus > 2)
+                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+                                0x80000000 | 0x1;
+        else
+                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+        address_reg = RM9000x2_OCD_HTCFGA;
+        data_reg =  RM9000x2_OCD_HTCFGD;
+
+        RM9K_WRITE(address_reg, address);
+
+        if ((offset & 0x3) == 0) {
+             offset1 = 0x3;
+        }
+        if ((offset & 0x3) == 1) {
+             offset1 = 0x2;
+        }
+        if ((offset & 0x3) == 2) {
+             offset1 = 0x1;
+        }
+        if ((offset & 0x3) == 3) {
+            offset1 = 0x0;
+        }
+
+        RM9K_WRITE_8(data_reg + offset1, val);
+        return PCIBIOS_SUCCESSFUL;
+}
+
+
+static void titan_pcibios_set_master(struct pci_dev *dev)
+{
+        u16 cmd;
+        int bus = dev->bus->number;
+
+	if (check_titan_htlink())
+            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
+
+	cmd |= PCI_COMMAND_MASTER;
+
+	if (check_titan_htlink())
+            titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
+}
+
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+        u16 cmd, old_cmd;
+        u8 tmp1;
+        int idx;
+        struct resource *r;
+        int bus = dev->bus->number;
+
+	if (check_titan_htlink())
+            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
+
+	old_cmd = cmd;
+        for (idx = 0; idx < 6; idx++) {
+                r = &dev->resource[idx];
+                if (!r->start && r->end) {
+                        printk(KERN_ERR
+                               "PCI: Device %s not available because of "
+                               "resource collisions\n", dev->slot_name);
+                        return -EINVAL;
+                }
+                if (r->flags & IORESOURCE_IO)
+                        cmd |= PCI_COMMAND_IO;
+                if (r->flags & IORESOURCE_MEM)
+                        cmd |= PCI_COMMAND_MEMORY;
+        }
+        if (cmd != old_cmd) {
+		if (check_titan_htlink())
+                   titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
+	}
+
+	if (check_titan_htlink())
+		titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+
+	if (tmp1 != 8) {
+                printk(KERN_WARNING "PCI setting cache line size to 8 from "
+                       "%d\n", tmp1);
+	}
+
+	if (check_titan_htlink())
+		titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+
+	if (check_titan_htlink())
+		titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+
+	if (tmp1 < 32 || tmp1 == 0xff) {
+                printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
+                       tmp1);
+	}
+
+	if (check_titan_htlink())
+		titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32);
+
+	return 0;
+}
+
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+        return pcibios_enable_resources(dev);
+}
+
+
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+                             struct resource *res, int resource)
+{
+        u32 new, check;
+        int reg;
+
+        return;
+
+        new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+        if (resource < 6) {
+                reg = PCI_BASE_ADDRESS_0 + 4 * resource;
+        } else if (resource == PCI_ROM_RESOURCE) {
+                res->flags |= PCI_ROM_ADDRESS_ENABLE;
+                reg = dev->rom_base_reg;
+        } else {
+                /*
+                 * Somebody might have asked allocation of a non-standard
+                 * resource
+                 */
+                return;
+        }
+
+        pci_write_config_dword(dev, reg, new);
+        pci_read_config_dword(dev, reg, &check);
+        if ((new ^ check) &
+            ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
+             PCI_BASE_ADDRESS_MEM_MASK)) {
+                printk(KERN_ERR "PCI: Error while updating region "
+                       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+                       new, check);
+        }
+}
+
+
+void pcibios_align_resource(void *data, struct resource *res,
+                            unsigned long size, unsigned long align)
+{
+        struct pci_dev *dev = data;
+
+        if (res->flags & IORESOURCE_IO) {
+                unsigned long start = res->start;
+
+                /* We need to avoid collisions with `mirrored' VGA ports
+                   and other strange ISA hardware, so we always want the
+                   addresses kilobyte aligned.  */
+                if (size > 0x100) {
+                        printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+                               " (%ld bytes)\n", dev->slot_name,
+                                dev->resource - res, size);
+                }
+
+                start = (start + 1024 - 1) & ~(1024 - 1);
+                res->start = start;
+        }
+}
+
+struct pci_ops titan_pci_ops = {
+        titan_ht_config_read_byte,
+        titan_ht_config_read_word,
+        titan_ht_config_read_dword,
+        titan_ht_config_write_byte,
+        titan_ht_config_write_word,
+        titan_ht_config_write_dword
+};
+
+
+struct pci_fixup pcibios_fixups[] = {
+        {0}
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+        titan_ht_pcibios_fixup_bus(c);
+}
+
+void __init pcibios_init(void)
+{
+
+        /* Reset PCI I/O and PCI MEM values */
+	/* XXX Need to add the proper values here */
+        ioport_resource.start = 0xe0000000;
+        ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
+        iomem_resource.start  = 0xc0000000;
+        iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;
+
+	/* XXX Need to add bus values */
+        pci_scan_bus(2, &titan_pci_ops, NULL);
+        pci_scan_bus(3, &titan_pci_ops, NULL);
+}
+
+/*
+ * for parsing "pci=" kernel boot arguments.
+ */
+char *pcibios_setup(char *str)
+{
+        printk(KERN_INFO "rr: pcibios_setup\n");
+        /* Nothing to do for now.  */
+
+        return str;
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+        /* We want to use the PCI bus detection done by PMON */
+        return 0;
+}
+
+#endif /* CONFIG_HYPERTRANSPORT */
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,186 @@
+/*
+ *  arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
+ *
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Detailed Description:
+ *
+ * This block implements the I2C interface to the slave devices like the Atmel 24C32
+ * EEPROM and the MAX 1619 Sensors device. The I2C Master interface can be controlled
+ * by the SCMB block. And the SCMB block kicks in only when using the Ethernet Mode of
+ * operation and __not__ the SysAD mode
+ *
+ * The SCMB controls the two modes: MDIO and the I2C. The MDIO mode is used to communicate
+ * with the Quad-PHY from Marvel. The I2C is used to communicate with the I2C slave devices.
+ * It seems that the driver does not explicitly deal with the control of SDA and SCL serial
+ * lines. So, the driver will set the slave address, drive the command and then the data. 
+ * The SCMB will then control the two serial lines as required. 
+ *
+ * It seems the documents are very unclear abt this. Hence, I took some time out to write
+ * the desciption to have an idea of how the I2C can actually work. Currently, this Linux 
+ * driver wont be integrated into the generic Linux I2C framework. And finally, the I2C 
+ * interface is also known as the 2BI interface. 2BI means 2-bit interface referring to
+ * SDA and SCL serial lines respectively.
+ *
+ * - Manish Lachwani (12/09/2003)
+ */
+
+#include "i2c-yosemite.h"
+
+/*
+ * Poll the I2C interface for the BUSY bit. 
+ */
+static int titan_i2c_poll(void)
+{
+	int		i = 0;
+	unsigned long	val = 0;
+
+	for (i = 0; i < TITAN_I2C_MAX_POLL; i++) {
+		val = TITAN_I2C_READ(TITAN_I2C_COMMAND);
+
+		if ( !(val & 0x8000))
+			return 0;
+	}
+
+	return TITAN_I2C_ERR_TIMEOUT;
+}
+
+/*
+ * Execute the I2C command
+ */
+int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command *cmd, 
+						int size, unsigned int *addr)
+{
+	int		loop = 0, bytes, i;
+	unsigned int	*write_data, data, *read_data;
+	unsigned long	reg_val, val;
+
+	write_data = cmd->data;
+	read_data = addr;
+
+	TITAN_I2C_WRITE(TITAN_I2C_SLAVE_ADDRESS, slave_addr);
+
+	if (cmd->type == TITAN_I2C_CMD_WRITE) 
+		loop = cmd->write_size;
+	else
+		loop = size;
+
+	while (loop > 0) {
+		if ( (cmd->type == TITAN_I2C_CMD_WRITE)  || 
+			(cmd->type == TITAN_I2C_CMD_READ_WRITE) ) {
+			
+			reg_val = TITAN_I2C_DATA;
+			for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; ++i,write_data += 2,
+								reg_val += 4) {
+				if (bytes < cmd->write_size) {
+					data = write_data[0];
+					++data;
+				}
+
+				if (bytes < cmd->write_size) {
+					data = write_data[1];
+					++data;
+				}
+
+				TITAN_I2C_WRITE(reg_val, data);
+			}
+		}
+
+		TITAN_I2C_WRITE(TITAN_I2C_COMMAND, (unsigned int)(cmd->type << 13));
+		if (titan_i2c_poll() != TITAN_I2C_ERR_OK)
+			return TITAN_I2C_ERR_TIMEOUT;
+
+		if ( (cmd->type == TITAN_I2C_CMD_READ)  ||
+			(cmd->type == TITAN_I2C_CMD_READ_WRITE) ) {
+			
+			reg_val = TITAN_I2C_DATA;
+			for (i = 0; i < TITAN_I2C_MAX_WORDS_PER_RW; ++i,read_data += 2,
+								reg_val += 4) {
+				data = TITAN_I2C_READ(reg_val);
+				
+				if (bytes < size) {
+					read_data[0] = data & 0xff;
+					++bytes;
+				}
+
+				if (bytes < size) {
+					read_data[1] = ((data >> 8) & 0xff);
+					++bytes;
+				}
+			}
+		}
+
+		loop -= (TITAN_I2C_MAX_WORDS_PER_RW * 2);
+	}
+						
+	/*
+	 * Read the Interrupt status and then return the appropriate error code 
+	 */
+
+	val = TITAN_I2C_READ(TITAN_I2C_INTERRUPTS);
+	if (val & 0x0020)
+		return TITAN_I2C_ERR_ARB_LOST;
+
+	if (val & 0x0040)
+		return TITAN_I2C_ERR_NO_RESP;
+
+	if (val & 0x0080)
+		return TITAN_I2C_ERR_DATA_COLLISION;
+
+	return TITAN_I2C_ERR_OK;
+}
+
+/*
+ * Init the I2C subsystem of the PMC-Sierra Yosemite board
+ */
+int titan_i2c_init(titan_i2c_config *config)
+{
+	unsigned int	val;
+
+	/*
+	 * Reset the SCMB and program into the I2C mode
+	 */
+	TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0xA000);
+	TITAN_I2C_WRITE(TITAN_I2C_SCMB_CONTROL, 0x2000);
+
+	/*
+	 * Configure the filtera and clka values
+	 */
+	val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_A);
+	val |= ( (val & ~(0xF000)) | ( (config->filtera << 12) & 0xF000));
+	val |= ( (val & ~(0x03FF)) | ( config->clka & 0x03FF));
+	TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_A, val);
+
+	/*
+	 * Configure the filterb and clkb values
+	 */
+	val = TITAN_I2C_READ(TITAN_I2C_SCMB_CLOCK_B);
+	val |= ( (val & ~(0xF000)) | ( (config->filterb << 12) & 0xF000));
+	val |= ( (val & ~(0x03FF)) | ( config->clkb & 0x03FF));
+	TITAN_I2C_WRITE(TITAN_I2C_SCMB_CLOCK_B, val);
+
+	return TITAN_I2C_ERR_OK;
+}
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/i2c-yosemite.h	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,96 @@
+/*
+ *  arch/mips/pmc-sierra/yosemite/i2c-yosemite.h
+ *
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __I2C_YOSEMITE_H
+#define __I2C_YOSEMITE_H
+
+/* Read and Write operations to the chip */
+
+#define TITAN_I2C_BASE			0xbb000000	/* XXX Needs to change */
+	
+#define	TITAN_I2C_WRITE(offset, data)	\
+					*(volatile unsigned long *)(TITAN_I2C_BASE + offset) = data
+
+#define	TITAN_I2C_READ(offset) *(volatile unsigned long *)(TITAN_I2C_BASE + offset)
+
+
+/* Local constansts*/
+#define TITAN_I2C_MAX_FILTER            15
+#define TITAN_I2C_MAX_CLK               1023
+#define TITAN_I2C_MAX_ARBF              15
+#define TITAN_I2C_MAX_NAK               15
+#define TITAN_I2C_MAX_MASTERCODE        7
+#define TITAN_I2C_MAX_WORDS_PER_RW      4
+#define TITAN_I2C_MAX_POLL		100
+
+/* Registers used for I2C work */
+#define TITAN_I2C_SCMB_CONTROL		0x0180  /* SCMB Control */
+#define TITAN_I2C_SCMB_CLOCK_A		0x0184  /* SCMB Clock A */
+#define TITAN_I2C_SCMB_CLOCK_B		0x0188  /* SCMB Clock B */
+#define	TITAN_I2C_CONFIG		0x01A0  /* I2C Config */
+#define TITAN_I2C_COMMAND		0x01A4  /* I2C Command */
+#define	TITAN_I2C_SLAVE_ADDRESS		0x01A8	/* I2C Slave Address */
+#define TITAN_I2C_DATA			0x01AC  /* I2C Data [15:0] */
+#define TITAN_I2C_INTERRUPTS		0x01BC  /* I2C Interrupts */
+
+/* Error */
+#define	TITAN_I2C_ERR_ARB_LOST		(-9220)
+#define	TITAN_I2C_ERR_NO_RESP		(-9221)
+#define	TITAN_I2C_ERR_DATA_COLLISION	(-9222)
+#define	TITAN_I2C_ERR_TIMEOUT		(-9223)
+#define	TITAN_I2C_ERR_OK		0
+
+/* I2C Command Type */
+typedef enum {
+	TITAN_I2C_CMD_WRITE		= 0,
+	TITAN_I2C_CMD_READ		= 1,
+	TITAN_I2C_CMD_READ_WRITE	= 2
+} titan_i2c_cmd_type;
+
+/* I2C structures */
+typedef struct {
+	int	filtera; 		/* Register 0x0184, bits 15 - 12*/
+	int	clka;			/* Register 0x0184, bits 9 - 0 */
+	int	filterb;		/* Register 0x0188, bits 15 - 12 */
+	int	clkb;			/* Register 0x0188, bits 9 - 0 */
+} titan_i2c_config;
+
+/* I2C command type */
+typedef struct {
+	titan_i2c_cmd_type	type;		/* Type of command */
+	int			num_arb;	/* Register 0x01a0, bits 15 - 12 */
+	int			num_nak;	/* Register 0x01a0, bits 11 - 8 */
+	int			addr_size;	/* Register 0x01a0, bit 7 */
+	int			mst_code;	/* Register 0x01a0, bits 6 - 4 */
+	int			arb_en;		/* Register 0x01a0, bit 1 */
+	int			speed;		/* Register 0x01a0, bit 0 */
+	int			slave_addr;	/* Register 0x01a8 */
+	int			write_size;	/* Register 0x01a4, bits 10 - 8 */
+	unsigned int		*data;		/* Register 0x01ac */
+} titan_i2c_command;
+
+#endif /* __I2C_YOSEMITE_H */ 
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/irq-handler.S linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/irq-handler.S
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/irq-handler.S	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/irq-handler.S	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com
+ *
+ * First-level interrupt router for the PMC-Sierra Titan board
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#define __ASSEMBLY__
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * IRQ router for the Titan board
+ */
+
+		.align	5
+		NESTED(titan_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0, CP0_CAUSE
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+	
+		andi	t1, t0, STATUSF_IP0	/* INTB0 hardware line */
+		bnez	t1, ll_pcia_irq		/* 64-bit PCI */
+		andi	t1, t0, STATUSF_IP1	/* INTB1 hardware line */
+		bnez	t1, ll_pcib_irq		/* second 64-bit PCI slot */
+		andi	t1, t0, STATUSF_IP2	/* INTB2 hardware line */
+		bnez	t1, ll_duart_irq	/* UART	*/
+		andi	t1, t0, STATUSF_IP3	/* INTB3 hardware line*/
+		bnez	t1, ll_ht_smp_irq		/* Hypertransport */
+		andi	t1, t0, STATUSF_IP5	/* INTB5 hardware line */
+		bnez	t1, ll_timer_irq	/* Timer */
+
+		nop
+		nop
+
+		/* Extended interrupts */
+		mfc0	t0, CPU_CAUSE
+		cfc0	t1, CP0_S1_INTCONTROL
+
+		sll	t2, t1, 8
+		
+		and	t0, t2
+		srl	t0, t0, 16
+
+		
+		andi	t1, t0, STATUSF_IP6	/* INTB6 hardware line */
+		bnez	t1, ll_phy0_irq		/* Ethernet port 0 */
+		andi	t1, t0, STATUSF_IP7	/* INTB7 hardware line */
+		bnez	t1, ll_phy1_irq		/* Ethernet port 1 */
+		andi	t1, t0, STATUSF_IP8	/* INTB8 hardware line */
+		bnez	t1, ll_phy2_irq		/* Ethernet Port 2 */
+
+		nop
+		nop
+
+		.set	reorder
+
+		/* No handler */
+		j	spurious_interrupt
+		nop
+		END(titan_handle_int)
+
+		.align	5
+
+/* Individual Handlers */
+
+ll_pcia_irq:
+		li	a0, 1
+		move	a2, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_pcib_irq:
+		li      a0, 2
+                move    a1, sp
+                jal     do_IRQ
+                j       ret_from_irq
+
+ll_duart_irq:
+		li	a0, 3
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_ht_irq:
+		li	a0, 4
+		move	a1, sp
+		jal	ll_ht_smp_irq_handler 	/* Detailed HT & SMP IRQ handling */
+		j	ret_from_irq
+
+ll_timer_irq:
+		li	a0, 5
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_phy0_irq:
+		li	a0, 6
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq	
+
+ll_phy1_irq:
+		li	a0, 7
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_phy2_irq:
+		li	a0, 8
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/irq.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/irq.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/irq.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/irq.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Second level Interrupt handlers for the PMC-Sierra Titan/Yosemite board
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+/* Hypertransport specific */
+#define IRQ_STATUS_REG_CPU0     0xbb001b30 	/* INT# 3 status register on CPU 0*/
+#define	IRQ_STATUS_REG_CPU1	0xbb002b30	/* INT# 3 status register on CPU 1*/
+#define IRQ_ACK_BITS            0x00000000 	/* Ack bits */
+#define IRQ_CLEAR_REG_CPU0      0xbb002b3c 	/* IRQ clear register on CPU 0*/
+#define IRQ_CLEAR_REG_CPU0      0xbb002b3c      /* IRQ clear register on CPU 1*/
+
+#define HYPERTRANSPORT_EOI      0xbb0006E0 	/* End of Interrupt */
+#define HYPERTRANSPORT_INTA     0x78    	/* INTA# */
+#define HYPERTRANSPORT_INTB     0x79    	/* INTB# */
+#define HYPERTRANSPORT_INTC     0x7a    	/* INTC# */
+#define HYPERTRANSPORT_INTD     0x7b    	/* INTD# */
+
+#define read_32bit_cp0_set1_register(source)                    \
+({ int __res;                                                   \
+        __asm__ __volatile__(                                   \
+        ".set\tpush\n\t"                                        \
+        ".set\treorder\n\t"                                     \
+        "cfc0\t%0,"STR(source)"\n\t"                            \
+        ".set\tpop"                                             \
+        : "=r" (__res));                                        \
+        __res;})
+
+#define write_32bit_cp0_set1_register(register,value)           \
+        __asm__ __volatile__(                                   \
+        "ctc0\t%0,"STR(register)"\n\t"                          \
+        "nop"                                                   \
+        : : "r" (value));
+
+static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
+
+/* Function for careful CP0 interrupt mask access */
+static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in)
+{
+        unsigned long status;
+        unsigned clr_mask;
+        unsigned set_mask;
+
+        /* do the low 8 bits first */
+        clr_mask = 0xff & clr_mask_in;
+        set_mask = 0xff & set_mask_in;
+        status = read_c0_status();
+        status &= ~((clr_mask & 0xFF) << 8);
+        status |= (set_mask & 0xFF) << 8 | 0x0000FF00;
+        write_c0_status(status);
+
+        /* do the high 8 bits */
+        clr_mask = 0xff & (clr_mask_in >> 8);
+        set_mask = 0xff & (set_mask_in >> 8);
+        status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL);
+        status &= ~((clr_mask & 0xFF) << 8);
+        status |= (set_mask & 0xFF) << 8;
+        write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status);
+}
+
+static inline void mask_irq(unsigned int irq)
+{
+        modify_cp0_intmask(irq, 0);
+}
+
+static inline void unmask_irq(unsigned int irq)
+{
+        modify_cp0_intmask(0, irq);
+}
+
+static void enable_rm9000_irq(unsigned int irq)
+{
+        unsigned long flags;
+
+        spin_lock_irqsave(&irq_lock, flags);
+        unmask_irq(1 << (irq-1));
+        spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+static unsigned int startup_rm9000_irq(unsigned int irq)
+{
+        enable_rm9000_irq(irq);
+
+        return 0;                               /* never anything pending */
+}
+
+static void disable_rm9000_irq(unsigned int irq)
+{
+        unsigned long flags;
+
+        spin_lock_irqsave(&irq_lock, flags);
+        mask_irq(1 << (irq-1));
+        spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+#define shutdown_rm9000_irq disable_rm9000_irq
+
+static void mask_and_ack_rm9000_irq(unsigned int irq)
+{
+        mask_irq(1 << (irq-1));
+}
+
+static void end_rm9000_irq(unsigned int irq)
+{
+        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+                unmask_irq(1 << (irq-1));
+}
+
+static struct hw_interrupt_type rm9000_hpcdma_irq_type = {
+        "RM9000",
+        startup_rm9000_irq,
+        shutdown_rm9000_irq,
+        enable_rm9000_irq,
+        disable_rm9000_irq,
+        mask_and_ack_rm9000_irq,
+        end_rm9000_irq,
+        NULL
+};
+
+extern asmlinkage void titan_handle_int(void);
+extern void jaguar_mailbox_irq(struct pt_regs *);
+
+/* 
+ * Handle hypertransport & SMP interrupts. The interrupt lines are scarce. For interprocessor
+ * interrupts, the best thing to do is to use the INTMSG register. We use the same external
+ * interrupt line, i.e. INTB3 and monitor another status bit
+ */
+asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs)
+{
+        u32 status;
+        status = *(volatile u_int32_t *)(IRQ_STATUS_REG_CPU0);
+
+	/* Ack all the bits that correspond to the interrupt sources */
+	if (status != 0)
+	        *(volatile u_int32_t *)(IRQ_STATUS_REG_CPU0) = IRQ_ACK_BITS;
+
+	status = *(volatile u_int32_t *)(IRQ_STATUS_REG_CPU1);
+	if (status != 0)
+                *(volatile u_int32_t *)(IRQ_STATUS_REG_CPU1) = IRQ_ACK_BITS;
+
+#ifdef CONFIG_SMP
+	if (status == 0x2) {
+		/* This is an SMP IPI sent from one core to another */
+		jaguar_mailbox_irq(regs);
+		goto done;
+	}
+#endif
+	
+#ifdef CONFIG_HT_LEVEL_TRIGGER
+        /*
+         * Level Trigger Mode only. Send the HT EOI message back to the source.
+         */
+        switch (status) {
+                case 0x1000000:
+                        *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA;
+                        break;
+                case 0x2000000:
+                        *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB;
+                        break;
+                case 0x4000000:
+                        *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC;
+                        break;
+                case 0x8000000:
+                        *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD;
+                        break;
+                case 0x0000001:
+                        /* PLX */
+                        *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = 0x20;
+                        *(volatile u_int32_t *)(IRQ_CLEAR_REG) = IRQ_ACK_BITS;
+                        break;
+                case 0xf000000:
+                        *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTA;
+                        *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTB;
+                        *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTC;
+                        *(volatile u_int32_t *)(HYPERTRANSPORT_EOI) = HYPERTRANSPORT_INTD;
+                        break;
+        }
+#endif /* CONFIG_HT_LEVEL_TRIGGER */
+
+done:
+	if (status != 0x2)
+		/* Not for SMP */
+		do_IRQ(irq, regs);	
+}
+
+/*
+ * Initialize the next level interrupt handler
+ */
+void __init init_IRQ(void)
+{
+	int	i;
+
+	clear_c0_status(ST0_IM | ST0_BEV);
+	__cli();
+
+	set_except_vector(0, titan_handle_int);
+	init_generic_irq();
+
+	for (i = 0; i < 13; i++) {
+                irq_desc[i].status      = IRQ_DISABLED;
+                irq_desc[i].action      = 0;
+                irq_desc[i].depth       = 1;
+                irq_desc[i].handler     = &rm9000_hpcdma_irq_type;
+        }
+}
+
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/pci-irq.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/pci-irq.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/pci-irq.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/pci-irq.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+/*
+ * PCI Bus fixup for the Titan
+ * XXX IRQ values need to change based on the board layout
+ */
+void __init titan_pcibios_fixup_bus(struct pci_bus *bus)
+{
+        struct pci_bus *current_bus = bus;
+        struct pci_dev *devices;
+        struct list_head *devices_link;
+
+	list_for_each(devices_link, &(current_bus->devices)) {
+                devices = pci_dev_b(devices_link);
+                if (devices == NULL)
+                        continue;
+
+                if ((current_bus->number == 0) &&
+                        (PCI_SLOT(devices->devfn) == 1)) {
+                        /* PCI-X A */
+                        devices->irq = 3;
+                } else if ((current_bus->number == 0) &&
+                        (PCI_SLOT(devices->devfn) == 2)) {
+                        /* PCI-X B */
+                        devices->irq = 4;
+                } else if ((current_bus->number == 1) &&
+                        (PCI_SLOT(devices->devfn) == 1)) {
+                        /* PCI A */
+                        devices->irq = 5;
+                } else if ((current_bus->number == 1) &&
+                        (PCI_SLOT(devices->devfn) == 2)) {
+                        /* PCI B */
+                        devices->irq = 6;
+                }
+	}
+}
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/pci.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/pci.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/pci.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/pci.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,387 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/titan_dep.h>
+
+void titan_pcibios_fixup_bus(struct pci_bus* c);
+
+/*
+ * Titan PCI Config Dword Read
+ */
+static int titan_pcibios_read_config_dword(struct pci_dev *device,
+					      int offset, u32* val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
+	data_reg = TITAN_PCI_0_CONFIG_DATA;
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	TITAN_WRITE(address_reg, address);
+
+	/* read the data */
+	TITAN_READ(data_reg, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Titan PCI Config Word Read
+ */
+static int titan_pcibios_read_config_word(struct pci_dev *device,
+					     int offset, u16* val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
+	data_reg = TITAN_PCI_0_CONFIG_DATA;
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	TITAN_WRITE(address_reg, address);
+
+	/* read the data */
+	TITAN_READ_16(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Titan PCI Config Read Byte
+ */
+static int titan_pcibios_read_config_byte(struct pci_dev *device,
+					     int offset, u8* val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
+	data_reg = TITAN_PCI_0_CONFIG_DATA;
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	TITAN_WRITE(address_reg, address);
+
+	/* write the data */
+	TITAN_READ_8(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* 
+ * Titan PCI Config Write Dword
+ */
+static int titan_pcibios_write_config_dword(struct pci_dev *device,
+					      int offset, u32 val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
+	data_reg = TITAN_PCI_0_CONFIG_DATA;
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	TITAN_WRITE(address_reg, address);
+
+	/* write the data */
+	TITAN_WRITE(data_reg, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Titan PCI Config Write Word
+ */
+static int titan_pcibios_write_config_word(struct pci_dev *device,
+					     int offset, u16 val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
+	data_reg = TITAN_PCI_0_CONFIG_DATA;
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	TITAN_WRITE(address_reg, address);
+
+	/* write the data */
+	TITAN_WRITE_16(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Titan PCI Config Byte Write
+ */
+static int titan_pcibios_write_config_byte(struct pci_dev *device,
+					     int offset, u8 val)
+{
+	int dev, bus, func;
+	uint32_t address_reg, data_reg;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
+	data_reg = TITAN_PCI_0_CONFIG_DATA;
+
+	address = (bus << 16) | (dev << 11) | (func << 8) |
+		(offset & 0xfc) | 0x80000000;
+
+	/* start the configuration cycle */
+	TITAN_WRITE(address_reg, address);
+
+	/* write the data */
+	TITAN_WRITE_8(data_reg + (offset & 0x3), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Titan PCI Set Bus Master
+ */
+static void titan_pcibios_set_master(struct pci_dev *dev)
+{
+	u16 cmd;
+
+	titan_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_MASTER;
+	titan_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+}
+
+/*
+ * Global export to pcibios_enable_resources
+ */
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	u8 tmp1;
+	int idx;
+	struct resource *r;
+
+	titan_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR
+			       "PCI: Device %s not available because of "
+			       "resource collisions\n", dev->slot_name);
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		titan_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	
+	titan_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+	if (tmp1 != 8) {
+		printk(KERN_WARNING "PCI setting cache line size to 8 from "
+		       "%d\n", tmp1);
+
+		 titan_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+	}
+
+	titan_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+	if (tmp1 < 32 || tmp1 == 0xff) {
+		printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
+		       tmp1);
+		titan_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
+	}
+
+	return 0;
+}
+
+/*
+ * Export for pcibios_enable_device
+ */
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	return pcibios_enable_resources(dev);
+}
+
+/*
+ * Export for pcibios_update_resource
+ */
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+			     struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4 * resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/*
+		 * Somebody might have asked allocation of a non-standard
+		 * resource
+		 */
+		return;
+	}
+
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) &
+	    ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
+	     PCI_BASE_ADDRESS_MEM_MASK)) {
+		printk(KERN_ERR "PCI: Error while updating region "
+		       "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+		       new, check);
+	}
+}
+
+/*
+ * Export to pcibios_align_resource
+ */
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
+{
+	struct pci_dev *dev = data;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		/* We need to avoid collisions with `mirrored' VGA ports
+		   and other strange ISA hardware, so we always want the
+		   addresses kilobyte aligned.	*/
+		if (size > 0x100) {
+			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+			       " (%ld bytes)\n", dev->slot_name,
+				dev->resource - res, size);
+		}
+
+		start = (start + 1024 - 1) & ~(1024 - 1);
+		res->start = start;
+	}
+}
+
+/*
+ * Titan PCI structure
+ */
+struct pci_ops titan_pci_ops = {
+	titan_pcibios_read_config_byte,
+	titan_pcibios_read_config_word,
+	titan_pcibios_read_config_dword,
+	titan_pcibios_write_config_byte,
+	titan_pcibios_write_config_word,
+	titan_pcibios_write_config_dword
+};
+
+struct pci_fixup pcibios_fixups[] = {
+	{0}
+};
+
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+	titan_pcibios_fixup_bus(c);
+}
+
+void __init pcibios_init(void)
+{
+	/* 
+	 * XXX These values below need to change
+	 */
+	ioport_resource.start = 0xe0000000;
+	ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
+	iomem_resource.start  = 0xc0000000;
+	iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;
+
+	pci_scan_bus(0, &titan_pci_ops, NULL);
+}
+
+/*
+ * for parsing "pci=" kernel boot arguments.
+ */
+char *pcibios_setup(char *str)
+{
+	printk(KERN_INFO "rr: pcibios_setup\n");
+	/* Nothing to do for now.  */
+
+	return str;
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/prom.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/prom.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/prom.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/prom.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,190 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <asm/bootinfo.h>
+
+#include "setup.h"
+
+/* Call Vectors */
+struct callvectors {
+        int     (*open) (char*, int, int);
+        int     (*close) (int);
+        int     (*read) (int, void*, int);
+        int     (*write) (int, void*, int);
+        off_t   (*lseek) (int, off_t, int);
+        int     (*printf) (const char*, ...);
+        void    (*cacheflush) (void);
+        char*   (*gets) (char*);
+};
+
+struct callvectors* debug_vectors;
+char arcs_cmdline[CL_SIZE];
+
+extern unsigned long yosemite_base;
+extern unsigned long cpu_clock;
+unsigned char titan_ge_mac_addr_base[6];
+
+const char *get_system_type(void)
+{
+        return "PMC-Sierra Yosemite";
+}
+
+static void prom_cpu0_exit(void)
+{
+	void	*nvram = YOSEMITE_NVRAM_BASE_ADDR;
+	
+	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+        writeb(0x84, nvram + 0xff7);
+
+        /* wait for the watchdog to go off */
+        mdelay(100+(1000/16));
+
+        /* if the watchdog fails for some reason, let people know */
+        printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+/*
+ * Reset the NVRAM over the local bus
+ */
+static void prom_exit(void)
+{
+#ifdef CONFIG_SMP
+	if (smp_processor_id())
+		/* CPU 1 */
+		smp_call_function(prom_cpu0_exit, NULL, 1, 1);
+#endif
+	prom_cpu0_exit;
+}
+
+/*
+ * Get the MAC address from the EEPROM using the I2C protocol
+ */
+void get_mac_address(char dest[6])
+{
+	/* Use the I2C command code in the i2c-yosemite */
+}
+
+/*
+ * Halt the system 
+ */
+static void prom_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+                __asm__(".set\tmips3\n\t"
+                        "wait\n\t"
+                        ".set\tmips0");
+}
+
+/*
+ * Init routine which accepts the variables from PMON
+ */
+__init prom_init(int argc, char **arg, char **env, struct callvectors *cv)
+{
+	int	i = 0;
+
+	/* Callbacks for halt, restart */
+	_machine_restart = (void (*)(char *))prom_exit;	
+	_machine_halt = prom_halt;
+	_machine_power_off = prom_halt;
+
+#ifdef CONFIG_MIPS64
+
+	/* Do nothing for the 64-bit for now. Just implement for the 32-bit */
+
+#else /* CONFIG_MIPS64 */
+
+	debug_vectors = cv;
+	arcs_cmdline[0] = '\0';
+
+	/* Get the boot parameters */
+	for (i = 1; i < argc; i++) {
+                if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= sizeof(arcs_cmdline))
+                        break;
+
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	while (*env) {
+		if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0) 
+			yosemite_base = simple_strtol(*env + strlen("ocd_base="),
+							NULL, 16);
+
+		if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) 
+			cpu_clock = simple_strtol(*env + strlen("cpuclock="),
+							NULL, 10);
+		
+		env++;
+	}
+#endif /* CONFIG_MIPS64 */
+
+	mips_machgroup = MACH_GROUP_TITAN;
+	mips_machtype = MACH_TITAN_YOSEMITE;
+
+	get_mac_address(titan_ge_mac_addr_base);
+
+	debug_vectors->printf("Booting Linux kernel...\n");
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
+
+extern void asmlinkage smp_bootstrap(void);
+
+/*
+ * SMP support
+ */
+int prom_setup_smp(void)
+{
+        int     num_cpus = 2;
+
+        /*
+         * We know that the RM9000 on the Jaguar ATX board has 2 cores. Hence, this
+         * can be hardcoded for now.
+         */
+        return num_cpus;
+}
+
+int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
+{
+        /* Clear the semaphore */
+        *(volatile u_int32_t *)(0xbb000a68) = 0x80000000;
+
+        return 1;
+}
+
+void prom_init_secondary(void)
+{
+        clear_c0_config(CONF_CM_CMASK);
+        set_c0_config(0x2);
+
+        clear_c0_status(ST0_IM);
+        set_c0_status(0x1ffff);
+}
+
+void prom_smp_finish(void)
+{
+}
+	
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/setup.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/setup.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/setup.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,158 @@
+/*
+ *  arch/mips/pmc-sierra/yosemite/setup.c
+ *
+ *  Copyright (C) 2003 PMC-Sierra Inc.
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mc146818rtc.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <linux/vmalloc.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <linux/bootmem.h>
+#include <linux/blk.h>
+
+#include "setup.h"
+
+unsigned long cpu_clock;
+unsigned long yosemite_base;
+
+void __init bus_error_init(void) 
+{ 
+	/* Do nothing */ 
+}
+
+unsigned long m48t37y_get_time(void)
+{
+	unsigned char	*rtc_base = YOSEMITE_RTC_BASE;
+	unsigned int	year, month, day, hour, min, sec;
+
+	/* Stop the update to the time */
+	rtc_base[0x7ff8] = 0x40;
+
+	year = CONV_BCD_TO_BIN(rtc_base[0x7fff]);
+	year += CONV_BCD_TO_BIN(rtc_base[0x7fff1]) * 100;
+
+	month = CONV_BCD_TO_BIN(rtc_base[0x7ffe]);
+	day = CONV_BCD_TO_BIN(rtc_base[0x7ffd]);
+	hour = CONV_BCD_TO_BIN(rtc_base[0x7ffb]);
+	min = CONV_BCD_TO_BIN(rtc_base[0x7ffa]);
+	sec = CONV_BCD_TO_BIN(rtc_base[0x7ff9]);
+
+	/* Start the update to the time again */
+	rtc_base[0x7ff8] = 0x00;
+
+	return mktime(year, month, day, hour, min, sec);
+}
+
+int m48t37y_set_time(unsigned long sec)
+{
+	unsigned char   *rtc_base = YOSEMITE_RTC_BASE;
+        unsigned int    year, month, day, hour, min, sec;
+
+        struct rtc_time tm;
+
+        /* convert to a more useful format -- note months count from 0 */
+        to_tm(sec, &tm);
+        tm.tm_mon += 1;
+
+        /* enable writing */
+        rtc_base[0x7ff8] = 0x80;
+
+        /* year */
+        rtc_base[0x7fff] = CONV_BIN_TO_BCD(tm.tm_year % 100);
+        rtc_base[0x7ff1] = CONV_BIN_TO_BCD(tm.tm_year / 100);
+
+        /* month */
+        rtc_base[0x7ffe] = CONV_BIN_TO_BCD(tm.tm_mon);
+
+        /* day */
+        rtc_base[0x7ffd] = CONV_BIN_TO_BCD(tm.tm_mday);
+
+        /* hour/min/sec */
+        rtc_base[0x7ffb] = CONV_BIN_TO_BCD(tm.tm_hour);
+        rtc_base[0x7ffa] = CONV_BIN_TO_BCD(tm.tm_min);
+        rtc_base[0x7ff9] = CONV_BIN_TO_BCD(tm.tm_sec);
+
+        /* day of week -- not really used, but let's keep it up-to-date */
+        rtc_base[0x7ffc] = CONV_BIN_TO_BCD(tm.tm_wday + 1);
+
+        /* disable writing */
+        rtc_base[0x7ff8] = 0x00;
+
+        return 0;
+}
+
+void yosemite_timer_setup(struct irqaction *irq)
+{
+	setup_irq(6, irq);
+}
+
+void yosemite_time_init(void)
+{
+	mips_counter_frequency = cpu_clock / 2;
+	board_timer_setup = yosemite_timer_setup;
+
+	rtc_get_time = m48t37y_get_time;
+	rtc_set_time = m48t37y_set_time;
+}
+
+void __init pmc_yosemite_setup(void)
+{
+	unsigned long	val = 0;
+
+	printk("PMC-Sierra Yosemite Board Setup  \n");
+	board_time_init = yosemite_time_init;
+
+	/* Add memory regions */
+	add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM);
+	add_memory_region(0x10000000, 0x10000000, BOOT_MEM_RAM);
+
+	/* Setup the HT controller */
+	val = *(volatile u_int32_t *)(HYPERTRANSPORT_CONFIG_REG);
+	val |= HYPERTRANSPORT_ENABLE;
+        *(volatile u_int32_t *)(HYPERTRANSPORT_CONFIG_REG) = val;
+
+        /* Set the BAR. Shifted mode */
+        *(volatile u_int32_t *)(HYPERTRANSPORT_BAR0_REG) = HYPERTRANSPORT_BAR0_ADDR;
+        *(volatile u_int32_t *)(HYPERTRANSPORT_SIZE0_REG) = HYPERTRANSPORT_SIZE0;
+}
+	
+
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/setup.h linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/setup.h
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/setup.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/setup.h	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Board specific definititions for the PMC-Sierra Yosemite
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __SETUP_H__
+#define __SETUP_H__
+
+/* Real Time Clock base */
+#define	YOSEMITE_RTC_BASE
+#define CONV_BCD_TO_BIN(val)    (((val) & 0xf) + (((val) >> 4) * 10))
+#define CONV_BIN_TO_BCD(val)    (((val) % 10) + (((val) / 10) << 4))
+
+/* NVRAM Base */
+#define	YOSEMITE_NVRAM_BASE_ADDR	0xbb000678	/* XXX Need change */
+#define	YOSEMITE_RTC_BASE		0xbb000679	/* XXX Need change */
+
+/*
+ * Hypertransport Specific 
+ */
+#define HYPERTRANSPORT_CONFIG_REG       0xbb000604
+#define HYPERTRANSPORT_BAR0_REG         0xbb000610
+#define HYPERTRANSPORT_SIZE0_REG        0xbb000688
+#define HYPERTRANSPORT_BAR0_ATTR_REG    0xbb000680
+
+#define HYPERTRANSPORT_BAR0_ADDR        0x00000006
+#define HYPERTRANSPORT_SIZE0            0x0fffffff
+#define HYPERTRANSPORT_BAR0_ATTR        0x00002000
+
+#define HYPERTRANSPORT_ENABLE           0x6
+
+/*
+ * EEPROM Size 
+ */
+#define	TITAN_ATMEL_24C32_SIZE		32768
+#define	TITAN_ATMEL_24C64_SIZE		65536
+
+
+#endif /* __SETUP_H__ */
+
diff -urN linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/smp.c linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/smp.c
--- linux-2.4.24-pre1/arch/mips/pmc-sierra/yosemite/smp.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/pmc-sierra/yosemite/smp.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/mmu_context.h>
+#include <asm/trace.h>
+
+extern void smp_call_function_interrupt(void);
+extern void asmlinkage smp_bootstrap(void);
+
+/*
+ * Send inter-processor interrupt
+ */
+void core_send_ipi(int cpu, unsigned int action)
+{
+        /*
+         * Generate and INTMSG so that it can be sent over to the destination CPU
+         * The INTMSG will put the STATUS bits based on the action desired
+         */
+        switch(action) {
+                case SMP_RESCHEDULE_YOURSELF:
+                        /* Do nothing */
+                        break;
+                case SMP_CALL_FUNCTION:
+                        if (cpu == 1)
+                                *(volatile u_int32_t *)(0xbb000a00) = 0x00610002;
+                        else
+                                *(volatile u_int32_t *)(0xbb000a00) = 0x00610001;
+                        break;
+
+                default:
+                        panic("core_send_ipi \n");
+        }
+}
+
+/*
+ * Mailbox interrupt to handle IPI
+ */
+void jaguar_mailbox_irq(struct pt_regs *regs)
+{
+        int cpu = smp_processor_id();
+
+        /* SMP_CALL_FUNCTION */
+        smp_call_function_interrupt();
+}
+
+extern atomic_t cpus_booted;
+extern int prom_setup_smp(void);
+extern int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
+
+void __init start_secondary(void)
+{
+        unsigned int cpu = smp_processor_id();
+        extern atomic_t smp_commenced;
+
+        if (current->processor != 1) {
+                printk("Impossible CPU %d \n", cpu);
+                current->processor = 1;
+                current->cpus_runnable = 1 << 1;
+                cpu = current->processor;
+        }
+
+        if (current->mm)
+                current->mm = NULL;
+
+        prom_init_secondary();
+        per_cpu_trap_init();
+
+        /*
+         * XXX parity protection should be folded in here when it's converted
+         * to an option instead of something based on .cputype
+         */
+        pgd_current[cpu] = init_mm.pgd;
+        cpu_data[cpu].udelay_val = loops_per_jiffy;
+        prom_smp_finish();
+        CPUMASK_SETB(cpu_online_map, cpu);
+        atomic_inc(&cpus_booted);
+        __flush_cache_all();
+
+        printk("Slave cpu booted successfully  \n");
+        *(volatile u_int32_t *)(0xbb000a68) = 0x00000000;
+        *(volatile u_int32_t *)(0xbb000a68) = 0x80000000;
+
+        while (*(volatile u_int32_t *)(0xbb000a68) != 0x00000000);
+
+        return cpu_idle();
+}
+
+void __init smp_boot_cpus(void)
+{
+        int i;
+        int cur_cpu = 0;
+
+        smp_num_cpus = prom_setup_smp();
+        printk("Detected %d available CPUs \n", smp_num_cpus);
+
+        init_new_context(current, &init_mm);
+        current->processor = 0;
+        cpu_data[0].udelay_val = loops_per_jiffy;
+        cpu_data[0].asid_cache = ASID_FIRST_VERSION;
+        CPUMASK_CLRALL(cpu_online_map);
+        CPUMASK_SETB(cpu_online_map, 0);
+        atomic_set(&cpus_booted, 1);  /* Master CPU is already booted... */
+        init_idle();
+
+        __cpu_number_map[0] = 0;
+        __cpu_logical_map[0] = 0;
+
+        /*
+         * This loop attempts to compensate for "holes" in the CPU
+         * numbering.  It's overkill, but general.
+         */
+        for (i = 1; i < smp_num_cpus; ) {
+                struct task_struct *p;
+                struct pt_regs regs;
+                int retval;
+                printk("Starting CPU %d... \n", i);
+
+                /* Spawn a new process normally.  Grab a pointer to
+                   its task struct so we can mess with it */
+                do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
+
+                p = init_task.prev_task;
+                if (!p)
+                        panic("failed fork for CPU %d", i);
+
+                /* This is current for the second processor */
+                p->processor = i;
+                p->cpus_runnable = 1 << i; /* we schedule the first task manually */
+                p->thread.reg31 = (unsigned long) start_secondary;
+
+                del_from_runqueue(p);
+                unhash_process(p);
+                init_tasks[i] = p;
+
+                __flush_cache_all();
+
+                do {
+                        /* Iterate until we find a CPU that comes up */
+                        cur_cpu++;
+                        retval = prom_boot_secondary(cur_cpu,
+                                            (unsigned long)p + KERNEL_STACK_SIZE - 32,
+                                            (unsigned long)p);
+
+                } while (!retval && (cur_cpu < NR_CPUS));
+                if (retval) {
+                        __cpu_number_map[cur_cpu] = i;
+                        __cpu_logical_map[i] = cur_cpu;
+                        i++;
+                } else {
+                        panic("CPU discovery disaster");
+                }
+        }
+
+        /* Local semaphore to both the CPUs */
+
+        *(volatile u_int32_t *)(0xbb000a68) = 0x80000000;
+        while (*(volatile u_int32_t *)(0xbb000a68) != 0x00000000);
+
+        smp_threads_ready = 1;
+}
diff -urN linux-2.4.24-pre1/arch/mips/sgi-ip22/ip22-setup.c linux-2.4.24-pre2/arch/mips/sgi-ip22/ip22-setup.c
--- linux-2.4.24-pre1/arch/mips/sgi-ip22/ip22-setup.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/sgi-ip22/ip22-setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -114,10 +114,9 @@
 extern void ip22_be_init(void) __init;
 extern void ip22_time_init(void) __init;
 
-extern int console_setup(char *) __init;
-
 void __init ip22_setup(void)
 {
+	struct console_cmdline *c;
 	char *ctype;
 #ifdef CONFIG_KGDB
 	char *kgdb_ttyd;
@@ -143,21 +142,26 @@
 	/* Set EISA IO port base for Indigo2 */
 	set_io_port_base(KSEG1ADDR(0x00080000));
 
+	/* Nothing registered console before us, so simply use first entry */
+	c = &console_cmdline[0];
+	ctype = ArcGetEnvironmentVariable("console");
 	/* ARCS console environment variable is set to "g?" for
 	 * graphics console, it is set to "d" for the first serial
 	 * line and "d2" for the second serial line.
 	 */
-	ctype = ArcGetEnvironmentVariable("console");
 	if (ctype && *ctype == 'd') {
-		static char con[16];
+		static char options[8];
 		char *dbaud = ArcGetEnvironmentVariable("dbaud");
-		sprintf(con, "ttyS%c,%s", *(ctype + 1) == '2' ? '1' : '0',
-					  dbaud ? dbaud : "9600");
-		console_setup(con);
+		strcpy(c->name, "ttyS");
+		c->index = *(ctype + 1) == '2' ? 1 : 0;
+		if (dbaud) {
+			strcpy(&options, dbaud);
+			c->options = options;
+		}
 	} else if (!ctype || *ctype != 'g') {
 		/* Use ARC if we don't want serial ('d') or Newport ('g'). */
 		prom_flags |= PROM_FLAG_USE_AS_CONSOLE;
-		console_setup("arc");
+		strcpy(c->name, "arc");
 	}
 
 #ifdef CONFIG_KGDB
diff -urN linux-2.4.24-pre1/arch/mips/sibyte/sb1250/smp.c linux-2.4.24-pre2/arch/mips/sibyte/sb1250/smp.c
--- linux-2.4.24-pre1/arch/mips/sibyte/sb1250/smp.c	2003-12-22 11:34:30.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/sibyte/sb1250/smp.c	2003-12-22 11:34:33.000000000 -0800
@@ -88,9 +88,54 @@
 }
 
 extern atomic_t cpus_booted;
-extern int prom_setup_smp(void);
+extern atomic_t smp_commenced;
+
+/*
+ * Clear all undefined state in the cpu, set up sp and gp to the passed
+ * values, and kick the cpu into smp_bootstrap();
+ */
 extern int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
 
+/*
+ *  After we've done initial boot, this function is called to allow the
+ *  board code to clean up state, if needed
+ */
+extern void prom_init_secondary(void);
+
+/*
+ * Do whatever setup needs to be done for SMP at the board level.  Return
+ * the number of cpus in the system, including this one
+ */
+extern int prom_setup_smp(void);
+
+extern void prom_smp_finish(void);
+
+/*
+ * Hook for doing final board-specific setup after the generic smp setup
+ * is done
+ */
+asmlinkage void start_secondary(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	cpu_probe();
+	prom_init_secondary();
+	per_cpu_trap_init();
+
+	/*
+	 * XXX parity protection should be folded in here when it's converted
+	 * to an option instead of something based on .cputype
+	 */
+	pgd_current[cpu] = init_mm.pgd;
+	cpu_data[cpu].udelay_val = loops_per_jiffy;
+	prom_smp_finish();
+	printk("Slave cpu booted successfully\n");
+	CPUMASK_SETB(cpu_online_map, cpu);
+	atomic_inc(&cpus_booted);
+	while (!atomic_read(&smp_commenced));
+	cpu_idle();
+}
+
 void __init smp_boot_cpus(void)
 {
 	int i;
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/Makefile linux-2.4.24-pre2/arch/mips/vr41xx/common/Makefile
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/Makefile	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/Makefile	2003-12-22 11:34:33.000000000 -0800
@@ -12,13 +12,12 @@
 
 O_TARGET := vr41xx.o
 
-obj-y := bcu.o cmu.o giu.o icu.o int-handler.o reset.o
+obj-y := bcu.o cmu.o giu.o icu.o int-handler.o ksyms.o reset.o rtc.o
 
-export-objs := vrc4173.o
+export-objs := ksyms.o vrc4173.o
 
 obj-$(CONFIG_PCI)		+= pciu.o
 obj-$(CONFIG_SERIAL)		+= serial.o
-obj-$(CONFIG_VR41XX_TIME_C)	+= time.o
 obj-$(CONFIG_VRC4173)		+= vrc4173.o
 obj-$(subst m,y,$(CONFIG_IDE))	+= ide.o
 
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/bcu.c linux-2.4.24-pre2/arch/mips/vr41xx/common/bcu.c
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/bcu.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/bcu.c	2003-12-22 11:34:33.000000000 -0800
@@ -36,20 +36,14 @@
  *  - New creation, NEC VR4122 and VR4131 are supported.
  *  - Added support for NEC VR4111 and VR4121.
  *
- *  Paul Mundt <lethal@chaoticdreams.org>
- *  - Calculate mips_hpt_frequency properly on VR4131.
- *
  *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *  - Added support for NEC VR4133.
  */
 #include <linux/init.h>
 #include <linux/types.h>
 
-#include <asm/addrspace.h>
 #include <asm/cpu.h>
 #include <asm/io.h>
-#include <asm/time.h>
-#include <asm/vr41xx/vr41xx.h>
 
 #define VR4111_CLKSPEEDREG	KSEG1ADDR(0x0b000014)
 #define VR4122_CLKSPEEDREG	KSEG1ADDR(0x0f000014)
@@ -66,9 +60,20 @@
  #define TDIVMODE(x)		(2 << (((x) & 0x1000) >> 12))
  #define VTDIVMODE(x)		(((x) & 0x0700) >> 8)
 
-unsigned long vr41xx_vtclock = 0;
+static unsigned long vr41xx_vtclock;
+static unsigned long vr41xx_tclock;
+
+unsigned long vr41xx_get_vtclock_frequency(void)
+{
+	return vr41xx_vtclock;
+}
+
+unsigned long vr41xx_get_tclock_frequency(void)
+{
+	return vr41xx_tclock;
+}
 
-static inline u16 read_clkspeed(void)
+static inline uint16_t read_clkspeed(void)
 {
 	switch (current_cpu_data.cputype) {
 	case CPU_VR4111:
@@ -84,7 +89,7 @@
 	return 0;
 }
 
-static inline unsigned long calculate_pclock(u16 clkspeed)
+static inline unsigned long calculate_pclock(uint16_t clkspeed)
 {
 	unsigned long pclock = 0;
 
@@ -134,46 +139,48 @@
 	return pclock;
 }
 
-static inline unsigned long calculate_vtclock(u16 clkspeed, unsigned long pclock)
+static inline unsigned long calculate_vtclock(uint16_t clkspeed, unsigned long pclock)
 {
+	unsigned long vtclock = 0;
+
 	switch (current_cpu_data.cputype) {
 	case CPU_VR4111:
 		/* The NEC VR4111 doesn't have the VTClock. */
 		break;
 	case CPU_VR4121:
-		vr41xx_vtclock = pclock;
+		vtclock = pclock;
 		/* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */
 		if (DIVVT(clkspeed) == 9)
-			vr41xx_vtclock = pclock * 6;
+			vtclock = pclock * 6;
 		/* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */
 		else if (DIVVT(clkspeed) == 10)
-			vr41xx_vtclock = pclock * 4;
-		vr41xx_vtclock /= DIVVT(clkspeed);
-		printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock);
+			vtclock = pclock * 4;
+		vtclock /= DIVVT(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
 		break;
 	case CPU_VR4122:
 		if(VTDIVMODE(clkspeed) == 7)
-			vr41xx_vtclock = pclock / 1;
+			vtclock = pclock / 1;
 		else if(VTDIVMODE(clkspeed) == 1)
-			vr41xx_vtclock = pclock / 2;
+			vtclock = pclock / 2;
 		else
-			vr41xx_vtclock = pclock / VTDIVMODE(clkspeed);
-		printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock);
+			vtclock = pclock / VTDIVMODE(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
 		break;
 	case CPU_VR4131:
 	case CPU_VR4133:
-		vr41xx_vtclock = pclock / VTDIVMODE(clkspeed);
-		printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock);
+		vtclock = pclock / VTDIVMODE(clkspeed);
+		printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
 		break;
 	default:
 		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
 		break;
 	}
 
-	return vr41xx_vtclock;
+	return vtclock;
 }
 
-static inline unsigned long calculate_tclock(u16 clkspeed, unsigned long pclock,
+static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pclock,
                                              unsigned long vtclock)
 {
 	unsigned long tclock = 0;
@@ -205,30 +212,14 @@
 	return tclock;
 }
 
-static inline unsigned long calculate_mips_hpt_frequency(unsigned long tclock)
-{
-	/*
-	 * VR4131 Revision 2.0 and 2.1 use a value of (tclock / 2).
-	 */
-	if ((current_cpu_data.processor_id == PRID_VR4131_REV2_0) ||
-	    (current_cpu_data.processor_id == PRID_VR4131_REV2_1))
-		tclock /= 2;
-	else
-		tclock /= 4;
-
-	return tclock;
-}
-
 void __init vr41xx_bcu_init(void)
 {
-	unsigned long pclock, vtclock, tclock;
-	u16 clkspeed;
+	unsigned long pclock;
+	uint16_t clkspeed;
 
 	clkspeed = read_clkspeed();
 
 	pclock = calculate_pclock(clkspeed);
-	vtclock = calculate_vtclock(clkspeed, pclock);
-	tclock = calculate_tclock(clkspeed, pclock, vtclock);
-
-	mips_hpt_frequency = calculate_mips_hpt_frequency(tclock);
+	vr41xx_vtclock = calculate_vtclock(clkspeed, pclock);
+	vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock);
 }
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/giu.c linux-2.4.24-pre2/arch/mips/vr41xx/common/giu.c
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/giu.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/giu.c	2003-12-22 11:34:33.000000000 -0800
@@ -44,7 +44,6 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 
-#include <asm/addrspace.h>
 #include <asm/cpu.h>
 #include <asm/io.h>
 #include <asm/vr41xx/vr41xx.h>
@@ -64,15 +63,19 @@
 #define GIUINTALSELH	0x16
 #define GIUINTHTSELL	0x18
 #define GIUINTHTSELH	0x1a
+#define GIUFEDGEINHL	0x20
+#define GIUFEDGEINHH	0x22
+#define GIUREDGEINHL	0x24
+#define GIUREDGEINHH	0x26
 
-u32 vr41xx_giu_base = 0;
+static uint32_t giu_base;
 
-#define read_giuint(offset)		readw(vr41xx_giu_base + (offset))
-#define write_giuint(val, offset)	writew((val), vr41xx_giu_base + (offset))
+#define read_giuint(offset)		readw(giu_base + (offset))
+#define write_giuint(val, offset)	writew((val), giu_base + (offset))
 
-static inline u16 set_giuint(u16 offset, u16 set)
+static inline uint16_t set_giuint(uint8_t offset, uint16_t set)
 {
-	u16 res;
+	uint16_t res;
 
 	res = read_giuint(offset);
 	res |= set;
@@ -81,9 +84,9 @@
 	return res;
 }
 
-static inline u16 clear_giuint(u16 offset, u16 clear)
+static inline uint16_t clear_giuint(uint8_t offset, uint16_t clear)
 {
-	u16 res;
+	uint16_t res;
 
 	res = read_giuint(offset);
 	res &= ~clear;
@@ -95,51 +98,83 @@
 void vr41xx_enable_giuint(int pin)
 {
 	if (pin < 16)
-		set_giuint(GIUINTENL, (u16)1 << pin);
+		set_giuint(GIUINTENL, (uint16_t)1 << pin);
 	else
-		set_giuint(GIUINTENH, (u16)1 << (pin - 16));
+		set_giuint(GIUINTENH, (uint16_t)1 << (pin - 16));
 }
 
 void vr41xx_disable_giuint(int pin)
 {
 	if (pin < 16)
-		clear_giuint(GIUINTENL, (u16)1 << pin);
+		clear_giuint(GIUINTENL, (uint16_t)1 << pin);
 	else
-		clear_giuint(GIUINTENH, (u16)1 << (pin - 16));
+		clear_giuint(GIUINTENH, (uint16_t)1 << (pin - 16));
 }
 
 void vr41xx_clear_giuint(int pin)
 {
 	if (pin < 16)
-		write_giuint((u16)1 << pin, GIUINTSTATL);
+		write_giuint((uint16_t)1 << pin, GIUINTSTATL);
 	else
-		write_giuint((u16)1 << (pin - 16), GIUINTSTATH);
+		write_giuint((uint16_t)1 << (pin - 16), GIUINTSTATH);
 }
 
 void vr41xx_set_irq_trigger(int pin, int trigger, int hold)
 {
-	u16 mask;
+	uint16_t mask;
 
 	if (pin < 16) {
-		mask = (u16)1 << pin;
-		if (trigger == TRIGGER_EDGE) {
+		mask = (uint16_t)1 << pin;
+		if (trigger != TRIGGER_LEVEL) {
         		set_giuint(GIUINTTYPL, mask);
 			if (hold == SIGNAL_HOLD)
 				set_giuint(GIUINTHTSELL, mask);
 			else
 				clear_giuint(GIUINTHTSELL, mask);
+			if (current_cpu_data.cputype == CPU_VR4133) {
+				switch (trigger) {
+				case TRIGGER_EDGE_FALLING:
+					set_giuint(GIUFEDGEINHL, mask);
+					clear_giuint(GIUREDGEINHL, mask);
+					break;
+				case TRIGGER_EDGE_RISING:
+					clear_giuint(GIUFEDGEINHL, mask);
+					set_giuint(GIUREDGEINHL, mask);
+					break;
+				default:
+					set_giuint(GIUFEDGEINHL, mask);
+					set_giuint(GIUREDGEINHL, mask);
+					break;
+				}
+			}
 		} else {
 			clear_giuint(GIUINTTYPL, mask);
 			clear_giuint(GIUINTHTSELL, mask);
 		}
 	} else {
-		mask = (u16)1 << (pin - 16);
-		if (trigger == TRIGGER_EDGE) {
+		mask = (uint16_t)1 << (pin - 16);
+		if (trigger != TRIGGER_LEVEL) {
 			set_giuint(GIUINTTYPH, mask);
 			if (hold == SIGNAL_HOLD)
 				set_giuint(GIUINTHTSELH, mask);
 			else
 				clear_giuint(GIUINTHTSELH, mask);
+			if (current_cpu_data.cputype == CPU_VR4133) {
+				switch (trigger) {
+				case TRIGGER_EDGE_FALLING:
+					set_giuint(GIUFEDGEINHH, mask);
+					clear_giuint(GIUREDGEINHH, mask);
+					break;
+				case TRIGGER_EDGE_RISING:
+					clear_giuint(GIUFEDGEINHH, mask);
+					set_giuint(GIUREDGEINHH, mask);
+					break;
+				default:
+					set_giuint(GIUFEDGEINHH, mask);
+					set_giuint(GIUREDGEINHH, mask);
+					break;
+				}
+			}
 		} else {
 			clear_giuint(GIUINTTYPH, mask);
 			clear_giuint(GIUINTHTSELH, mask);
@@ -151,16 +186,16 @@
 
 void vr41xx_set_irq_level(int pin, int level)
 {
-	u16 mask;
+	uint16_t mask;
 
 	if (pin < 16) {
-		mask = (u16)1 << pin;
+		mask = (uint16_t)1 << pin;
 		if (level == LEVEL_HIGH)
 			set_giuint(GIUINTALSELL, mask);
 		else
 			clear_giuint(GIUINTALSELL, mask);
 	} else {
-		mask = (u16)1 << (pin - 16);
+		mask = (uint16_t)1 << (pin - 16);
 		if (level == LEVEL_HIGH)
 			set_giuint(GIUINTALSELH, mask);
 		else
@@ -201,7 +236,7 @@
 	if(!get_irq_number)
 		return -EINVAL;
 
-	pin = irq - GIU_IRQ(0);
+	pin = GIU_IRQ_TO_PIN(irq);
 	giuint_cascade[pin].flag = GIUINT_CASCADE;
 	giuint_cascade[pin].get_irq_number = get_irq_number;
 
@@ -222,7 +257,7 @@
 
 	disable_irq(GIUINT_CASCADE_IRQ);
 	cascade = &giuint_cascade[pin];
-	giuint_irq = pin + GIU_IRQ(0);
+	giuint_irq = GIU_IRQ(pin);
 	if (cascade->flag == GIUINT_CASCADE) {
 		cascade_irq = cascade->get_irq_number(giuint_irq);
 		disable_irq(giuint_irq);
@@ -245,12 +280,12 @@
 	switch (current_cpu_data.cputype) {
 	case CPU_VR4111:
 	case CPU_VR4121:
-		vr41xx_giu_base = VR4111_GIUIOSELL;
+		giu_base = VR4111_GIUIOSELL;
 		break;
 	case CPU_VR4122:
 	case CPU_VR4131:
 	case CPU_VR4133:
-		vr41xx_giu_base = VR4122_GIUIOSELL;
+		giu_base = VR4122_GIUIOSELL;
 		break;
 	default:
 		panic("GIU: Unexpected CPU of NEC VR4100 series");
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/icu.c linux-2.4.24-pre2/arch/mips/vr41xx/common/icu.c
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/icu.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/icu.c	2003-12-22 11:34:33.000000000 -0800
@@ -1,9 +1,9 @@
 /*
  * FILE NAME
- *	arch/mips/vr41xx/vr4122/common/icu.c
+ *	arch/mips/vr41xx/common/icu.c
  *
  * BRIEF MODULE DESCRIPTION
- *	Interrupt Control Unit routines for the NEC VR4122 and VR4131.
+ *	Interrupt Control Unit routines for the NEC VR4100 series.
  *
  * Author: Yoichi Yuasa
  *         yyuasa@mvista.com or source@mvista.com
@@ -36,11 +36,8 @@
  *  - New creation, NEC VR4122 and VR4131 are supported.
  *  - Added support for NEC VR4111 and VR4121.
  *
- *  Paul Mundt <lethal@chaoticdreams.org>
- *  - kgdb support.
- *
  *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
- *  - Added support for NEC VR4133.
+ *  - Coped with INTASSIGN of NEC VR4133.
  */
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -48,23 +45,27 @@
 #include <linux/irq.h>
 #include <linux/types.h>
 
-#include <asm/addrspace.h>
 #include <asm/cpu.h>
-#include <asm/gdb-stub.h>
 #include <asm/io.h>
-#include <asm/mipsregs.h>
+#include <asm/irq.h>
+#include <asm/irq_cpu.h>
 #include <asm/vr41xx/vr41xx.h>
 
 extern asmlinkage void vr41xx_handle_interrupt(void);
 
-extern void __init init_generic_irq(void);
-extern void mips_cpu_irq_init(u32 irq_base);
-
 extern void vr41xx_giuint_init(void);
+extern void vr41xx_enable_giuint(int pin);
+extern void vr41xx_disable_giuint(int pin);
+extern void vr41xx_clear_giuint(int pin);
 extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs);
 
-static u32 vr41xx_icu1_base = 0;
-static u32 vr41xx_icu2_base = 0;
+static uint32_t icu1_base;
+static uint32_t icu2_base;
+
+static unsigned char sysint1_assign[16] = {
+	0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static unsigned char sysint2_assign[16] = {
+	2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
 #define VR4111_SYSINT1REG	KSEG1ADDR(0x0b000080)
 #define VR4111_SYSINT2REG	KSEG1ADDR(0x0b000200)
@@ -73,26 +74,36 @@
 #define VR4122_SYSINT2REG	KSEG1ADDR(0x0f0000a0)
 
 #define SYSINT1REG	0x00
+#define INTASSIGN0	0x04
+#define INTASSIGN1	0x06
 #define GIUINTLREG	0x08
 #define MSYSINT1REG	0x0c
 #define MGIUINTLREG	0x14
 #define NMIREG		0x18
 #define SOFTREG		0x1a
+#define INTASSIGN2	0x1c
+#define INTASSIGN3	0x1e
 
 #define SYSINT2REG	0x00
 #define GIUINTHREG	0x02
 #define MSYSINT2REG	0x06
 #define MGIUINTHREG	0x08
 
-#define read_icu1(offset)	readw(vr41xx_icu1_base + (offset))
-#define write_icu1(val, offset)	writew((val), vr41xx_icu1_base + (offset))
+#define SYSINT1_IRQ_TO_PIN(x)	((x) - SYSINT1_IRQ_BASE)	/* Pin 0-15 */
+#define SYSINT2_IRQ_TO_PIN(x)	((x) - SYSINT2_IRQ_BASE)	/* Pin 0-15 */
+
+#define read_icu1(offset)	readw(icu1_base + (offset))
+#define write_icu1(val, offset)	writew((val), icu1_base + (offset))
 
-#define read_icu2(offset)	readw(vr41xx_icu2_base + (offset))
-#define write_icu2(val, offset)	writew((val), vr41xx_icu2_base + (offset))
+#define read_icu2(offset)	readw(icu2_base + (offset))
+#define write_icu2(val, offset)	writew((val), icu2_base + (offset))
 
-static inline u16 set_icu1(u16 offset, u16 set)
+#define INTASSIGN_MAX	4
+#define INTASSIGN_MASK	0x0007
+
+static inline uint16_t set_icu1(uint8_t offset, uint16_t set)
 {
-	u16 res;
+	uint16_t res;
 
 	res = read_icu1(offset);
 	res |= set;
@@ -101,9 +112,9 @@
 	return res;
 }
 
-static inline u16 clear_icu1(u16 offset, u16 clear)
+static inline uint16_t clear_icu1(uint8_t offset, uint16_t clear)
 {
-	u16 res;
+	uint16_t res;
 
 	res = read_icu1(offset);
 	res &= ~clear;
@@ -112,9 +123,9 @@
 	return res;
 }
 
-static inline u16 set_icu2(u16 offset, u16 set)
+static inline uint16_t set_icu2(uint8_t offset, uint16_t set)
 {
-	u16 res;
+	uint16_t res;
 
 	res = read_icu2(offset);
 	res |= set;
@@ -123,9 +134,9 @@
 	return res;
 }
 
-static inline u16 clear_icu2(u16 offset, u16 clear)
+static inline uint16_t clear_icu2(uint8_t offset, uint16_t clear)
 {
-	u16 res;
+	uint16_t res;
 
 	res = read_icu2(offset);
 	res &= ~clear;
@@ -138,17 +149,17 @@
 
 static void enable_sysint1_irq(unsigned int irq)
 {
-	set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+	set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));
 }
 
 static void disable_sysint1_irq(unsigned int irq)
 {
-	clear_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+	clear_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));
 }
 
 static unsigned int startup_sysint1_irq(unsigned int irq)
 {
-	set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+	set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));
 
 	return 0; /* never anything pending */
 }
@@ -159,35 +170,34 @@
 static void end_sysint1_irq(unsigned int irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE));
+		set_icu1(MSYSINT1REG, (uint16_t)1 << SYSINT1_IRQ_TO_PIN(irq));
 }
 
 static struct hw_interrupt_type sysint1_irq_type = {
-	"SYSINT1",
-	startup_sysint1_irq,
-	shutdown_sysint1_irq,
-	enable_sysint1_irq,
-	disable_sysint1_irq,
-	ack_sysint1_irq,
-	end_sysint1_irq,
-	NULL
+	.typename	= "SYSINT1",
+	.startup	= startup_sysint1_irq,
+	.shutdown	= shutdown_sysint1_irq,
+	.enable		= enable_sysint1_irq,
+	.disable	= disable_sysint1_irq,
+	.ack		= ack_sysint1_irq,
+	.end		= end_sysint1_irq,
 };
 
 /*=======================================================================*/
 
 static void enable_sysint2_irq(unsigned int irq)
 {
-	set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+	set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));
 }
 
 static void disable_sysint2_irq(unsigned int irq)
 {
-	clear_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+	clear_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));
 }
 
 static unsigned int startup_sysint2_irq(unsigned int irq)
 {
-	set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+	set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));
 
 	return 0; /* never anything pending */
 }
@@ -198,18 +208,17 @@
 static void end_sysint2_irq(unsigned int irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE));
+		set_icu2(MSYSINT2REG, (uint16_t)1 << SYSINT2_IRQ_TO_PIN(irq));
 }
 
 static struct hw_interrupt_type sysint2_irq_type = {
-	"SYSINT2",
-	startup_sysint2_irq,
-	shutdown_sysint2_irq,
-	enable_sysint2_irq,
-	disable_sysint2_irq,
-	ack_sysint2_irq,
-	end_sysint2_irq,
-	NULL
+	.typename	= "SYSINT2",
+	.startup	= startup_sysint2_irq,
+	.shutdown	= shutdown_sysint2_irq,
+	.enable		= enable_sysint2_irq,
+	.disable	= disable_sysint2_irq,
+	.ack		= ack_sysint2_irq,
+	.end		= end_sysint2_irq,
 };
 
 /*=======================================================================*/
@@ -218,12 +227,11 @@
 {
 	int pin;
 
-	pin = irq - GIU_IRQ_BASE;
+	pin = GIU_IRQ_TO_PIN(irq);
 	if (pin < 16)
-		set_icu1(MGIUINTLREG, (u16)1 << pin);
+		set_icu1(MGIUINTLREG, (uint16_t)1 << pin);
 	else
-		set_icu2(MGIUINTHREG, (u16)1 << (pin - 16));
-
+		set_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16));
 	vr41xx_enable_giuint(pin);
 }
 
@@ -231,18 +239,17 @@
 {
 	int pin;
 
-	pin = irq - GIU_IRQ_BASE;
+	pin = GIU_IRQ_TO_PIN(irq);
 	vr41xx_disable_giuint(pin);
-
 	if (pin < 16)
-		clear_icu1(MGIUINTLREG, (u16)1 << pin);
+		clear_icu1(MGIUINTLREG, (uint16_t)1 << pin);
 	else
-		clear_icu2(MGIUINTHREG, (u16)1 << (pin - 16));
+		clear_icu2(MGIUINTHREG, (uint16_t)1 << (pin - 16));
 }
 
 static unsigned int startup_giuint_irq(unsigned int irq)
 {
-	vr41xx_clear_giuint(irq - GIU_IRQ_BASE);
+	vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq));
 
 	enable_giuint_irq(irq);
 
@@ -255,7 +262,7 @@
 {
 	disable_giuint_irq(irq);
 
-	vr41xx_clear_giuint(irq - GIU_IRQ_BASE);
+	vr41xx_clear_giuint(GIU_IRQ_TO_PIN(irq));
 }
 
 static void end_giuint_irq(unsigned int irq)
@@ -265,14 +272,13 @@
 }
 
 static struct hw_interrupt_type giuint_irq_type = {
-	"GIUINT",
-	startup_giuint_irq,
-	shutdown_giuint_irq,
-	enable_giuint_irq,
-	disable_giuint_irq,
-	ack_giuint_irq,
-	end_giuint_irq,
-	NULL
+	.typename	= "GIUINT",
+	.startup	= startup_giuint_irq,
+	.shutdown	= shutdown_giuint_irq,
+	.enable		= enable_giuint_irq,
+	.disable	= disable_giuint_irq,
+	.ack		= ack_giuint_irq,
+	.end		= end_giuint_irq,
 };
 
 /*=======================================================================*/
@@ -286,14 +292,14 @@
 	switch (current_cpu_data.cputype) {
 	case CPU_VR4111:
 	case CPU_VR4121:
-		vr41xx_icu1_base = VR4111_SYSINT1REG;
-		vr41xx_icu2_base = VR4111_SYSINT2REG;
+		icu1_base = VR4111_SYSINT1REG;
+		icu2_base = VR4111_SYSINT2REG;
 		break;
 	case CPU_VR4122:
 	case CPU_VR4131:
 	case CPU_VR4133:
-		vr41xx_icu1_base = VR4122_SYSINT1REG;
-		vr41xx_icu2_base = VR4122_SYSINT2REG;
+		icu1_base = VR4122_SYSINT1REG;
+		icu2_base = VR4122_SYSINT2REG;
 		break;
 	default:
 		panic("Unexpected CPU of NEC VR4100 series");
@@ -315,7 +321,11 @@
 			irq_desc[i].handler = &giuint_irq_type;
 	}
 
-	setup_irq(ICU_CASCADE_IRQ, &icu_cascade);
+	setup_irq(INT0_CASCADE_IRQ, &icu_cascade);
+	setup_irq(INT1_CASCADE_IRQ, &icu_cascade);
+	setup_irq(INT2_CASCADE_IRQ, &icu_cascade);
+	setup_irq(INT3_CASCADE_IRQ, &icu_cascade);
+	setup_irq(INT4_CASCADE_IRQ, &icu_cascade);
 }
 
 void __init init_IRQ(void)
@@ -329,31 +339,171 @@
 	vr41xx_giuint_init();
 
 	set_except_vector(0, vr41xx_handle_interrupt);
+}
+
+/*=======================================================================*/
+
+static inline int set_sysint1_assign(unsigned int irq, unsigned char assign)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	uint16_t intassign0, intassign1;
+	unsigned int pin;
+
+	pin = SYSINT1_IRQ_TO_PIN(irq);
+
+	spin_lock_irq(&desc->lock);
+
+	intassign0 = read_icu1(INTASSIGN0);
+	intassign1 = read_icu1(INTASSIGN1);
+
+	switch (pin) {
+	case 0:
+		intassign0 &= ~INTASSIGN_MASK;
+		intassign0 |= (uint16_t)assign;
+		break;
+	case 1:
+		intassign0 &= ~(INTASSIGN_MASK << 3);
+		intassign0 |= (uint16_t)assign << 3;
+		break;
+	case 2:
+		intassign0 &= ~(INTASSIGN_MASK << 6);
+		intassign0 |= (uint16_t)assign << 6;
+		break;
+	case 3:
+		intassign0 &= ~(INTASSIGN_MASK << 9);
+		intassign0 |= (uint16_t)assign << 9;
+		break;
+	case 8:
+		intassign0 &= ~(INTASSIGN_MASK << 12);
+		intassign0 |= (uint16_t)assign << 12;
+		break;
+	case 9:
+		intassign1 &= ~INTASSIGN_MASK;
+		intassign1 |= (uint16_t)assign;
+		break;
+	case 11:
+		intassign1 &= ~(INTASSIGN_MASK << 6);
+		intassign1 |= (uint16_t)assign << 6;
+		break;
+	case 12:
+		intassign1 &= ~(INTASSIGN_MASK << 9);
+		intassign1 |= (uint16_t)assign << 9;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sysint1_assign[pin] = assign;
+	write_icu1(intassign0, INTASSIGN0);
+	write_icu1(intassign1, INTASSIGN1);
+
+	spin_unlock_irq(&desc->lock);
+
+	return 0;
+}
+
+static inline int set_sysint2_assign(unsigned int irq, unsigned char assign)
+{
+	irq_desc_t *desc = irq_desc + irq;
+	uint16_t intassign2, intassign3;
+	unsigned int pin;
 
-#ifdef CONFIG_KGDB
-	printk("Setting debug traps - please connect the remote debugger.\n");
-	set_debug_traps();
-	breakpoint();
-#endif
+	pin = SYSINT2_IRQ_TO_PIN(irq);
+
+	spin_lock_irq(&desc->lock);
+
+	intassign2 = read_icu1(INTASSIGN2);
+	intassign3 = read_icu1(INTASSIGN3);
+
+	switch (pin) {
+	case 0:
+		intassign2 &= ~INTASSIGN_MASK;
+		intassign2 |= (uint16_t)assign;
+		break;
+	case 1:
+		intassign2 &= ~(INTASSIGN_MASK << 3);
+		intassign2 |= (uint16_t)assign << 3;
+		break;
+	case 3:
+		intassign2 &= ~(INTASSIGN_MASK << 6);
+		intassign2 |= (uint16_t)assign << 6;
+		break;
+	case 4:
+		intassign2 &= ~(INTASSIGN_MASK << 9);
+		intassign2 |= (uint16_t)assign << 9;
+		break;
+	case 5:
+		intassign2 &= ~(INTASSIGN_MASK << 12);
+		intassign2 |= (uint16_t)assign << 12;
+		break;
+	case 6:
+		intassign3 &= ~INTASSIGN_MASK;
+		intassign3 |= (uint16_t)assign;
+		break;
+	case 7:
+		intassign3 &= ~(INTASSIGN_MASK << 3);
+		intassign3 |= (uint16_t)assign << 3;
+		break;
+	case 8:
+		intassign3 &= ~(INTASSIGN_MASK << 6);
+		intassign3 |= (uint16_t)assign << 6;
+		break;
+	case 9:
+		intassign3 &= ~(INTASSIGN_MASK << 9);
+		intassign3 |= (uint16_t)assign << 9;
+		break;
+	case 10:
+		intassign3 &= ~(INTASSIGN_MASK << 12);
+		intassign3 |= (uint16_t)assign << 12;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	sysint2_assign[pin] = assign;
+	write_icu1(intassign2, INTASSIGN2);
+	write_icu1(intassign3, INTASSIGN3);
+
+	spin_unlock_irq(&desc->lock);
+
+	return 0;
+}
+
+int vr41xx_set_intassign(unsigned int irq, unsigned char intassign)
+{
+	int retval = -EINVAL;
+
+	if (current_cpu_data.cputype != CPU_VR4133)
+		return -EINVAL;
+
+	if (intassign > INTASSIGN_MAX)
+		return -EINVAL;
+
+	if (irq >= SYSINT1_IRQ_BASE && irq <= SYSINT1_IRQ_LAST)
+		retval = set_sysint1_assign(irq, intassign);
+	else if (irq >= SYSINT2_IRQ_BASE && irq <= SYSINT2_IRQ_LAST)
+		retval = set_sysint2_assign(irq, intassign);
+
+	return retval;
 }
 
 /*=======================================================================*/
 
-static inline void giuint_irqdispatch(u16 pendl, u16 pendh, struct pt_regs *regs)
+static inline void giuint_irq_dispatch(uint16_t pendl, uint16_t pendh,
+                                       struct pt_regs *regs)
 {
 	int i;
 
 	if (pendl) {
 		for (i = 0; i < 16; i++) {
-			if (pendl & (0x0001 << i)) {
+			if (pendl & ((uint16_t)1 << i)) {
 				giuint_do_IRQ(i, regs);
 				return;
 			}
 		}
-	}
-	else if (pendh) {
+	} else {
 		for (i = 0; i < 16; i++) {
-			if (pendh & (0x0001 << i)) {
+			if (pendh & ((uint16_t)1 << i)) {
 				giuint_do_IRQ(i + 16, regs);
 				return;
 			}
@@ -361,10 +511,10 @@
 	}
 }
 
-asmlinkage void icu_irqdispatch(struct pt_regs *regs)
+asmlinkage void irq_dispatch(unsigned char intnum, struct pt_regs *regs)
 {
-	u16 pend1, pend2, pendl, pendh;
-	u16 mask1, mask2, maskl, maskh;
+	uint16_t pend1, pend2, pendl, pendh;
+	uint16_t mask1, mask2, maskl, maskh;
 	int i;
 
 	pend1 = read_icu1(SYSINT1REG);
@@ -379,31 +529,36 @@
 	pendh = read_icu2(GIUINTHREG);
 	maskh = read_icu2(MGIUINTHREG);
 
-	pend1 &= mask1;
-	pend2 &= mask2;
-	pendl &= maskl;
-	pendh &= maskh;
-
-	if (pend1) {
-		if ((pend1 & 0x01ff) == 0x0100) {
-			giuint_irqdispatch(pendl, pendh, regs);
-		}
-		else {
-			for (i = 0; i < 16; i++) {
-				if (pend1 & (0x0001 << i)) {
-					do_IRQ(SYSINT1_IRQ_BASE + i, regs);
-					break;
+	mask1 &= pend1;
+	mask2 &= pend2;
+	maskl &= pendl;
+	maskh &= pendh;
+
+	if (mask1) {
+		for (i = 0; i < 16; i++) {
+			if (intnum == sysint1_assign[i] &&
+			    (mask1 & ((uint16_t)1 << i))) {
+				if (i == 8 && (maskl | maskh)) {
+					giuint_irq_dispatch(maskl, maskh, regs);
+					return;
+				} else {
+					do_IRQ(SYSINT1_IRQ(i), regs);
+					return;
 				}
 			}
 		}
-		return;
 	}
-	else if (pend2) {
+
+	if (mask2) {
 		for (i = 0; i < 16; i++) {
-			if (pend2 & (0x0001 << i)) {
-				do_IRQ(SYSINT2_IRQ_BASE + i, regs);
-				break;
+			if (intnum == sysint2_assign[i] &&
+			    (mask2 & ((uint16_t)1 << i))) {
+				do_IRQ(SYSINT2_IRQ(i), regs);
+				return;
 			}
 		}
 	}
+
+	printk(KERN_ERR "spurious interrupt: %04x,%04x,%04x,%04x\n", pend1, pend2, pendl, pendh);
+	atomic_inc(&irq_err_count);
 }
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/int-handler.S linux-2.4.24-pre2/arch/mips/vr41xx/common/int-handler.S
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/int-handler.S	2002-11-28 15:53:10.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/int-handler.S	2003-12-22 11:34:33.000000000 -0800
@@ -34,6 +34,9 @@
  * Changes:
  *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
  *  - New creation, NEC VR4100 series are supported.
+ *
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  - Coped with INTASSIGN of NEC VR4133.
  */
 #include <asm/asm.h>
 #include <asm/regdef.h>
@@ -59,55 +62,52 @@
 		andi	t0, 0xff00
 		and	t0, t0, t1
 
-		andi	t1, t0, CAUSEF_IP7	# timer interrupt
-		beqz	t1, 1f
+		andi	t1, t0, CAUSEF_IP7	# MIPS timer interrupt
+		bnez	t1, handle_irq
 		li	a0, 7
-		jal	ll_timer_interrupt
-		move	a1, sp
-		j	ret_from_irq
 
-1:
-		andi	t1, t0, 0x7800		# check for IP3-6
-		beqz	t1, 2f
+		andi	t1, t0, 0x7800		# check for Int1-4
+		beqz	t1, 1f
 
-		andi	t1, t0, CAUSEF_IP3	# check for IP3
-		bnez	t1, handle_it
+		andi	t1, t0, CAUSEF_IP3	# check for Int1
+		bnez	t1, handle_int
+		li	a0, 1
+
+		andi	t1, t0, CAUSEF_IP4	# check for Int2
+		bnez	t1, handle_int
+		li	a0, 2
+
+		andi	t1, t0, CAUSEF_IP5	# check for Int3
+		bnez	t1, handle_int
 		li	a0, 3
 
-		andi	t1, t0, CAUSEF_IP4	# check for IP4
-		bnez	t1, handle_it
+		andi	t1, t0, CAUSEF_IP6	# check for Int4
+		bnez	t1, handle_int
 		li	a0, 4
 
-		andi	t1, t0, CAUSEF_IP5	# check for IP5
-		bnez	t1, handle_it
-		li	a0, 5
-
-		andi	t1, t0, CAUSEF_IP6	# check for IP6
-		bnez	t1, handle_it
-		li	a0, 6
-
-2:
-		andi	t1, t0, CAUSEF_IP2	# check for IP2
-		beqz	t1, 3f
-		move	a0, sp
-		jal	icu_irqdispatch
-		nop
-		j	ret_from_irq
-		nop
+1:
+		andi	t1, t0, CAUSEF_IP2	# check for Int0
+		bnez	t1, handle_int
+		li	a0, 0
 
-3:
 		andi	t1, t0, CAUSEF_IP0	# check for IP0
-		bnez	t1, handle_it
+		bnez	t1, handle_irq
 		li	a0, 0
 
 		andi	t1, t0, CAUSEF_IP1	# check for IP1
-		bnez	t1, handle_it
+		bnez	t1, handle_irq
 		li	a0, 1
 
 		j	spurious_interrupt
 		nop
 
-handle_it:
+handle_int:
+		jal	irq_dispatch
+		move	a1, sp
+		j	ret_from_irq
+		nop
+
+handle_irq:
 		jal	do_IRQ
 		move	a1, sp
 		j	ret_from_irq
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/ksyms.c linux-2.4.24-pre2/arch/mips/vr41xx/common/ksyms.c
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/ksyms.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/ksyms.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,35 @@
+/*
+ *   ksyms.c, Export NEC VR4100 series specific functions needed for loadable modules.
+ *
+ *  Copyright (C) 2003  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <asm/vr41xx/vr41xx.h>
+
+EXPORT_SYMBOL(vr41xx_get_vtclock_frequency);
+EXPORT_SYMBOL(vr41xx_get_tclock_frequency);
+
+EXPORT_SYMBOL(vr41xx_set_intassign);
+
+EXPORT_SYMBOL(vr41xx_set_rtclong1_cycle);
+EXPORT_SYMBOL(vr41xx_read_rtclong1_counter);
+EXPORT_SYMBOL(vr41xx_set_rtclong2_cycle);
+EXPORT_SYMBOL(vr41xx_read_rtclong2_counter);
+EXPORT_SYMBOL(vr41xx_set_tclock_cycle);
+EXPORT_SYMBOL(vr41xx_read_tclock_counter);
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/pciu.c linux-2.4.24-pre2/arch/mips/vr41xx/common/pciu.c
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/pciu.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/pciu.c	2003-12-22 11:34:33.000000000 -0800
@@ -51,8 +51,6 @@
 
 #include "pciu.h"
 
-extern unsigned long vr41xx_vtclock;
-
 static inline int vr41xx_pci_config_access(struct pci_dev *dev, int where)
 {
 	unsigned char bus = dev->bus->number;
@@ -196,6 +194,7 @@
 void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map)
 {
 	struct vr41xx_pci_address_space *s;
+	unsigned long vtclock;
 	u32 config;
 	int n;
 
@@ -215,11 +214,12 @@
 	udelay(1);
 
 	/* Select PCI clock */
-	if (vr41xx_vtclock < MAX_PCI_CLOCK)
+	vtclock = vr41xx_get_vtclock_frequency();
+	if (vtclock < MAX_PCI_CLOCK)
 		writel(EQUAL_VTCLOCK, PCICLKSELREG);
-	else if ((vr41xx_vtclock / 2) < MAX_PCI_CLOCK)
+	else if ((vtclock / 2) < MAX_PCI_CLOCK)
 		writel(HALF_VTCLOCK, PCICLKSELREG);
-	else if ((vr41xx_vtclock / 4) < MAX_PCI_CLOCK)
+	else if ((vtclock / 4) < MAX_PCI_CLOCK)
 		writel(QUARTER_VTCLOCK, PCICLKSELREG);
 	else
 		printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n");
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/rtc.c linux-2.4.24-pre2/arch/mips/vr41xx/common/rtc.c
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/rtc.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/rtc.c	2003-12-22 11:34:33.000000000 -0800
@@ -0,0 +1,312 @@
+/*
+ *  rtc.c, RTC(has only timer function) routines for NEC VR4100 series.
+ *
+ *  Copyright (C) 2003  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/vr41xx/vr41xx.h>
+
+static uint32_t rtc1_base;
+static uint32_t rtc2_base;
+
+static uint64_t previous_elapsedtime;
+static unsigned int remainder_per_sec;
+static unsigned int cycles_per_sec;
+static unsigned int cycles_per_jiffy;
+static unsigned long epoch_time;
+
+#define CLOCK_TICK_RATE		32768	/* 32.768kHz */
+
+#define CYCLES_PER_JIFFY	(CLOCK_TICK_RATE / HZ)
+#define REMAINDER_PER_SEC	(CLOCK_TICK_RATE - (CYCLES_PER_JIFFY * HZ))
+#define CYCLES_PER_100USEC	((CLOCK_TICK_RATE + (10000 / 2)) / 10000)
+
+#define VR4111_ETIMELREG	KSEG1ADDR(0x0b0000c0)
+#define VR4111_TCLKLREG		KSEG1ADDR(0x0b0001c0)
+
+#define VR4122_ETIMELREG	KSEG1ADDR(0x0f000100)
+#define VR4122_TCLKLREG		KSEG1ADDR(0x0f000120)
+
+/* RTC 1 registers */
+#define ETIMELREG		0x00
+#define ETIMEMREG		0x02
+#define ETIMEHREG		0x04
+/* RFU */
+#define ECMPLREG		0x08
+#define ECMPMREG		0x0a
+#define ECMPHREG		0x0c
+/* RFU */
+#define RTCL1LREG		0x10
+#define RTCL1HREG		0x12
+#define RTCL1CNTLREG		0x14
+#define RTCL1CNTHREG		0x16
+#define RTCL2LREG		0x18
+#define RTCL2HREG		0x1a
+#define RTCL2CNTLREG		0x1c
+#define RTCL2CNTHREG		0x1e
+
+/* RTC 2 registers */
+#define TCLKLREG		0x00
+#define TCLKHREG		0x02
+#define TCLKCNTLREG		0x04
+#define TCLKCNTHREG		0x06
+/* RFU */
+#define RTCINTREG		0x1e
+ #define TCLOCK_INT		0x08
+ #define RTCLONG2_INT		0x04
+ #define RTCLONG1_INT		0x02
+ #define ELAPSEDTIME_INT	0x01
+
+#define read_rtc1(offset)	readw(rtc1_base + (offset))
+#define write_rtc1(val, offset)	writew((val), rtc1_base + (offset))
+
+#define read_rtc2(offset)	readw(rtc2_base + (offset))
+#define write_rtc2(val, offset)	writew((val), rtc2_base + (offset))
+
+static inline uint64_t read_elapsedtime_counter(void)
+{
+	uint64_t first, second;
+	uint32_t first_mid, first_low;
+	uint32_t second_mid, second_low;
+
+	do {
+		first_low = (uint32_t)read_rtc1(ETIMELREG);
+		first_mid = (uint32_t)read_rtc1(ETIMEMREG);
+		first = (uint64_t)read_rtc1(ETIMEHREG);
+		second_low = (uint32_t)read_rtc1(ETIMELREG);
+		second_mid = (uint32_t)read_rtc1(ETIMEMREG);
+		second = (uint64_t)read_rtc1(ETIMEHREG);
+	} while (first_low != second_low || first_mid != second_mid ||
+	         first != second);
+
+	return (first << 32) | (uint64_t)((first_mid << 16) | first_low);
+}
+
+static inline void write_elapsedtime_counter(uint64_t time)
+{
+	write_rtc1((uint16_t)time, ETIMELREG);
+	write_rtc1((uint16_t)(time >> 16), ETIMEMREG);
+	write_rtc1((uint16_t)(time >> 32), ETIMEHREG);
+}
+
+static inline void write_elapsedtime_compare(uint64_t time)
+{
+	write_rtc1((uint16_t)time, ECMPLREG);
+	write_rtc1((uint16_t)(time >> 16), ECMPMREG);
+	write_rtc1((uint16_t)(time >> 32), ECMPHREG);
+}
+
+void vr41xx_set_rtclong1_cycle(uint32_t cycles)
+{
+	write_rtc1((uint16_t)cycles, RTCL1LREG);
+	write_rtc1((uint16_t)(cycles >> 16), RTCL1HREG);
+}
+
+uint32_t vr41xx_read_rtclong1_counter(void)
+{
+	uint32_t first_high, first_low;
+	uint32_t second_high, second_low;
+
+	do {
+		first_low = (uint32_t)read_rtc1(RTCL1CNTLREG);
+		first_high = (uint32_t)read_rtc1(RTCL1CNTHREG);
+		second_low = (uint32_t)read_rtc1(RTCL1CNTLREG);
+		second_high = (uint32_t)read_rtc1(RTCL1CNTHREG);
+	} while (first_low != second_low || first_high != second_high);
+
+	return (first_high << 16) | first_low;
+}
+
+void vr41xx_set_rtclong2_cycle(uint32_t cycles)
+{
+	write_rtc1((uint16_t)cycles, RTCL2LREG);
+	write_rtc1((uint16_t)(cycles >> 16), RTCL2HREG);
+}
+
+uint32_t vr41xx_read_rtclong2_counter(void)
+{
+	uint32_t first_high, first_low;
+	uint32_t second_high, second_low;
+
+	do {
+		first_low = (uint32_t)read_rtc1(RTCL2CNTLREG);
+		first_high = (uint32_t)read_rtc1(RTCL2CNTHREG);
+		second_low = (uint32_t)read_rtc1(RTCL2CNTLREG);
+		second_high = (uint32_t)read_rtc1(RTCL2CNTHREG);
+	} while (first_low != second_low || first_high != second_high);
+
+	return (first_high << 16) | first_low;
+}
+
+void vr41xx_set_tclock_cycle(uint32_t cycles)
+{
+	write_rtc2((uint16_t)cycles, TCLKLREG);
+	write_rtc2((uint16_t)(cycles >> 16), TCLKHREG);
+}
+
+uint32_t vr41xx_read_tclock_counter(void)
+{
+	uint32_t first_high, first_low;
+	uint32_t second_high, second_low;
+
+	do {
+		first_low = (uint32_t)read_rtc2(TCLKCNTLREG);
+		first_high = (uint32_t)read_rtc2(TCLKCNTHREG);
+		second_low = (uint32_t)read_rtc2(TCLKCNTLREG);
+		second_high = (uint32_t)read_rtc2(TCLKCNTHREG);
+	} while (first_low != second_low || first_high != second_high);
+
+	return (first_high << 16) | first_low;
+}
+
+static void vr41xx_timer_ack(void)
+{
+	uint64_t cur;
+
+	write_rtc2(ELAPSEDTIME_INT, RTCINTREG);
+
+	previous_elapsedtime += (uint64_t)cycles_per_jiffy;
+	cycles_per_sec += cycles_per_jiffy;
+
+	if (cycles_per_sec >= CLOCK_TICK_RATE) {
+		cycles_per_sec = 0;
+		remainder_per_sec = REMAINDER_PER_SEC;
+	}
+
+	cycles_per_jiffy = 0;
+
+	do {
+		cycles_per_jiffy += CYCLES_PER_JIFFY;
+		if (remainder_per_sec > 0) {
+			cycles_per_jiffy++;
+			remainder_per_sec--;
+		}
+
+		cur = read_elapsedtime_counter();
+	} while (cur >= previous_elapsedtime + (uint64_t)cycles_per_jiffy);
+
+	write_elapsedtime_compare(previous_elapsedtime + (uint64_t)cycles_per_jiffy);
+}
+
+static void vr41xx_hpt_init(unsigned int count)
+{
+}
+
+static unsigned int vr41xx_hpt_read(void)
+{
+	uint64_t cur;
+
+	cur = read_elapsedtime_counter();
+
+	return (unsigned int)cur;
+}
+
+static unsigned long vr41xx_gettimeoffset(void)
+{
+	uint64_t cur;
+	unsigned long gap;
+
+	cur = read_elapsedtime_counter();
+	gap = (unsigned long)(cur - previous_elapsedtime);
+	gap = gap / CYCLES_PER_100USEC * 100;	/* usec */
+
+	return gap;
+}
+
+static unsigned long vr41xx_get_time(void)
+{
+	uint64_t counts;
+
+	counts = read_elapsedtime_counter();
+	counts >>= 15;
+
+	return epoch_time + (unsigned long)counts;
+
+}
+
+static int vr41xx_set_time(unsigned long sec)
+{
+	if (sec < epoch_time)
+		return -EINVAL;
+
+	sec -= epoch_time;
+
+	write_elapsedtime_counter((uint64_t)sec << 15);
+
+	return 0;
+}
+
+void vr41xx_set_epoch_time(unsigned long time)
+{
+	epoch_time = time;
+}
+
+void __init vr41xx_time_init(void)
+{
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		rtc1_base = VR4111_ETIMELREG;
+		rtc2_base = VR4111_TCLKLREG;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133:
+		rtc1_base = VR4122_ETIMELREG;
+		rtc2_base = VR4122_TCLKLREG;
+		break;
+	default:
+		panic("Unexpected CPU of NEC VR4100 series");
+		break;
+	}
+
+	mips_timer_ack = vr41xx_timer_ack;
+
+	mips_hpt_init = vr41xx_hpt_init;
+	mips_hpt_read = vr41xx_hpt_read;
+	mips_hpt_frequency = CLOCK_TICK_RATE;
+
+	if (epoch_time == 0)
+		epoch_time = mktime(1970, 1, 1, 0, 0, 0);
+
+	rtc_get_time = vr41xx_get_time;
+	rtc_set_time = vr41xx_set_time;
+}
+
+void __init vr41xx_timer_setup(struct irqaction *irq)
+{
+	do_gettimeoffset = vr41xx_gettimeoffset;
+
+	remainder_per_sec = REMAINDER_PER_SEC;
+	cycles_per_jiffy = CYCLES_PER_JIFFY;
+
+	if (remainder_per_sec > 0) {
+		cycles_per_jiffy++;
+		remainder_per_sec--;
+	}
+
+	previous_elapsedtime = read_elapsedtime_counter();
+	write_elapsedtime_compare(previous_elapsedtime + (uint64_t)cycles_per_jiffy);
+	write_rtc2(ELAPSEDTIME_INT, RTCINTREG);
+
+	setup_irq(ELAPSEDTIME_IRQ, irq);
+}
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/time.c linux-2.4.24-pre2/arch/mips/vr41xx/common/time.c
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/time.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/time.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,95 +0,0 @@
-/*
- * FILE NAME
- *	arch/mips/vr41xx/common/time.c
- *
- * BRIEF MODULE DESCRIPTION
- *	Timer routines for the NEC VR4100 series.
- *
- * Author: Yoichi Yuasa
- *         yyuasa@mvista.com or source@mvista.com
- *
- * Copyright 2001,2002 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-/*
- * Changes:
- *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
- *  - New creation, NEC VR4100 series are supported.
- *  - Added support for NEC VR4100 series RTC Unit.
- *
- *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
- *  - Added support for NEC VR4133.
- */
-#include <linux/config.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/types.h>
-
-#include <asm/cpu.h>
-#include <asm/io.h>
-#include <asm/mipsregs.h>
-#include <asm/param.h>
-#include <asm/time.h>
-#include <asm/vr41xx/vr41xx.h>
-
-#define VR4111_ETIMELREG	KSEG1ADDR(0x0b0000c0)
-#define VR4122_ETIMELREG	KSEG1ADDR(0x0f000100)
-
-u32 vr41xx_rtc_base = 0;
-
-#ifdef CONFIG_VR41XX_RTC
-extern unsigned long vr41xx_rtc_get_time(void);
-extern int vr41xx_rtc_set_time(unsigned long sec);
-#endif
-
-void vr41xx_time_init(void)
-{
-	switch (current_cpu_data.cputype) {
-	case CPU_VR4111:
-	case CPU_VR4121:
-		vr41xx_rtc_base = VR4111_ETIMELREG;
-		break;
-	case CPU_VR4122:
-	case CPU_VR4131:
-	case CPU_VR4133:
-                vr41xx_rtc_base = VR4122_ETIMELREG;
-                break;
-        default:
-                panic("Unexpected CPU of NEC VR4100 series");
-                break;
-        }
-
-#ifdef CONFIG_VR41XX_RTC
-        rtc_get_time = vr41xx_rtc_get_time;
-        rtc_set_time = vr41xx_rtc_set_time;
-#endif
-}
-
-void vr41xx_timer_setup(struct irqaction *irq)
-{
-	u32 count;
-
-	setup_irq(MIPS_COUNTER_IRQ, irq);
-
-	count = read_c0_count();
-	write_c0_compare(count + (mips_hpt_frequency / HZ));
-}
diff -urN linux-2.4.24-pre1/arch/mips/vr41xx/common/vrc4173.c linux-2.4.24-pre2/arch/mips/vr41xx/common/vrc4173.c
--- linux-2.4.24-pre1/arch/mips/vr41xx/common/vrc4173.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips/vr41xx/common/vrc4173.c	2003-12-22 11:34:33.000000000 -0800
@@ -195,8 +195,8 @@
 	
 	vrc4173_outw(0, VRC4173_MSYSINT1REG);
 
-	vr41xx_set_irq_trigger(cascade_irq - GIU_IRQ(0), TRIGGER_LEVEL, SIGNAL_THROUGH);
-	vr41xx_set_irq_level(cascade_irq - GIU_IRQ(0), LEVEL_LOW);
+	vr41xx_set_irq_trigger(GIU_IRQ_TO_PIN(cascade_irq), TRIGGER_LEVEL, SIGNAL_THROUGH);
+	vr41xx_set_irq_level(GIU_IRQ_TO_PIN(cascade_irq), LEVEL_LOW);
 
 	for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++)
                 irq_desc[i].handler = &vrc4173_irq_type;
diff -urN linux-2.4.24-pre1/arch/mips64/Makefile linux-2.4.24-pre2/arch/mips64/Makefile
--- linux-2.4.24-pre1/arch/mips64/Makefile	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/Makefile	2003-12-22 11:34:33.000000000 -0800
@@ -345,7 +345,7 @@
 
 ifdef CONFIG_MAPPED_KERNEL
 vmlinux.64: vmlinux
-	$(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xbfffffff40000000 $< $@
+	$(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xc000000080000000 $< $@
 else
 vmlinux.64: vmlinux
 	$(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xa800000080000000 $< $@
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig linux-2.4.24-pre2/arch/mips64/defconfig
--- linux-2.4.24-pre1/arch/mips64/defconfig	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -75,7 +76,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
@@ -106,6 +106,7 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
 CONFIG_SMP=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
@@ -141,6 +142,7 @@
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -544,6 +546,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig-atlas linux-2.4.24-pre2/arch/mips64/defconfig-atlas
--- linux-2.4.24-pre1/arch/mips64/defconfig-atlas	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig-atlas	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
@@ -105,6 +103,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -138,6 +139,7 @@
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -568,6 +570,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig-decstation linux-2.4.24-pre2/arch/mips64/defconfig-decstation
--- linux-2.4.24-pre1/arch/mips64/defconfig-decstation	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig-decstation	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
@@ -100,6 +98,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -132,6 +133,7 @@
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -572,6 +574,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig-ip22 linux-2.4.24-pre2/arch/mips64/defconfig-ip22
--- linux-2.4.24-pre1/arch/mips64/defconfig-ip22	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig-ip22	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ARC32=y
@@ -108,6 +106,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -143,6 +144,7 @@
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -531,7 +533,6 @@
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-CONFIG_INDYDOG=y
 # CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
@@ -611,6 +612,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig-ip27 linux-2.4.24-pre2/arch/mips64/defconfig-ip27
--- linux-2.4.24-pre1/arch/mips64/defconfig-ip27	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig-ip27	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -75,7 +76,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF64=y
@@ -106,6 +106,7 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
 CONFIG_SMP=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
@@ -141,6 +142,7 @@
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -544,6 +546,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig-jaguar linux-2.4.24-pre2/arch/mips64/defconfig-jaguar
--- linux-2.4.24-pre1/arch/mips64/defconfig-jaguar	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig-jaguar	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 # CONFIG_MIPS_AU1000 is not set
@@ -97,6 +95,9 @@
 # CONFIG_CPU_RM7000 is not set
 CONFIG_CPU_RM9000=y
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_BOARD_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_RM7000_CPU_SCACHE=y
@@ -133,6 +134,7 @@
 CONFIG_MIPS32_N32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -506,6 +508,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig-malta linux-2.4.24-pre2/arch/mips64/defconfig-malta
--- linux-2.4.24-pre1/arch/mips64/defconfig-malta	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig-malta	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
@@ -110,6 +108,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -142,6 +143,7 @@
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -571,6 +573,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig-ocelotc linux-2.4.24-pre2/arch/mips64/defconfig-ocelotc
--- linux-2.4.24-pre1/arch/mips64/defconfig-ocelotc	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig-ocelotc	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 CONFIG_MOMENCO_OCELOT_C=y
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -70,9 +71,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_PCI=y
@@ -102,6 +100,9 @@
 CONFIG_CPU_RM7000=y
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_BOARD_SCACHE=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_RM7000_CPU_SCACHE=y
@@ -138,6 +139,7 @@
 CONFIG_MIPS32_N32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -557,6 +559,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig-sb1250-swarm linux-2.4.24-pre2/arch/mips64/defconfig-sb1250-swarm
--- linux-2.4.24-pre1/arch/mips64/defconfig-sb1250-swarm	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig-sb1250-swarm	2003-12-22 11:34:33.000000000 -0800
@@ -52,6 +52,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -94,9 +95,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_NEW_TIME_C=y
@@ -126,6 +124,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 CONFIG_CPU_SB1=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_SMP=y
 # CONFIG_SIBYTE_DMA_PAGEOPS is not set
 CONFIG_SB1_PASS_1_WORKAROUNDS=y
@@ -164,6 +165,7 @@
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -538,6 +540,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 
 #
 # Network File Systems
diff -urN linux-2.4.24-pre1/arch/mips64/defconfig-sead linux-2.4.24-pre2/arch/mips64/defconfig-sead
--- linux-2.4.24-pre1/arch/mips64/defconfig-sead	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/defconfig-sead	2003-12-22 11:34:33.000000000 -0800
@@ -50,6 +50,7 @@
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
 # CONFIG_DDB5477 is not set
@@ -68,9 +69,6 @@
 # CONFIG_VICTOR_MPC30X is not set
 # CONFIG_ZAO_CAPCELLA is not set
 # CONFIG_HIGHMEM is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
@@ -100,6 +98,9 @@
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
 CONFIG_CPU_HAS_LLSC=y
@@ -132,6 +133,7 @@
 # CONFIG_MIPS32_N32 is not set
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -348,6 +350,11 @@
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
 # CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_ZISOFS_FS is not set
diff -urN linux-2.4.24-pre1/arch/mips64/kernel/Makefile linux-2.4.24-pre2/arch/mips64/kernel/Makefile
--- linux-2.4.24-pre1/arch/mips64/kernel/Makefile	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips64/kernel/Makefile	2003-12-22 11:34:33.000000000 -0800
@@ -12,7 +12,7 @@
 
 O_TARGET := kernel.o
 
-export-objs	= irq.o mips64_ksyms.o pci-dma.o setup.o smp.o time.o
+export-objs	= irq.o mips64_ksyms.o pci-dma.o setup.o semaphore.o smp.o time.o
 
 obj-y		:= branch.o cpu-probe.o entry.o irq.o proc.o process.o \
 		   ptrace.o r4k_cache.o r4k_fpu.o r4k_genex.o r4k_switch.o \
diff -urN linux-2.4.24-pre1/arch/mips64/kernel/cpu-probe.c linux-2.4.24-pre2/arch/mips64/kernel/cpu-probe.c
--- linux-2.4.24-pre1/arch/mips64/kernel/cpu-probe.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/kernel/cpu-probe.c	2003-12-22 11:34:33.000000000 -0800
@@ -452,7 +452,7 @@
 }
 
 #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \
-		| MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX)
+		| MIPS_CPU_COUNTER)
 
 static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
 {
diff -urN linux-2.4.24-pre1/arch/mips64/kernel/ioctl32.c linux-2.4.24-pre2/arch/mips64/kernel/ioctl32.c
--- linux-2.4.24-pre1/arch/mips64/kernel/ioctl32.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/kernel/ioctl32.c	2003-12-22 11:34:33.000000000 -0800
@@ -12,32 +12,43 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/ioctl.h>
 #include <linux/if.h>
-#include <linux/mm.h>
-#include <linux/mtio.h>
-#include <linux/init.h>
-#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/hdreg.h>
+#include <linux/raid/md_u.h>
+#include <linux/kd.h>
+#include <linux/route.h>
+#include <linux/vt.h>
 #include <linux/fs.h>
 #include <linux/ppp_defs.h>
 #include <linux/if_ppp.h>
 #include <linux/if_pppox.h>
+#include <linux/if_tun.h>
+#include <linux/mtio.h>
 #include <linux/cdrom.h>
 #include <linux/loop.h>
-#include <linux/fb.h>
-#include <linux/vt.h>
+#include <linux/auto_fs.h>
+#include <linux/auto_fs4.h>
+#include <linux/devfs_fs.h>
+#include <linux/tty.h>
 #include <linux/vt_kern.h>
-#include <linux/kd.h>
+#include <linux/fb.h>
+#include <linux/ext2_fs.h>
+#include <linux/videodev.h>
 #include <linux/netdevice.h>
-#include <linux/route.h>
-#include <linux/hdreg.h>
+#include <linux/raw.h>
 #include <linux/blkpg.h>
-#include <linux/blkdev.h>
+#include <linux/blk.h>
 #include <linux/elevator.h>
-#include <linux/auto_fs.h>
-#include <linux/auto_fs4.h>
-#include <linux/ext2_fs.h>
-#include <linux/raid/md_u.h>
-#include <linux/serial.h>
+#include <linux/rtc.h>
+#include <linux/pci.h>
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+#include <linux/lvm.h>
+#endif /* LVM */
 
 #include <scsi/scsi.h>
 #undef __KERNEL__		/* This file was born to be ugly ...  */
@@ -47,11 +58,10 @@
 
 #include <asm/types.h>
 #include <asm/uaccess.h>
+#include <linux/soundcard.h>
 
-#include <linux/rtc.h>
-#ifdef CONFIG_MTD_CHAR
 #include <linux/mtd/mtd.h>
-#endif
+#include <linux/serial.h>
 
 #ifdef CONFIG_SIBYTE_TBPROF
 #include <asm/sibyte/trace_prof.h>
@@ -537,6 +547,246 @@
 	return sys_ioctl(fd, cmd, arg);
 }
 
+struct video_tuner32 {
+	s32 tuner;
+	u8 name[32];
+	u32 rangelow, rangehigh;
+	u32 flags;
+	u16 mode, signal;
+};
+
+static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
+{
+	int i;
+
+	if(get_user(kp->tuner, &up->tuner))
+		return -EFAULT;
+	for(i = 0; i < 32; i++)
+		__get_user(kp->name[i], &up->name[i]);
+	__get_user(kp->rangelow, &up->rangelow);
+	__get_user(kp->rangehigh, &up->rangehigh);
+	__get_user(kp->flags, &up->flags);
+	__get_user(kp->mode, &up->mode);
+	__get_user(kp->signal, &up->signal);
+	return 0;
+}
+
+static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 *up)
+{
+	int i;
+
+	if(put_user(kp->tuner, &up->tuner))
+		return -EFAULT;
+	for(i = 0; i < 32; i++)
+		__put_user(kp->name[i], &up->name[i]);
+	__put_user(kp->rangelow, &up->rangelow);
+	__put_user(kp->rangehigh, &up->rangehigh);
+	__put_user(kp->flags, &up->flags);
+	__put_user(kp->mode, &up->mode);
+	__put_user(kp->signal, &up->signal);
+	return 0;
+}
+
+struct video_buffer32 {
+	/* void * */ u32 base;
+	s32 height, width, depth, bytesperline;
+};
+
+static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
+{
+	u32 tmp;
+
+	if(get_user(tmp, &up->base))
+		return -EFAULT;
+	kp->base = (void *) ((unsigned long)tmp);
+	__get_user(kp->height, &up->height);
+	__get_user(kp->width, &up->width);
+	__get_user(kp->depth, &up->depth);
+	__get_user(kp->bytesperline, &up->bytesperline);
+	return 0;
+}
+
+static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 *up)
+{
+	u32 tmp = (u32)((unsigned long)kp->base);
+
+	if(put_user(tmp, &up->base))
+		return -EFAULT;
+	__put_user(kp->height, &up->height);
+	__put_user(kp->width, &up->width);
+	__put_user(kp->depth, &up->depth);
+	__put_user(kp->bytesperline, &up->bytesperline);
+	return 0;
+}
+
+struct video_clip32 {
+	s32 x, y, width, height;
+	/* struct video_clip32 * */ u32 next;
+};
+
+struct video_window32 {
+	u32 x, y, width, height, chromakey, flags;
+	/* struct video_clip32 * */ u32 clips;
+	s32 clipcount;
+};
+
+static void free_kvideo_clips(struct video_window *kp)
+{
+	struct video_clip *cp;
+
+	cp = kp->clips;
+	if(cp != NULL)
+		kfree(cp);
+}
+
+static int get_video_window32(struct video_window *kp, struct video_window32 *up)
+{
+	struct video_clip32 *ucp;
+	struct video_clip *kcp;
+	int nclips, err, i;
+	u32 tmp;
+
+	if(get_user(kp->x, &up->x))
+		return -EFAULT;
+	__get_user(kp->y, &up->y);
+	__get_user(kp->width, &up->width);
+	__get_user(kp->height, &up->height);
+	__get_user(kp->chromakey, &up->chromakey);
+	__get_user(kp->flags, &up->flags);
+	__get_user(kp->clipcount, &up->clipcount);
+	__get_user(tmp, &up->clips);
+	ucp = (struct video_clip32 *)A(tmp);
+	kp->clips = NULL;
+
+	nclips = kp->clipcount;
+	if(nclips == 0)
+		return 0;
+
+	if(ucp == 0)
+		return -EINVAL;
+
+	/* Peculiar interface... */
+	if(nclips < 0)
+		nclips = VIDEO_CLIPMAP_SIZE;
+
+	kcp = kmalloc(nclips * sizeof(struct video_clip), GFP_KERNEL);
+	err = -ENOMEM;
+	if(kcp == NULL)
+		goto cleanup_and_err;
+
+	kp->clips = kcp;
+	for(i = 0; i < nclips; i++) {
+		__get_user(kcp[i].x, &ucp[i].x);
+		__get_user(kcp[i].y, &ucp[i].y);
+		__get_user(kcp[i].width, &ucp[i].width);
+		__get_user(kcp[i].height, &ucp[i].height);
+		kcp[nclips].next = NULL;
+	}
+
+	return 0;
+
+cleanup_and_err:
+	free_kvideo_clips(kp);
+	return err;
+}
+
+/* You get back everything except the clips... */
+static int put_video_window32(struct video_window *kp, struct video_window32 *up)
+{
+	if(put_user(kp->x, &up->x))
+		return -EFAULT;
+	__put_user(kp->y, &up->y);
+	__put_user(kp->width, &up->width);
+	__put_user(kp->height, &up->height);
+	__put_user(kp->chromakey, &up->chromakey);
+	__put_user(kp->flags, &up->flags);
+	__put_user(kp->clipcount, &up->clipcount);
+	return 0;
+}
+
+#define VIDIOCGTUNER32		_IOWR('v',4, struct video_tuner32)
+#define VIDIOCSTUNER32		_IOW('v',5, struct video_tuner32)
+#define VIDIOCGWIN32		_IOR('v',9, struct video_window32)
+#define VIDIOCSWIN32		_IOW('v',10, struct video_window32)
+#define VIDIOCGFBUF32		_IOR('v',11, struct video_buffer32)
+#define VIDIOCSFBUF32		_IOW('v',12, struct video_buffer32)
+#define VIDIOCGFREQ32		_IOR('v',14, u32)
+#define VIDIOCSFREQ32		_IOW('v',15, u32)
+
+static int do_video_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	union {
+		struct video_tuner vt;
+		struct video_buffer vb;
+		struct video_window vw;
+		unsigned long vx;
+	} karg;
+	mm_segment_t old_fs = get_fs();
+	void *up = (void *)arg;
+	int err = 0;
+
+	/* First, convert the command. */
+	switch(cmd) {
+	case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break;
+	case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break;
+	case VIDIOCGWIN32: cmd = VIDIOCGWIN; break;
+	case VIDIOCSWIN32: cmd = VIDIOCSWIN; break;
+	case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break;
+	case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break;
+	case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break;
+	case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break;
+	};
+
+	switch(cmd) {
+	case VIDIOCSTUNER:
+	case VIDIOCGTUNER:
+		err = get_video_tuner32(&karg.vt, up);
+		break;
+
+	case VIDIOCSWIN:
+		err = get_video_window32(&karg.vw, up);
+		break;
+
+	case VIDIOCSFBUF:
+		err = get_video_buffer32(&karg.vb, up);
+		break;
+
+	case VIDIOCSFREQ:
+		err = get_user(karg.vx, (u32 *)up);
+		break;
+	};
+	if(err)
+		goto out;
+
+	set_fs(KERNEL_DS);
+	err = sys_ioctl(fd, cmd, (unsigned long)&karg);
+	set_fs(old_fs);
+
+	if(cmd == VIDIOCSWIN)
+		free_kvideo_clips(&karg.vw);
+
+	if(err == 0) {
+		switch(cmd) {
+		case VIDIOCGTUNER:
+			err = put_video_tuner32(&karg.vt, up);
+			break;
+
+		case VIDIOCGWIN:
+			err = put_video_window32(&karg.vw, up);
+			break;
+
+		case VIDIOCGFBUF:
+			err = put_video_buffer32(&karg.vb, up);
+			break;
+
+		case VIDIOCGFREQ:
+			err = put_user(((u32)karg.vx), (u32 *)up);
+			break;
+		};
+	}
+out:
+	return err;
+}
 struct hd_geometry32 {
 	unsigned char heads;
 	unsigned char sectors;
@@ -586,6 +836,12 @@
 	return -EINVAL;
 }
 
+static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	/* The mkswap binary hard codes it to Intel value :-((( */
+	return w_long(fd, BLKGETSIZE, arg);
+}
+
 struct blkpg_ioctl_arg32 {
 	int op;
 	int flags;
@@ -623,6 +879,39 @@
 	return err;
 }
 
+/* Fix sizeof(sizeof()) breakage */
+#define BLKELVGET_32	_IOR(0x12,106,int)
+#define BLKELVSET_32	_IOW(0x12,107,int)
+#define BLKBSZGET_32	_IOR(0x12,112,int)
+#define BLKBSZSET_32	_IOW(0x12,113,int)
+#define BLKGETSIZE64_32	_IOR(0x12,114,int)
+
+static int do_blkelvget(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return sys_ioctl(fd, BLKELVGET, arg);
+}
+
+static int do_blkelvset(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return sys_ioctl(fd, BLKELVSET, arg);
+}
+
+static int do_blkbszget(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return sys_ioctl(fd, BLKBSZGET, arg);
+}
+
+static int do_blkbszset(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	return sys_ioctl(fd, BLKBSZSET, arg);
+}
+
+static int do_blkgetsize64(unsigned int fd, unsigned int cmd,
+			   unsigned long arg)
+{
+	return sys_ioctl(fd, BLKGETSIZE64, arg);
+}
+
 struct mtget32 {
 	__u32	mt_type;
 	__u32	mt_resid;
@@ -874,11 +1163,11 @@
 	return err;
 }
 
+#ifdef CONFIG_VT
+
 extern int tty_ioctl(struct inode * inode, struct file * file,
 	unsigned int cmd, unsigned long arg);
 
-#ifdef CONFIG_VT
-
 static int vt_check(struct file *file)
 {
 	struct tty_struct *tty;
@@ -989,6 +1278,443 @@
 
 #endif /* CONFIG_VT */
 
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+/* Ugh, LVM. Pitty it was not cleaned up before accepted :((. */
+typedef struct {
+	uint8_t vg_name[NAME_LEN];
+	uint32_t vg_number;
+	uint32_t vg_access;
+	uint32_t vg_status;
+	uint32_t lv_max;
+	uint32_t lv_cur;
+	uint32_t lv_open;
+	uint32_t pv_max;
+	uint32_t pv_cur;
+	uint32_t pv_act;
+	uint32_t dummy;
+	uint32_t vgda;
+	uint32_t pe_size;
+	uint32_t pe_total;
+	uint32_t pe_allocated;
+	uint32_t pvg_total;
+	u32 proc;
+	u32 pv[ABS_MAX_PV + 1];
+	u32 lv[ABS_MAX_LV + 1];
+    	uint8_t vg_uuid[UUID_LEN+1];	/* volume group UUID */
+	uint8_t dummy1[200];
+} vg32_t;
+
+typedef struct {
+	uint8_t id[2];
+	uint16_t version;
+	lvm_disk_data_t pv_on_disk;
+	lvm_disk_data_t vg_on_disk;
+	lvm_disk_data_t pv_namelist_on_disk;
+	lvm_disk_data_t lv_on_disk;
+	lvm_disk_data_t pe_on_disk;
+	uint8_t pv_name[NAME_LEN];
+	uint8_t vg_name[NAME_LEN];
+	uint8_t system_id[NAME_LEN];
+	kdev_t pv_dev;
+	uint32_t pv_number;
+	uint32_t pv_status;
+	uint32_t pv_allocatable;
+	uint32_t pv_size;
+	uint32_t lv_cur;
+	uint32_t pe_size;
+	uint32_t pe_total;
+	uint32_t pe_allocated;
+	uint32_t pe_stale;
+	u32 pe;
+	u32 inode;
+	uint8_t pv_uuid[UUID_LEN+1];
+} pv32_t;
+
+typedef struct {
+	char lv_name[NAME_LEN];
+	u32 lv;
+} lv_req32_t;
+
+typedef struct {
+	u32 lv_index;
+	u32 lv;
+	/* Transfer size because user space and kernel space differ */
+	uint16_t size;
+} lv_status_byindex_req32_t;
+
+typedef struct {
+	__kernel_dev_t32 dev;
+	u32   lv;
+} lv_status_bydev_req32_t;
+
+typedef struct {
+	uint8_t lv_name[NAME_LEN];
+	kdev_t old_dev;
+	kdev_t new_dev;
+	u32 old_pe;
+	u32 new_pe;
+} le_remap_req32_t;
+
+typedef struct {
+	char pv_name[NAME_LEN];
+	u32 pv;
+} pv_status_req32_t;
+
+typedef struct {
+	uint8_t lv_name[NAME_LEN];
+	uint8_t vg_name[NAME_LEN];
+	uint32_t lv_access;
+	uint32_t lv_status;
+	uint32_t lv_open;
+	kdev_t lv_dev;
+	uint32_t lv_number;
+	uint32_t lv_mirror_copies;
+	uint32_t lv_recovery;
+	uint32_t lv_schedule;
+	uint32_t lv_size;
+	u32 lv_current_pe;
+	uint32_t lv_current_le;
+	uint32_t lv_allocated_le;
+	uint32_t lv_stripes;
+	uint32_t lv_stripesize;
+	uint32_t lv_badblock;
+	uint32_t lv_allocation;
+	uint32_t lv_io_timeout;
+	uint32_t lv_read_ahead;
+	/* delta to version 1 starts here */
+	u32 lv_snapshot_org;
+	u32 lv_snapshot_prev;
+	u32 lv_snapshot_next;
+	u32 lv_block_exception;
+	uint32_t lv_remap_ptr;
+	uint32_t lv_remap_end;
+	uint32_t lv_chunk_size;
+	uint32_t lv_snapshot_minor;
+	char dummy[200];
+} lv32_t;
+
+typedef struct {
+	u32 hash[2];
+	u32 rsector_org;
+	kdev_t rdev_org;
+	u32 rsector_new;
+	kdev_t rdev_new;
+} lv_block_exception32_t;
+
+static void put_lv_t(lv_t *l)
+{
+	if (l->lv_current_pe) vfree(l->lv_current_pe);
+	if (l->lv_block_exception) vfree(l->lv_block_exception);
+	kfree(l);
+}
+
+static lv_t *get_lv_t(u32 p, int *errp)
+{
+	int err, i;
+	u32 ptr1, ptr2;
+	size_t size;
+	lv_block_exception32_t *lbe32;
+	lv_block_exception_t *lbe;
+	lv32_t *ul = (lv32_t *)A(p);
+	lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL);
+
+	if (!l) {
+		*errp = -ENOMEM;
+		return NULL;
+	}
+	memset(l, 0, sizeof(lv_t));
+	err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe);
+	err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le,
+				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
+	err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr,
+				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
+	err |= __get_user(ptr1, &ul->lv_current_pe);
+	err |= __get_user(ptr2, &ul->lv_block_exception);
+	if (err) {
+		kfree(l);
+		*errp = -EFAULT;
+		return NULL;
+	}
+	if (ptr1) {
+		size = l->lv_allocated_le * sizeof(pe_t);
+		l->lv_current_pe = vmalloc(size);
+		if (l->lv_current_pe)
+			err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size);
+	}
+	if (!err && ptr2) {
+		size = l->lv_remap_end * sizeof(lv_block_exception_t);
+		l->lv_block_exception = lbe = vmalloc(size);
+		if (l->lv_block_exception) {
+			lbe32 = (lv_block_exception32_t *)A(ptr2);
+			memset(lbe, 0, size);
+			for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) {
+				err |= get_user(lbe->rsector_org, &lbe32->rsector_org);
+				err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);
+				err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);
+				err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);
+			}
+		}
+	}
+	if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) {
+		if (!err)
+			*errp = -ENOMEM;
+		else
+			*errp = -EFAULT;
+		put_lv_t(l);
+		return NULL;
+	}
+	return l;
+}
+
+static int copy_lv_t(u32 ptr, lv_t *l)
+{
+	int err;
+	lv32_t *ul = (lv32_t *)A(ptr);
+	u32 ptr1;
+	size_t size;
+
+	err = get_user(ptr1, &ul->lv_current_pe);
+	if (err)
+		return -EFAULT;
+	err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe);
+	err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le,
+				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));
+	err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr,
+				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));
+	size = l->lv_allocated_le * sizeof(pe_t);
+	if (ptr1)
+		err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);
+	return err ? -EFAULT : 0;
+}
+
+static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	vg_t *v = NULL;
+	union {
+		lv_req_t lv_req;
+		le_remap_req_t le_remap;
+		lv_status_byindex_req_t lv_byindex;
+	        lv_status_bydev_req_t lv_bydev;
+		pv_status_req_t pv_status;
+	} u;
+	pv_t p;
+	int err;
+	u32 ptr = 0;
+	int i;
+	mm_segment_t old_fs;
+	void *karg = &u;
+
+	switch (cmd) {
+	case VG_STATUS:
+		v = kmalloc(sizeof(vg_t), GFP_KERNEL);
+		if (!v)
+			return -ENOMEM;
+		karg = v;
+		break;
+
+	case VG_CREATE_OLD:
+	case VG_CREATE:
+		v = kmalloc(sizeof(vg_t), GFP_KERNEL);
+		if (!v)
+			return -ENOMEM;
+		if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) {
+			kfree(v);
+			return -EFAULT;
+		}
+		/* 'proc' field is unused, just NULL it out. */
+		v->proc = NULL;
+		if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {
+			kfree(v);
+			return -EFAULT;
+		}
+		    
+		karg = v;
+		memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv));
+		if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV)
+			return -EPERM;
+		for (i = 0; i < v->pv_max; i++) {
+			err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);
+			if (err)
+				break;
+			if (ptr) {
+				v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);
+				if (!v->pv[i]) {
+					err = -ENOMEM;
+					break;
+				}
+				err = copy_from_user(v->pv[i], (void *)A(ptr),
+						     sizeof(pv32_t) - 8 - UUID_LEN+1);
+				if (err) {
+					err = -EFAULT;
+					break;
+				}
+				err = copy_from_user(v->pv[i]->pv_uuid,
+						     ((pv32_t *)A(ptr))->pv_uuid,
+						     UUID_LEN+1);
+				if (err) {
+				        err = -EFAULT;
+					break;
+				}
+
+				v->pv[i]->pe = NULL;
+				v->pv[i]->bd = NULL;
+			}
+		}
+		if (!err) {
+			for (i = 0; i < v->lv_max; i++) {
+				err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);
+				if (err)
+					break;
+				if (ptr) {
+					v->lv[i] = get_lv_t(ptr, &err);
+					if (err)
+						break;
+				}
+			}
+		}
+		break;
+
+	case LV_CREATE:
+	case LV_EXTEND:
+	case LV_REDUCE:
+	case LV_REMOVE:
+	case LV_RENAME:
+	case LV_STATUS_BYNAME:
+	        err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));
+		if (err)
+			return -EFAULT;
+		if (cmd != LV_REMOVE) {
+			err = __get_user(ptr, &((lv_req32_t *)arg)->lv);
+			if (err)
+				return err;
+			u.lv_req.lv = get_lv_t(ptr, &err);
+		} else
+			u.lv_req.lv = NULL;
+		break;
+
+	case LV_STATUS_BYINDEX:
+		err = get_user(u.lv_byindex.lv_index,
+			       &((lv_status_byindex_req32_t *)arg)->lv_index);
+		err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);
+		if (err)
+			return err;
+		u.lv_byindex.lv = get_lv_t(ptr, &err);
+		break;
+
+	case LV_STATUS_BYDEV:
+	        err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);
+		err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv);
+		if (err)
+			return err;
+		u.lv_bydev.lv = get_lv_t(ptr, &err);
+		break;
+
+	case VG_EXTEND:
+		err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
+		if (err)
+			return -EFAULT;
+		err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
+		if (err)
+			return -EFAULT;
+		p.pe = NULL;
+		p.bd = NULL;
+		karg = &p;
+		break;
+
+	case PV_CHANGE:
+	case PV_STATUS:
+		err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));
+		if (err)
+			return -EFAULT;
+		err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);
+		if (err)
+			return err;
+		u.pv_status.pv = &p;
+		if (cmd == PV_CHANGE) {
+			err = copy_from_user(&p, (void *)A(ptr),
+					     sizeof(pv32_t) - 8 - UUID_LEN+1);
+			if (err)
+				return -EFAULT;
+			p.pe = NULL;
+			p.bd = NULL;
+		}
+		break;
+	};
+
+        old_fs = get_fs(); set_fs (KERNEL_DS);
+        err = sys_ioctl (fd, cmd, (unsigned long)karg);
+        set_fs (old_fs);
+
+	switch (cmd) {
+	case VG_STATUS:
+		if (!err) {
+			if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) ||
+			    clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc))
+				err = -EFAULT;
+		}
+		if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) {
+		        err = -EFAULT;
+		}
+		kfree(v);
+		break;
+
+	case VG_CREATE_OLD:
+	case VG_CREATE:
+		for (i = 0; i < v->pv_max; i++) {
+			if (v->pv[i])
+				kfree(v->pv[i]);
+		}
+		for (i = 0; i < v->lv_max; i++) {
+			if (v->lv[i])
+				put_lv_t(v->lv[i]);
+		}
+		kfree(v);
+		break;
+
+	case LV_STATUS_BYNAME:
+		if (!err && u.lv_req.lv)
+			err = copy_lv_t(ptr, u.lv_req.lv);
+		/* Fall through */
+
+        case LV_CREATE:
+	case LV_EXTEND:
+	case LV_REDUCE:
+		if (u.lv_req.lv)
+			put_lv_t(u.lv_req.lv);
+		break;
+
+	case LV_STATUS_BYINDEX:
+		if (u.lv_byindex.lv) {
+			if (!err)
+				err = copy_lv_t(ptr, u.lv_byindex.lv);
+			put_lv_t(u.lv_byindex.lv);
+		}
+		break;
+
+	case LV_STATUS_BYDEV:
+	        if (u.lv_bydev.lv) {
+			if (!err)
+				err = copy_lv_t(ptr, u.lv_bydev.lv);
+			put_lv_t(u.lv_byindex.lv);
+	        }
+	        break;
+
+	case PV_STATUS:
+		if (!err) {
+			err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);
+			if (err)
+				return -EFAULT;
+			err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);
+			if (err)
+				return -EFAULT;
+		}
+		break;
+	};
+
+	return err;
+}
+#endif /* CONFIG_BLK_DEV_LVM */
+
 struct ioctl32_handler {
 	unsigned int cmd;
 	int (*function)(unsigned int, unsigned int, unsigned long);
@@ -1059,6 +1785,7 @@
 	IOCTL32_DEFAULT(FBIOPAN_DISPLAY),
 #endif /* CONFIG_FB */
 
+#ifdef CONFIG_VT
 	/* Big K */
 	IOCTL32_DEFAULT(PIO_FONT),
 	IOCTL32_DEFAULT(GIO_FONT),
@@ -1091,14 +1818,13 @@
 	IOCTL32_DEFAULT(PIO_UNISCRNMAP),
 	IOCTL32_DEFAULT(PIO_FONTRESET),
 	IOCTL32_DEFAULT(PIO_UNIMAPCLR),
-
-#ifdef CONFIG_VT
 	IOCTL32_HANDLER(PIO_FONTX, do_fontx_ioctl),
 	IOCTL32_HANDLER(KDFONTOP, do_kdfontop_ioctl),
-#endif /* CONFIG_VT */
 
 	/* Big S */
 	IOCTL32_DEFAULT(SCSI_IOCTL_GET_IDLUN),
+	IOCTL32_DEFAULT(SCSI_IOCTL_PROBE_HOST),
+	IOCTL32_DEFAULT(SCSI_IOCTL_GET_PCI),
 	IOCTL32_DEFAULT(SCSI_IOCTL_DOORLOCK),
 	IOCTL32_DEFAULT(SCSI_IOCTL_DOORUNLOCK),
 	IOCTL32_DEFAULT(SCSI_IOCTL_TEST_UNIT_READY),
@@ -1107,6 +1833,13 @@
 	IOCTL32_DEFAULT(SCSI_IOCTL_GET_BUS_NUMBER),
 	IOCTL32_DEFAULT(SCSI_IOCTL_SEND_COMMAND),
 
+	/* Big T */
+	IOCTL32_DEFAULT(TUNSETNOCSUM),
+	IOCTL32_DEFAULT(TUNSETDEBUG),
+	IOCTL32_DEFAULT(TUNSETIFF),
+	IOCTL32_DEFAULT(TUNSETPERSIST),
+	IOCTL32_DEFAULT(TUNSETOWNER),
+
 	/* Big V */
 	IOCTL32_DEFAULT(VT_SETMODE),
 	IOCTL32_DEFAULT(VT_GETMODE),
@@ -1120,6 +1853,39 @@
 	IOCTL32_DEFAULT(VT_RESIZEX),
 	IOCTL32_DEFAULT(VT_LOCKSWITCH),
 	IOCTL32_DEFAULT(VT_UNLOCKSWITCH),
+#endif /* CONFIG_VT */
+
+	/* Little v, the video4linux ioctls */
+	IOCTL32_DEFAULT(VIDIOCGCAP),
+	IOCTL32_DEFAULT(VIDIOCGCHAN),
+	IOCTL32_DEFAULT(VIDIOCSCHAN),
+	IOCTL32_DEFAULT(VIDIOCGPICT),
+	IOCTL32_DEFAULT(VIDIOCSPICT),
+	IOCTL32_DEFAULT(VIDIOCCAPTURE),
+
+	IOCTL32_DEFAULT(VIDIOCGWIN),
+	IOCTL32_DEFAULT(VIDIOCSWIN),
+	IOCTL32_DEFAULT(VIDIOCGFBUF),
+	IOCTL32_DEFAULT(VIDIOCSFBUF),
+
+	IOCTL32_DEFAULT(VIDIOCKEY),
+	IOCTL32_DEFAULT(VIDIOCGAUDIO),
+	IOCTL32_DEFAULT(VIDIOCSAUDIO),
+	IOCTL32_DEFAULT(VIDIOCSYNC),
+	IOCTL32_DEFAULT(VIDIOCMCAPTURE),
+	IOCTL32_DEFAULT(VIDIOCGMBUF),
+	IOCTL32_DEFAULT(VIDIOCGUNIT),
+	IOCTL32_DEFAULT(VIDIOCGCAPTURE),
+	IOCTL32_DEFAULT(VIDIOCSCAPTURE),
+	/* BTTV specific... */
+	IOCTL32_DEFAULT(_IOW('v',  BASE_VIDIOCPRIVATE+0, char [256])),
+	IOCTL32_DEFAULT(_IOR('v',  BASE_VIDIOCPRIVATE+1, char [256])),
+	IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)),
+	IOCTL32_DEFAULT(_IOW('v' , BASE_VIDIOCPRIVATE+3, char [16])), /* struct bttv_pll_info */
+	IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+4, int)),
+	IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+5, int)),
+	IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+6, int)),
+	IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)),
 
 #ifdef CONFIG_NET
 	/* Socket level stuff */
@@ -1230,6 +1996,158 @@
 	IOCTL32_DEFAULT(LOOP_CLR_FD),
 	IOCTL32_HANDLER(LOOP_SET_STATUS, loop_status),
 	IOCTL32_HANDLER(LOOP_GET_STATUS, loop_status),
+	/* Big Q for sound/OSS */
+	IOCTL32_DEFAULT(SNDCTL_SEQ_RESET),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_SYNC),
+	IOCTL32_DEFAULT(SNDCTL_SYNTH_INFO),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_CTRLRATE),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_GETOUTCOUNT),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_GETINCOUNT),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_PERCMODE),
+	IOCTL32_DEFAULT(SNDCTL_FM_LOAD_INSTR),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_TESTMIDI),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_RESETSAMPLES),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_NRSYNTHS),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_NRMIDIS),
+	IOCTL32_DEFAULT(SNDCTL_MIDI_INFO),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_THRESHOLD),
+	IOCTL32_DEFAULT(SNDCTL_SYNTH_MEMAVL),
+	IOCTL32_DEFAULT(SNDCTL_FM_4OP_ENABLE),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_PANIC),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_OUTOFBAND),
+	IOCTL32_DEFAULT(SNDCTL_SEQ_GETTIME),
+	IOCTL32_DEFAULT(SNDCTL_SYNTH_ID),
+	IOCTL32_DEFAULT(SNDCTL_SYNTH_CONTROL),
+	IOCTL32_DEFAULT(SNDCTL_SYNTH_REMOVESAMPLE),
+	/* Big T for sound/OSS */
+	IOCTL32_DEFAULT(SNDCTL_TMR_TIMEBASE),
+	IOCTL32_DEFAULT(SNDCTL_TMR_START),
+	IOCTL32_DEFAULT(SNDCTL_TMR_STOP),
+	IOCTL32_DEFAULT(SNDCTL_TMR_CONTINUE),
+	IOCTL32_DEFAULT(SNDCTL_TMR_TEMPO),
+	IOCTL32_DEFAULT(SNDCTL_TMR_SOURCE),
+	IOCTL32_DEFAULT(SNDCTL_TMR_METRONOME),
+	IOCTL32_DEFAULT(SNDCTL_TMR_SELECT),
+	/* Little m for sound/OSS */
+	IOCTL32_DEFAULT(SNDCTL_MIDI_PRETIME),
+	IOCTL32_DEFAULT(SNDCTL_MIDI_MPUMODE),
+	IOCTL32_DEFAULT(SNDCTL_MIDI_MPUCMD),
+	/* Big P for sound/OSS */
+	IOCTL32_DEFAULT(SNDCTL_DSP_RESET),
+	IOCTL32_DEFAULT(SNDCTL_DSP_SYNC),
+	IOCTL32_DEFAULT(SNDCTL_DSP_SPEED),
+	IOCTL32_DEFAULT(SNDCTL_DSP_STEREO),
+	IOCTL32_DEFAULT(SNDCTL_DSP_GETBLKSIZE),
+	IOCTL32_DEFAULT(SNDCTL_DSP_CHANNELS),
+	IOCTL32_DEFAULT(SOUND_PCM_WRITE_FILTER),
+	IOCTL32_DEFAULT(SNDCTL_DSP_POST),
+	IOCTL32_DEFAULT(SNDCTL_DSP_SUBDIVIDE),
+	IOCTL32_DEFAULT(SNDCTL_DSP_SETFRAGMENT),
+	IOCTL32_DEFAULT(SNDCTL_DSP_GETFMTS),
+	IOCTL32_DEFAULT(SNDCTL_DSP_SETFMT),
+	IOCTL32_DEFAULT(SNDCTL_DSP_GETOSPACE),
+	IOCTL32_DEFAULT(SNDCTL_DSP_GETISPACE),
+	IOCTL32_DEFAULT(SNDCTL_DSP_NONBLOCK),
+	IOCTL32_DEFAULT(SNDCTL_DSP_GETCAPS),
+	IOCTL32_DEFAULT(SNDCTL_DSP_GETTRIGGER),
+	IOCTL32_DEFAULT(SNDCTL_DSP_SETTRIGGER),
+	IOCTL32_DEFAULT(SNDCTL_DSP_GETIPTR),
+	IOCTL32_DEFAULT(SNDCTL_DSP_GETOPTR),
+	/* SNDCTL_DSP_MAPINBUF,  XXX needs translation */
+	/* SNDCTL_DSP_MAPOUTBUF,  XXX needs translation */
+	IOCTL32_DEFAULT(SNDCTL_DSP_SETSYNCRO),
+	IOCTL32_DEFAULT(SNDCTL_DSP_SETDUPLEX),
+	IOCTL32_DEFAULT(SNDCTL_DSP_GETODELAY),
+	IOCTL32_DEFAULT(SNDCTL_DSP_PROFILE),
+	IOCTL32_DEFAULT(SOUND_PCM_READ_RATE),
+	IOCTL32_DEFAULT(SOUND_PCM_READ_CHANNELS),
+	IOCTL32_DEFAULT(SOUND_PCM_READ_BITS),
+	IOCTL32_DEFAULT(SOUND_PCM_READ_FILTER),
+	/* Big C for sound/OSS */
+	IOCTL32_DEFAULT(SNDCTL_COPR_RESET),
+	IOCTL32_DEFAULT(SNDCTL_COPR_LOAD),
+	IOCTL32_DEFAULT(SNDCTL_COPR_RDATA),
+	IOCTL32_DEFAULT(SNDCTL_COPR_RCODE),
+	IOCTL32_DEFAULT(SNDCTL_COPR_WDATA),
+	IOCTL32_DEFAULT(SNDCTL_COPR_WCODE),
+	IOCTL32_DEFAULT(SNDCTL_COPR_RUN),
+	IOCTL32_DEFAULT(SNDCTL_COPR_HALT),
+	IOCTL32_DEFAULT(SNDCTL_COPR_SENDMSG),
+	IOCTL32_DEFAULT(SNDCTL_COPR_RCVMSG),
+	/* Big M for sound/OSS */
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_VOLUME),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_BASS),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_TREBLE),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_SYNTH),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_PCM),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_SPEAKER),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_MIC),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_CD),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_IMIX),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_ALTPCM),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_RECLEV),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_IGAIN),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_OGAIN),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE1),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE2),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_LINE3),
+	IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_DIGITAL1)),
+	IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_DIGITAL2)),
+	IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_DIGITAL3)),
+	IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_PHONEIN)),
+	IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_PHONEOUT)),
+	IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_VIDEO)),
+	IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_RADIO)),
+	IOCTL32_DEFAULT(MIXER_READ(SOUND_MIXER_MONITOR)),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_MUTE),
+	/* SOUND_MIXER_READ_ENHANCE,  same value as READ_MUTE */
+	/* SOUND_MIXER_READ_LOUD,  same value as READ_MUTE */
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_RECSRC),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_DEVMASK),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_RECMASK),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_STEREODEVS),
+	IOCTL32_DEFAULT(SOUND_MIXER_READ_CAPS),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_VOLUME),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_BASS),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_TREBLE),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_SYNTH),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_PCM),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_SPEAKER),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_MIC),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_CD),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_IMIX),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_ALTPCM),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_RECLEV),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_IGAIN),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_OGAIN),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE1),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE2),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_LINE3),
+	IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_DIGITAL1)),
+	IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_DIGITAL2)),
+	IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_DIGITAL3)),
+	IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_PHONEIN)),
+	IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_PHONEOUT)),
+	IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_VIDEO)),
+	IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_RADIO)),
+	IOCTL32_DEFAULT(MIXER_WRITE(SOUND_MIXER_MONITOR)),
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_MUTE),
+	/* SOUND_MIXER_WRITE_ENHANCE,  same value as WRITE_MUTE */
+	/* SOUND_MIXER_WRITE_LOUD,  same value as WRITE_MUTE */
+	IOCTL32_DEFAULT(SOUND_MIXER_WRITE_RECSRC),
+	IOCTL32_DEFAULT(SOUND_MIXER_INFO),
+	IOCTL32_DEFAULT(SOUND_OLD_MIXER_INFO),
+	IOCTL32_DEFAULT(SOUND_MIXER_ACCESS),
+	IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE1),
+	IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE2),
+	IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE3),
+	IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE4),
+	IOCTL32_DEFAULT(SOUND_MIXER_PRIVATE5),
+	IOCTL32_DEFAULT(SOUND_MIXER_GETLEVELS),
+	IOCTL32_DEFAULT(SOUND_MIXER_SETLEVELS),
+	IOCTL32_DEFAULT(OSS_GETVERSION),
 
 	/* And these ioctls need translation */
 	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
@@ -1275,11 +2193,53 @@
 
 #endif /* CONFIG_NET */
 
+	IOCTL32_HANDLER(BLKRAGET, w_long),
+	IOCTL32_HANDLER(BLKGETSIZE, w_long),
+	// IOCTL32_HANDLER(0x1260, broken_blkgetsize),
+	IOCTL32_HANDLER(BLKFRAGET, w_long),
+	IOCTL32_HANDLER(BLKSECTGET, w_long),
+	IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans),
+
 	IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl),
 	IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl),
 	IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
 	IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
 
+	IOCTL32_HANDLER(VIDIOCGTUNER32, do_video_ioctl),
+	IOCTL32_HANDLER(VIDIOCSTUNER32, do_video_ioctl),
+	IOCTL32_HANDLER(VIDIOCGWIN32, do_video_ioctl),
+	IOCTL32_HANDLER(VIDIOCSWIN32, do_video_ioctl),
+	IOCTL32_HANDLER(VIDIOCGFBUF32, do_video_ioctl),
+	IOCTL32_HANDLER(VIDIOCSFBUF32, do_video_ioctl),
+	IOCTL32_HANDLER(VIDIOCGFREQ32, do_video_ioctl),
+	IOCTL32_HANDLER(VIDIOCSFREQ32, do_video_ioctl),
+
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+	IOCTL32_HANDLER(VG_STATUS, do_lvm_ioctl),
+	IOCTL32_HANDLER(VG_CREATE_OLD, do_lvm_ioctl),
+	IOCTL32_HANDLER(VG_CREATE, do_lvm_ioctl),
+	IOCTL32_HANDLER(VG_EXTEND, do_lvm_ioctl),
+	IOCTL32_HANDLER(LV_CREATE, do_lvm_ioctl),
+	IOCTL32_HANDLER(LV_REMOVE, do_lvm_ioctl),
+	IOCTL32_HANDLER(LV_EXTEND, do_lvm_ioctl),
+	IOCTL32_HANDLER(LV_REDUCE, do_lvm_ioctl),
+	IOCTL32_HANDLER(LV_RENAME, do_lvm_ioctl),
+	IOCTL32_HANDLER(LV_STATUS_BYNAME, do_lvm_ioctl),
+	IOCTL32_HANDLER(LV_STATUS_BYINDEX, do_lvm_ioctl),
+	IOCTL32_HANDLER(LV_STATUS_BYDEV, do_lvm_ioctl),
+	IOCTL32_HANDLER(PV_CHANGE, do_lvm_ioctl),
+	IOCTL32_HANDLER(PV_STATUS, do_lvm_ioctl),
+#endif /* LVM */
+
+	/* take care of sizeof(sizeof()) breakage */
+	/* elevator */
+	IOCTL32_HANDLER(BLKELVGET_32, do_blkelvget),
+	IOCTL32_HANDLER(BLKELVSET_32, do_blkelvset),
+	/* block stuff */
+	IOCTL32_HANDLER(BLKBSZGET_32, do_blkbszget),
+	IOCTL32_HANDLER(BLKBSZSET_32, do_blkbszset),
+	IOCTL32_HANDLER(BLKGETSIZE64_32, do_blkgetsize64),
+
 	IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo),	/* hdreg.h ioctls  */
 	IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
 	IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
@@ -1308,21 +2268,33 @@
 	IOCTL32_DEFAULT(BLKROSET),			/* fs.h ioctls  */
 	IOCTL32_DEFAULT(BLKROGET),
 	IOCTL32_DEFAULT(BLKRRPART),
-	IOCTL32_HANDLER(BLKGETSIZE, w_long),
-
 	IOCTL32_DEFAULT(BLKFLSBUF),
 	IOCTL32_DEFAULT(BLKRASET),
-	IOCTL32_HANDLER(BLKRAGET, w_long),
 	IOCTL32_DEFAULT(BLKFRASET),
-	IOCTL32_HANDLER(BLKFRAGET, w_long),
 	IOCTL32_DEFAULT(BLKSECTSET),
-	IOCTL32_HANDLER(BLKSECTGET, w_long),
 	IOCTL32_DEFAULT(BLKSSZGET),
-	IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans),
-	IOCTL32_DEFAULT(BLKELVGET),
-	IOCTL32_DEFAULT(BLKELVSET),
-	IOCTL32_DEFAULT(BLKBSZGET),
-	IOCTL32_DEFAULT(BLKBSZSET),
+
+	/* RAID */
+	IOCTL32_DEFAULT(RAID_VERSION),
+	IOCTL32_DEFAULT(GET_ARRAY_INFO),
+	IOCTL32_DEFAULT(GET_DISK_INFO),
+	IOCTL32_DEFAULT(PRINT_RAID_DEBUG),
+	IOCTL32_DEFAULT(CLEAR_ARRAY),
+	IOCTL32_DEFAULT(ADD_NEW_DISK),
+	IOCTL32_DEFAULT(HOT_REMOVE_DISK),
+	IOCTL32_DEFAULT(SET_ARRAY_INFO),
+	IOCTL32_DEFAULT(SET_DISK_INFO),
+	IOCTL32_DEFAULT(WRITE_RAID_INFO),
+	IOCTL32_DEFAULT(UNPROTECT_ARRAY),
+	IOCTL32_DEFAULT(PROTECT_ARRAY),
+	IOCTL32_DEFAULT(HOT_ADD_DISK),
+	IOCTL32_DEFAULT(SET_DISK_FAULTY),
+	IOCTL32_DEFAULT(RUN_ARRAY),
+	IOCTL32_DEFAULT(START_ARRAY),
+	IOCTL32_DEFAULT(STOP_ARRAY),
+	IOCTL32_DEFAULT(STOP_ARRAY_RO),
+	IOCTL32_DEFAULT(RESTART_ARRAY_RW),
+	IOCTL32_DEFAULT(RAID_AUTORUN),
 
 #ifdef CONFIG_MD
 	/* status */
@@ -1378,6 +2350,39 @@
 	IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE),
 	IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE_MULTI),
 
+	/* DEVFS */
+	IOCTL32_DEFAULT(DEVFSDIOC_GET_PROTO_REV),
+	IOCTL32_DEFAULT(DEVFSDIOC_SET_EVENT_MASK),
+	IOCTL32_DEFAULT(DEVFSDIOC_RELEASE_EVENT_QUEUE),
+	IOCTL32_DEFAULT(DEVFSDIOC_SET_DEBUG_MASK),
+
+	/* Raw devices */
+	IOCTL32_DEFAULT(RAW_SETBIND),
+	IOCTL32_DEFAULT(RAW_GETBIND),
+
+#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
+	/* 0xfe - lvm */
+	IOCTL32_DEFAULT(VG_SET_EXTENDABLE),
+	IOCTL32_DEFAULT(VG_STATUS_GET_COUNT),
+	IOCTL32_DEFAULT(VG_STATUS_GET_NAMELIST),
+	IOCTL32_DEFAULT(VG_REMOVE),
+	IOCTL32_DEFAULT(VG_RENAME),
+	IOCTL32_DEFAULT(VG_REDUCE),
+	IOCTL32_DEFAULT(PE_LOCK_UNLOCK),
+	IOCTL32_DEFAULT(PV_FLUSH),
+	IOCTL32_DEFAULT(LVM_LOCK_LVM),
+	IOCTL32_DEFAULT(LVM_GET_IOP_VERSION),
+#ifdef LVM_TOTAL_RESET
+	IOCTL32_DEFAULT(LVM_RESET),
+#endif
+	IOCTL32_DEFAULT(LV_SET_ACCESS),
+	IOCTL32_DEFAULT(LV_SET_STATUS),
+	IOCTL32_DEFAULT(LV_SET_ALLOCATION),
+	IOCTL32_DEFAULT(LE_REMAP),
+	IOCTL32_DEFAULT(LV_BMAP),
+	IOCTL32_DEFAULT(LV_SNAPSHOT_USE_RATE),
+#endif /* LVM */
+
 	/* Little p (/dev/rtc, /dev/envctrl, etc.) */
 	IOCTL32_DEFAULT(_IOR('p', 20, int[7])), /* RTCGET */
 	IOCTL32_DEFAULT(_IOW('p', 21, int[7])), /* RTCSET */
@@ -1395,6 +2400,7 @@
 	IOCTL32_DEFAULT(RTC_SET_TIME),
 	IOCTL32_DEFAULT(RTC_WKALM_SET),
 	IOCTL32_DEFAULT(RTC_WKALM_RD),
+
 #ifdef CONFIG_MTD_CHAR
 	/* Big M */
 	IOCTL32_DEFAULT(MEMGETINFO),
diff -urN linux-2.4.24-pre1/arch/mips64/kernel/mips64_ksyms.c linux-2.4.24-pre2/arch/mips64/kernel/mips64_ksyms.c
--- linux-2.4.24-pre1/arch/mips64/kernel/mips64_ksyms.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips64/kernel/mips64_ksyms.c	2003-12-22 11:34:33.000000000 -0800
@@ -62,7 +62,7 @@
 EXPORT_SYMBOL_NOVERS(strtok);
 EXPORT_SYMBOL_NOVERS(strpbrk);
 
-EXPORT_SYMBOL(_clear_page);
+EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(kernel_thread);
 
 /*
diff -urN linux-2.4.24-pre1/arch/mips64/kernel/setup.c linux-2.4.24-pre2/arch/mips64/kernel/setup.c
--- linux-2.4.24-pre1/arch/mips64/kernel/setup.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/kernel/setup.c	2003-12-22 11:34:33.000000000 -0800
@@ -428,6 +428,9 @@
 #ifdef CONFIG_DECSTATION
 	decstation_setup();
 #endif
+#ifdef  CONFIG_PMC_YOSEMITE
+	pmc_yosemite_setup();
+#endif
 #ifdef CONFIG_SGI_IP22
 	ip22_setup();
 #endif
diff -urN linux-2.4.24-pre1/arch/mips64/kernel/smp.c linux-2.4.24-pre2/arch/mips64/kernel/smp.c
--- linux-2.4.24-pre1/arch/mips64/kernel/smp.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips64/kernel/smp.c	2003-12-22 11:34:33.000000000 -0800
@@ -93,34 +93,6 @@
 #endif
 }
 
-#ifndef CONFIG_SGI_IP27
-/*
- * Hook for doing final board-specific setup after the generic smp setup
- * is done
- */
-asmlinkage void start_secondary(void)
-{
-	unsigned int cpu = smp_processor_id();
-
-	cpu_probe();
-	prom_init_secondary();
-	per_cpu_trap_init();
-
-	/*
-	 * XXX parity protection should be folded in here when it's converted
-	 * to an option instead of something based on .cputype
-	 */
-	pgd_current[cpu] = init_mm.pgd;
-	cpu_data[cpu].udelay_val = loops_per_jiffy;
-	prom_smp_finish();
-	printk("Slave cpu booted successfully\n");
-	CPUMASK_SETB(cpu_online_map, cpu);
-	atomic_inc(&cpus_booted);
-	while (!atomic_read(&smp_commenced));
-	cpu_idle();
-}
-#endif /* CONFIG_SGI_IP27 */
-
 void __init smp_commence(void)
 {
 	wmb();
diff -urN linux-2.4.24-pre1/arch/mips64/kernel/traps.c linux-2.4.24-pre2/arch/mips64/kernel/traps.c
--- linux-2.4.24-pre1/arch/mips64/kernel/traps.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/kernel/traps.c	2003-12-22 11:34:33.000000000 -0800
@@ -232,6 +232,7 @@
 	printk("epc     : %016lx    %s\nbadvaddr: %016lx\n",
 	       regs->cp0_epc, print_tainted(), regs->cp0_badvaddr);
 	printk("Status  : %08x  [ ", (unsigned int) regs->cp0_status);
+
 	if (regs->cp0_status & ST0_KX) printk("KX ");
 	if (regs->cp0_status & ST0_SX) printk("SX ");
 	if (regs->cp0_status & ST0_UX) printk("UX ");
@@ -247,6 +248,7 @@
 	printk("]\n");
 
 	printk("Cause   : %08x\n", (unsigned int) regs->cp0_cause);
+	printk("PrId  : %08x\n", read_c0_prid());
 }
 
 void show_registers(struct pt_regs *regs)
diff -urN linux-2.4.24-pre1/arch/mips64/mm/c-r4k.c linux-2.4.24-pre2/arch/mips64/mm/c-r4k.c
--- linux-2.4.24-pre1/arch/mips64/mm/c-r4k.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/mm/c-r4k.c	2003-12-22 11:34:33.000000000 -0800
@@ -28,27 +28,6 @@
 
 static unsigned long icache_size, dcache_size, scache_size;
 
-extern void andes_clear_page(void * page);
-extern void r4k_clear_page32_d16(void * page);
-extern void r4k_clear_page32_d32(void * page);
-extern void r4k_clear_page_d16(void * page);
-extern void r4k_clear_page_d32(void * page);
-extern void r4k_clear_page_r4600_v1(void * page);
-extern void r4k_clear_page_r4600_v2(void * page);
-extern void r4k_clear_page_s16(void * page);
-extern void r4k_clear_page_s32(void * page);
-extern void r4k_clear_page_s64(void * page);
-extern void r4k_clear_page_s128(void * page);
-extern void andes_copy_page(void * to, void * from);
-extern void r4k_copy_page_d16(void * to, void * from);
-extern void r4k_copy_page_d32(void * to, void * from);
-extern void r4k_copy_page_r4600_v1(void * to, void * from);
-extern void r4k_copy_page_r4600_v2(void * to, void * from);
-extern void r4k_copy_page_s16(void * to, void * from);
-extern void r4k_copy_page_s32(void * to, void * from);
-extern void r4k_copy_page_s64(void * to, void * from);
-extern void r4k_copy_page_s128(void * to, void * from);
-
 /*
  * Dummy cache handling routines for machines without boardcaches
  */
@@ -775,6 +754,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 2;
 		c->dcache.waybit= ffs(dcache_size/2) - 1;
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_R5432:
@@ -788,6 +769,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 2;
 		c->dcache.waybit = 0;
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_TX49XX:
@@ -800,6 +783,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 4;
 		c->dcache.waybit = 0;
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_R4000PC:
@@ -818,6 +803,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 1;
 		c->dcache.waybit = 0;	/* does not matter */
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_R10000:
@@ -831,6 +818,8 @@
 		c->dcache.linesz = 32;
 		c->dcache.ways = 2;
 		c->dcache.waybit = 0;
+
+		c->options |= MIPS_CPU_PREFETCH;
 		break;
 
 	case CPU_VR4133:
@@ -845,6 +834,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 2;
 		c->dcache.waybit = ffs(dcache_size/2) - 1;
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_VR41XX:
@@ -862,6 +853,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 1;
 		c->dcache.waybit = 0;	/* does not matter */
+
+		c->options |= MIPS_CPU_CACHE_CDEX;
 		break;
 
 	case CPU_RM7000:
@@ -877,6 +870,8 @@
 		c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
 		c->dcache.ways = 4;
 		c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1;
+
+		c->options |= MIPS_CPU_CACHE_CDEX | MIPS_CPU_PREFETCH;
 		break;
 
 	default:
@@ -920,6 +915,8 @@
 		              c->dcache.ways *
 		              c->dcache.linesz;
 		c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1;
+
+		c->options |= MIPS_CPU_PREFETCH;
 		break;
 	}
 
@@ -1040,71 +1037,6 @@
 	return 1;
 }
 
-static void __init setup_noscache_funcs(void)
-{
-	unsigned int prid;
-
-	switch (current_cpu_data.dcache.linesz) {
-	case 16:
-		if (cpu_has_64bits)
-			_clear_page = r4k_clear_page_d16;
-		else
-			_clear_page = r4k_clear_page32_d16;
-		_copy_page = r4k_copy_page_d16;
-
-		break;
-	case 32:
-		prid = read_c0_prid() & 0xfff0;
-		if (prid == 0x2010) {			/* R4600 V1.7 */
-			_clear_page = r4k_clear_page_r4600_v1;
-			_copy_page = r4k_copy_page_r4600_v1;
-		} else if (prid == 0x2020) {		/* R4600 V2.0 */
-			_clear_page = r4k_clear_page_r4600_v2;
-			_copy_page = r4k_copy_page_r4600_v2;
-		} else {
-			if (cpu_has_64bits)
-				_clear_page = r4k_clear_page_d32;
-			else
-				_clear_page = r4k_clear_page32_d32;
-			_copy_page = r4k_copy_page_d32;
-		}
-		break;
-	}
-}
-
-static void __init setup_scache_funcs(void)
-{
-	struct cpuinfo_mips *c = &current_cpu_data;
-
-	if (c->dcache.linesz > c->scache.linesz)
-		panic("Invalid primary cache configuration detected");
-
-	if (c->cputype == CPU_R10000 || c->cputype == CPU_R12000) {
-		_clear_page = andes_clear_page;
-		_copy_page = andes_copy_page;
-		return;
-	}
-
-	switch (c->scache.linesz) {
-	case 16:
-		_clear_page = r4k_clear_page_s16;
-		_copy_page = r4k_copy_page_s16;
-		break;
-	case 32:
-		_clear_page = r4k_clear_page_s32;
-		_copy_page = r4k_copy_page_s32;
-		break;
-	case 64:
-		_clear_page = r4k_clear_page_s64;
-		_copy_page = r4k_copy_page_s64;
-		break;
-	case 128:
-		_clear_page = r4k_clear_page_s128;
-		_copy_page = r4k_copy_page_s128;
-		break;
-	}
-}
-
 typedef int (*probe_func_t)(unsigned long);
 extern int r5k_sc_init(void);
 extern int rm7k_sc_init(void);
@@ -1143,7 +1075,6 @@
 
 	case CPU_R5000:
 	case CPU_NEVADA:
-		setup_noscache_funcs();
 #ifdef CONFIG_R5000_CPU_SCACHE
 		r5k_sc_init();
 #endif
@@ -1151,7 +1082,6 @@
 
 	case CPU_RM7000:
 	case CPU_RM9000:
-		setup_noscache_funcs();
 #ifdef CONFIG_RM7000_CPU_SCACHE
 		rm7k_sc_init();
 #endif
@@ -1161,10 +1091,8 @@
 		sc_present = 0;
 	}
 
-	if (!sc_present) {
-		setup_noscache_funcs();
+	if (!sc_present)
 		return;
-	}
 
 	if ((c->isa_level == MIPS_CPU_ISA_M32 ||
 	     c->isa_level == MIPS_CPU_ISA_M64) &&
@@ -1180,7 +1108,6 @@
 	       scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
 
 	c->options |= MIPS_CPU_SUBSET_CACHES;
-        setup_scache_funcs();
 }
 
 static inline void coherency_setup(void)
@@ -1209,6 +1136,8 @@
 
 void __init ld_mmu_r4xx0(void)
 {
+	extern void build_clear_page(void);
+	extern void build_copy_page(void);
 	extern char except_vec2_generic;
 	struct cpuinfo_mips *c = &current_cpu_data;
 
@@ -1251,4 +1180,7 @@
 #endif
 
 	__flush_cache_all();
+
+	build_clear_page();
+	build_copy_page();
 }
diff -urN linux-2.4.24-pre1/arch/mips64/mm/c-sb1.c linux-2.4.24-pre2/arch/mips64/mm/c-sb1.c
--- linux-2.4.24-pre1/arch/mips64/mm/c-sb1.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/mm/c-sb1.c	2003-12-22 11:34:33.000000000 -0800
@@ -25,14 +25,7 @@
 #include <asm/cpu.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
 extern void sb1_dma_init(void);
-extern void sb1_clear_page_dma(void * page);
-extern void sb1_copy_page_dma(void * to, void * from);
-#else
-extern void sb1_clear_page(void * page);
-extern void sb1_copy_page(void * to, void * from);
-#endif
 
 /* These are probed at ld_mmu time */
 static unsigned long icache_size;
@@ -565,12 +558,7 @@
 	probe_cache_sizes();
 
 #ifdef CONFIG_SIBYTE_DMA_PAGEOPS
-	_clear_page = sb1_clear_page_dma;
-	_copy_page = sb1_copy_page_dma;
 	sb1_dma_init();
-#else
-	_clear_page = sb1_clear_page;
-	_copy_page = sb1_copy_page;
 #endif
 
 	/*
diff -urN linux-2.4.24-pre1/arch/mips64/mm/loadmmu.c linux-2.4.24-pre2/arch/mips64/mm/loadmmu.c
--- linux-2.4.24-pre1/arch/mips64/mm/loadmmu.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/arch/mips64/mm/loadmmu.c	2003-12-22 11:34:33.000000000 -0800
@@ -22,10 +22,6 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
-/* memory functions */
-void (*_clear_page)(void * page);
-void (*_copy_page)(void * to, void * from);
-
 /* Cache operations. */
 void (*_flush_cache_all)(void);
 void (*___flush_cache_all)(void);
diff -urN linux-2.4.24-pre1/arch/mips64/mm/pg-r4k.c linux-2.4.24-pre2/arch/mips64/mm/pg-r4k.c
--- linux-2.4.24-pre1/arch/mips64/mm/pg-r4k.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips64/mm/pg-r4k.c	2003-12-22 11:34:33.000000000 -0800
@@ -3,706 +3,468 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- * Copyright (C) 1997, 98, 99, 2000, 01, 02, 03 Ralf Baechle (ralf@gnu.org)
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
- * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com)
+ * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org)
  */
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 
 #include <asm/cacheops.h>
+#include <asm/inst.h>
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <asm/prefetch.h>
 #include <asm/system.h>
 #include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
 #include <asm/mmu_context.h>
 #include <asm/cpu.h>
+#include <asm/war.h>
 
 /*
- * Zero an entire page.  Basically a simple unrolled loop should do the
- * job but we want more performance by saving memory bus bandwidth.  We
- * have five flavours of the routine available for:
+ * Maximum sizes:
  *
- * - 16byte cachelines and no second level cache
- * - 32byte cachelines second level cache
- * - a version which handles the buggy R4600 v1.x
- * - a version which handles the buggy R4600 v2.0
- * - Finally a last version without fancy cache games for the SC and MC
- *   versions of R4000 and R4400.
+ * R4000 16 bytes D-cache, 128 bytes S-cache:		0x78 bytes
+ * R4600 v1.7:						0x5c bytes
+ * R4600 v2.0:						0x60 bytes
+ * With prefetching, 16 byte strides			0xa0 bytes
  */
 
-void r4k_clear_page_d16(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"cache\t%3,16(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"cache\t%3,-16(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
-		: "memory");
-}
-
-void r4k_clear_page_d32(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
-		: "memory");
-}
+static unsigned int clear_page_array[0xa0 / 4];
 
+void clear_page(void * page) __attribute__((alias("clear_page_array")));
 
 /*
- * This flavour of r4k_clear_page is for the R4600 V1.x.  Cite from the
- * IDT R4600 V1.7 errata:
- *
- *  18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
- *      Hit_Invalidate_D and Create_Dirty_Excl_D should only be
- *      executed if there is no other dcache activity. If the dcache is
- *      accessed for another instruction immeidately preceding when these
- *      cache instructions are executing, it is possible that the dcache
- *      tag match outputs used by these cache instructions will be
- *      incorrect. These cache instructions should be preceded by at least
- *      four instructions that are not any kind of load or store
- *      instruction.
+ * Maximum sizes:
  *
- *      This is not allowed:    lw
- *                              nop
- *                              nop
- *                              nop
- *                              cache       Hit_Writeback_Invalidate_D
- *
- *      This is allowed:        lw
- *                              nop
- *                              nop
- *                              nop
- *                              nop
- *                              cache       Hit_Writeback_Invalidate_D
- */
-void r4k_clear_page_r4600_v1(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tnop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"cache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
-		: "memory");
-}
-
-/*
- * And this one is for the R4600 V2.0
- */
-void r4k_clear_page_r4600_v2(void * page)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	*(volatile unsigned int *)KSEG1;
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D)
-		: "memory");
-	local_irq_restore(flags);
-}
-
-/*
- * The next 4 versions are optimized for all possible scache configurations
- * of the SC / MC versions of R4000 and R4400 ...
- *
- * Todo: For even better performance we should have a routine optimized for
- * every legal combination of dcache / scache linesize.  When I (Ralf) tried
- * this the kernel crashed shortly after mounting the root filesystem.  CPU
- * bug?  Weirdo cache instruction semantics?
- */
-void r4k_clear_page_s16(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"cache\t%3,16(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"cache\t%3,-16(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
-		: "memory");
-}
-
-void r4k_clear_page_s32(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"cache\t%3,-32(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
-		: "memory");
-}
-
-void r4k_clear_page_s64(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
-		: "memory");
-}
-
-void r4k_clear_page_s128(void * page)
-{
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tcache\t%3,(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"sd\t$0,32(%0)\n\t"
-		"sd\t$0,40(%0)\n\t"
-		"sd\t$0,48(%0)\n\t"
-		"sd\t$0,56(%0)\n\t"
-		"daddiu\t%0,128\n\t"
-		"sd\t$0,-64(%0)\n\t"
-		"sd\t$0,-56(%0)\n\t"
-		"sd\t$0,-48(%0)\n\t"
-		"sd\t$0,-40(%0)\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD)
-		: "memory");
-}
-
-/*
- * This version has been tuned on an Origin.  For other machines the arguments
- * of the pref instructin may have to be tuned differently.
+ * R4000 16 bytes D-cache, 128 bytes S-cache:		0xbc bytes
+ * R4600 v1.7:						0x80 bytes
+ * R4600 v2.0:						0x84 bytes
+ * With prefetching, 16 byte strides			0xb8 bytes
  */
-void andes_clear_page(void * page)
-{
-	__asm__ __volatile__(
-		".set\tpush\n\t"
-		".set\tmips4\n\t"
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%2\n"
-		"1:\tpref 7,512(%0)\n\t"
-		"sd\t$0,(%0)\n\t"
-		"sd\t$0,8(%0)\n\t"
-		"sd\t$0,16(%0)\n\t"
-		"sd\t$0,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"sd\t$0,-32(%0)\n\t"
-		"sd\t$0,-24(%0)\n\t"
-		"sd\t$0,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		"sd\t$0,-8(%0)\n\t"
-		".set\tpop"
-		: "=r" (page)
-		: "0" (page), "I" (PAGE_SIZE)
-		: "memory");
-}
+static unsigned int copy_page_array[0xb8 / 4];
 
+void copy_page(void *to, void *from) __attribute__((alias("copy_page_array")));
 
 /*
- * This is still inefficient.  We only can do better if we know the
- * virtual address where the copy will be accessed.
+ * An address fits into a single register so it's safe to use 64-bit registers
+ * if we have 64-bit adresses.
  */
-
-void r4k_copy_page_d16(void * to, void * from)
-{
-	unsigned long dummy1, dummy2, reg1, reg2;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%6\n"
-		"1:\tcache\t%7,(%0)\n\t"
-		"ld\t%2,(%1)\n\t"
-		"ld\t%3,8(%1)\n\t"
-		"sd\t%2,(%0)\n\t"
-		"sd\t%3,8(%0)\n\t"
-		"cache\t%7,16(%0)\n\t"
-		"ld\t%2,16(%1)\n\t"
-		"ld\t%3,24(%1)\n\t"
-		"sd\t%2,16(%0)\n\t"
-		"sd\t%3,24(%0)\n\t"
-		"cache\t%7,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"ld\t%2,-32(%1)\n\t"
-		"ld\t%3,-24(%1)\n\t"
-		"sd\t%2,-32(%0)\n\t"
-		"sd\t%3,-24(%0)\n\t"
-		"cache\t%7,-16(%0)\n\t"
-		"ld\t%2,-16(%1)\n\t"
-		"ld\t%3,-8(%1)\n\t"
-		"sd\t%2,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		" sd\t%3,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
-		:"0" (to), "1" (from), "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-}
-
-void r4k_copy_page_d32(void * to, void * from)
-{
-	unsigned long dummy1, dummy2, reg1, reg2;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%6\n"
-		"1:\tcache\t%7,(%0)\n\t"
-		"ld\t%2,(%1)\n\t"
-		"ld\t%3,8(%1)\n\t"
-		"sd\t%2,(%0)\n\t"
-		"sd\t%3,8(%0)\n\t"
-		"ld\t%2,16(%1)\n\t"
-		"ld\t%3,24(%1)\n\t"
-		"sd\t%2,16(%0)\n\t"
-		"sd\t%3,24(%0)\n\t"
-		"cache\t%7,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"ld\t%2,-32(%1)\n\t"
-		"ld\t%3,-24(%1)\n\t"
-		"sd\t%2,-32(%0)\n\t"
-		"sd\t%3,-24(%0)\n\t"
-		"ld\t%2,-16(%1)\n\t"
-		"ld\t%3,-8(%1)\n\t"
-		"sd\t%2,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		" sd\t%3,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
-		:"0" (to), "1" (from), "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-}
+#define cpu_has_64bit_registers	cpu_has_64bit_addresses
 
 /*
- * Again a special version for the R4600 V1.x
+ * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
+ * with 64-bit kernels.  The prefetch offsets have been experimentally tuned
+ * an Origin 200.
  */
-void r4k_copy_page_r4600_v1(void * to, void * from)
-{
-	unsigned long dummy1, dummy2, reg1, reg2;
+static int pref_offset_clear __initdata = 512;
+static int pref_offset_copy  __initdata = 256;
 
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%6\n"
-		"1:\tnop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"\tcache\t%7,(%0)\n\t"
-		"ld\t%2,(%1)\n\t"
-		"ld\t%3,8(%1)\n\t"
-		"sd\t%2,(%0)\n\t"
-		"sd\t%3,8(%0)\n\t"
-		"ld\t%2,16(%1)\n\t"
-		"ld\t%3,24(%1)\n\t"
-		"sd\t%2,16(%0)\n\t"
-		"sd\t%3,24(%0)\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"cache\t%7,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"ld\t%2,-32(%1)\n\t"
-		"ld\t%3,-24(%1)\n\t"
-		"sd\t%2,-32(%0)\n\t"
-		"sd\t%3,-24(%0)\n\t"
-		"ld\t%2,-16(%1)\n\t"
-		"ld\t%3,-8(%1)\n\t"
-		"sd\t%2,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		" sd\t%3,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
-		:"0" (to), "1" (from), "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-}
-
-void r4k_copy_page_r4600_v2(void * to, void * from)
-{
-	unsigned long dummy1, dummy2, reg1, reg2;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%6\n"
-		"1:\tnop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"\tcache\t%7,(%0)\n\t"
-		"ld\t%2,(%1)\n\t"
-		"ld\t%3,8(%1)\n\t"
-		"sd\t%2,(%0)\n\t"
-		"sd\t%3,8(%0)\n\t"
-		"ld\t%2,16(%1)\n\t"
-		"ld\t%3,24(%1)\n\t"
-		"sd\t%2,16(%0)\n\t"
-		"sd\t%3,24(%0)\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"nop\n\t"
-		"cache\t%7,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"ld\t%2,-32(%1)\n\t"
-		"ld\t%3,-24(%1)\n\t"
-		"sd\t%2,-32(%0)\n\t"
-		"sd\t%3,-24(%0)\n\t"
-		"ld\t%2,-16(%1)\n\t"
-		"ld\t%3,-8(%1)\n\t"
-		"sd\t%2,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		" sd\t%3,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
-		:"0" (to), "1" (from), "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_D));
-	local_irq_restore(flags);
-}
+static unsigned int pref_src_mode __initdata;
+static unsigned int pref_dst_mode __initdata;
 
-/*
- * These are for R4000SC / R4400MC
- */
-void r4k_copy_page_s16(void * to, void * from)
-{
-	unsigned long dummy1, dummy2, reg1, reg2;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%6\n"
-		"1:\tcache\t%7,(%0)\n\t"
-		"ld\t%2,(%1)\n\t"
-		"ld\t%3,8(%1)\n\t"
-		"sd\t%2,(%0)\n\t"
-		"sd\t%3,8(%0)\n\t"
-		"cache\t%7,16(%0)\n\t"
-		"ld\t%2,16(%1)\n\t"
-		"ld\t%3,24(%1)\n\t"
-		"sd\t%2,16(%0)\n\t"
-		"sd\t%3,24(%0)\n\t"
-		"cache\t%7,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"ld\t%2,-32(%1)\n\t"
-		"ld\t%3,-24(%1)\n\t"
-		"sd\t%2,-32(%0)\n\t"
-		"sd\t%3,-24(%0)\n\t"
-		"cache\t%7,-16(%0)\n\t"
-		"ld\t%2,-16(%1)\n\t"
-		"ld\t%3,-8(%1)\n\t"
-		"sd\t%2,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		" sd\t%3,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
-		:"0" (to), "1" (from), "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD));
-}
-
-void r4k_copy_page_s32(void * to, void * from)
-{
-	unsigned long dummy1, dummy2, reg1, reg2;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%6\n"
-		"1:\tcache\t%7,(%0)\n\t"
-		"ld\t%2,(%1)\n\t"
-		"ld\t%3,8(%1)\n\t"
-		"sd\t%2,(%0)\n\t"
-		"sd\t%3,8(%0)\n\t"
-		"ld\t%2,16(%1)\n\t"
-		"ld\t%3,24(%1)\n\t"
-		"sd\t%2,16(%0)\n\t"
-		"sd\t%3,24(%0)\n\t"
-		"cache\t%7,32(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"ld\t%2,-32(%1)\n\t"
-		"ld\t%3,-24(%1)\n\t"
-		"sd\t%2,-32(%0)\n\t"
-		"sd\t%3,-24(%0)\n\t"
-		"ld\t%2,-16(%1)\n\t"
-		"ld\t%3,-8(%1)\n\t"
-		"sd\t%2,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		" sd\t%3,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
-		:"0" (to), "1" (from), "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD));
-}
-
-void r4k_copy_page_s64(void * to, void * from)
-{
-	unsigned long dummy1, dummy2, reg1, reg2;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%6\n"
-		"1:\tcache\t%7,(%0)\n\t"
-		"ld\t%2,(%1)\n\t"
-		"ld\t%3,8(%1)\n\t"
-		"sd\t%2,(%0)\n\t"
-		"sd\t%3,8(%0)\n\t"
-		"ld\t%2,16(%1)\n\t"
-		"ld\t%3,24(%1)\n\t"
-		"sd\t%2,16(%0)\n\t"
-		"sd\t%3,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"ld\t%2,-32(%1)\n\t"
-		"ld\t%3,-24(%1)\n\t"
-		"sd\t%2,-32(%0)\n\t"
-		"sd\t%3,-24(%0)\n\t"
-		"ld\t%2,-16(%1)\n\t"
-		"ld\t%3,-8(%1)\n\t"
-		"sd\t%2,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		" sd\t%3,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2)
-		:"0" (to), "1" (from), "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD));
-}
-
-void r4k_copy_page_s128(void * to, void * from)
-{
-	unsigned long dummy1, dummy2;
-	unsigned long reg1, reg2, reg3, reg4;
-
-	__asm__ __volatile__(
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tcache\t%9,(%0)\n\t"
-		"ld\t%2,(%1)\n\t"
-		"ld\t%3,8(%1)\n\t"
-		"ld\t%4,16(%1)\n\t"
-		"ld\t%5,24(%1)\n\t"
-		"sd\t%2,(%0)\n\t"
-		"sd\t%3,8(%0)\n\t"
-		"sd\t%4,16(%0)\n\t"
-		"sd\t%5,24(%0)\n\t"
-		"ld\t%2,32(%1)\n\t"
-		"ld\t%3,40(%1)\n\t"
-		"ld\t%4,48(%1)\n\t"
-		"ld\t%5,56(%1)\n\t"
-		"sd\t%2,32(%0)\n\t"
-		"sd\t%3,40(%0)\n\t"
-		"sd\t%4,48(%0)\n\t"
-		"sd\t%5,56(%0)\n\t"
-		"daddiu\t%0,128\n\t"
-		"daddiu\t%1,128\n\t"
-		"ld\t%2,-64(%1)\n\t"
-		"ld\t%3,-56(%1)\n\t"
-		"ld\t%4,-48(%1)\n\t"
-		"ld\t%5,-40(%1)\n\t"
-		"sd\t%2,-64(%0)\n\t"
-		"sd\t%3,-56(%0)\n\t"
-		"sd\t%4,-48(%0)\n\t"
-		"sd\t%5,-40(%0)\n\t"
-		"ld\t%2,-32(%1)\n\t"
-		"ld\t%3,-24(%1)\n\t"
-		"ld\t%4,-16(%1)\n\t"
-		"ld\t%5,-8(%1)\n\t"
-		"sd\t%2,-32(%0)\n\t"
-		"sd\t%3,-24(%0)\n\t"
-		"sd\t%4,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		" sd\t%5,-8(%0)\n\t"
-		".set\tat\n\t"
-		".set\treorder"
-		:"=r" (dummy1), "=r" (dummy2),
-		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from),
-		 "I" (PAGE_SIZE),
-		 "i" (Create_Dirty_Excl_SD));
-}
-
-/*
- * This version has been tuned on an Origin.  For other machines the arguments
- * of the pref instructin may have to be tuned differently.
- */
-void andes_copy_page(void * to, void * from)
-{
-	unsigned long dummy1, dummy2, reg1, reg2, reg3, reg4;
+static int has_scache __initdata = 0;
+static int load_offset __initdata = 0;
+static int store_offset __initdata = 0;
+
+static unsigned int __initdata *dest, *epc;
+
+static inline void build_src_pref(int advance)
+{
+	if (!(load_offset & (cpu_dcache_line_size() - 1))) {
+		union mips_instruction mi;
+
+		mi.i_format.opcode     = pref_op;
+		mi.i_format.rs         = 5;		/* $a1 */
+		mi.i_format.rt         = pref_src_mode;
+		mi.i_format.simmediate = load_offset + advance;
+
+		*epc++ = mi.word;
+	}
+}
+
+static inline void __build_load_reg(int reg)
+{
+	union mips_instruction mi;
+
+	if (cpu_has_64bit_registers)
+		mi.i_format.opcode     = ld_op;
+	else
+		mi.i_format.opcode     = lw_op;
+	mi.i_format.rs         = 5;		/* $a1 */
+	mi.i_format.rt         = reg;		/* $zero */
+	mi.i_format.simmediate = load_offset;
+
+	load_offset += (cpu_has_64bit_registers ? 8 : 4);
+
+	*epc++ = mi.word;
+}
+
+static inline void build_load_reg(int reg)
+{
+	if (cpu_has_prefetch)
+		build_src_pref(pref_offset_copy);
+
+	__build_load_reg(reg);
+}
+
+static inline void build_dst_pref(int advance)
+{
+	if (!(store_offset & (cpu_dcache_line_size() - 1))) {
+		union mips_instruction mi;
+
+		mi.i_format.opcode     = pref_op;
+		mi.i_format.rs         = 4;		/* $a0 */
+		mi.i_format.rt         = pref_dst_mode;
+		mi.i_format.simmediate = store_offset + advance;
+
+		*epc++ = mi.word;
+	}
+}
+
+static inline void build_cdex(void)
+{
+	union mips_instruction mi;
+
+	if (has_scache && !(store_offset & (cpu_scache_line_size() - 1))) {
+
+		mi.c_format.opcode     = cache_op;
+		mi.c_format.rs         = 4;	/* $a0 */
+		mi.c_format.c_op       = 3;	/* Create Dirty Exclusive */
+		mi.c_format.cache      = 3;	/* Secondary Data Cache */
+		mi.c_format.simmediate = store_offset;
+
+		*epc++ = mi.word;
+	}
+
+	if (store_offset & (cpu_dcache_line_size() - 1))
+		return;
+
+	if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) {
+		*epc++ = 0;			/* nop */
+		*epc++ = 0;			/* nop */
+		*epc++ = 0;			/* nop */
+		*epc++ = 0;			/* nop */
+	}
+
+	mi.c_format.opcode     = cache_op;
+	mi.c_format.rs         = 4;		/* $a0 */
+	mi.c_format.c_op       = 3;		/* Create Dirty Exclusive */
+	mi.c_format.cache      = 1;		/* Data Cache */
+	mi.c_format.simmediate = store_offset;
+
+	*epc++ = mi.word;
+}
+
+static inline void __build_store_zero_reg(void)
+{
+	union mips_instruction mi;
+
+	if (cpu_has_64bits)
+		mi.i_format.opcode     = sd_op;
+	else
+		mi.i_format.opcode     = sw_op;
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = 0;		/* $zero */
+	mi.i_format.simmediate = store_offset;
+
+	store_offset += (cpu_has_64bits ? 8 : 4);
+
+	*epc++ = mi.word;
+}
+
+static inline void __build_store_reg(int reg)
+{
+	union mips_instruction mi;
+	int reg_size;
+
+#ifdef CONFIG_MIPS32
+	if (cpu_has_64bit_registers && reg == 0) {
+		mi.i_format.opcode     = sd_op;
+		reg_size               = 8;
+	} else {
+		mi.i_format.opcode     = sw_op;
+		reg_size               = 4;
+	}
+#endif
+#ifdef CONFIG_MIPS64
+	mi.i_format.opcode     = sd_op;
+	reg_size               = 8;
+#endif
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = reg;		/* $zero */
+	mi.i_format.simmediate = store_offset;
+
+	store_offset += reg_size;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_store_reg(int reg)
+{
+	if (cpu_has_prefetch)
+		if (reg)
+			build_dst_pref(pref_offset_copy);
+		else
+			build_dst_pref(pref_offset_clear);
+	else if (cpu_has_cache_cdex)
+		build_cdex();
+
+	__build_store_reg(reg);
+}
+
+static inline void build_addiu_at_a0(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = 1;		/* $at */
+	mi.i_format.simmediate = offset;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_addiu_a1(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 5;		/* $a1 */
+	mi.i_format.rt         = 5;		/* $a1 */
+	mi.i_format.simmediate = offset;
+
+	load_offset -= offset;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_addiu_a0(unsigned long offset)
+{
+	union mips_instruction mi;
+
+	BUG_ON(offset > 0x7fff);
+
+	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
+	mi.i_format.rs         = 4;		/* $a0 */
+	mi.i_format.rt         = 4;		/* $a0 */
+	mi.i_format.simmediate = offset;
+
+	store_offset -= offset;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_bne(unsigned int *dest)
+{
+	union mips_instruction mi;
+
+	mi.i_format.opcode = bne_op;
+	mi.i_format.rs     = 1;			/* $at */
+	mi.i_format.rt     = 4;			/* $a0 */
+	mi.i_format.simmediate = dest - epc - 1;
+
+	*epc++ = mi.word;
+}
+
+static inline void build_nop(void)
+{
+	*epc++ = 0;
+}
+
+static inline void build_jr_ra(void)
+{
+	union mips_instruction mi;
+
+	mi.r_format.opcode = spec_op;
+	mi.r_format.rs     = 31;
+	mi.r_format.rt     = 0;
+	mi.r_format.rd     = 0;
+	mi.r_format.re     = 0;
+	mi.r_format.func   = jr_op;
+
+	*epc++ = mi.word;
+}
+
+void __init build_clear_page(void)
+{
+	epc = (unsigned int *) &clear_page_array;
+
+	if (cpu_has_prefetch) {
+		switch (current_cpu_data.cputype) {
+		case CPU_R10000:
+		case CPU_R12000:
+			pref_src_mode = Pref_LoadStreamed;
+			pref_dst_mode = Pref_StoreRetained;
+			break;
+		default:
+			pref_src_mode = Pref_LoadStreamed;
+			pref_dst_mode = Pref_PrepareForStore;
+			break;
+		}
+	}
+
+	build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) {
+		*epc++ = 0x40026000;		/* mfc0    $v0, $12	*/
+		*epc++ = 0x34410001;		/* ori     $at, v0, 0x1	*/
+		*epc++ = 0x38210001;		/* xori    $at, at, 0x1	*/
+		*epc++ = 0x40816000;		/* mtc0    $at, $12	*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x3c01a000;		/* lui     $at, 0xa000  */
+		*epc++ = 0x8c200000;		/* lw      $zero, ($at) */
+	}
+
+dest = epc;
+	build_store_reg(0);
+	build_store_reg(0);
+	build_store_reg(0);
+	build_store_reg(0);
+	if (has_scache && cpu_scache_line_size() == 128) {
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+	}
+	build_addiu_a0(2 * store_offset);
+	build_store_reg(0);
+	build_store_reg(0);
+	if (has_scache && cpu_scache_line_size() == 128) {
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+		build_store_reg(0);
+	}
+	build_store_reg(0);
+	build_bne(dest);
+	 build_store_reg(0);
+
+	if (cpu_has_prefetch && pref_offset_clear) {
+		build_addiu_at_a0(pref_offset_clear);
+	dest = epc;
+		__build_store_reg(0);
+		__build_store_reg(0);
+		__build_store_reg(0);
+		__build_store_reg(0);
+		build_addiu_a0(2 * store_offset);
+		__build_store_reg(0);
+		__build_store_reg(0);
+		__build_store_reg(0);
+		build_bne(dest);
+		 __build_store_reg(0);
+	}
+
+	build_jr_ra();
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		*epc++ = 0x40826000;		/* mtc0    $v0, $12	*/
+	else
+		build_nop();
+
+	flush_icache_range((unsigned long)&clear_page_array,
+	                   (unsigned long) epc);
+
+	BUG_ON(epc > clear_page_array + ARRAY_SIZE(clear_page_array));
+}
+
+void __init build_copy_page(void)
+{
+	epc = (unsigned int *) &copy_page_array;
+
+	build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) {
+		*epc++ = 0x40026000;		/* mfc0    $v0, $12	*/
+		*epc++ = 0x34410001;		/* ori     $at, v0, 0x1	*/
+		*epc++ = 0x38210001;		/* xori    $at, at, 0x1	*/
+		*epc++ = 0x40816000;		/* mtc0    $at, $12	*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x00000000;		/* nop			*/
+		*epc++ = 0x3c01a000;		/* lui     $at, 0xa000  */
+		*epc++ = 0x8c200000;		/* lw      $zero, ($at) */
+	}
+
+dest = epc;
+	build_load_reg( 8);
+	build_load_reg( 9);
+	build_load_reg(10);
+	build_load_reg(11);
+	build_store_reg( 8);
+	build_store_reg( 9);
+	build_store_reg(10);
+	build_store_reg(11);
+	if (has_scache && cpu_scache_line_size() == 128) {
+		build_load_reg( 8);
+		build_load_reg( 9);
+		build_load_reg(10);
+		build_load_reg(11);
+		build_store_reg( 8);
+		build_store_reg( 9);
+		build_store_reg(10);
+		build_store_reg(11);
+	}
+	build_addiu_a0(2 * store_offset);
+	build_addiu_a1(2 * load_offset);
+	build_load_reg( 8);
+	build_load_reg( 9);
+	build_load_reg(10);
+	build_load_reg(11);
+	build_store_reg( 8);
+	build_store_reg( 9);
+	build_store_reg(10);
+	if (has_scache && cpu_scache_line_size() == 128) {
+		build_store_reg(11);
+		build_load_reg( 8);
+		build_load_reg( 9);
+		build_load_reg(10);
+		build_load_reg(11);
+		build_store_reg( 8);
+		build_store_reg( 9);
+		build_store_reg(10);
+	}
+	build_bne(dest);
+	 build_store_reg(11);
+
+	if (cpu_has_prefetch && pref_offset_copy) {
+		build_addiu_at_a0(pref_offset_copy);
+	dest = epc;
+		__build_load_reg( 8);
+		__build_load_reg( 9);
+		__build_load_reg(10);
+		__build_load_reg(11);
+		__build_store_reg( 8);
+		__build_store_reg( 9);
+		__build_store_reg(10);
+		__build_store_reg(11);
+		build_addiu_a0(2 * store_offset);
+		build_addiu_a1(2 * load_offset);
+		__build_load_reg( 8);
+		__build_load_reg( 9);
+		__build_load_reg(10);
+		__build_load_reg(11);
+		__build_store_reg( 8);
+		__build_store_reg( 9);
+		__build_store_reg(10);
+		build_bne(dest);
+		 __build_store_reg(11);
+	}
+
+	build_jr_ra();
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		*epc++ = 0x40826000;		/* mtc0    $v0, $12	*/
+	else
+		build_nop();
 
-	__asm__ __volatile__(
-		".set\tpush\n\t"
-		".set\tmips4\n\t"
-		".set\tnoreorder\n\t"
-		".set\tnoat\n\t"
-		"daddiu\t$1,%0,%8\n"
-		"1:\tpref\t0,2*128(%1)\n\t"
-		"pref\t1,2*128(%0)\n\t"
-		"ld\t%2,(%1)\n\t"
-		"ld\t%3,8(%1)\n\t"
-		"ld\t%4,16(%1)\n\t"
-		"ld\t%5,24(%1)\n\t"
-		"sd\t%2,(%0)\n\t"
-		"sd\t%3,8(%0)\n\t"
-		"sd\t%4,16(%0)\n\t"
-		"sd\t%5,24(%0)\n\t"
-		"daddiu\t%0,64\n\t"
-		"daddiu\t%1,64\n\t"
-		"ld\t%2,-32(%1)\n\t"
-		"ld\t%3,-24(%1)\n\t"
-		"ld\t%4,-16(%1)\n\t"
-		"ld\t%5,-8(%1)\n\t"
-		"sd\t%2,-32(%0)\n\t"
-		"sd\t%3,-24(%0)\n\t"
-		"sd\t%4,-16(%0)\n\t"
-		"bne\t$1,%0,1b\n\t"
-		" sd\t%5,-8(%0)\n\t"
-		".set\tpop\n\t"
-		:"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2),
-		 "=&r" (reg3), "=&r" (reg4)
-		:"0" (to), "1" (from), "I" (PAGE_SIZE));
+	BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
 }
diff -urN linux-2.4.24-pre1/arch/mips64/mm/pg-sb1.c linux-2.4.24-pre2/arch/mips64/mm/pg-sb1.c
--- linux-2.4.24-pre1/arch/mips64/mm/pg-sb1.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/mips64/mm/pg-sb1.c	2003-12-22 11:34:33.000000000 -0800
@@ -2,6 +2,7 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 2000 SiByte, Inc.
+ * Copyright (C) 2002, 2003 Broadcom Corporation
  *
  * Written by Justin Carlson of SiByte, Inc.
  *         and Kip Walker of Broadcom Corp.
@@ -40,8 +41,11 @@
 #define SB1_PREF_STORE_STREAMED_HINT "5"
 #endif
 
-/* These are the functions hooked by the memory management function pointers */
-void sb1_clear_page(void *page)
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+static inline void clear_page_cpu(void *page)
+#else
+void clear_page(void *page)
+#endif
 {
 	/*
 	 * JDCXXX - This should be bottlenecked by the write buffer, but these
@@ -80,7 +84,11 @@
 
 }
 
-void sb1_copy_page(void *to, void *from)
+#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+static inline void copy_page_cpu(void *to, void *from)
+#else
+void copy_page(void *to, void *from)
+#endif
 {
 	/*
 	 * This should be optimized in assembly...can't use ld/sd, though,
@@ -168,13 +176,13 @@
 	      IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE));
 }
 
-void sb1_clear_page_dma(void *page)
+void clear_page(void *page)
 {
 	int cpu = smp_processor_id();
 
 	/* if the page is above Kseg0, use old way */
 	if (KSEGX(page) != K0BASE)
-		return sb1_clear_page(page);
+		return clear_page_cpu(page);
 
 	page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
 	page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
@@ -189,7 +197,7 @@
 	in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE));
 }
 
-void sb1_copy_page_dma(void *to, void *from)
+void copy_page(void *to, void *from)
 {
 	unsigned long from_phys = PHYSADDR(from);
 	unsigned long to_phys = PHYSADDR(to);
@@ -197,7 +205,7 @@
 
 	/* if either page is above Kseg0, use old way */
 	if ((KSEGX(to) != K0BASE) || (KSEGX(from) != K0BASE))
-		return sb1_copy_page(to, from);
+		return copy_page_cpu(to, from);
 
 	page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
 	page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
@@ -212,4 +220,4 @@
 	in64(IO_SPACE_BASE + A_DM_REGISTER(cpu, R_DM_DSCR_BASE));
 }
 
-#endif
+#endif /* CONFIG_SIBYTE_DMA_PAGEOPS */
diff -urN linux-2.4.24-pre1/arch/ppc64/Makefile linux-2.4.24-pre2/arch/ppc64/Makefile
--- linux-2.4.24-pre1/arch/ppc64/Makefile	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/Makefile	2003-12-22 11:34:34.000000000 -0800
@@ -19,11 +19,11 @@
 CHECKS		= checks
 endif
 
-HAS_BIARCH      := $(shell if gcc -m64 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi;)
+HAS_BIARCH      := $(shell if $(CC) -m64 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi;)
 ifeq ($(HAS_BIARCH),y)
 AS              := $(AS) -64
 LD              := $(LD) -m elf64ppc
-CC		:= gcc -m64
+CC		:= $(CC) -m64
 endif
 
 LINKFLAGS	= -T arch/ppc64/vmlinux.lds -Bstatic \
@@ -33,6 +33,11 @@
 		-mtraceback=full
 CPP		= $(CC) -E $(CFLAGS)
 
+HAVE_ZERO_BSS := $(shell if $(CC) -fno-zero-initialized-in-bss -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
+
+ifeq ($(HAVE_ZERO_BSS),y)
+CFLAGS		+= -fno-zero-initialized-in-bss
+endif
 
 HEAD := arch/ppc64/kernel/head.o
 
diff -urN linux-2.4.24-pre1/arch/ppc64/boot/Makefile linux-2.4.24-pre2/arch/ppc64/boot/Makefile
--- linux-2.4.24-pre1/arch/ppc64/boot/Makefile	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/boot/Makefile	2003-12-22 11:34:34.000000000 -0800
@@ -31,6 +31,10 @@
 
 OBJCOPYFLAGS = contents,alloc,load,readonly,data
 
+LDVARS=	\
+	--defsym _vmlinux_memsize=0x`$(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | sed '$$s/^........\([^ ]*\).*/\1/p;d'` \
+	--defsym _vmlinux_filesize=0x`ls -l $(TOPDIR)/vmlinux | awk '{ printf "%x\n", $$5 }'`
+
 .c.o:
 	$(BOOTCC) $(BOOTCFLAGS) -c -o $*.o $<
 .S.o:
@@ -39,7 +43,7 @@
 CFLAGS	= $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS
 LD_ARGS = -Ttext 0x00400000 -e _start
 
-OBJS = crt0.o string.o prom.o zImage.o zlib.o imagesize.o
+OBJS = crt0.o string.o prom.o zImage.o zlib.o
 LIBS =
 
 ifeq ($(CONFIG_SMP),y)
@@ -88,12 +92,13 @@
 	$(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c
 
 
-imagesize.c: $(TOPDIR)/vmlinux
-	ls -l $(TOPDIR)/vmlinux | awk '{printf "/* generated -- do not edit! */\nunsigned long vmlinux_filesize = %d;\n", $$5}' > imagesize.c
-	$(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | awk '{i=$$1}END{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr(i,8)}' >> imagesize.c
-
 zImage.o: $(TOPDIR)/vmlinux
 
+uts_string: uts_string.txt
+	$(OBJCOPY) zImage.o \
+		--add-section=.kernel:$@=$@.txt \
+		--set-section-flags=.kernel:$@=$(OBJCOPYFLAGS)
+
 vmlinux .config System.map: % : $(TOPDIR)/% zImage.o
 	gzip -cvf9 $(TOPDIR)/$@ > kernel-$@.gz
 	$(OBJCOPY) zImage.o \
@@ -105,17 +110,23 @@
 		--add-section=.kernel:$@=ramdisk.image.gz \
 		--set-section-flags=.kernel:$@=$(OBJCOPYFLAGS)
 
-zImage: $(OBJS) addnote vmlinux .config System.map
-	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS)
+uts_string.txt: $(TOPDIR)/vmlinux
+	strings $(TOPDIR)/vmlinux | \
+	grep -E 'Linux version .* .gcc version' > $@
+
+zImage: $(OBJS) addnote uts_string vmlinux .config System.map
+	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) \
+        $(LDVARS)
 	./addnote $@
 
-zImage.initrd: $(OBJS) addnote vmlinux .config System.map initrd
-	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS)
+zImage.initrd: $(OBJS) addnote uts_string vmlinux .config System.map initrd
+	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS) \
+        $(LDVARS)
 	./addnote $@
 
 clean:
 	rm -f add{note,RamDisk,SystemMap} $(OBJS) initrd.o \
-		vmlinux.{sm,initrd} zImage{,.initrd} imagesize.c \
+		vmlinux.{sm,initrd} zImage{,.initrd} uts_string.txt \
 		kernel-{vmlinux,.config,System.map}.gz
 
 fastdep:
diff -urN linux-2.4.24-pre1/arch/ppc64/boot/zImage.c linux-2.4.24-pre2/arch/ppc64/boot/zImage.c
--- linux-2.4.24-pre1/arch/ppc64/boot/zImage.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/boot/zImage.c	2003-12-22 11:34:34.000000000 -0800
@@ -12,7 +12,6 @@
 #include "ppc32-types.h"
 #include "zlib.h"
 #include <linux/elf.h>
-#include <linux/version.h>
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/bootinfo.h>
@@ -53,8 +52,9 @@
 extern char _sysmap_end[];
 extern char _initrd_start[];
 extern char _initrd_end[];
-extern unsigned long vmlinux_filesize;
-extern unsigned long vmlinux_memsize;
+
+extern void *_vmlinux_filesize;
+extern void *_vmlinux_memsize;
 
 struct addr_range {
 	unsigned long addr;
@@ -69,8 +69,8 @@
 static char scratch[128<<10];	/* 128kB of scratch space for gunzip */
 
 typedef void (*kernel_entry_t)( unsigned long,
-                                unsigned long,
-                                void *,
+		                unsigned long,
+		                void *,
 				struct bi_record *);
 
 
@@ -86,13 +86,12 @@
 start(unsigned long a1, unsigned long a2, void *promptr)
 {
 	unsigned long i, claim_addr, claim_size;
+	unsigned long vmlinux_filesize;
 	extern char _start;
 	struct bi_record *bi_recs;
 	kernel_entry_t kernel_entry;
 	Elf64_Ehdr *elf64;
 	Elf64_Phdr *elf64ph;
-	/* tell userland tools about uname -r */
-	unsigned char this_uts[] = "Linux version " UTS_RELEASE;
 
 	prom = (int (*)(void *)) promptr;
 	chosen_handle = finddevice("/chosen");
@@ -104,20 +103,7 @@
 	if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
 		exit();
 
-	printf("zImage starting: loaded at 0x%x\n\r", (unsigned)&_start);
-	printf("%s\n\r", this_uts);
-
-#if 0
-	sysmap.size = (unsigned long)(_sysmap_end - _sysmap_start);
-	sysmap.memsize = sysmap.size;
-	if ( sysmap.size > 0 ) {
-		sysmap.addr = (RAM_END - sysmap.size) & ~0xFFF;
-		claim(sysmap.addr, RAM_END - sysmap.addr, 0);
-		printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
-		       sysmap.addr, (unsigned long)_sysmap_start, sysmap.size);
-		memcpy((void *)sysmap.addr, (void *)_sysmap_start, sysmap.size);
-	}
-#endif
+	printf("\n\rzImage starting: loaded at 0x%x\n\r", (unsigned)&_start);
 
 	initrd.size = (unsigned long)(_initrd_end - _initrd_start);
 	initrd.memsize = initrd.size;
@@ -133,12 +119,13 @@
 	vmlinuz.addr = (unsigned long)_vmlinux_start;
 	vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
 	vmlinux.addr = (unsigned long)(void *)-1;
+	vmlinux_filesize = (unsigned long)&_vmlinux_filesize;
 	vmlinux.size = PAGE_ALIGN(vmlinux_filesize);
-	vmlinux.memsize = vmlinux_memsize;
+	vmlinux.memsize = (unsigned long)&_vmlinux_memsize;
 
 	claim_size = vmlinux.memsize /* PPPBBB: + fudge for bi_recs */;
-	for(claim_addr = PROG_START; 
-	    claim_addr <= PROG_START * 8; 
+	for(claim_addr = PROG_START;
+	    claim_addr <= PROG_START * 8;
 	    claim_addr += 0x100000) {
 		printf("    trying: 0x%08lx\n\r", claim_addr);
 		vmlinux.addr = (unsigned long)claim(claim_addr, claim_size, 0);
diff -urN linux-2.4.24-pre1/arch/ppc64/boot/zImage.lds linux-2.4.24-pre2/arch/ppc64/boot/zImage.lds
--- linux-2.4.24-pre1/arch/ppc64/boot/zImage.lds	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/boot/zImage.lds	2003-12-22 11:34:34.000000000 -0800
@@ -58,6 +58,8 @@
     CONSTRUCTORS
   }
 
+  .kernel:uts_string : { *(.kernel:uts_string) }
+
   . = ALIGN(4096);
   _vmlinux_start =  .;
   .kernel:vmlinux : { *(.kernel:vmlinux) }
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/HvCall.c linux-2.4.24-pre2/arch/ppc64/kernel/HvCall.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/HvCall.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/HvCall.c	2003-12-22 11:34:34.000000000 -0800
@@ -1,7 +1,7 @@
 /*
  * HvCall.c
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -60,7 +60,7 @@
 	curPtr = virt_to_absolute( (unsigned long) buffer );
 	for(i=0; i<npages; i++) {
 		bufList[i].addr = curPtr;
-      
+
 		leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
 
 		if (leftThisPage > bytesLeft) {
@@ -90,11 +90,11 @@
 	struct HvLpBufferList bufList;
 	u64 bytesLeft = bufLen;
 	u64 leftThisPage;
-	u64 curPtr = virt_to_absolute( (unsigned long) buffer );
+	u64 curPtr = virt_to_absolute((unsigned long) buffer);
 
 	while (bytesLeft) {
 		bufList.addr = curPtr;
-      
+
 		leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
 
 		if (leftThisPage > bytesLeft) {
@@ -105,11 +105,11 @@
 			bytesLeft -= leftThisPage;
 		}
 
-		curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
-	}
-
 
-	HvCall2(HvCallBaseWriteLogBuffer,
-		virt_to_absolute((unsigned long)&bufList), bufLen);
+		HvCall2(HvCallBaseWriteLogBuffer,
+			virt_to_absolute((unsigned long) &bufList),
+			bufList.len);
 
+		curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
+	}
 }
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/Makefile linux-2.4.24-pre2/arch/ppc64/kernel/Makefile
--- linux-2.4.24-pre1/arch/ppc64/kernel/Makefile	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/Makefile	2003-12-22 11:34:34.000000000 -0800
@@ -17,7 +17,7 @@
 
 O_TARGET := kernel.o
 
-export-objs         := ppc_ksyms.o setup.o
+export-objs         := ppc_ksyms.o setup.o vio.o viopath.o
 
 obj-y               :=	ppc_ksyms.o setup.o entry.o traps.o irq.o idle.o \
 			time.o process.o signal.o syscalls.o misc.o ptrace.o \
@@ -27,12 +27,13 @@
 			pmc.o mf_proc.o proc_pmc.o proc_pcifr.o iSeries_setup.o \
 			ItLpQueue.o hvCall.o mf.o HvLpEvent.o ras.o \
 			iSeries_proc.o HvCall.o flight_recorder.o HvLpConfig.o \
-			rtc.o perfmon.o cputable.o
+			rtc.o perfmon.o cputable.o vio.o
 
 obj-$(CONFIG_PCI) +=  pci.o pci_dn.o pci_dma.o pSeries_lpar.o pSeries_hvCall.o
 
 ifeq ($(CONFIG_PPC_ISERIES),y)
 obj-$(CONFIG_PCI) += iSeries_pci.o iSeries_pci_reset.o iSeries_IoMmTable.o iSeries_irq.o iSeries_VpdInfo.o XmPciLpEvent.o 
+obj-$(CONFIG_VIOPATH) += viopath.o
 endif
 ifeq ($(CONFIG_PPC_PSERIES),y)
 obj-$(CONFIG_PCI) += pSeries_pci.o eeh.o
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/chrp_setup.c linux-2.4.24-pre2/arch/ppc64/kernel/chrp_setup.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/chrp_setup.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/chrp_setup.c	2003-12-22 11:34:34.000000000 -0800
@@ -82,6 +82,7 @@
 extern void pckbd_init_hw(void);
 extern unsigned char pckbd_sysrq_xlate[128];
 extern void openpic_init_IRQ(void);
+extern void openpic_init_irq_desc(irq_desc_t *);
 extern void init_ras_IRQ(void);
 
 extern void find_and_init_phbs(void);
@@ -264,10 +265,12 @@
 	ppc_md.setup_residual = NULL;
 	ppc_md.get_cpuinfo    = chrp_get_cpuinfo;
 	if(naca->interrupt_controller == IC_OPEN_PIC) {
-		ppc_md.init_IRQ       = openpic_init_IRQ; 
+		ppc_md.init_IRQ       = openpic_init_IRQ;
+		ppc_md.init_irq_desc  = openpic_init_irq_desc;
 		ppc_md.get_irq        = openpic_get_irq;
 	} else {
 		ppc_md.init_IRQ       = xics_init_IRQ;
+		ppc_md.init_irq_desc  = xics_init_irq_desc;
 		ppc_md.get_irq        = xics_get_irq;
 	}
 	ppc_md.init_ras_IRQ = init_ras_IRQ;
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/cputable.c linux-2.4.24-pre2/arch/ppc64/kernel/cputable.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/cputable.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/kernel/cputable.c	2003-12-22 11:34:34.000000000 -0800
@@ -101,6 +101,15 @@
 	    __setup_cpu_power4,
 	    COMMON_PPC64_FW
     },
+    {	/* Power5 */
+	    0xffff0000, 0x003a0000, "Power5",
+	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+	    CPU_FTR_PPCAS_ARCH_V2,
+	    COMMON_USER_PPC64,
+	    128, 128,
+	    __setup_cpu_power4,
+	    COMMON_PPC64_FW
+    },
     {	/* default match */
 	    0x00000000, 0x00000000, "(Power4-Compatible)",
   	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
@@ -124,4 +133,13 @@
     {FW_FEATURE_DUMP,		"hcall-dump"},
     {FW_FEATURE_INTERRUPT,	"hcall-interrupt"},
     {FW_FEATURE_MIGRATE,	"hcall-migrate"},
+    {FW_FEATURE_PERFMON,	"hcall-perfmon"},
+    {FW_FEATURE_CRQ,    	"hcall-crq"},
+    {FW_FEATURE_VIO,	        "hcall-vio"},
+    {FW_FEATURE_RDMA,	        "hcall-rdma"},
+    {FW_FEATURE_LLAN,	        "hcall-lLAN"},
+    {FW_FEATURE_BULK,   	"hcall-bulk"},
+    {FW_FEATURE_XDABR,  	"hcall-xdabr"},
+    {FW_FEATURE_MULTITCE,	"hcall-multi-tce"},
+    {FW_FEATURE_SPLPAR,	        "hcall-splpar"},
 };
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/entry.S linux-2.4.24-pre2/arch/ppc64/kernel/entry.S
--- linux-2.4.24-pre1/arch/ppc64/kernel/entry.S	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/entry.S	2003-12-22 11:34:34.000000000 -0800
@@ -46,16 +46,17 @@
  */
 	.text
 _GLOBAL(DoSyscall)
-	std	r0,THREAD+LAST_SYSCALL(r13)
 	ld	r11,_CCR(r1)	/* Clear SO bit in CR */
 	lis	r10,0x1000
 	andc	r11,r11,r10
 	std	r11,_CCR(r1)
+	ld	r10,PACACURRENT(r13)
+	std	r0,THREAD+LAST_SYSCALL(r10)
 #ifdef SHOW_SYSCALLS
 # ifdef SHOW_SYSCALLS_TASK
 	LOADBASE(r31,show_syscalls_task)
 	ld	r31,show_syscalls_task@l(r31)
-	cmp	0,r13,r31
+	cmp	0,r10,r31
 	bne	1f
 # endif /* SHOW_SYSCALLS_TASK */
 	LOADADDR(r3,7f)
@@ -69,7 +70,7 @@
 	LOADADDR(r3,77f)
 	ld	r4,GPR8(r1)
 	ld	r5,GPR9(r1)
-	mr	r6,r13
+	ld	r6, PACACURRENT(r13)
 	bl	.printk
 	ld	r0,GPR0(r1)
 	ld	r3,GPR3(r1)
@@ -80,8 +81,8 @@
 	ld	r8,GPR8(r1)
 1:
 #endif /* SHOW_SYSCALLS */
-	ld	r10,TASK_PTRACE(r13)
-	andi.	r10,r10,PT_TRACESYS
+	ld	r11,TASK_PTRACE(r10)
+	andi.	r11,r11,PT_TRACESYS
 	bne-	50f
 	cmpli	0,r0,NR_syscalls
 	bge-	66f
@@ -90,10 +91,10 @@
  *
  */
 #ifdef CONFIG_BINFMT_ELF32
-	ld	r10,THREAD+THREAD_FLAGS(r13)
-	andi.	r10,r10,PPC_FLAG_32BIT
+	ld	r11,THREAD+THREAD_FLAGS(r10)
+	andi.	r11,r11,PPC_FLAG_32BIT
 	beq-	15f
-	LOADADDR(r10,.sys_call_table32)
+	LOADADDR(r11,.sys_call_table32)
 /* Now mung the first 4 parameters into shape, by making certain that
  * the high bits (most significant 32 bits in 64 bit reg) are 0
  * for the first 4 parameter regs(3-6).
@@ -105,10 +106,10 @@
 	b	17f
 15:
 #endif
-	LOADADDR(r10,.sys_call_table)
+	LOADADDR(r11,.sys_call_table)
 17:
 	slwi	r0,r0,3
-	ldx	r10,r10,r0	/* Fetch system call handler [ptr] */
+	ldx	r10,r11,r0	/* Fetch system call handler [ptr] */
 	mtlr	r10
 	addi	r9,r1,STACK_FRAME_OVERHEAD
 	blrl			/* Call handler */
@@ -153,7 +154,8 @@
 	cmpli	0,r0,NR_syscalls
 	bge-	66f
 #ifdef CONFIG_BINFMT_ELF32
-	ld	r10,THREAD+THREAD_FLAGS(r13)
+	ld	r10,PACACURRENT(r13)
+	ld	r10,THREAD+THREAD_FLAGS(r10)
 	andi.	r10,r10,PPC_FLAG_32BIT
 	beq-	55f
 	LOADADDR(r10,.sys_call_table32)
@@ -214,7 +216,8 @@
 _GLOBAL(ppc64_rt_sigreturn)
 	bl	.sys_rt_sigreturn
 
-80:	ld	r10,TASK_PTRACE(r13)
+80:	ld	r10,PACACURRENT(r13)
+	ld	r10,TASK_PTRACE(r10)
 	andi.	r10,r10,PT_TRACESYS
 	bne-	81f
 	cmpi	0,r3,0
@@ -266,10 +269,9 @@
 	std	r6,TRAP(r1)
 	std	r1,KSP(r3)	/* Set old stack pointer */
 
-	mfspr	r5,SPRG3	/* Get Paca */
 	addi	r3,r3,-THREAD	/* old 'current' for return value */
-	addi	r13,r4,-THREAD	/* Convert THREAD to 'current' */
-	std	r13,PACACURRENT(r5)	/* Set new 'current' */
+	addi	r7,r4,-THREAD	/* Convert THREAD to 'current' */
+	std	r7,PACACURRENT(r13)	/* Set new 'current' */
 
 #ifdef CONFIG_PPC_ISERIES
 	ld	r7,THREAD_FLAGS(r4)	/* Get run light flag */
@@ -292,7 +294,8 @@
 
 _GLOBAL(ret_from_fork)
 	bl	.schedule_tail
-	ld	r0,TASK_PTRACE(r13)
+	ld	r4,PACACURRENT(r13)
+	ld	r0,TASK_PTRACE(r4)
 	andi.	r0,r0,PT_TRACESYS
 	beq+	.ret_from_except
 	bl	.syscall_trace
@@ -308,9 +311,8 @@
 	CHECKANYINT(r3,r4)
 	beq+	4f	/* skip do_IRQ if no interrupts */
 
-	mfspr	r5,SPRG3
 	li	r3,0
-	stb	r3,PACAPROCENABLED(r5)	/* ensure we are disabled */
+	stb	r3,PACAPROCENABLED(r13)	/* ensure we are disabled */
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.do_IRQ
 	b	irq_recheck	/* loop back and handle more */
@@ -322,14 +324,16 @@
 	beq+	restore		/* if so, check need_resched and signals */
 _GLOBAL(ret_to_user_hook)
 	nop
-	/* NEED_RESCHED is a volatile long (64-bits) */ 
-	ld	r3,NEED_RESCHED(r13)
+	/* NEED_RESCHED is a volatile long (64-bits) */
+	ld	r3,PACACURRENT(r13)
+	ld	r3,NEED_RESCHED(r3)
 	cmpi	0,r3,0		/* check need_resched flag */
 	beq+	7f
 	bl	.schedule
 	/* SIGPENDING is an int (32-bits) */
-7:	
-	lwz	r5,SIGPENDING(r13) /* Check for pending unblocked signals */
+7:
+	ld	r5,PACACURRENT(r13)
+	lwz	r5,SIGPENDING(r5) /* Check for pending unblocked signals */
 	cmpwi	0,r5,0
 	beq+	restore
 	li	r3,0
@@ -372,26 +376,31 @@
 #endif
 	stdcx.	r0,0,r1		/* to clear the reservation */
 
-	mfspr	r4,SPRG3	/* current task's PACA */
 #ifdef DO_SOFT_DISABLE
 	ld	r0,SOFTE(r1)
-	stb	r0,PACAPROCENABLED(r4)
+	stb	r0,PACAPROCENABLED(r13)
 #endif
 	/* if returning to user mode, save kernel SP */
 	ld	r0,_MSR(r1)
 	andi.	r0,r0,MSR_PR
 	beq+	1f
+	ld	r4,PACACURRENT(r13)
 	addi	r0,r1,INT_FRAME_SIZE	/* size of frame */
-	std	r0,THREAD+KSP(r13)	/* save kernel stack pointer */
-	std	r1,PACAKSAVE(r4)	/* save exception stack pointer */
+	std	r0,THREAD+KSP(r4)	/* save kernel stack pointer */
+	std	r1,PACAKSAVE(r13)	/* save exception stack pointer */
+	REST_GPR(13,r1)
 1:
+	mfmsr	r0
+	li	r2, MSR_RI
+	andc	r0,r0,r2
+	mtmsrd	r0,1
+
 	ld	r0,_MSR(r1)
 	mtspr	SRR1,r0
 	ld	r2,_CCR(r1)
 	mtcrf	0xFF,r2
 	ld	r2,_NIP(r1)
 	mtspr	SRR0,r2
-	REST_GPR(13,r1)
 	ld	r0,GPR0(r1)
 	ld	r2,GPR2(r1)
 	ld	r3,GPR3(r1)
@@ -440,11 +449,10 @@
 	/* Unfortunately, the stack pointer and the MSR are also clobbered,
 	 * so they are saved in the PACA (SPRG3) which allows us to restore
 	 * our original state after RTAS returns.
-         */
-	mfspr	r4,SPRG3		/* Get PACA */
-	std	r1,PACAR1(r4)
+	 */
+	std	r1,PACAR1(r13)
 	mfmsr	r6
-        std	r6,PACASAVEDMSR(r4)
+	std	r6,PACASAVEDMSR(r13)
 
 	/* Setup our real return addr */	
 	SET_REG_TO_LABEL(r4,.rtas_return_loc)
@@ -473,13 +481,19 @@
 
 _STATIC(rtas_return_loc)
 	/* relocation is off at this point */
-	mfspr	r4,SPRG3	        /* Get PACA */
+	mfspr	r13,SPRG3	        /* Get PACA */
 	SET_REG_TO_CONST(r5, KERNELBASE)
-        sub     r4,r4,r5                /* RELOC the PACA base pointer */
-        
-        ld	r1,PACAR1(r4)           /* Restore our SP */
+	sub     r13,r13,r5              /* RELOC the PACA base pointer */
+
+	mfmsr	r6			/* Clear RI while SRR0/1 are live */
+	li	r0,MSR_RI
+	andc	r6,r6,r0
+	sync
+	mtmsrd	r6
+
+	ld	r1,PACAR1(r13)           /* Restore our SP */
 	LOADADDR(r3,.rtas_restore_regs)
-        ld	r4,PACASAVEDMSR(r4)     /* Restore our MSR */
+	ld	r4,PACASAVEDMSR(r13)     /* Restore our MSR */
 
 	mtspr	SRR0,r3
 	mtspr	SRR1,r4
@@ -492,9 +506,8 @@
 	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
 	REST_10GPRS(22, r1)		/* ditto */
 
-	/* put back current in r13 */
-        mfspr	r4,SPRG3
-	ld	r13,PACACURRENT(r4)
+	/* put back paca in r13 */
+	mfspr	r13,SPRG3
 
 	ld	r4,_CCR(r1)
 	mtcr	r4
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/head.S linux-2.4.24-pre2/arch/ppc64/kernel/head.S
--- linux-2.4.24-pre1/arch/ppc64/kernel/head.S	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/kernel/head.S	2003-12-22 11:34:34.000000000 -0800
@@ -38,6 +38,15 @@
 #define DO_SOFT_DISABLE
 #endif
 
+/* copy saved SOFTE bit or EE bit from saved MSR depending
+ * if we are doing soft-disable or not
+ */
+#ifdef DO_SOFT_DISABLE
+#define DO_COPY_EE()	ld	r20,SOFTE(r1)
+#else
+#define DO_COPY_EE()	rldicl	r20,r23,49,63
+#endif
+
 /*
  * hcall interface to pSeries LPAR
  */
@@ -130,6 +139,10 @@
  * All of it must fit below the first exception vector at 0x100.
  */
 _GLOBAL(__secondary_hold)
+	mfmsr	r24
+	ori	r24,r24,MSR_RI
+	mtmsrd	r24			/* RI on */
+
 	/* Grab our linux cpu number */
 	mr      r24,r3
 
@@ -201,7 +214,7 @@
 		                        /*   assumes *_common < 16b   */ \
 	mfmsr   r23;                                                     \
 	rotldi  r23,r23,4;                                               \
-	ori     r23,r23,0x30B;          /* Set IR, DR, SF, ISF, HV    */ \
+	ori     r23,r23,0x32B;          /* Set IR, DR, RI, SF, ISF, HV*/ \
 	rotldi  r23,r23,60;             /* for generic handlers       */ \
 	mtspr   SRR0,r22;                                                \
 	mtspr   SRR1,r23;                                                \
@@ -285,7 +298,7 @@
 	SAVE_8GPRS(2, r1);              /* save r2 - r13 in stackframe */ \
 	SAVE_4GPRS(10, r1);                                               \
 	ld      r2,PACATOC(r20);	                                  \
-	ld      r13,PACACURRENT(r20)
+	mr	r13,r20
 
 /*
  * Note: code which follows this uses cr0.eq (set if from kernel),
@@ -436,8 +449,8 @@
 
 	.globl SystemReset_Iseries
 SystemReset_Iseries:
-	mfspr	25,SPRG3		/* Get paca address */
-	lhz	r24,PACAPACAINDEX(r25)	/* Get processor # */
+	mfspr	13,SPRG3		/* Get paca address */
+	lhz	r24,PACAPACAINDEX(r13)	/* Get processor # */
 	cmpi	0,r24,0			/* Are we processor 0? */
 	beq	.__start_initialization_iSeries	/* Start up the first processor */
 	mfspr	r4,CTRLF
@@ -448,7 +461,7 @@
 1:
 	HMT_LOW
 #ifdef CONFIG_SMP
-	lbz	r23,PACAPROCSTART(r25)	/* Test if this processor
+	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor
 					 * should start */
 	sync
 	LOADADDR(r3,current_set)
@@ -478,7 +491,7 @@
 #endif /* CONFIG_SMP */
 	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
 	sc				/* Invoke the hypervisor via a system call */
-	mfspr	r25,SPRG3		/* Put r25 back ???? */
+	mfspr	r13,SPRG3		/* Put r13 back - why???? */
 	b	1b			/* If SMP not configured, secondaries
 					 * loop forever */
 
@@ -570,6 +583,12 @@
 	REST_GPR(0, r1)
 	REST_8GPRS(2, r1)
 	REST_4GPRS(10, r1)
+
+	mfmsr	r20
+	li	r21, MSR_RI
+	andc	r20,r20,r21
+	mtmsrd	r20,1
+
 	mtspr   SRR1,r23
 	mtspr   SRR0,r22
 	REST_4GPRS(20, r1)
@@ -613,11 +632,7 @@
 	ld      r4,_DAR(r1)
 	ld      r5,_DSISR(r1)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-#ifdef DO_SOFT_DISABLE
-	ld	r20,SOFTE(r1)		/* Copy saved SOFTE bit */
-#else
-	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
-#endif
+	DO_COPY_EE()
 	li	r6,0x300
 	bl      .save_remaining_regs
 	bl      .do_page_fault
@@ -639,11 +654,7 @@
 	or.	r3,r3,r3		/* Check return code */
 	beq     fast_exception_return   /* Return if we succeeded */
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-#ifdef DO_SOFT_DISABLE
-	ld	r20,SOFTE(r1)
-#else
-	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
-#endif
+	DO_COPY_EE()
 	li	r6,0x380
 	li	r5,0
 	bl      .save_remaining_regs
@@ -669,11 +680,7 @@
 	mr	r4,r22
 	rlwinm	r5,r23,0,4,4		/* We only care about PR in error_code */
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-#ifdef DO_SOFT_DISABLE
-	ld	r20,SOFTE(r1)
-#else
-	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
-#endif
+	DO_COPY_EE()
 	li	r6,0x400
 	bl      .save_remaining_regs
 	bl      .do_page_fault
@@ -689,11 +696,7 @@
 	beq     fast_exception_return   /* Return if we succeeded */
 
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-#ifdef DO_SOFT_DISABLE
-	ld	r20,SOFTE(r1)
-#else
-	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
-#endif
+	DO_COPY_EE()
 	li	r6,0x480
 	li	r5,0
 	bl      .save_remaining_regs
@@ -766,11 +769,7 @@
 Alignment_common:
 	EXCEPTION_PROLOG_COMMON
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-#ifdef DO_SOFT_DISABLE
-	ld	r20,SOFTE(r1)
-#else
-	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
-#endif
+	DO_COPY_EE()
 	li	r6,0x600
 	bl      .save_remaining_regs
 	bl      .AlignmentException
@@ -780,11 +779,7 @@
 ProgramCheck_common:
 	EXCEPTION_PROLOG_COMMON
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-#ifdef DO_SOFT_DISABLE
-	ld	r20,SOFTE(r1)
-#else
-	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
-#endif
+	DO_COPY_EE()
 	li	r6,0x700
 	bl      .save_remaining_regs
 	bl      .ProgramCheckException
@@ -795,11 +790,7 @@
 	EXCEPTION_PROLOG_COMMON
 	bne	.load_up_fpu		/* if from user, just load it up */
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-#ifdef DO_SOFT_DISABLE
-	ld	r20,SOFTE(r1)
-#else
-	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
-#endif
+	DO_COPY_EE()
 	li	r6,0x800
 	bl      .save_remaining_regs
 	bl      .KernelFPUnavailableException
@@ -816,11 +807,7 @@
 1:
 #endif
 	std	r3,ORIG_GPR3(r1)
-#ifdef DO_SOFT_DISABLE
-	ld	r20,SOFTE(r1)
-#else
-	rldicl	r20,r23,49,63   	/* copy EE bit from saved MSR */
-#endif
+	DO_COPY_EE()
 	li	r6,0xC00
 	bl      .save_remaining_regs
 	bl      .DoSyscall
@@ -1143,6 +1130,12 @@
 	lwz	r23,EX_CCR(r21)		/* get saved CR */
 	/* note that this is almost identical to maskable_exception_exit */
 	mtcr    r23                     /* restore CR */
+
+	mfmsr	r22
+	li	r23, MSR_RI
+	andc	r22,r22,r23
+	mtmsrd	r22,1
+
 	ld	r22,EX_SRR0(r21)	/* Get SRR0 from exc. frame */
 	ld	r23,EX_SRR1(r21)	/* Get SRR1 from exc. frame */
 	mtspr	SRR0,r22
@@ -1184,7 +1177,7 @@
 	slbmfee	r23,r22
 	rldicl  r23,r23,37,63
 	cmpwi   r23,0
-	beq     3f              /* Found an invalid entry              */
+	beq     4f              /* Found an invalid entry              */
 
 	addi	r22,r22,1
 	cmpldi	r22,64
@@ -1193,16 +1186,36 @@
 	/* No free entry - just take the next entry, round-robin */
 	/* XXX we should get the number of SLB entries from the naca */
 SLB_NUM_ENTRIES = 64
-	mfspr	r21,SPRG3
+2:	mfspr	r21,SPRG3
 	ld	r22,PACASTABRR(r21)
 	addi	r23,r22,1
 	cmpdi	r23,SLB_NUM_ENTRIES
-	blt	2f
+	blt	3f
 	li	r23,1
-2:	std	r23,PACASTABRR(r21)
+3:	std	r23,PACASTABRR(r21)
 
 	/* r20 = vsid, r22 = entry */
-3:
+
+	/*
+	 * Never cast out the segment for our kernel stack. Since we
+	 * dont invalidate the ERAT we could have a valid translation
+	 * for the kernel stack during the first part of exception exit
+	 * which gets invalidated due to a tlbie from another cpu at a
+	 * non recoverable point (after setting srr0/1) - Anton
+	 */
+	slbmfee	r23,r22
+	srdi	r23,r23,28
+	/*
+	 * This is incorrect (r1 is not the kernel stack) if we entered
+	 * from userspace but there is no critical window from userspace
+	 * so this should be OK. Also if we cast out the userspace stack
+	 * segment while in userspace we will fault it straight back in.
+	 */
+	srdi	r21,r1,28
+	cmpd	r21,r23
+	beq-	2b
+	
+4:
 	/* Put together the vsid portion of the entry. */
 	li      r21,0
 	rldimi  r21,r20,12,0
@@ -1237,6 +1250,12 @@
 	lwz	r23,EX_CCR(r21)		/* get saved CR */
 	/* note that this is almost identical to maskable_exception_exit */
 	mtcr    r23                     /* restore CR */
+
+	mfmsr	r22
+	li	r23, MSR_RI
+	andc	r22,r22,r23
+	mtmsrd	r22,1
+
 	ld	r22,EX_SRR0(r21)	/* Get SRR0 from exc. frame */
 	ld	r23,EX_SRR1(r21)	/* Get SRR1 from exc. frame */
 	mtspr	SRR0,r22
@@ -1295,21 +1314,21 @@
 	 * Indicate that r1 contains the kernel stack and
 	 * get the Kernel TOC and CURRENT pointers from the paca
 	 */
-	mfspr	r23,SPRG3		/* Get PACA */
-	std	r22,PACAKSAVE(r23)	/* r1 is now kernel sp */
-	ld	r2,PACATOC(r23)		/* Get Kernel TOC pointer */
+	std	r22,PACAKSAVE(r13)	/* r1 is now kernel sp */
+	ld	r2,PACATOC(r13)		/* Get Kernel TOC pointer */
 
 	/*
 	 * If from user state, update THREAD.regs
 	 */
 	beq	2f			/* Modify THREAD.regs if from user */
 	addi	r24,r1,STACK_FRAME_OVERHEAD
-	std	r24,THREAD+PT_REGS(r13)
+	ld	r22,PACACURRENT(r13)
+	std	r24,THREAD+PT_REGS(r22)
 2:
 	SET_REG_TO_CONST(r22, MSR_KERNEL)
 
 #ifdef DO_SOFT_DISABLE
-	stb	r20,PACAPROCENABLED(r23) /* possibly soft enable */
+	stb	r20,PACAPROCENABLED(r13) /* possibly soft enable */
 	ori	r22,r22,MSR_EE		/* always hard enable */
 #else
 	rldimi	r22,r20,15,48		/* Insert desired EE value */
@@ -1356,20 +1375,20 @@
 
 	/* Set up a paca value for this processor. */
 	LOADADDR(r24, paca) 		 /* Get base vaddr of Paca array  */
-	mulli	r25,r3,PACA_SIZE	 /* Calculate vaddr of right Paca */
-	add	r25,r25,r24              /* for this processor.           */
+	mulli	r13,r3,PACA_SIZE	 /* Calculate vaddr of right Paca */
+	add	r13,r13,r24              /* for this processor.           */
 
-	mtspr	SPRG3,r25		 /* Save vaddr of Paca in SPRG3   */
+	mtspr	SPRG3,r13		 /* Save vaddr of Paca in SPRG3   */
 	mr	r24,r3			 /* __secondary_start needs cpu#  */
 
 1:
 	HMT_LOW
-	lbz	r23,PACAPROCSTART(r25)	 /* Test if this processor should */
+	lbz	r23,PACAPROCSTART(r13)	 /* Test if this processor should */
 					 /* start.                        */
 	sync
 
         /* Create a temp kernel stack for use before relocation is on.    */
-        mr      r1,r25
+	mr	r1,r13
         addi    r1,r1,PACAGUARD
         addi    r1,r1,0x1000
         subi    r1,r1,STACK_FRAME_OVERHEAD
@@ -1609,16 +1628,17 @@
 1:
 #endif /* CONFIG_SMP */
 	/* enable use of FP after return */
-	addi	r5,r13,THREAD
-	ld	r4,THREAD_FPEXC_MODE(r5)
+	ld	r4,PACACURRENT(r13)
+	addi	r5,r4,THREAD		/* Get THREAD */
+	ld	r20,THREAD_FPEXC_MODE(r5)
 	ori	r23,r23,MSR_FP
-	or	r23,r23,r4
+	or	r23,r23,r20
 	lfd	fr0,THREAD_FPSCR(r5)
 	mtfsf	0xff,fr0
 	REST_32FPRS(0, r5)
 #ifndef CONFIG_SMP
 	/* Update last_task_used_math to 'current' */
-	std	r13,last_task_used_math@l(r3)
+	std	r4,last_task_used_math@l(r3)
 #endif /* CONFIG_SMP */
 	/* restore registers and return */
 	b	fast_exception_return
@@ -1685,7 +1705,7 @@
  * On entry the following are set:
  *   r1    = stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
  *   r24   = cpu# (in Linux terms)
- *   r25   = paca virtual address
+ *   r13   = paca virtual address
  *   SPRG3 = paca virtual address
  */
 _GLOBAL(__secondary_start)
@@ -1697,10 +1717,10 @@
 	addi    r2,r2,0x4000
 	addi    r2,r2,0x4000
 
-	std	r2,PACATOC(r25)
+	std	r2,PACATOC(r13)
 	li	r6,0
-	std	r6,PACAKSAVE(r25)
-	stb	r6,PACAPROCENABLED(r25)
+	std	r6,PACAKSAVE(r13)
+	stb	r6,PACAPROCENABLED(r13)
 
 #ifndef CONFIG_PPC_ISERIES
 	/* Initialize the page table pointer register. */
@@ -1709,18 +1729,18 @@
 	mtspr	SDR1,r6			/* set the htab location  */
 #endif
 	/* Initialize the first segment table (or SLB) entry                */
-	ld	r3,PACASTABVIRT(r25)    /* get addr of segment table        */
+	ld	r3,PACASTABVIRT(r13)    /* get addr of segment table        */
 	bl	.stab_initialize
 
 	/* Initialize the kernel stack.  Just a repeat for iSeries.         */
 	LOADADDR(r3,current_set)
 	sldi	r28,r24,4		/* get current_set[cpu#] */
-	ldx	r13,r3,r28
-	std	r13,PACACURRENT(r25)
-	addi	r1,r13,TASK_UNION_SIZE
+	ldx	r28,r3,r28
+	std	r28,PACACURRENT(r13)
+	addi	r1,r28,TASK_UNION_SIZE
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 
-	ld	r3,PACASTABREAL(r25)    /* get raddr of segment table       */
+	ld	r3,PACASTABREAL(r13)    /* get raddr of segment table       */
 	ori	r4,r3,1			/* turn on valid bit                */
 
 #ifdef CONFIG_PPC_ISERIES
@@ -1737,9 +1757,13 @@
 	bne   	98f
 	mfspr	r3,PVR
 	srwi	r3,r3,16
-	cmpwi	r3,0x37         /* SStar */
+	cmpwi	r3,0x37         /* SStar  */
+	beq	97f
+	cmpwi	r3,0x36         /* IStar  */
+	beq	97f
+	cmpwi	r3,0x34         /* Pulsar */
 	bne	98f
-	li	r3,H_SET_ASR    /* hcall = H_SET_ASR */
+97:	li	r3,H_SET_ASR    /* hcall = H_SET_ASR */
 	HSC     		/* Invoking hcall */
 	b	99f
 98:                             /* !(rpa hypervisor) || !(sstar) */
@@ -1807,6 +1831,10 @@
 	bl	.reloc_offset
 	mr	r26,r3
 
+	mfmsr	r6
+	ori	r6,r6,MSR_RI
+	mtmsrd	r6			/* RI on */
+
 	/* setup the systemcfg pointer which is needed by *tab_initialize  */
 	LOADADDR(r6,systemcfg)
 	sub	r6,r6,r26                /* addr of the variable systemcfg */
@@ -1880,9 +1908,9 @@
 	/* stab_initialize                                                 */
 	li	r27,0x4000
 	ld	r6,PACA(r27)            /* Get the base paca pointer       */
-	sub	r6,r6,r26		/* convert to physical addr         */
-	mtspr	SPRG3,r6		/* PPPBBB: Temp... -Peter */
-	ld	r3,PACASTABREAL(r6)
+	sub	r13,r6,r26		/* convert to physical addr         */
+	mtspr	SPRG3,r13		/* PPPBBB: Temp... -Peter */
+	ld	r3,PACASTABREAL(r13)
 	ori	r4,r3,1			/* turn on valid bit                */
 
 	/* set the ASR */
@@ -1893,8 +1921,12 @@
 	mfspr	r3,PVR
 	srwi	r3,r3,16
 	cmpwi	r3,0x37         /* SStar */
+	beq	97f
+	cmpwi	r3,0x36         /* IStar  */
+	beq	97f
+	cmpwi	r3,0x34         /* Pulsar */
 	bne	98f
-	li	r3,H_SET_ASR    /* hcall = H_SET_ASR */
+97:	li	r3,H_SET_ASR    /* hcall = H_SET_ASR */
 	HSC     	        /* Invoking hcall */
 	b     	99f
 98:                 /* This is not a hypervisor machine */
@@ -1973,16 +2005,16 @@
 
 	LOADADDR(r4,naca)               /* Get naca ptr address           */
 	ld	r4,0(r4)                /* Get the location of the naca   */
-	ld	r4,PACA(r4)             /* Get the base paca pointer      */
-	mtspr	SPRG3,r4
+	ld	r13,PACA(r4)            /* Get the base paca pointer      */
+	mtspr	SPRG3,r13
 
 	/* ptr to current */
-	LOADADDR(r13,init_task_union)
-	std	r13,PACACURRENT(r4)
+	LOADADDR(r4,init_task_union)
+	std	r4,PACACURRENT(r13)
 
-	std	r2,PACATOC(r4)
+	std	r2,PACATOC(r13)
 	li	r5,0
-	std	r0,PACAKSAVE(r4)
+	std	r0,PACAKSAVE(r13)
 
 	/* ptr to hardware interrupt stack for processor 0                */
 	LOADADDR(r3, hardware_int_paca0)
@@ -1991,10 +2023,10 @@
 	subi    r5,r5,STACK_FRAME_OVERHEAD
 
 	add     r3,r3,r5
-	std     r3,PACAHRDWINTSTACK(r4)
+	std     r3,PACAHRDWINTSTACK(r13)
 
 	li      r3,0
-	stb     r3,PACAHRDWINTCOUNT(r4)
+	stb     r3,PACAHRDWINTCOUNT(r13)
 
 	/* Restore the parms passed in from the bootloader. */
 	mr	r3,r31
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/htab.c linux-2.4.24-pre2/arch/ppc64/kernel/htab.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/htab.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/htab.c	2003-12-22 11:34:34.000000000 -0800
@@ -1179,7 +1179,7 @@
                 "mr    5, %3\n"
                 "mr    6, %4\n"
                 "mr    7, %5\n"
-                HSC    
+		HVSC
                 "mr    %0, 3\n"
                 "mr    %1, 4\n"
 		: "=r" (lpar_rc), "=r" (slot)
@@ -1200,7 +1200,7 @@
 			      "mr    5, %3\n"
 			      "mr    6, %4\n"
 			      "mr    7, %5\n"
-			      HSC    
+			      HVSC
 			      "mr    %0, 3\n"
 			      "mr    %1, 4\n"
 			      : "=r" (lpar_rc), "=r" (slot)
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/i8259.c linux-2.4.24-pre2/arch/ppc64/kernel/i8259.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/i8259.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/i8259.c	2003-12-22 11:34:34.000000000 -0800
@@ -123,7 +123,8 @@
 
 static void i8259_end_irq(unsigned int irq)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+	if (!(irqdesc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) &&
+	    irqdesc(irq)->action)
 		i8259_unmask_irq(irq);
 }
 
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/iSeries_irq.c linux-2.4.24-pre2/arch/ppc64/kernel/iSeries_irq.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/iSeries_irq.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/iSeries_irq.c	2003-12-22 11:34:34.000000000 -0800
@@ -70,15 +70,24 @@
 
 void iSeries_init_irqMap(int irq);
 
+void iSeries_init_irq_desc(irq_desc_t *desc)
+{
+	if (!desc->handler)
+		desc->handler = &iSeries_IRQ_handler;
+}
+
 /*  This is called by init_IRQ.  set in ppc_md.init_IRQ by iSeries_setup.c */
 void __init iSeries_init_IRQ(void)
 {
 	int i;
+	irq_desc_t *desc;
+
 	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc[i].handler = &iSeries_IRQ_handler;
-		irq_desc[i].status = 0;
-		irq_desc[i].status |= IRQ_DISABLED;
-		irq_desc[i].depth = 1;
+		desc = real_irqdesc(i);
+		desc->handler = &iSeries_IRQ_handler;
+		desc->status = 0;
+		desc->status |= IRQ_DISABLED;
+		desc->depth = 1;
 		iSeries_init_irqMap(i);
 	}
 	/* Register PCI event handler and open an event path */
@@ -117,6 +126,7 @@
 	u32 dsa = (busNumber << 16) | (subBusNumber << 8) | deviceId;
 	struct iSeries_irqEntry* newEntry;
 	unsigned long flags;
+	irq_desc_t *desc = irqdesc(irq);
 
 	if (irq < 0 || irq >= NR_IRQS) {
 		return -1;
@@ -132,7 +142,7 @@
 	* done during buswalk, but it should not hurt anything except a 
 	* little performance to be smp safe.
 	*******************************************************************/
-	spin_lock_irqsave(&irq_desc[irq].lock, flags);
+	spin_lock_irqsave(&desc->lock, flags);
 
 	if (iSeries_irqMap[irq].valid) {
 		/* Push the new element onto the irq stack */
@@ -147,7 +157,7 @@
 		kfree(newEntry);
 		rc = -1;
     }
-	spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+	spin_unlock_irqrestore(&desc->lock, flags);
 	return rc;
 }
 
@@ -179,10 +189,11 @@
 	int irq;
 	unsigned long flags;
 	for (irq=0; irq < NR_IRQS; irq++) {
-		spin_lock_irqsave(&irq_desc[irq].lock, flags);
-		irq_desc[irq].handler->startup(irq);
-		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
-    	}
+		irq_desc_t *desc = irqdesc(irq);
+		spin_lock_irqsave(&desc->lock, flags);
+		desc->handler->startup(irq);
+		spin_unlock_irqrestore(&desc->lock, flags);
+	}
 }
 
 /*  this is not called anywhere currently */
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/iSeries_setup.c linux-2.4.24-pre2/arch/ppc64/kernel/iSeries_setup.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/iSeries_setup.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/kernel/iSeries_setup.c	2003-12-22 11:34:34.000000000 -0800
@@ -63,6 +63,7 @@
 extern void iSeries_pcibios_init(void);
 extern void iSeries_pcibios_fixup(void);
 extern void iSeries_pcibios_fixup_bus(int);
+extern void iSeries_init_irq_desc(irq_desc_t *desc);
 
 /* Global Variables */
 
@@ -307,6 +308,7 @@
 	ppc_md.get_cpuinfo	 	= iSeries_get_cpuinfo;
 	ppc_md.irq_cannonicalize 	= NULL;
 	ppc_md.init_IRQ		 	= iSeries_init_IRQ;
+	ppc_md.init_irq_desc            = iSeries_init_irq_desc;
 	ppc_md.init_ras_IRQ		= NULL;
 	ppc_md.get_irq		 	= iSeries_get_irq;
 	ppc_md.init		 	= NULL;
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/idle.c linux-2.4.24-pre2/arch/ppc64/kernel/idle.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/idle.c	2003-06-13 07:51:31.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/idle.c	2003-12-22 11:34:34.000000000 -0800
@@ -2,7 +2,12 @@
  * Idle daemon for PowerPC.  Idle daemon will handle any action
  * that needs to be taken when the system becomes idle.
  *
- * Written by Cort Dougan (cort@cs.nmt.edu)
+ * Originally Written by Cort Dougan (cort@cs.nmt.edu)
+ *
+ * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com>
+ *
+ * Additional shared processor, SMT, and firmware support
+ *    Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -10,6 +15,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/config.h>
+#include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -28,17 +34,19 @@
 #include <asm/processor.h>
 #include <asm/mmu.h>
 #include <asm/cache.h>
+#include <asm/cputable.h>
 
 #include <asm/time.h>
 #include <asm/iSeries/LparData.h>
 #include <asm/iSeries/HvCall.h>
 #include <asm/iSeries/ItLpQueue.h>
 
+int (*idle_loop)(void);
+
 #ifdef CONFIG_PPC_ISERIES
 static void yield_shared_processor(void)
 {
 	struct paca_struct *lpaca = get_paca();
-	unsigned long tb;
 
 	HvCall_setEnabledInterrupts( HvCall_MaskIPI |
 				     HvCall_MaskLpEvent |
@@ -46,68 +54,180 @@
 				     HvCall_MaskTimeout );
 
 	if ( ! ItLpQueue_isLpIntPending( paca->lpQueuePtr ) ) {
-	  tb = get_tb();
-	  /* Compute future tb value when yield should expire */
-	  HvCall_yieldProcessor( HvCall_YieldTimed, tb+tb_ticks_per_jiffy );
+		/*
+		 * Compute future tb value when yield should expire.
+		 * We want to be woken up when the next decrementer is
+		 * to fire.
+		 */
 	  
-	  /* The decrementer stops during the yield.  Force a fake decrementer
-	   * here and let the timer_interrupt code sort out the actual time.
+		__cli();
+		lpaca->yielded = 1;        /* Indicate a prod is desired */
+		lpaca->xLpPaca.xIdle = 1;  /* Inform the HV we are idle  */
+
+		HvCall_yieldProcessor(HvCall_YieldTimed,
+				      lpaca->next_jiffy_update_tb);
+
+		lpaca->yielded = 0;        /* Back to IPI's */
+		__sti();
+
+		/*
+		 * The decrementer stops during the yield.  Force a fake
+		 * decrementer here and let the timer_interrupt code sort
+		 * out the actual time.
 	   */
 	  lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 1;
 	}
 	  
 	process_iSeries_events();
 }
-#endif /* CONFIG_PPC_ISERIES */
 
-int idled(void)
+int idle_iSeries(void)
 {
 	struct paca_struct *lpaca;
 	long oldval;
-#ifdef CONFIG_PPC_ISERIES
 	unsigned long CTRL;
-#endif
 
 	/* endless loop with no priority at all */
 	current->nice = 20;
 	current->counter = -100;
-#ifdef CONFIG_PPC_ISERIES
+
 	/* ensure iSeries run light will be out when idle */
 	current->thread.flags &= ~PPC_FLAG_RUN_LIGHT;
 	CTRL = mfspr(CTRLF);
 	CTRL &= ~RUNLATCH;
 	mtspr(CTRLT, CTRL);
-#endif
 	init_idle();	
 
 	lpaca = get_paca();
 
 	for (;;) {
-#ifdef CONFIG_PPC_ISERIES
 		if ( lpaca->xLpPaca.xSharedProc ) {
 			if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) )
 				process_iSeries_events();
 			if ( !current->need_resched )
 				yield_shared_processor();
-		}
-		else 
-#endif
-		{
+		} else {
 			/* Avoid an IPI by setting need_resched */
 			oldval = xchg(&current->need_resched, -1);
 			if (!oldval) {
 				while(current->need_resched == -1) {
-#ifdef CONFIG_PPC_ISERIES
 					HMT_medium();
 					if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) )
 						process_iSeries_events();
+					HMT_low();
+				}
+			}
+		}
+		HMT_medium();
+		if (current->need_resched) {
+			lpaca->xLpPaca.xIdle = 0;
+			schedule();
+			check_pgt_cache();
+		}
+	}
+	return 0;
+}
 #endif
+
+int idle_default(void)
+{
+	long oldval;
+
+	current->nice = 20;
+	current->counter = -100;
+	init_idle();
+
+	for (;;) {
+		/* Avoid an IPI by setting need_resched */
+		oldval = xchg(&current->need_resched, -1);
+		if (!oldval) {
+			while(current->need_resched == -1) {
 					HMT_low();
+			}
+		}
+		HMT_medium();
+		if (current->need_resched) {
+			schedule();
+			check_pgt_cache();
+		}
+	}
+	return 0;
+}
+
+int idle_dedicated(void)
+{
+	long oldval;
+	struct paca_struct *lpaca = get_paca(), *ppaca;;
+	unsigned long start_snooze;
+
+	ppaca = &paca[(lpaca->xPacaIndex) ^ 1];
+	current->nice = 20;
+	current->counter = -100;
+	init_idle();
+
+	for (;;) {
+		/* Indicate to the HV that we are idle.  Now would be
+		 * a good time to find other work to dispatch. */
+		lpaca->xLpPaca.xIdle = 1;
+
+		/* Avoid an IPI by setting need_resched */
+		oldval = xchg(&current->need_resched, -1);
+		if (!oldval) {
+			start_snooze = __get_tb();
+			while(current->need_resched == -1) {
+				if (__get_tb() <
+				    (start_snooze +
+				     naca->smt_snooze_delay*tb_ticks_per_usec)) {
+					HMT_low(); /* Low thread priority */
+					continue;
+				}
+
+				HMT_very_low(); /* Low power mode */
+
+				/* If the SMT mode is system controlled & the
+				 * partner thread is doing work, switch into
+				 * ST mode.
+				 */
+				if((naca->smt_state == SMT_DYNAMIC) &&
+				   (!(ppaca->xLpPaca.xIdle))) {
+					/* need_resched could be 1 or -1 at this
+					 * point.  If it is -1, set it to 0, so
+					 * an IPI/Prod is sent.  If it is 1, keep
+					 * it that way & schedule work.
+					 */
+					oldval = xchg(&current->need_resched, 0);
+					if(oldval == 1) {
+						current->need_resched = oldval;
+						break;
+					}
+
+					/* DRENG: Go HMT_medium here ? */
+					__cli();
+					lpaca->yielded = 1;
+
+					/* SMT dynamic mode.  Cede will result
+					 * in this thread going dormant, if the
+					 * partner thread is still doing work.
+					 * Thread wakes up if partner goes idle,
+					 * an interrupt is presented, or a prod
+					 * occurs.  Returning from the cede
+					 * enables external interrupts.
+					 */
+					cede_processor();
+
+					lpaca->yielded = 0;
+				} else {
+					/* Give the HV an opportunity at the
+					 * processor, since we are not doing
+					 * any work.
+					 */
+					poll_pending();
 				}
 			}
 		}
 		HMT_medium();
 		if (current->need_resched) {
+			lpaca->xLpPaca.xIdle = 0;
 			schedule();
 			check_pgt_cache();
 		}
@@ -115,12 +235,78 @@
 	return 0;
 }
 
+int idle_shared(void)
+{
+	struct paca_struct *lpaca = get_paca();
+
+	/* endless loop with no priority at all */
+	current->nice = 20;
+	current->counter = -100;
+
+	init_idle();
+
+	for (;;) {
+		/* Indicate to the HV that we are idle.  Now would be
+		 * a good time to find other work to dispatch. */
+		lpaca->xLpPaca.xIdle = 1;
+
+		if (!current->need_resched) {
+			__cli();
+			lpaca->yielded = 1;
+
 /*
- * SMP entry into the idle task - calls the same thing as the
- * non-smp versions. -- Cort
+			 * Yield the processor to the hypervisor.  We return if
+			 * an external interrupt occurs (which are driven prior
+			 * to returning here) or if a prod occurs from another
+			 * processor.  When returning here, external interrupts
+			 * are enabled.
  */
+			cede_processor();
+
+			lpaca->yielded = 0;
+		}
+
+		HMT_medium();
+		if (current->need_resched) {
+			lpaca->xLpPaca.xIdle = 0;
+			schedule();
+			check_pgt_cache();
+		}
+	}
+
+	return 0;
+}
+
 int cpu_idle(void)
 {
-	idled();
+	idle_loop();
 	return 0; 
 }
+
+int idle_setup(void)
+{
+#ifdef CONFIG_PPC_ISERIES
+	idle_loop = idle_iSeries;
+#else
+	if (systemcfg->platform & PLATFORM_PSERIES) {
+		if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
+			if(get_paca()->xLpPaca.xSharedProc) {
+				printk("idle = idle_shared\n");
+				idle_loop = idle_shared;
+			} else {
+				printk("idle = idle_dedicated\n");
+				idle_loop = idle_dedicated;
+			}
+		} else {
+			printk("idle = idle_default\n");
+			idle_loop = idle_default;
+		}
+	} else {
+		printk("idle_setup: unknown platform, use idle_default\n");
+		idle_loop = idle_default;
+	}
+#endif
+
+	return 1;
+}
+
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/ioctl32.c linux-2.4.24-pre2/arch/ppc64/kernel/ioctl32.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/ioctl32.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/ioctl32.c	2003-12-22 11:34:34.000000000 -0800
@@ -566,11 +566,52 @@
 		goto out;
 	}
 	switch (ethcmd) {
-	case ETHTOOL_GDRVINFO:	len = sizeof(struct ethtool_drvinfo); break;
+	case ETHTOOL_GSTRINGS:	{
+		struct ethtool_gstrings *stringsaddr = (struct ethtool_gstrings *)A(data);
+		if (get_user(len, (u32 *)&stringsaddr->len)) {
+			err = -EFAULT;
+			goto out;
+		}
+		if (len > (PAGE_SIZE - sizeof(struct ethtool_gstrings))/ETH_GSTRING_LEN ) {
+			err = -EINVAL;
+			goto out;
+		}
+		len = (len*ETH_GSTRING_LEN) + sizeof(struct ethtool_gstrings);
+		break;
+	}
+	case ETHTOOL_GSTATS:	{
+		struct ethtool_stats *statsaddr = (struct ethtool_stats *)A(data);
+		if (get_user(len, (u32 *)&statsaddr->n_stats)) {
+			err = -EFAULT;
+			goto out;
+		}
+		if (len > (PAGE_SIZE - sizeof(struct ethtool_stats))/sizeof(u64) ) {
+			err = -EINVAL;
+			goto out;
+		}
+		len = (len*sizeof(u64)) + sizeof(struct ethtool_stats);
+		break;
+	}
+	case ETHTOOL_SWOL:
+	case ETHTOOL_GWOL:
+		len = sizeof(struct ethtool_wolinfo);
+		break;
+	case ETHTOOL_GDRVINFO:
+		len = sizeof(struct ethtool_drvinfo);
+		break;
 	case ETHTOOL_GMSGLVL:
 	case ETHTOOL_SMSGLVL:
 	case ETHTOOL_GLINK:
-	case ETHTOOL_NWAY_RST:	len = sizeof(struct ethtool_value); break;
+	case ETHTOOL_NWAY_RST:
+	case ETHTOOL_SSG:
+	case ETHTOOL_GSG:
+	case ETHTOOL_GTXCSUM:
+	case ETHTOOL_STXCSUM:
+	case ETHTOOL_GRXCSUM:
+	case ETHTOOL_SRXCSUM:
+	case ETHTOOL_PHYS_ID:
+		len = sizeof(struct ethtool_value);
+		break;
 	case ETHTOOL_GREGS: {
 		struct ethtool_regs *regaddr = (struct ethtool_regs *)A(data);
 		/* darned variable size arguments */
@@ -578,22 +619,44 @@
 			err = -EFAULT;
 			goto out;
 		}
+		if (len > PAGE_SIZE - sizeof(struct ethtool_regs)) {
+			err = -EINVAL;
+			goto out;
+		}
 		len += sizeof(struct ethtool_regs);
 		break;
 	}
-	case ETHTOOL_GEEPROM: 
-	case ETHTOOL_SEEPROM: { 
-		struct ethtool_eeprom *promaddr = (struct ethtool_eeprom *)A(data); 
-		/* darned variable size arguments */ 
-		if (get_user(len, (u32 *)&promaddr->len)) { 
-			err = -EFAULT; 
-			goto out; 
-		} 
-		len += sizeof(struct ethtool_eeprom); 
-		break; 
-	} 
+	case ETHTOOL_GEEPROM:
+	case ETHTOOL_SEEPROM: {
+		struct ethtool_eeprom *promaddr = (struct ethtool_eeprom *)A(data);
+		/* darned variable size arguments */
+		if (get_user(len, (u32 *)&promaddr->len)) {
+			err = -EFAULT;
+			goto out;
+		}
+		if (len > PAGE_SIZE - sizeof(struct ethtool_eeprom)) {
+			err = -EINVAL;
+			goto out;
+		}
+		len += sizeof(struct ethtool_eeprom);
+		break;
+	}
+	case ETHTOOL_GRINGPARAM:
+	case ETHTOOL_SRINGPARAM:
+		len = sizeof(struct ethtool_ringparam);
+		break;
+	case ETHTOOL_GPAUSEPARAM:
+	case ETHTOOL_SPAUSEPARAM:
+		len = sizeof(struct ethtool_pauseparam);
+		break;
+	case ETHTOOL_GCOALESCE:
+	case ETHTOOL_SCOALESCE:
+		len = sizeof(struct ethtool_coalesce);
+		break;
 	case ETHTOOL_GSET:
-	case ETHTOOL_SSET:	len = sizeof(struct ethtool_cmd); break;
+	case ETHTOOL_SSET:
+		len = sizeof(struct ethtool_cmd);
+		break;
 	default:
 		err = -EOPNOTSUPP;
 		goto out;
@@ -1238,12 +1301,16 @@
 	u32 iov_len;
 } sg_iovec32_t;
 
+#define EMU_SG_MAX 128
+
 static int alloc_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
 {
 	sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
 	sg_iovec_t *kiov;
 	int i;
 
+	if (sgp->iovec_count > EMU_SG_MAX)
+		return -EINVAL;
 	sgp->dxferp = kmalloc(sgp->iovec_count *
 			      sizeof(sg_iovec_t), GFP_KERNEL);
 	if (!sgp->dxferp)
@@ -1257,39 +1324,9 @@
 		if (__get_user(iov_base32, &uiov->iov_base) ||
 		    __get_user(kiov->iov_len, &uiov->iov_len))
 			return -EFAULT;
-
-		kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL);
-		if (!kiov->iov_base)
-			return -ENOMEM;
-		if (copy_from_user(kiov->iov_base,
-				   (void *) A(iov_base32),
-				   kiov->iov_len))
+		if (verify_area(VERIFY_WRITE, (void *)A(iov_base32), kiov->iov_len))
 			return -EFAULT;
-
-		uiov++;
-		kiov++;
-	}
-
-	return 0;
-}
-
-static int copy_back_sg_iovec(sg_io_hdr_t *sgp, u32 uptr32)
-{
-	sg_iovec32_t *uiov = (sg_iovec32_t *) A(uptr32);
-	sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
-	int i;
-
-	for (i = 0; i < sgp->iovec_count; i++) {
-		u32 iov_base32;
-
-		if (__get_user(iov_base32, &uiov->iov_base))
-			return -EFAULT;
-
-		if (copy_to_user((void *) A(iov_base32),
-				 kiov->iov_base,
-				 kiov->iov_len))
-			return -EFAULT;
-
+		kiov->iov_base = (void *)A(iov_base32);
 		uiov++;
 		kiov++;
 	}
@@ -1299,16 +1336,6 @@
 
 static void free_sg_iovec(sg_io_hdr_t *sgp)
 {
-	sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
-	int i;
-
-	for (i = 0; i < sgp->iovec_count; i++) {
-		if (kiov->iov_base) {
-			kfree(kiov->iov_base);
-			kiov->iov_base = NULL;
-		}
-		kiov++;
-	}
 	kfree(sgp->dxferp);
 	sgp->dxferp = NULL;
 }
@@ -1337,6 +1364,10 @@
 	sg_io64.sbp = NULL;
 
 	err |= __get_user(cmdp32, &sg_io32->cmdp);
+	if (sg_io64.cmd_len > 4*PAGE_SIZE || sg_io64.mx_sb_len > 4*PAGE_SIZE) {
+		err = -EINVAL;
+		goto out;
+	}
 	sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);
 	if (!sg_io64.cmdp) {
 		err = -ENOMEM;
@@ -1371,6 +1402,10 @@
 			goto out;
 		}
 	} else {
+		if (sg_io64.dxfer_len > 4*PAGE_SIZE) {
+			err = -EINVAL;
+			goto out;
+		}
 		sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);
 		if (!sg_io64.dxferp) {
 			err = -ENOMEM;
@@ -1411,7 +1446,7 @@
 	err |= copy_to_user((void *)A(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);
 	if (sg_io64.dxferp) {
 		if (sg_io64.iovec_count)
-			err |= copy_back_sg_iovec(&sg_io64, dxferp32);
+			;
 		else
 			err |= copy_to_user((void *)A(dxferp32),
 					    sg_io64.dxferp,
@@ -1467,6 +1502,8 @@
 	case PPPIOCSCOMPRESS32:
 		if (copy_from_user(&data32, (struct ppp_option_data32 *)arg, sizeof(struct ppp_option_data32)))
 			return -EFAULT;
+		if (data32.length > PAGE_SIZE)
+			return -EINVAL;
 		data.ptr = kmalloc (data32.length, GFP_KERNEL);
 		if (!data.ptr)
 			return -ENOMEM;
@@ -1669,10 +1706,9 @@
 		err |= __get_user(addr, &((struct cdrom_read_audio32 *)arg)->buf);
 		if (err)
 			return -EFAULT;
-		data = kmalloc(cdreadaudio.nframes * 2352, GFP_KERNEL);
-		if (!data)
-			return -ENOMEM;
-		cdreadaudio.buf = data;
+		if (verify_area(VERIFY_WRITE, (void *)A(addr), cdreadaudio.nframes*2352))
+			return -EFAULT;
+		cdreadaudio.buf = (void *)A(addr);
 		break;
 	case CDROM_SEND_PACKET:
 		karg = &cgc;
@@ -1681,9 +1717,9 @@
 		err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
 		if (err)
 			return -EFAULT;
-		if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)
-			return -ENOMEM;
-		cgc.buffer = data;
+		if (verify_area(VERIFY_WRITE, (void *)A(addr), cgc.buflen))
+			return -EFAULT;
+		cgc.buffer = (void *)A(addr);
 		break;
 	default:
 		do {
@@ -1698,18 +1734,6 @@
 	set_fs (KERNEL_DS);
 	err = sys_ioctl (fd, cmd, (unsigned long)karg);
 	set_fs (old_fs);
-	if (err)
-		goto out;
-	switch (cmd) {
-	case CDROMREADAUDIO:
-		err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);
-		break;
-	case CDROM_SEND_PACKET:
-		err = copy_to_user((char *)A(addr), data, cgc.buflen);
-		break;
-	default:
-		break;
-	}
 out:	if (data)
 		kfree(data);
 	return err ? -EFAULT : 0;
@@ -2126,37 +2150,16 @@
 	if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) {
 		iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
 	} else {
-		iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL);
-		if (iobuf.buffer == NULL) {
-			err = -ENOMEM;
-			goto out;
-		}
-
-		err = copy_from_user(iobuf.buffer, (void *)A(iobuf32.buffer), iobuf.length);
-		if (err) {
-			err = -EFAULT;
-			goto out;
-		}
+		iobuf.buffer = A(iobuf32.buffer);
+		if (verify_area(VERIFY_WRITE, iobuf.buffer, iobuf.length))
+			return -EINVAL;
 	}
 
 	old_fs = get_fs(); set_fs (KERNEL_DS);
-	err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);      
+	err = sys_ioctl (fd, cmd, (unsigned long)&iobuf);
 	set_fs (old_fs);
-        if (err)
-		goto out;
-
-        if (iobuf.buffer && iobuf.length > 0) {
-		err = copy_to_user((void *)A(iobuf32.buffer), iobuf.buffer, iobuf.length);
-		if (err) {
-			err = -EFAULT;
-			goto out;
-		}
-	}
-	err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
-
- out:
-        if (iobuf32.buffer && iobuf32.length > 0)
-		kfree(iobuf.buffer);
+	if (!err)
+		err = __put_user(iobuf.length, &(((struct atm_iobuf32*)arg)->length));
 
 	return err;
 }
@@ -2179,40 +2182,19 @@
         
 	if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) {
 		sioc.arg = (void*)(unsigned long)sioc32.arg;
-        } else {
-                sioc.arg = kmalloc(sioc.length, GFP_KERNEL);
-                if (sioc.arg == NULL) {
-                        err = -ENOMEM;
-			goto out;
-		}
-                
-                err = copy_from_user(sioc.arg, (void *)A(sioc32.arg), sioc32.length);
-                if (err) {
-                        err = -EFAULT;
-                        goto out;
-                }
-        }
-        
-        old_fs = get_fs(); set_fs (KERNEL_DS);
-        err = sys_ioctl (fd, cmd, (unsigned long)&sioc);	
-        set_fs (old_fs);
-        if (err) {
-                goto out;
+	} else {
+		sioc.arg = A(sioc32.arg);
+		if (verify_area(VERIFY_WRITE, sioc.arg, sioc32.length))
+			return -EFAULT;
 	}
-        
-        if (sioc.arg && sioc.length > 0) {
-                err = copy_to_user((void *)A(sioc32.arg), sioc.arg, sioc.length);
-                if (err) {
-                        err = -EFAULT;
-                        goto out;
-                }
-        }
-        err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
-        
- out:
-        if (sioc32.arg && sioc32.length > 0)
-		kfree(sioc.arg);
-        
+
+	old_fs = get_fs(); set_fs (KERNEL_DS);
+	err = sys_ioctl (fd, cmd, (unsigned long)&sioc);
+	set_fs (old_fs);
+
+	if (!err)
+		err = __put_user(sioc.length, &(((struct atmif_sioc32*)arg)->length));
+
 	return err;
 }
 
@@ -2428,12 +2410,24 @@
 		return NULL;
 	}
 	if (ptr1) {
+		if (l->lv_allocated_le > 2*PAGE_SIZE/sizeof(pe_t)) {
+			kfree(l);
+			*errp = -EINVAL;
+			return NULL;
+		}
 		size = l->lv_allocated_le * sizeof(pe_t);
 		l->lv_current_pe = vmalloc(size);
 		if (l->lv_current_pe)
 			err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size);
 	}
 	if (!err && ptr2) {
+		/* small limit */
+		/* just verify area it? */
+		if (l->lv_remap_end > 256*PAGE_SIZE/sizeof(lv_block_exception_t)) {
+			put_lv_t(l);
+			*errp = -EINVAL;
+			return NULL;
+		}
 		size = l->lv_remap_end * sizeof(lv_block_exception_t);
 		l->lv_block_exception = lbe = vmalloc(size);
 		if (l->lv_block_exception) {
@@ -3597,17 +3591,11 @@
 		goto out;
 	uptr = (void *) A(udata);
 
-	err = -ENOMEM;
 	buflen = kurb->buffer_length;
-	kptr = kmalloc(buflen, GFP_KERNEL);
-	if (!kptr)
-		goto out;
-
-	kurb->buffer = kptr;
 
-	err = -EFAULT;
-	if (copy_from_user(kptr, uptr, buflen))
-		goto out_kptr;
+	err = verify_area(VERIFY_WRITE, uptr, buflen);
+	if (err)
+		goto out;
 
 	old_fs = get_fs();
 	set_fs(KERNEL_DS);
@@ -3618,15 +3606,9 @@
 		/* XXX Shit, this doesn't work for async URBs :-( XXX */
 		if (put_urb32(kurb, uurb)) {
 			err = -EFAULT;
-		} else if ((kurb->endpoint & USB_DIR_IN) != 0) {
-			if (copy_to_user(uptr, kptr, buflen))
-				err = -EFAULT;
 		}
 	}
 
-out_kptr:
-	kfree(kptr);
-
 out:
 	kfree(kurb);
 	return err;
@@ -3698,14 +3680,13 @@
 #define MEMWRITEOOB32 	_IOWR('M',3,struct mtd_oob_buf32)
 #define MEMREADOOB32 	_IOWR('M',4,struct mtd_oob_buf32)
 
-static inline int 
+static inline int
 mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
 	mm_segment_t 			old_fs 	= get_fs();
 	struct mtd_oob_buf32	*uarg 	= (struct mtd_oob_buf32 *)arg;
 	struct mtd_oob_buf		karg;
 	u32 tmp;
-	char *ptr;
 	int ret;
 
 	if (get_user(karg.start, &uarg->start) 		||
@@ -3713,21 +3694,12 @@
 	    get_user(tmp, &uarg->ptr))
 		return -EFAULT;
 
-	ptr = (char *)A(tmp);
-	if (0 >= karg.length) 
-		return -EINVAL;
-
-	karg.ptr = kmalloc(karg.length, GFP_KERNEL);
-	if (NULL == karg.ptr)
-		return -ENOMEM;
-
-	if (copy_from_user(karg.ptr, ptr, karg.length)) {
-		kfree(karg.ptr);
+	karg.ptr = A(tmp);
+	if (verify_area(VERIFY_WRITE, karg.ptr, karg.length))
 		return -EFAULT;
-	}
 
 	set_fs(KERNEL_DS);
-	if (MEMREADOOB32 == cmd) 
+	if (MEMREADOOB32 == cmd)
 		ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg);
 	else if (MEMWRITEOOB32 == cmd)
 		ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg);
@@ -3736,14 +3708,12 @@
 	set_fs(old_fs);
 
 	if (0 == ret && cmd == MEMREADOOB32) {
-		ret = copy_to_user(ptr, karg.ptr, karg.length);
-		ret |= put_user(karg.start, &uarg->start);
+		ret = put_user(karg.start, &uarg->start);
 		ret |= put_user(karg.length, &uarg->length);
 	}
 
-	kfree(karg.ptr);
-	return ((0 == ret) ? 0 : -EFAULT);
-}	
+	return ret;
+}
 
 /* Fix sizeof(sizeof()) breakage */
 #define BLKELVGET_32	_IOR(0x12,106,int)
@@ -3801,6 +3771,7 @@
 COMPATIBLE_IOCTL(TCSETAW),
 COMPATIBLE_IOCTL(TCSETAF),
 COMPATIBLE_IOCTL(TCSBRK),
+COMPATIBLE_IOCTL(TCSBRKP),
 COMPATIBLE_IOCTL(TCXONC),
 COMPATIBLE_IOCTL(TCFLSH),
 COMPATIBLE_IOCTL(TCGETS),
@@ -3836,6 +3807,8 @@
 COMPATIBLE_IOCTL(TIOCSSERIAL),
 COMPATIBLE_IOCTL(TIOCSERGETLSR),
 COMPATIBLE_IOCTL(TIOCSLTC),
+COMPATIBLE_IOCTL(TIOCMIWAIT),
+COMPATIBLE_IOCTL(TIOCGICOUNT),
 /* Big F */
 COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO),
 COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO),
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/irq.c linux-2.4.24-pre2/arch/ppc64/kernel/irq.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/irq.c	2002-11-28 15:53:11.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/kernel/irq.c	2003-12-22 11:34:34.000000000 -0800
@@ -41,6 +41,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/random.h>
+#include <linux/bootmem.h>
 
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
@@ -56,8 +57,47 @@
 #include <asm/paca.h>
 #include <asm/perfmon.h>
 
-#include "local_irq.h"
+/*
+ * Because the name space for interrupts is so large on ppc64 systems we
+ * avoid declaring a single array of "NR_IRQ" interrupts and instead build
+ * a three level tree leading to the irq_desc_t (similar to page tables).
+ *
+ * Currently we cover 24-bit irq values:
+ *    10-bits:  the "base" dir (2-pages)
+ *     9-bits:  the "middle" dir (1-page)
+ *     5-bits:  the "bottom" page (1-page) holding 128byte irq_desc's.
+ *
+ * We pack a hw_irq_stat struct directly after the irq_desc in the otherwise
+ * wasted space of the cacheline.
+ *
+ * MAX_IRQS is the max this implementation will support.
+ * It is much larger than NR_IRQS which is bogus on this arch and often used
+ * to declare arrays.
+ *
+ * Note that all "undefined" mid table and bottom table pointers will point
+ * to dummy tables.  Therefore, we don't need to check for NULL on spurious
+ * interrupts.
+ */
+
+#define IRQ_BASE_INDEX_SIZE  10
+#define IRQ_MID_INDEX_SIZE  9
+#define IRQ_BOT_DESC_SIZE 5
+
+#define IRQ_BASE_PTRS	(1 << IRQ_BASE_INDEX_SIZE)
+#define IRQ_MID_PTRS	(1 << IRQ_MID_INDEX_SIZE)
+#define IRQ_BOT_DESCS (1 << IRQ_BOT_DESC_SIZE)
+
+#define IRQ_BASE_IDX_SHIFT (IRQ_MID_INDEX_SIZE + IRQ_BOT_DESC_SIZE)
+#define IRQ_MID_IDX_SHIFT (IRQ_BOT_DESC_SIZE)
 
+#define IRQ_MID_IDX_MASK  ((1 << IRQ_MID_INDEX_SIZE) - 1)
+#define IRQ_BOT_IDX_MASK  ((1 << IRQ_BOT_DESC_SIZE) - 1)
+
+irq_desc_t **irq_desc_base_dir[IRQ_BASE_PTRS] __page_aligned = {0};
+irq_desc_t **irq_desc_mid_null;
+irq_desc_t *irq_desc_bot_null;
+
+unsigned int _next_irq(unsigned int irq);
 atomic_t ipi_recv;
 atomic_t ipi_sent;
 void enable_irq(unsigned int irq_nr);
@@ -72,9 +112,10 @@
 
 irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
 	{ [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}};
-	
+
+static irq_desc_t *add_irq_desc(unsigned int irq);
+
 int ppc_spurious_interrupts = 0;
-struct irqaction *ppc_irq_action[NR_IRQS];
 unsigned long lpEvent_count = 0;
 #ifdef CONFIG_XMON
 extern void xmon(struct pt_regs *regs);
@@ -93,16 +134,200 @@
 extern void (*debugger_fault_handler)(struct pt_regs *regs);
 #endif
 
-/* nasty hack for shared irq's since we need to do kmalloc calls but
- * can't very early in the boot when we need to do a request irq.
- * this needs to be removed.
- * -- Cort
- */
 #define IRQ_KMALLOC_ENTRIES 16
 static int cache_bitmask = 0;
 static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES];
 extern int mem_init_done;
 
+/* The hw_irq_stat struct is stored directly after the irq_desc_t
+ * in the same cacheline.  We need to use care to make sure we don't
+ * overrun the size of the cacheline.
+ *
+ * Currently sizeof(irq_desc_t) is 40 bytes or less and this hw_irq_stat
+ * fills the rest of the cache line.
+ */
+struct hw_irq_stat {
+	unsigned long irqs;		/* statistic per irq */
+	unsigned long *per_cpu_stats;
+	struct proc_dir_entry *irq_dir, *smp_affinity;
+	unsigned long irq_affinity;	/* ToDo: cpu bitmask */
+};
+
+static inline struct hw_irq_stat *get_irq_stat(irq_desc_t *desc)
+{
+	/* WARNING: this assumes lock is the last field! */
+	return (struct hw_irq_stat *)(&desc->lock+1);
+}
+
+static inline unsigned long *get_irq_per_cpu(struct hw_irq_stat *hw)
+{
+	return hw->per_cpu_stats;
+}
+
+static inline irq_desc_t **get_irq_mid_table(unsigned int irq)
+{
+	/* Assume irq < MAX_IRQS so we won't index off the end. */
+	return irq_desc_base_dir[irq >> IRQ_BASE_IDX_SHIFT];
+}
+
+static inline irq_desc_t *get_irq_bot_table(unsigned int irq,
+					    irq_desc_t **mid_ptr)
+{
+	return mid_ptr[(irq >> IRQ_MID_IDX_SHIFT) & IRQ_MID_IDX_MASK];
+}
+
+/* This should be inline. */
+void *_irqdesc(unsigned int irq)
+{
+	irq_desc_t **mid_table, *bot_table, *desc;
+
+	mid_table = get_irq_mid_table(irq);
+	bot_table = get_irq_bot_table(irq, mid_table);
+
+	desc = bot_table + (irq & IRQ_BOT_IDX_MASK);
+	return desc;
+}
+
+/*
+ * This is used by the for_each_irq(i) macro to iterate quickly over
+ * all interrupts.  It optimizes by skipping over ptrs to the null tables
+ * when possible, but it may produce false positives.
+ */
+unsigned int _next_irq(unsigned int irq)
+{
+	irq_desc_t **mid_table, *bot_table;
+
+	irq++;
+	/* Easy case first...staying on the current bot_table. */
+	if (irq & IRQ_BOT_IDX_MASK)
+		return irq;
+
+	/* Now skip empty mid tables */
+	while (irq < MAX_IRQS &&
+	       (mid_table = get_irq_mid_table(irq)) == irq_desc_mid_null) {
+		/* index to the next base index (i.e. the next mid table) */
+		irq = (irq & ~(IRQ_BASE_IDX_SHIFT-1)) + IRQ_BASE_IDX_SHIFT;
+	}
+	/* And skip empty bot tables */
+	while (irq < MAX_IRQS &&
+	       (bot_table = get_irq_bot_table(irq, mid_table)) == irq_desc_bot_null) {
+		/* index to the next mid index (i.e. the next bot table) */
+		irq = (irq & ~(IRQ_MID_IDX_SHIFT-1)) + IRQ_MID_IDX_SHIFT;
+	}
+	return irq;
+}
+
+
+/* Same as irqdesc(irq) except it will "fault in" a real desc as needed
+ * rather than return the null entry.
+ * This is used by code that is actually defining the irq.
+ *
+ * NULL may be returned on memory allocation failure.  In general, init code
+ * doesn't look for this, but setup_irq does.  In this failure case the desc
+ * is left pointing at the null pages so callers of irqdesc() should
+ * always return something.
+ */
+void *_real_irqdesc(unsigned int irq)
+{
+	irq_desc_t *desc = irqdesc(irq);
+	if (((unsigned long)desc & PAGE_MASK) ==
+	    (unsigned long)irq_desc_bot_null) {
+		desc = add_irq_desc(irq);
+	}
+	return desc;
+}
+
+/* Allocate an irq middle page and init entries to null page. */
+static irq_desc_t **alloc_irq_mid_page(void)
+{
+	irq_desc_t **m, **ent;
+
+	if (mem_init_done)
+		m = (irq_desc_t **)__get_free_page(GFP_KERNEL);
+	else
+		m = (irq_desc_t **)alloc_bootmem_pages(PAGE_SIZE);
+	if (m) {
+		for (ent = m; ent < m + IRQ_MID_PTRS; ent++) {
+			*ent = irq_desc_bot_null;
+		}
+	}
+	return m;
+}
+
+/* Allocate an irq bottom page and init the entries. */
+static irq_desc_t *alloc_irq_bot_page(void)
+{
+	irq_desc_t *b, *ent;
+	if (mem_init_done)
+		b = (irq_desc_t *)get_zeroed_page(GFP_KERNEL);
+	else
+		b = (irq_desc_t *)alloc_bootmem_pages(PAGE_SIZE);
+	if (b) {
+		for (ent = b; ent < b + IRQ_BOT_DESCS; ent++) {
+			ent->lock = SPIN_LOCK_UNLOCKED;
+		}
+	}
+	return b;
+}
+
+/*
+ * The universe of interrupt numbers ranges from 0 to 2^24.
+ * Use a sparsely populated tree to map from the irq to the handler.
+ * Top level is 2 contiguous pages, covering the 10 most significant
+ * bits.  Mid level is 1 page, covering 9 bits.  Last page covering
+ * 5 bits is the irq_desc, each of which is 128B.
+ */
+static void irq_desc_init(void) {
+	irq_desc_t ***entry_p;
+
+	/*
+	 * Now initialize the tables to point though the NULL tables for
+	 * the default case of no interrupt handler (spurious).
+	 */
+	irq_desc_bot_null = alloc_irq_bot_page();
+	irq_desc_mid_null = alloc_irq_mid_page();
+	if (!irq_desc_bot_null || !irq_desc_mid_null)
+		panic("irq_desc_init: could not allocate pages\n");
+	for(entry_p = irq_desc_base_dir;
+	    entry_p < irq_desc_base_dir + IRQ_BASE_PTRS;
+	    entry_p++) {
+		*entry_p = irq_desc_mid_null;
+	}
+}
+
+/*
+ * Add a new irq desc for the given irq if needed.
+ * This breaks any ptr to the "null" middle or "bottom" irq desc page.
+ * Note that we don't ever coalesce pages as the interrupts are released.
+ * This isn't worth the effort.  We add the cpu stats info when the
+ * interrupt is actually requested.
+ *
+ * May return NULL if memory could not be allocated.
+ */
+static irq_desc_t *add_irq_desc(unsigned int irq)
+{
+	irq_desc_t **mid_table_p, *bot_table_p;
+
+	mid_table_p = get_irq_mid_table(irq);
+	if(mid_table_p == irq_desc_mid_null) {
+		/* No mid table for this IRQ - create it */
+		mid_table_p = alloc_irq_mid_page();
+		if (!mid_table_p) return NULL;
+		irq_desc_base_dir[irq >> IRQ_BASE_IDX_SHIFT] = mid_table_p;
+	}
+
+	bot_table_p = (irq_desc_t *)(*(mid_table_p + ((irq >> 5) & 0x1ff)));
+
+	if(bot_table_p == irq_desc_bot_null) {
+		/* No bot table for this IRQ - create it */
+		bot_table_p = alloc_irq_bot_page();
+		if (!bot_table_p) return NULL;
+		mid_table_p[(irq >> IRQ_MID_IDX_SHIFT) & IRQ_MID_IDX_MASK] = bot_table_p;
+	}
+
+	return bot_table_p + (irq & IRQ_BOT_IDX_MASK);
+}
+
 void *irq_kmalloc(size_t size, int pri)
 {
 	unsigned int i;
@@ -127,13 +352,44 @@
 	kfree(ptr);
 }
 
+void allocate_per_cpu_stats(struct hw_irq_stat *hwstat)
+{
+	unsigned long *p;
+
+	if (mem_init_done) {
+		p = (unsigned long *)kmalloc(sizeof(long)*NR_CPUS, GFP_KERNEL);
+		if (p) memset(p, 0, sizeof(long)*NR_CPUS);
+	} else
+		p = (unsigned long *)alloc_bootmem(sizeof(long)*NR_CPUS);
+	hwstat->per_cpu_stats = p;
+}
+
 int
 setup_irq(unsigned int irq, struct irqaction * new)
 {
 	int shared = 0;
 	unsigned long flags;
 	struct irqaction *old, **p;
-	irq_desc_t *desc = irq_desc + irq;
+	irq_desc_t *desc = real_irqdesc(irq);
+	struct hw_irq_stat *hwstat;
+
+	if (!desc)
+		return -ENOMEM;
+
+	ppc_md.init_irq_desc(desc);
+
+	hwstat = get_irq_stat(desc);
+
+#ifdef CONFIG_IRQ_ALL_CPUS
+	hwstat->irq_affinity = ~0;
+#else
+	hwstat->irq_affinity = 0;
+#endif
+
+	/* Now is the time to add per-cpu kstat data to the desc
+	 * since it appears we are actually going to use the irq.
+	 */
+	allocate_per_cpu_stats(hwstat);
 
 	/*
 	 * Some drivers like serial.c use request_irq() heavily,
@@ -189,11 +445,10 @@
 static int
 do_free_irq(int irq, void* dev_id)
 {
-	irq_desc_t *desc;
+	irq_desc_t *desc = irqdesc(irq);
 	struct irqaction **p;
 	unsigned long flags;
 
-	desc = irq_desc + irq;
 	spin_lock_irqsave(&desc->lock,flags);
 	p = &desc->action;
 	for (;;) {
@@ -233,8 +488,9 @@
 	struct irqaction *action;
 	int retval;
 
-	if (irq >= NR_IRQS)
+	if (irq >= MAX_IRQS)
 		return -EINVAL;
+
 	if (!handler)
 		/* We could implement really free_irq() instead of that... */
 		return do_free_irq(irq, dev_id);
@@ -285,7 +541,7 @@
  
  void disable_irq_nosync(unsigned int irq)
 {
-	irq_desc_t *desc = irq_desc + irq;
+	irq_desc_t *desc = irqdesc(irq);
 	unsigned long flags;
 
 	spin_lock_irqsave(&desc->lock, flags);
@@ -317,7 +573,7 @@
 	if (!local_irq_count(smp_processor_id())) {
 		do {
 			barrier();
-		} while (irq_desc[irq].status & IRQ_INPROGRESS);
+		} while (irqdesc(irq)->status & IRQ_INPROGRESS);
 	}
 }
 
@@ -333,7 +589,7 @@
  
 void enable_irq(unsigned int irq)
 {
-	irq_desc_t *desc = irq_desc + irq;
+	irq_desc_t *desc = irqdesc(irq);
 	unsigned long flags;
 
 	spin_lock_irqsave(&desc->lock, flags);
@@ -357,82 +613,57 @@
 	spin_unlock_irqrestore(&desc->lock, flags);
 }
 
-/* one would think this function has one foot in the grave */
+/* This function as implemented was a potential source of data
+ * corruption.  I pulled it for now, until it can be properly
+ * implemented. DRENG
+ */
 int get_irq_list(char *buf)
 {
-   int i, len = 0, j;
-   struct irqaction * action;
-
-   len += sprintf(buf+len, "           ");
-   for (j=0; j<smp_num_cpus; j++)
-       len += sprintf(buf+len, "CPU%d       ",j);
-   *(char *)(buf+len++) = '\n';
-
-   for (i = 0 ; i < NR_IRQS ; i++) {
-       action = irq_desc[i].action;
-       if ( !action || !action->handler )
-           continue;
-       len += sprintf(buf+len, "%3d: ", i);
-#ifdef CONFIG_SMP
-       for (j = 0; j < smp_num_cpus; j++)
-           len += sprintf(buf+len, "%10u ",
-               kstat.irqs[cpu_logical_map(j)][i]);
-#else
-       len += sprintf(buf+len, "%10u ", kstat_irqs(i));
-#endif /* CONFIG_SMP */
-if ( irq_desc[i].handler )
-len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename );
-else
-len += sprintf(buf+len, "  None      ");
-len += sprintf(buf+len, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
-len += sprintf(buf+len, "    %s",action->name);
-for (action=action->next; action; action = action->next) {
-len += sprintf(buf+len, ", %s", action->name);
-}
-len += sprintf(buf+len, "\n");
+	return(0);
 }
-#ifdef CONFIG_SMP
-/* should this be per processor send/receive? */
-len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n",
-atomic_read(&ipi_recv), atomic_read(&ipi_sent));
-#endif
-len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts);
-return len;
-}
-
-
 
 int show_interrupts(struct seq_file *p, void *v)
 {
 	int i, j;
 	struct irqaction * action;
+	irq_desc_t *desc;
+	struct hw_irq_stat *hwstat;
+	unsigned long *per_cpus;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<smp_num_cpus; j++)
 		seq_printf(p, "CPU%d       ",j);
 	seq_putc(p, '\n');
 
-	for (i = 0 ; i < NR_IRQS ; i++) {
-		action = irq_desc[i].action;
+	for_each_irq(i) {
+		desc = irqdesc(i);
+		spin_lock_irqsave(&desc->lock, flags);
+		action = desc->action;
+
 		if (!action || !action->handler)
-			continue;
-		seq_printf(p, "%3d: ", i);		
-#ifdef CONFIG_SMP
+			goto skip;
+		seq_printf(p, "%3d: ", i);
+		hwstat = get_irq_stat(desc);
+		per_cpus = get_irq_per_cpu(hwstat);
+		if (per_cpus) {
 		for (j = 0; j < smp_num_cpus; j++)
-			seq_printf(p, "%10u ",
-				kstat.irqs[cpu_logical_map(j)][i]);
-#else		
-		seq_printf(p, "%10u ", kstat_irqs(i));
-#endif /* CONFIG_SMP */
-		if (irq_desc[i].handler)		
-			seq_printf(p, " %s ", irq_desc[i].handler->typename );
+				seq_printf(p, "%10lu ", per_cpus[j]);
+		} else {
+			seq_printf(p, "%10lu ", hwstat->irqs);
+		}
+
+		if (irqdesc(i)->handler)
+			seq_printf(p, " %s ", irqdesc(i)->handler->typename );
 		else
 			seq_printf(p, "  None      ");
-		seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
+		seq_printf(p, "%s", (irqdesc(i)->status & IRQ_LEVEL) ? "Level " : "Edge  ");
 		seq_printf(p, "    %s",action->name);
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&desc->lock, flags);
 	}
 #ifdef CONFIG_SMP
 	/* should this be per processor send/receive? */
@@ -470,9 +701,24 @@
 	int status;
 	struct irqaction *action;
 	int cpu = smp_processor_id();
-	irq_desc_t *desc = irq_desc + irq;
+	irq_desc_t *desc = irqdesc(irq);
+	struct hw_irq_stat *hwstat;
+	unsigned long *per_cpus;
+
+	/* Statistics. */
+	hwstat = get_irq_stat(desc);	/* same cache line as desc */
+	hwstat->irqs++;
+	per_cpus = get_irq_per_cpu(hwstat); /* same cache line for < 8 cpus */
+	if (per_cpus)
+		per_cpus[cpu]++;
 
+	if(irq < NR_IRQS) {
 	kstat.irqs[cpu][irq]++;
+	} else {
+		kstat.irqs[cpu][NR_IRQS-1]++;
+	}
+
+
 	spin_lock(&desc->lock);
 	ack_irq(irq);	
 	/*
@@ -544,11 +790,11 @@
 	 * 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);
 	}
 	spin_unlock(&desc->lock);
 }
@@ -638,7 +884,10 @@
 		return;
 	else
 		once++;
-	
+
+	/* Initialize the irq tree */
+	irq_desc_init();
+
 	ppc_md.init_IRQ();
 	if(ppc_md.init_ras_IRQ) ppc_md.init_ras_IRQ(); 
 }
@@ -794,6 +1043,7 @@
 #endif /* CONFIG_SMP */
 
 static struct proc_dir_entry * root_irq_dir;
+#if 0
 static struct proc_dir_entry * irq_dir [NR_IRQS];
 static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
 
@@ -802,15 +1052,19 @@
 #else  /* CONFIG_IRQ_ALL_CPUS */
 unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000};
 #endif /* CONFIG_IRQ_ALL_CPUS */
+#endif
 
 #define HEX_DIGITS 8
 
 static int irq_affinity_read_proc (char *page, char **start, off_t off,
 			int count, int *eof, void *data)
 {
+	irq_desc_t *desc = irqdesc((long)data);
+	struct hw_irq_stat *hwstat = get_irq_stat(desc);
+
 	if (count < HEX_DIGITS+1)
 		return -EINVAL;
-	return sprintf (page, "%08x\n", irq_affinity[(int)(long)data]);
+	return sprintf(page, "%16lx\n", hwstat->irq_affinity);
 }
 
 static unsigned int parse_hex_value (const char *buffer,
@@ -853,10 +1107,13 @@
 static int irq_affinity_write_proc (struct file *file, const char *buffer,
 					unsigned long count, void *data)
 {
-	int irq = (int)(long) data, full_count = count, err;
+	unsigned int irq = (long)data;
+	irq_desc_t *desc = irqdesc(irq);
+	struct hw_irq_stat *hwstat = get_irq_stat(desc);
+	int full_count = count, err;
 	unsigned long new_value;
 
-	if (!irq_desc[irq].handler->set_affinity)
+	if (!desc->handler->set_affinity)
 		return -EIO;
 
 	err = parse_hex_value(buffer, count, &new_value);
@@ -871,10 +1128,8 @@
 	if (!(new_value & cpu_online_map))
 		return -EINVAL;
 #endif
-
-	irq_affinity[irq] = new_value;
-	irq_desc[irq].handler->set_affinity(irq, new_value);
-
+	hwstat->irq_affinity = new_value;
+	desc->handler->set_affinity(irq, new_value);
 	return full_count;
 }
 
@@ -923,25 +1178,39 @@
 {
 	struct proc_dir_entry *entry;
 	char name [MAX_NAMELEN];
+	irq_desc_t *desc;
+	struct hw_irq_stat *hwstat;
 
-	if (!root_irq_dir || (irq_desc[irq].handler == NULL))
+	desc = real_irqdesc(irq);
+	if (!root_irq_dir || !desc || !desc->handler)
+		return;
+	hwstat = get_irq_stat(desc);
+	if (hwstat->irq_dir)
 		return;
 
 	memset(name, 0, MAX_NAMELEN);
 	sprintf(name, "%d", irq);
 
 	/* create /proc/irq/1234 */
-	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+	hwstat->irq_dir = proc_mkdir(name, root_irq_dir);
+	if(hwstat->irq_dir == NULL) {
+		printk(KERN_ERR "register_irq_proc: proc_mkdir failed.\n");
+		return;
+	}
 
 	/* create /proc/irq/1234/smp_affinity */
-	entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
+	entry = create_proc_entry("smp_affinity", 0600, hwstat->irq_dir);
 
-	entry->nlink = 1;
-	entry->data = (void *)(long)irq;
-	entry->read_proc = irq_affinity_read_proc;
-	entry->write_proc = irq_affinity_write_proc;
+	if(entry) {
+		entry->nlink = 1;
+		entry->data = (void *)(long)irq;
+		entry->read_proc = irq_affinity_read_proc;
+		entry->write_proc = irq_affinity_write_proc;
+	} else {
+		printk(KERN_ERR "register_irq_proc: create_proc_entry failed.\n");
+	}
 
-	smp_affinity_entry[irq] = entry;
+	hwstat->smp_affinity = entry;
 }
 
 unsigned long prof_cpu_mask = -1;
@@ -953,20 +1222,27 @@
 
 	/* create /proc/irq */
 	root_irq_dir = proc_mkdir("irq", 0);
+	if(root_irq_dir == NULL) {
+		printk(KERN_ERR "init_irq_proc: proc_mkdir failed.\n");
+	}
 
 	/* create /proc/irq/prof_cpu_mask */
 	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
 
-	entry->nlink = 1;
-	entry->data = (void *)&prof_cpu_mask;
-	entry->read_proc = prof_cpu_mask_read_proc;
-	entry->write_proc = prof_cpu_mask_write_proc;
+	if(entry) {
+		entry->nlink = 1;
+		entry->data = (void *)&prof_cpu_mask;
+		entry->read_proc = prof_cpu_mask_read_proc;
+		entry->write_proc = prof_cpu_mask_write_proc;
+	} else {
+		printk(KERN_ERR "init_irq_proc: create_proc_entry failed.\n");
+	}
 
 	/*
 	 * Create entries for all existing IRQs.
 	 */
-	for (i = 0; i < NR_IRQS; i++) {
-		if (irq_desc[i].handler == NULL)
+	for_each_irq(i) {
+		if (irqdesc(i)->handler == NULL)
 			continue;
 		register_irq_proc(i);
 	}
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/mf_proc.c linux-2.4.24-pre2/arch/ppc64/kernel/mf_proc.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/mf_proc.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/mf_proc.c	2003-12-22 11:34:34.000000000 -0800
@@ -220,19 +220,22 @@
 
 int proc_mf_change_side(struct file *file, const char *buffer, unsigned long count, void *data)
 {
+	char side;
+
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
+	if (count == 0)
+		return 0;
+	if (get_user(side, buffer))
+		return -EFAULT;
 
-	if ((*buffer != 'A') &&
-	    (*buffer != 'B') &&
-	    (*buffer != 'C') &&
-	    (*buffer != 'D'))
+	if ((side != 'A') && (side != 'B') && (side != 'C') && (side != 'D'))
 	{
 		printk(KERN_ERR "mf_proc.c: proc_mf_change_side: invalid side\n");
 		return -EINVAL;
 	}
 
-	mf_setSide(*buffer);
+	mf_setSide(side);
 
 	return count;			
 }
@@ -256,20 +259,24 @@
 
 int proc_mf_change_src(struct file *file, const char *buffer, unsigned long count, void *data)
 {
+	char stkbuf[10];
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 
-	if ((count < 4) && (count != 1))
-	{
+	if ((count < 4) && (count != 1)) {
 		printk(KERN_ERR "mf_proc: invalid src\n");
 		return -EINVAL;
 	}
 
-	if ((count == 1) && ((*buffer) == '\0'))
-	{
+	if (count > 9)
+		count = 9;
+	if (copy_from_user (stkbuf, buffer, count))
+		return -EFAULT;
+
+	if ((count == 1) && ((*stkbuf) == '\0')) {
 		mf_clearSrc();
 	} else {
-		mf_displaySrc(*(u32 *)buffer);
+		mf_displaySrc(*(u32 *)stkbuf);
 	}
 
 	return count;			
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/misc.S linux-2.4.24-pre2/arch/ppc64/kernel/misc.S
--- linux-2.4.24-pre1/arch/ppc64/kernel/misc.S	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/misc.S	2003-12-22 11:34:34.000000000 -0800
@@ -69,16 +69,14 @@
 _GLOBAL(__no_use_save_flags)
 	mfspr	r4,SPRG3
 	lbz	r3,PACAPROCENABLED(r4)
+	/* shift into position of MSR.EE */
+	sldi	r3,r3,15
 	blr
 
-/* void __no_use_restore_flags(unsigned long flags) */	
+/* void __no_use_restore_flags(unsigned long flags) */
 _GLOBAL(__no_use_restore_flags)
-/*
- * Just set/clear the MSR_EE bit through restore/flags but do not
- * change anything else.  This is needed by the RT system and makes
- * sense anyway.
- *    -- Cort
- */
+	/* shift from position of MSR.EE */
+	srdi	r3,r3,15
 	mfspr	r6,SPRG3
 	lbz	r5,PACAPROCENABLED(r6)
 	 /* Check if things are setup the way we want _already_. */
@@ -104,6 +102,8 @@
 	lbz	r3,PACAPROCENABLED(r5)
 	li	r4,0
 	stb	r4,PACAPROCENABLED(r5)
+	/* shift into position of MSR.EE */
+	sldi	r3,r3,15
 	blr			/* Done */
 
 _GLOBAL(__no_use_sti)
@@ -578,9 +578,10 @@
 	bnelr			/* return if parent */
 
 	li	r0,0		/* clear out p->thread.regs */
-	std	r0,THREAD+PT_REGS(r13)	/* since we don't have user ctx */
+	ld	r7,PACACURRENT(r13)
+	std	r0,THREAD+PT_REGS(r7)	/* since we don't have user ctx */
 	li	r0,RUN_FLAG		/* Run light on */
-	std	r0,THREAD+THREAD_FLAGS(r13)
+	std	r0,THREAD+THREAD_FLAGS(r7)
 
 	ld	r2,8(r6)
 	ld	r6,0(r6)
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/open_pic.c linux-2.4.24-pre2/arch/ppc64/kernel/open_pic.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/open_pic.c	2002-11-28 15:53:11.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/kernel/open_pic.c	2003-12-22 11:34:34.000000000 -0800
@@ -20,7 +20,7 @@
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/prom.h>
-
+#include <asm/smp.h>
 #include <asm/machdep.h>
 
 #include "local_irq.h"
@@ -131,13 +131,23 @@
 
 #define GET_ISU(source)	ISU[(source) >> 4][(source) & 0xf]
 
+void
+openpic_init_irq_desc(irq_desc_t *desc)
+{
+	/* Don't mess with the handler if already set.
+	 * This leaves the setup of isa/ipi handlers undisturbed.
+	 */
+	if (!desc->handler)
+		desc->handler = &open_pic;
+}
+
 void __init openpic_init_IRQ(void)
 {
         struct device_node *np;
         int i;
         unsigned int *addrp;
         unsigned char* chrp_int_ack_special = 0;
-        unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
+	unsigned char init_senses[NR_IRQS - NUM_ISA_INTERRUPTS];
         int nmi_irq = -1;
 #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
         struct device_node *kbd;
@@ -152,13 +162,13 @@
 			__ioremap(addrp[prom_n_addr_cells(np)-1], 1, _PAGE_NO_CACHE);
         /* hydra still sets OpenPIC_InitSenses to a static set of values */
         if (OpenPIC_InitSenses == NULL) {
-                prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS);
-                OpenPIC_InitSenses = init_senses;
-                OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
-        }
-        openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq);
-        for ( i = 0 ; i < NUM_8259_INTERRUPTS  ; i++ )
-                irq_desc[i].handler = &i8259_pic;
+		prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS);
+		OpenPIC_InitSenses = init_senses;
+		OpenPIC_NumInitSenses = NR_IRQS - NUM_ISA_INTERRUPTS;
+	}
+	openpic_init(1, NUM_ISA_INTERRUPTS, chrp_int_ack_special, nmi_irq);
+	for ( i = 0 ; i < NUM_ISA_INTERRUPTS  ; i++ )
+		real_irqdesc(i)->handler = &i8259_pic;
         i8259_init();
 }
 
@@ -343,8 +353,8 @@
 		/* Disabled, Priority 10..13 */
 		openpic_initipi(i, 10+i, openpic_vec_ipi+i);
 		/* IPIs are per-CPU */
-		irq_desc[openpic_vec_ipi+i].status |= IRQ_PER_CPU;
-		irq_desc[openpic_vec_ipi+i].handler = &open_pic_ipi;
+		real_irqdesc(openpic_vec_ipi+i)->status |= IRQ_PER_CPU;
+		real_irqdesc(openpic_vec_ipi+i)->handler = &open_pic_ipi;
 	}
 #endif
 
@@ -369,7 +379,7 @@
 		pri = (i == programmer_switch_irq)? 9: 8;
 		sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1;
 		if (sense)
-			irq_desc[i+offset].status = IRQ_LEVEL;
+			real_irqdesc(i+offset)->status = IRQ_LEVEL;
 
 		/* Enabled, Priority 8 or 9 */
 		openpic_initirq(i, pri, i+offset, !sense, sense);
@@ -377,10 +387,6 @@
 		openpic_mapirq(i, 1<<get_hard_smp_processor_id(0));
 	}
 
-	/* Init descriptors */
-	for (i = offset; i < NumSources + offset; i++)
-		irq_desc[i].handler = &open_pic;
-
 	/* Initialize the spurious interrupt */
 	ppc64_boot_msg(0x24, "OpenPic Spurious");
 	openpic_set_spurious(openpic_vec_spurious);
@@ -755,7 +761,7 @@
 
 static void openpic_end_irq(unsigned int irq_nr)
 {
-	if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
+	if ((irqdesc(irq_nr)->status & IRQ_LEVEL) != 0)
 		openpic_eoi();
 }
 
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/open_pic.h linux-2.4.24-pre2/arch/ppc64/kernel/open_pic.h
--- linux-2.4.24-pre1/arch/ppc64/kernel/open_pic.h	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/open_pic.h	2003-12-22 11:34:34.000000000 -0800
@@ -37,9 +37,4 @@
 extern void openpic_setup_ISU(int isu_num, unsigned long addr);
 extern void openpic_cause_IPI(u_int ipi, u_int cpumask);
 
-extern inline int openpic_to_irq(int irq)
-{
-	return irq += NUM_8259_INTERRUPTS;
-}
-/*extern int open_pic_irq_offset;*/
 #endif /* _PPC64_KERNEL_OPEN_PIC_H */
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/pSeries_hvCall.S linux-2.4.24-pre2/arch/ppc64/kernel/pSeries_hvCall.S
--- linux-2.4.24-pre1/arch/ppc64/kernel/pSeries_hvCall.S	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/pSeries_hvCall.S	2003-12-22 11:34:34.000000000 -0800
@@ -23,7 +23,7 @@
 /*
  * hcall interface to pSeries LPAR
  */
-#define HSC .long 0x44000022
+#define HVSC	.long 0x44000022
 
 /* long plpar_hcall(unsigned long opcode,	 R3 
 		 unsigned long arg1,		 R4 
@@ -45,7 +45,7 @@
         std     r9,-16(r1)
         std     r10,-24(r1)
 	
-	HSC                     /* invoke the hypervisor */
+	HVSC                    /* invoke the hypervisor */
 
         ld      r10,-8(r1)      /* Fetch r4-r7 ret args. */
         std     r4,0(r10)
@@ -60,11 +60,85 @@
 	blr                     /* return r3 = status */
 
 
+/* long plpar_hcall_4out(unsigned long opcode,	 R3
+		 unsigned long arg1,		 R4
+		 unsigned long arg2,		 R5
+		 unsigned long arg3,		 R6
+		 unsigned long arg4,		 R7
+		 unsigned long *out1,	(r4)	 R8
+		 unsigned long *out2,	(r5)	 R9
+		 unsigned long *out3,   (r6)     R10
+		 unsigned long *out4);	(r7)	 112(R1). From Parameter save area. 
+ */
+_GLOBAL(plpar_hcall_4out)
+	mfcr	r0
+	std	r0,-8(r1)
+	ld      r14,112(r1)
+	stdu	r1,-48(r1)
+
+	std     r8,32(r1)       /* Save out ptrs. */
+	std     r9,24(r1)
+	std     r10,16(r1)
+	std     r14,8(r1)
+
+	HVSC                    /* invoke the hypervisor */
+
+	ld      r14,32(r1)      /* Fetch r4-r7 ret args. */
+	std     r4,0(r14)
+	ld      r14,24(r1)
+	std     r5,0(r14)
+	ld      r14,16(r1)
+	std     r6,0(r14)
+	ld      r14,8(r1)
+	std     r7,0(r14)
+
+	ld	r1,0(r1) 
+	ld	r0,-8(r1)
+	mtcrf	0xff,r0
+	blr                     /* return r3 = status */
+
+
 /* Simple interface with no output values (other than status) */
 _GLOBAL(plpar_hcall_norets)
 	mfcr	r0
 	std	r0,-8(r1)
-	HSC                     /* invoke the hypervisor */
+	HVSC                    /* invoke the hypervisor */
+	ld	r0,-8(r1)
+	mtcrf	0xff,r0
+	blr                     /* return r3 = status */
+
+
+/* long plpar_hcall_8arg_2ret(unsigned long opcode,		 R3
+				unsigned long arg1,		 R4
+				unsigned long arg2,		 R5
+				unsigned long arg3,		 R6
+				unsigned long arg4,		 R7
+				unsigned long arg5,		 R8
+				unsigned long arg6,		 R9
+				unsigned long arg7,		 R10
+				unsigned long arg8,		 112(R1)
+				unsigned long *out1);		 120(R1)
+
+ */
+
+	.text
+_GLOBAL(plpar_hcall_8arg_2ret)
+	mfcr	r0
+
+	ld	r11, 112(r1) /* put arg8 and out1 in R11 and R12 */
+	ld	r12, 120(r1)
+
+	std	r0,-8(r1)
+	stdu	r1,-32(r1)
+
+	std	r12,-8(r1)      /* Save out ptr */
+
+	HVSC                     /* invoke the hypervisor */
+
+	ld	r10,-8(r1)      /* Fetch r4 ret arg */
+	std	r4,0(r10)
+
+	ld	r1,0(r1)
 	ld	r0,-8(r1)
 	mtcrf	0xff,r0
 	blr                     /* return r3 = status */
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/pSeries_lpar.c linux-2.4.24-pre2/arch/ppc64/kernel/pSeries_lpar.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/pSeries_lpar.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/pSeries_lpar.c	2003-12-22 11:34:34.000000000 -0800
@@ -35,6 +35,30 @@
 #include <linux/pci.h>
 #include <asm/naca.h>
 #include <asm/hvcall.h>
+long poll_pending(void)
+{
+	unsigned long dummy;
+	return plpar_hcall(H_POLL_PENDING, 0, 0, 0, 0,
+			   &dummy, &dummy, &dummy);
+}
+
+long prod_processor(void)
+{
+	plpar_hcall_norets(H_PROD);
+	return(0);
+}
+
+long cede_processor(void)
+{
+	plpar_hcall_norets(H_CEDE);
+	return(0);
+}
+
+long register_vpa(unsigned long flags, unsigned long proc, unsigned long vpa)
+{
+	plpar_hcall_norets(H_REGISTER_VPA, flags, proc, vpa);
+	return(0);
+}
 
 long plpar_tce_get(unsigned long liobn,
 		   unsigned long ioba,
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/pSeries_pci.c linux-2.4.24-pre2/arch/ppc64/kernel/pSeries_pci.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/pSeries_pci.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/pSeries_pci.c	2003-12-22 11:34:34.000000000 -0800
@@ -208,6 +208,7 @@
 		PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s No Interrupt used by device.\n",Pci_Dev->slot_name);
 		return 0;	
 	}
+
 	Node = pci_device_to_OF_node(Pci_Dev);
 	if ( Node == NULL) { 
 		PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s Device Node not found.\n",Pci_Dev->slot_name);
@@ -524,13 +525,22 @@
 		}
 
 		phb->local_number = ((reg_struct.address >> 12) & 0xf) - 0x8;
-	/***************************************************************
-	* Trying to build a known just gets the code in trouble.
-	***************************************************************/
-	} else { 
+	} else {
 		PPCDBG(PPCDBG_PHBINIT, "\tUnknown PHB Type!\n");
-		printk("PCI: Unknown Phb Type!\n");
-		return NULL;
+
+		if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
+
+			phb=pci_alloc_pci_controller("PHB UK",phb_type_unknown);
+			if (phb == NULL) return NULL;
+
+			phb->cfg_addr = NULL;
+			phb->cfg_data = NULL;
+			phb->phb_regs = NULL;
+			phb->chip_regs = NULL;
+		} else {
+			printk("PCI: Unknown Phb Type!\n");
+			return NULL;
+		}
 	}
 
 	/* Add a linux,phbnum property to the device tree so user code
@@ -703,10 +713,6 @@
 		pci_read_irq_line(dev);
 		PPCDBGCALL(PPCDBG_PHBINIT, dumpPci_Dev(dev) );
 	}
-
-	if (naca->interrupt_controller == IC_PPC_XIC) {
-		xics_isa_init(); 
-	}
 }
 
 /*********************************************************************** 
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/pci_dma.c linux-2.4.24-pre2/arch/ppc64/kernel/pci_dma.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/pci_dma.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/pci_dma.c	2003-12-22 11:34:34.000000000 -0800
@@ -97,11 +97,8 @@
 			   unsigned order );
 
 /* allocates a range of tces and sets them to the pages  */
-static inline dma_addr_t get_tces( struct TceTable *, 
-				   unsigned order, 
-				   void *page, 
-				   unsigned numPages,
-				   int direction );
+dma_addr_t get_tces(struct TceTable *, unsigned order, void *page,
+		    unsigned numPages, int direction);
 
 static long test_tce_range( struct TceTable *, 
 			    long tcenum, 
@@ -219,7 +216,7 @@
  * Build a TceTable structure.  This contains a multi-level bit map which
  * is used to manage allocation of the tce space.
  */
-static struct TceTable *build_tce_table( struct TceTable * tbl )
+struct TceTable *build_tce_table(struct TceTable * tbl)
 {
 	unsigned long bits, bytes, totalBytes;
 	unsigned long numBits[NUM_TCE_LEVELS], numBytes[NUM_TCE_LEVELS];
@@ -527,7 +524,8 @@
 	return retval;
 }
 
-static inline dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *page, unsigned numPages, int direction )
+inline dma_addr_t get_tces(struct TceTable *tbl, unsigned order,
+			   void *page, unsigned numPages, int direction)
 {
 	long tcenum;
 	unsigned long uaddr;
@@ -537,8 +535,8 @@
 	uaddr = (unsigned long)page & PAGE_MASK;
 	
 	/* Allocate a range of tces */
-	tcenum = alloc_tce_range( tbl, order );
-	if ( tcenum != -1 ) {
+	tcenum = alloc_tce_range(tbl, order);
+	if (tcenum != -1) {
 		/* We got the tces we wanted */
 		tcenum += tbl->startOffset;	/* Offset into real TCE table */
 		retTce = tcenum << PAGE_SHIFT;	/* Set the return dma address */
@@ -553,9 +551,9 @@
 		   the TCE table with the MMIO that will send
 		   the bus address to the IOA */
 		__asm__ __volatile__ ("sync" : : : "memory");
-	}
-	else {
-		panic("PCI_DMA: Tce Allocation failure in get_tces. 0x%p\n",tbl);
+	} else {
+		panic("get_tces: TCE allocation failed. 0x%p 0x%x\n",
+		      tbl, order);
 	}
 
 	return retTce; 
@@ -586,8 +584,8 @@
 
 }
 
-static void tce_free(struct TceTable *tbl, dma_addr_t dma_addr, 
-			     unsigned order, unsigned num_pages)
+void tce_free(struct TceTable *tbl, dma_addr_t dma_addr,
+	      unsigned order, unsigned num_pages)
 {
 	long tcenum, total_tces, free_tce;
 	unsigned i;
@@ -1009,34 +1007,34 @@
 
  	/* Client asked for way to much space.  This is checked later anyway */
 	/* It is easier to debug here for the drivers than in the tce tables.*/
- 	if(order >= NUM_TCE_LEVELS) {
- 		printk("PCI_DMA: pci_alloc_consistent size to large: 0x%lx \n",size);
- 		return (void *)NO_TCE;
+ 	if (order >= NUM_TCE_LEVELS) {
+ 		printk("PCI_DMA: pci_alloc_consistent size too large: 0x%lx\n",
+		       size);
+ 		return (void *)NULL;
  	}
 
 	tbl = get_tce_table(hwdev); 
 
-	if ( tbl ) {
+	if (tbl) {
 		/* Alloc enough pages (and possibly more) */
 		ret = (void *)__get_free_pages( GFP_ATOMIC, order );
-		if ( ret ) {
+		if (ret) {
 			/* Page allocation succeeded */
 			memset(ret, 0, nPages << PAGE_SHIFT);
 			/* Set up tces to cover the allocated range */
 			tce = get_tces( tbl, order, ret, nPages, PCI_DMA_BIDIRECTIONAL );
-			if ( tce == NO_TCE ) {
-				PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: get_tces failed\n" );
+			if (tce == NO_TCE) {
 				free_pages( (unsigned long)ret, order );
 				ret = NULL;
-			}
-			else
-			{
+			} else {
 				*dma_handle = tce;
 			}
+		} else {
+			printk("pci_alloc_consistent: __get_free_pages failed for order = %d\n", order);
 		}
-		else PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: __get_free_pages failed for order = %d\n", order);
+	} else {
+		panic("pci_alloc_consistent: unable to find TCE table\n");
 	}
-	else PPCDBG(PPCDBG_TCE, "pci_alloc_consistent: get_tce_table failed for 0x%016lx\n", hwdev);
 
 	PPCDBG(PPCDBG_TCE, "\tpci_alloc_consistent: dma_handle = 0x%16.16lx\n", *dma_handle);	
 	PPCDBG(PPCDBG_TCE, "\tpci_alloc_consistent: return     = 0x%16.16lx\n", ret);	
@@ -1059,7 +1057,7 @@
  	/* Client asked for way to much space.  This is checked later anyway */
 	/* It is easier to debug here for the drivers than in the tce tables.*/
  	if(order >= NUM_TCE_LEVELS) {
- 		printk("PCI_DMA: pci_free_consistent size to large: 0x%lx \n",size);
+ 		printk("PCI_DMA: pci_free_consistent size too large: 0x%lx \n",size);
  		return;
  	}
 	
@@ -1087,7 +1085,7 @@
 
 	PPCDBG(PPCDBG_TCE, "pci_map_single:\n");
 	PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, size = 0x%16.16lx, direction = 0x%16.16lx, vaddr = 0x%16.16lx\n", hwdev, size, direction, vaddr);	
-	if ( direction == PCI_DMA_NONE )
+	if (direction == PCI_DMA_NONE)
 		BUG();
 	
 	uaddr = (unsigned long)vaddr;
@@ -1098,15 +1096,18 @@
  	/* Client asked for way to much space.  This is checked later anyway */
 	/* It is easier to debug here for the drivers than in the tce tables.*/
  	if(order >= NUM_TCE_LEVELS) {
- 		printk("PCI_DMA: pci_map_single size to large: 0x%lx \n",size);
- 		return NO_TCE;
+		panic("PCI_DMA: pci_map_single size too large: 0x%lx \n", size);
+		return dma_handle;
  	}
 
 	tbl = get_tce_table(hwdev); 
 
-	if ( tbl ) {
+	if (tbl) {
+		/* get_tces panics if there are no entries available */
 		dma_handle = get_tces( tbl, order, vaddr, nPages, direction );
 		dma_handle |= ( uaddr & ~PAGE_MASK );
+	} else {
+		panic("PCI_DMA: Unable to find TCE table.\n");
 	}
 
 	return dma_handle;
@@ -1129,7 +1130,7 @@
  	/* Client asked for way to much space.  This is checked later anyway */
 	/* It is easier to debug here for the drivers than in the tce tables.*/
  	if(order >= NUM_TCE_LEVELS) {
- 		printk("PCI_DMA: pci_unmap_single size to large: 0x%lx \n",size);
+ 		printk("PCI_DMA: pci_unmap_single size too large: 0x%lx \n",size);
  		return;
  	}
 	
@@ -1151,6 +1152,7 @@
 {
 	unsigned long nTces, numPages, startPage, endPage, prevEndPage;
 	unsigned i;
+	void *address;
 
 	prevEndPage = 0;
 	nTces = 0;
@@ -1159,8 +1161,10 @@
 		/* Compute the starting page number and
 		 * the ending page number for this entry
 		 */
-		startPage = (unsigned long)sg->address >> PAGE_SHIFT;
-		endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT;
+		address = sg->address ? sg->address :
+			(page_address(sg->page) + sg->offset);
+		startPage = (unsigned long)address >> PAGE_SHIFT;
+		endPage = ((unsigned long)address + sg->length - 1) >> PAGE_SHIFT;
 		numPages = endPage - startPage + 1;
 		/* Simple optimization: if the previous entry ended
 		 * in the same page in which this entry starts
@@ -1187,17 +1191,20 @@
 	u32 cur_start_dma;
 	unsigned long cur_len_dma, cur_end_virt, uaddr;
 	unsigned num_dma_ents;
+	void *address;
 
 	dma_sg = sg;
 	num_dma_ents = 1;
 
 	/* Process the first sg entry */
-	cur_start_dma = dma_addr + ((unsigned long)sg->address & (~PAGE_MASK));
+	address = sg->address ? sg->address :
+		(page_address(sg->page) + sg->offset);
+	cur_start_dma = dma_addr + ((unsigned long)address & (~PAGE_MASK));
 	cur_len_dma = sg->length;
 	/* cur_end_virt holds the address of the byte immediately after the
 	 * end of the current buffer.
 	 */
-	cur_end_virt = (unsigned long)sg->address + cur_len_dma;
+	cur_end_virt = (unsigned long)address + cur_len_dma;
 	/* Later code assumes that unused sg->dma_address and sg->dma_length
 	 * fields will be zero.  Other archs seem to assume that the user
 	 * (device driver) guarantees that...I don't want to depend on that
@@ -1222,7 +1229,9 @@
 		 * or if the previous entry ends at a page boundary
 		 * and the current entry starts at a page boundary.
 		 */
-		uaddr = (unsigned long)sg->address;
+		address = sg->address ? sg->address :
+			(page_address(sg->page) + sg->offset);
+		uaddr = (unsigned long)address;
 		if ( ( uaddr != cur_end_virt ) &&
 		     ( ( ( uaddr | cur_end_virt ) & (~PAGE_MASK) ) ||
 		       ( ( uaddr & PAGE_MASK ) == ( ( cur_end_virt-1 ) & PAGE_MASK ) ) ) ) {
@@ -1273,13 +1282,14 @@
 /* Call the hypervisor to create the TCE entries.
  * return the number of TCEs created
  */
-static dma_addr_t create_tces_sg( struct TceTable *tbl, struct scatterlist *sg, 
-		   int nents, unsigned numTces, int direction )
+static dma_addr_t create_tces_sg(struct TceTable *tbl, struct scatterlist *sg, 
+				 int nents, unsigned numTces, int direction)
 {
 	unsigned order, i, j;
 	unsigned long startPage, endPage, prevEndPage, numPages, uaddr;
 	long tcenum, starttcenum;
 	dma_addr_t dmaAddr;
+	void *address;
 
 	dmaAddr = NO_TCE;
 
@@ -1287,23 +1297,26 @@
  	/* Client asked for way to much space.  This is checked later anyway */
 	/* It is easier to debug here for the drivers than in the tce tables.*/
  	if(order >= NUM_TCE_LEVELS) {
-		printk("PCI_DMA: create_tces_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT));
+		printk("PCI_DMA: create_tces_sg size too large: 0x%llx \n",(numTces << PAGE_SHIFT));
+		panic("numTces is off");
  		return NO_TCE;
  	}
 
 	/* allocate a block of tces */
-	tcenum = alloc_tce_range( tbl, order );
-	if ( tcenum != -1 ) {
+	tcenum = alloc_tce_range(tbl, order);
+	if (tcenum != -1) {
 		tcenum += tbl->startOffset;
 		starttcenum = tcenum;
 		dmaAddr = tcenum << PAGE_SHIFT;
 		prevEndPage = 0;
 		for (j=0; j<nents; ++j) {
-			startPage = (unsigned long)sg->address >> PAGE_SHIFT;
-			endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT;
+			address = sg->address ? sg->address :
+				(page_address(sg->page) + sg->offset);
+			startPage = (unsigned long)address >> PAGE_SHIFT;
+			endPage = ((unsigned long)address + sg->length - 1) >> PAGE_SHIFT;
 			numPages = endPage - startPage + 1;
 			
-			uaddr = (unsigned long)sg->address;
+			uaddr = (unsigned long)address;
 
 			/* If the previous entry ended in the same page that
 			 * the current page starts then they share that
@@ -1335,6 +1348,9 @@
 	    		PPCDBG(PPCDBG_TCE, "create_tces_sg: numTces %d, tces used %d\n",
 		   		numTces, (unsigned)(tcenum - starttcenum));
 
+	} else {
+		panic("PCI_DMA: TCE allocation failure in create_tces_sg. 0x%p 0x%x\n",
+		      tbl, order);
 	}
 
 	return dmaAddr;
@@ -1346,25 +1362,26 @@
 	unsigned numTces;
 	int num_dma = 0;
 	dma_addr_t dma_handle;
+	void *address;
 
-	PPCDBG(PPCDBG_TCE, "pci_map_sg:\n");
-	PPCDBG(PPCDBG_TCE, "\thwdev = 0x%16.16lx, sg = 0x%16.16lx, direction = 0x%16.16lx, nents = 0x%16.16lx\n", hwdev, sg, direction, nents);	
 	/* Fast path for a single entry scatterlist */
 	if ( nents == 1 ) {
-		sg->dma_address = pci_map_single( hwdev, sg->address, 
-					sg->length, direction );
+ 		address = sg->address ? sg->address :
+ 			(page_address(sg->page) + sg->offset);
+ 		sg->dma_address = pci_map_single( hwdev, address,
+ 						  sg->length, direction );
 		sg->dma_length = sg->length;
 		return 1;
 	}
 	
-	if ( direction == PCI_DMA_NONE )
+	if (direction == PCI_DMA_NONE)
 		BUG();
 	
 	tbl = get_tce_table(hwdev); 
 
-	if ( tbl ) {
+	if (tbl) {
 		/* Compute the number of tces required */
-		numTces = num_tces_sg( sg, nents );
+		numTces = num_tces_sg(sg, nents);
 		/* Create the tces and get the dma address */ 
 		dma_handle = create_tces_sg( tbl, sg, nents, numTces, direction );
 
@@ -1372,6 +1389,8 @@
 
 		/* Fill in the dma scatterlist */
 		num_dma = fill_scatterlist_sg( sg, nents, dma_handle, numTces );
+	} else {
+		panic("pci_map_sg: unable to find TCE table\n");
 	}
 
 	return num_dma;
@@ -1407,7 +1426,7 @@
 	/* It is easier to debug here for the drivers than in the tce tables.*/
  	if(order >= NUM_TCE_LEVELS) {
 		printk("PCI_DMA: dma_start_page:0x%lx  dma_end_page:0x%lx\n",dma_start_page,dma_end_page);
-		printk("PCI_DMA: pci_unmap_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT));
+		printk("PCI_DMA: pci_unmap_sg size too large: 0x%x \n",(numTces << PAGE_SHIFT));
  		return;
  	}
 	
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/pmc.c linux-2.4.24-pre2/arch/ppc64/kernel/pmc.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/pmc.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/pmc.c	2003-12-22 11:34:34.000000000 -0800
@@ -74,7 +74,6 @@
                                 page_table_lock : SPIN_LOCK_UNLOCKED};
 
 extern spinlock_t hash_table_lock[];
-extern inline unsigned long get_lock_slot(unsigned long vpn);
 
 char *
 ppc64_pmc_stab(int file)
@@ -241,7 +240,7 @@
 		lock_slot = get_lock_slot(vpn); 
 		rpn = pa >> PAGE_SHIFT;
 
-		spin_lock(&hash_table_lock[lock_slot].lock);
+		spin_lock(&hash_table_lock[lock_slot]);
 		/* Get a pointer to the linux page table entry for this page
 		 * allocating pmd or pte pages along the way as needed.  Note
 		 * that the pmd & pte pages are not themselfs bolted.
@@ -266,7 +265,7 @@
 
 		*ptep = pte;
 
-		spin_unlock(&hash_table_lock[lock_slot].lock);
+		spin_unlock(&hash_table_lock[lock_slot]);
 	}
 
 	spin_unlock(&btmalloc_mm.page_table_lock);
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/proc_pmc.c linux-2.4.24-pre2/arch/ppc64/kernel/proc_pmc.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/proc_pmc.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/proc_pmc.c	2003-12-22 11:34:34.000000000 -0800
@@ -58,6 +58,8 @@
 static int proc_ppc64_page_read(char *page, char **start, off_t off,
 				int count, int *eof, void *data);
 static void proc_ppc64_create_paca(int num, struct proc_dir_entry *paca_dir);
+void proc_ppc64_create_smt(void);
+
 int proc_ppc64_pmc_find_file(void *data);
 int proc_ppc64_pmc_read(char *page, char **start, off_t off,
 			int count, int *eof, char *buffer);
@@ -182,6 +184,8 @@
 		rtas_proc_dir = proc_mkdir("rtas", proc_ppc64_root);
 	}
 
+	proc_ppc64_create_smt();
+
 	/* Create the /proc/ppc64/pcifr for the Pci Flight Recorder.	 */
 	proc_pciFr_init(proc_ppc64_root);
 
@@ -202,7 +206,7 @@
 			ent->nlink = 1;
 			ent->data = (void *)proc_ppc64_pmc_cpu_root[i];
 			ent->read_proc = (void *)proc_ppc64_pmc_stab_read;
-			ent->write_proc = (void *)proc_ppc64_pmc_stab_read;
+			ent->write_proc = NULL;
 		}
 
 		ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, 
@@ -211,7 +215,7 @@
 			ent->nlink = 1;
 			ent->data = (void *)proc_ppc64_pmc_cpu_root[i];
 			ent->read_proc = (void *)proc_ppc64_pmc_htab_read;
-			ent->write_proc = (void *)proc_ppc64_pmc_htab_read;
+			ent->write_proc = NULL;
 		}
 	}
 
@@ -221,7 +225,7 @@
 		ent->nlink = 1;
 		ent->data = (void *)proc_ppc64_pmc_system_root;
 		ent->read_proc = (void *)proc_ppc64_pmc_stab_read;
-		ent->write_proc = (void *)proc_ppc64_pmc_stab_read;
+		ent->write_proc = NULL;
 	}
 
 	ent = create_proc_entry("htab", S_IRUGO | S_IWUSR, 
@@ -230,7 +234,7 @@
 		ent->nlink = 1;
 		ent->data = (void *)proc_ppc64_pmc_system_root;
 		ent->read_proc = (void *)proc_ppc64_pmc_htab_read;
-		ent->write_proc = (void *)proc_ppc64_pmc_htab_read;
+		ent->write_proc = NULL;
 	}
 
 	ent = create_proc_entry("profile", S_IWUSR | S_IRUGO, proc_ppc64_pmc_system_root);
@@ -261,7 +265,7 @@
 			ent->nlink = 1;
 			ent->data = (void *)proc_ppc64_pmc_cpu_root[i];
 			ent->read_proc = (void *)proc_ppc64_pmc_hw_read;
-			ent->write_proc = (void *)proc_ppc64_pmc_hw_read;
+			ent->write_proc = NULL;
 		}
 	}
 
@@ -271,7 +275,7 @@
 		ent->nlink = 1;
 		ent->data = (void *)proc_ppc64_pmc_system_root;
 		ent->read_proc = (void *)proc_ppc64_pmc_hw_read;
-		ent->write_proc = (void *)proc_ppc64_pmc_hw_read;
+		ent->write_proc = NULL;
 	}
 }
 
@@ -449,6 +453,7 @@
 static ssize_t write_profile(struct file * file, const char * buf,
 			     size_t count, loff_t *ppos)
 {
+	return(0);
 }
 
 static ssize_t read_trace(struct file *file, char *buf,
@@ -473,6 +478,7 @@
 static ssize_t write_trace(struct file * file, const char * buf,
 			     size_t count, loff_t *ppos)
 {
+	return(0);
 }
 
 static ssize_t read_timeslice(struct file *file, char *buf,
@@ -481,7 +487,6 @@
 	unsigned long p = *ppos;
 	ssize_t read;
 	char * pnt;
-	unsigned int sample_step = 4;
 
 	if (p >= (perfmon_base.timeslice_length)) return 0;
 	if (count > (perfmon_base.timeslice_length) - p)
@@ -498,6 +503,7 @@
 static ssize_t write_timeslice(struct file * file, const char * buf,
 			       size_t count, loff_t *ppos)
 {
+	return(0);
 }
 
 int 
@@ -882,15 +888,24 @@
 
 int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data )
 {
-	if      ( ! strncmp( buffer, "stop", 4 ) )
+	char stkbuf[10];
+
+	if (count > 9)
+		count = 9;
+	if (copy_from_user (stkbuf, buffer, count))
+		return -EFAULT;
+
+	stkbuf[count] = 0;
+
+	if      ( ! strncmp( stkbuf, "stop", 4 ) )
 		proc_pmc_stop();
-	else if ( ! strncmp( buffer, "start", 5 ) )
+	else if ( ! strncmp( stkbuf, "start", 5 ) )
 		proc_pmc_start();
-	else if ( ! strncmp( buffer, "reset", 5 ) )
+	else if ( ! strncmp( stkbuf, "reset", 5 ) )
 		proc_pmc_reset();
-	else if ( ! strncmp( buffer, "cpi", 3 ) )
+	else if ( ! strncmp( stkbuf, "cpi", 3 ) )
 		proc_pmc_cpi();
-	else if ( ! strncmp( buffer, "tlb", 3 ) )
+	else if ( ! strncmp( stkbuf, "tlb", 3 ) )
 		proc_pmc_tlb();
 	
 	/* IMPLEMENT ME */
@@ -1061,3 +1076,85 @@
 	remap_page_range( vma->vm_start, __pa(dp->data), dp->size, vma->vm_page_prot );
 	return 0;
 }
+
+static int proc_ppc64_smt_snooze_read(char *page, char **start, off_t off,
+				      int count, int *eof, void *data)
+{
+	if (naca->smt_snooze_delay)
+		return sprintf(page, "%lu\n", naca->smt_snooze_delay);
+	else
+		return sprintf(page, "disabled\n");
+}
+
+static int proc_ppc64_smt_snooze_write(struct file* file, const char *buffer,
+				       unsigned long count, void *data)
+{
+	unsigned long val;
+	char val_string[22];
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	if (count > sizeof(val_string) - 1)
+		return -EINVAL;
+
+	if (copy_from_user(val_string, buffer, count))
+		return -EFAULT;
+
+	val_string[count] = '\0';
+
+	if (val_string[0] == '0' && (val_string[1] == '\n' || val_string[1] == '\0')) {
+		naca->smt_snooze_delay = 0;
+		return count;
+	}
+
+	val = simple_strtoul(val_string, NULL, 10);
+	if (val != 0)
+		naca->smt_snooze_delay = val;
+	else
+		return -EINVAL;
+
+	return count;
+}
+
+static int proc_ppc64_smt_state_read(char *page, char **start, off_t off,
+				      int count, int *eof, void *data)
+{
+	switch(naca->smt_state) {
+	case SMT_OFF:
+		return sprintf(page, "off\n");
+		break;
+	case SMT_ON:
+		return sprintf(page, "on\n");
+		break;
+	case SMT_DYNAMIC:
+		return sprintf(page, "dynamic\n");
+		break;
+	default:
+		return sprintf(page, "unknown\n");
+		break;
+	}
+}
+
+void proc_ppc64_create_smt(void)
+{
+	struct proc_dir_entry *ent_snooze =
+		create_proc_entry("smt-snooze-delay", S_IRUGO | S_IWUSR,
+				  proc_ppc64_root);
+	struct proc_dir_entry *ent_enabled =
+		create_proc_entry("smt-enabled", S_IRUGO | S_IWUSR,
+				  proc_ppc64_root);
+	if (ent_snooze) {
+		ent_snooze->nlink = 1;
+		ent_snooze->data = NULL;
+		ent_snooze->read_proc = (void *)proc_ppc64_smt_snooze_read;
+		ent_snooze->write_proc = (void *)proc_ppc64_smt_snooze_write;
+	}
+
+	if (ent_enabled) {
+		ent_enabled->nlink = 1;
+		ent_enabled->data = NULL;
+		ent_enabled->read_proc = (void *)proc_ppc64_smt_state_read;
+		ent_enabled->write_proc = NULL;
+	}
+}
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/prom.c linux-2.4.24-pre2/arch/ppc64/kernel/prom.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/prom.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/prom.c	2003-12-22 11:34:34.000000000 -0800
@@ -180,12 +180,9 @@
 char *bootpath = 0;
 char *bootdevice = 0;
 
-struct device_node *allnodes = 0;
+#define MAX_CPU_THREADS 2
 
-#define UNDEFINED_IRQ 0xffff
-unsigned short real_irq_to_virt_map[NR_HW_IRQS];
-unsigned short virt_irq_to_real_map[NR_IRQS];
-int last_virt_irq = 2;	/* index of last virt_irq.  Skip through IPI */
+struct device_node *allnodes = 0;
 
 static unsigned long call_prom(const char *service, int nargs, int nret, ...);
 static void prom_exit(void);
@@ -941,7 +938,7 @@
 		 * By doing this, we avoid the pitfalls of trying to DMA to
 		 * MMIO space and the DMA alias hole.
 		 */
-		minsize = 4UL << 20;
+		minsize = 8UL << 20;
 
 		/* Align to the greater of the align or size */
 		align = (minalign < minsize) ? minsize : minalign;
@@ -1054,6 +1051,9 @@
 	unsigned long offset = reloc_offset();
 	char type[64], *path;
 	int cpuid = 0;
+	unsigned int interrupt_server[MAX_CPU_THREADS];
+	unsigned int cpu_threads, hw_cpu_num;
+	int propsize;
 	extern void __secondary_hold(void);
         extern unsigned long __secondary_hold_spinloop;
         extern unsigned long __secondary_hold_acknowledge;
@@ -1117,18 +1117,12 @@
 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
 			  &reg, sizeof(reg));
 
-		/* Only need to start secondary procs, not ourself. */
-		if ( reg == _prom->cpu )
-			continue;
-
 		path = (char *) mem;
 		memset(path, 0, 256);
 		if ((long) call_prom(RELOC("package-to-path"), 3, 1,
 				     node, path, 255) < 0)
 			continue;
 
-		cpuid++;
-
 #ifdef DEBUG_PROM
 		prom_print_nl();
 		prom_print(RELOC("cpuid        = 0x"));
@@ -1140,56 +1134,80 @@
 #endif
 		_xPaca[cpuid].xHwProcNum = reg;
 
-		prom_print(RELOC("starting cpu "));
-		prom_print(path);
-
 		/* Init the acknowledge var which will be reset by
 		 * the secondary cpu when it awakens from its OF
 		 * spinloop.
 		 */
 		*acknowledge = (unsigned long)-1;
 
-#ifdef DEBUG_PROM
-		prom_print(RELOC("    3) spinloop       = 0x"));
-		prom_print_hex(spinloop);
-		prom_print_nl();
-		prom_print(RELOC("    3) *spinloop      = 0x"));
-		prom_print_hex(*spinloop);
-		prom_print_nl();
-		prom_print(RELOC("    3) acknowledge    = 0x"));
-		prom_print_hex(acknowledge);
-		prom_print_nl();
-		prom_print(RELOC("    3) *acknowledge   = 0x"));
-		prom_print_hex(*acknowledge);
-		prom_print_nl();
-		prom_print(RELOC("    3) secondary_hold = 0x"));
-		prom_print_hex(secondary_hold);
-		prom_print_nl();
-		prom_print(RELOC("    3) cpuid = 0x"));
-		prom_print_hex(cpuid);
-		prom_print_nl();
-#endif
-		call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid);
-		prom_print(RELOC("..."));
-		for ( i = 0 ; (i < 100000000) && 
-			      (*acknowledge == ((unsigned long)-1)); i++ ) ;
-#ifdef DEBUG_PROM
-		{
-			unsigned long *p = 0x0;
-			prom_print(RELOC("    4) 0x0 = 0x"));
-			prom_print_hex(*p);
-			prom_print_nl();
+		propsize = call_prom(RELOC("getprop"), 4, 1, node,
+				     RELOC("ibm,ppc-interrupt-server#s"),
+				     &interrupt_server,
+				     sizeof(interrupt_server));
+		if (propsize < 0) {
+			/* no property.  old hardware has no SMT */
+			cpu_threads = 1;
+			interrupt_server[0] = reg; /* fake it with phys id */
+		} else {
+			/* We have a threaded processor */
+			cpu_threads = propsize / sizeof(u32);
+			if (cpu_threads > MAX_CPU_THREADS) {
+				prom_print(RELOC("SMT: too many threads!\nSMT: found "));
+				prom_print_hex(cpu_threads);
+				prom_print(RELOC(", max is "));
+				prom_print_hex(MAX_CPU_THREADS);
+				prom_print_nl();
+				cpu_threads = 1; /* ToDo: panic? */
+			}
 		}
-#endif
-		if (*acknowledge == cpuid) {
-			prom_print(RELOC("ok\n"));
-			/* Set the number of active processors. */
-			_systemcfg->processorCount++;
+
+		hw_cpu_num = interrupt_server[0];
+		if (hw_cpu_num != _prom->cpu) {
+			/* Primary Thread of non-boot cpu */
+			prom_print_hex(cpuid);
+			prom_print(RELOC(" : starting cpu "));
+			prom_print(path);
+			prom_print(RELOC(" ... "));
+			call_prom(RELOC("start-cpu"), 3, 0, node,
+				  secondary_hold, cpuid);
+
+			for(i = 0; (i < 100000000) &&
+			  (*acknowledge == ((unsigned long)-1)); i++ );
+
+			if (*acknowledge == cpuid) {
+				prom_print(RELOC("ok\n"));
+				/* Set the number of active processors. */
+				_systemcfg->processorCount++;
+				_xPaca[cpuid].active = 1;
+				_xPaca[cpuid].available = 1;
+			} else {
+				prom_print(RELOC("failed: "));
+				prom_print_hex(*acknowledge);
+				prom_print_nl();
+				/* prom_panic(RELOC("cpu failed to start")); */
+			}
 		} else {
-			prom_print(RELOC("failed: "));
-			prom_print_hex(*acknowledge);
+			prom_print_hex(cpuid);
+			prom_print(RELOC(" : booting  cpu "));
+			prom_print(path);
 			prom_print_nl();
 		}
+
+		/* Init paca for secondary threads.   They start later. */
+		for (i=1; i < cpu_threads; i++) {
+			cpuid++;
+			_xPaca[cpuid].xHwProcNum = interrupt_server[i];
+			prom_print_hex(interrupt_server[i]);
+			prom_print(RELOC(" : preparing thread ... "));
+			if (_naca->smt_state) {
+				_xPaca[cpuid].available = 1;
+				prom_print(RELOC("available"));
+			} else {
+				prom_print(RELOC("not available"));
+			}
+			prom_print_nl();
+		}
+		cpuid++;
 	}
 #ifdef CONFIG_HMT
 	/* Only enable HMT on processors that provide support. */
@@ -1236,6 +1254,104 @@
 #endif
 }
 
+static void
+smt_setup(void)
+{
+	char *p, *q;
+	char my_smt_enabled = SMT_DYNAMIC;
+	unsigned long my_smt_snooze_delay;
+	ihandle prom_options = NULL;
+	char option[9];
+	unsigned long offset = reloc_offset();
+	struct naca_struct *_naca = RELOC(naca);
+	char found = 0;
+
+	if (strstr(RELOC(cmd_line), RELOC("smt-enabled="))) {
+		for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-enabled="))) != 0; ) {
+			q = p + 12;
+			if (p > RELOC(cmd_line) && p[-1] != ' ')
+				continue;
+			found = 1;
+			if (q[0] == 'o' && q[1] == 'f' &&
+			    q[2] == 'f' && (q[3] == ' ' || q[3] == '\0')) {
+				my_smt_enabled = SMT_OFF;
+			} else if (q[0]=='o' && q[1] == 'n' &&
+				   (q[2] == ' ' || q[2] == '\0')) {
+				my_smt_enabled = SMT_ON;
+			} else {
+				my_smt_enabled = SMT_DYNAMIC;
+			}
+		}
+	}
+	if (!found) {
+		prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options"));
+		if (prom_options != (ihandle) -1) {
+			call_prom(RELOC("getprop"),
+				4, 1, prom_options,
+				RELOC("ibm,smt-enabled"),
+				option, sizeof(option));
+			if (option[0] != 0) {
+				found = 1;
+				if (!strcmp(option, "off"))
+					my_smt_enabled = SMT_OFF;
+				else if (!strcmp(option, "on"))
+					my_smt_enabled = SMT_ON;
+				else
+					my_smt_enabled = SMT_DYNAMIC;
+			}
+		}
+	}
+
+	if (!found )
+		my_smt_enabled = SMT_DYNAMIC; /* default to on */
+
+	found = 0;
+	if (my_smt_enabled) {
+		if (strstr(RELOC(cmd_line), RELOC("smt-snooze-delay="))) {
+			for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-snooze-delay="))) != 0; ) {
+				q = p + 17;
+				if (p > RELOC(cmd_line) && p[-1] != ' ')
+					continue;
+				found = 1;
+				/* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */
+				my_smt_snooze_delay = 0;
+				while (*q >= '0' && *q <= '9') {
+					my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0';
+					q++;
+				}
+			}
+		}
+
+		if (!found) {
+			prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options"));
+			if (prom_options != (ihandle) -1) {
+				call_prom(RELOC("getprop"),
+					4, 1, prom_options,
+					RELOC("ibm,smt-snooze-delay"),
+					option, sizeof(option));
+				if (option[0] != 0) {
+					found = 1;
+					/* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */
+					my_smt_snooze_delay = 0;
+					q = option;
+					while (*q >= '0' && *q <= '9') {
+						my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0';
+						q++;
+					}
+				}
+			}
+		}
+
+		if (!found) {
+			my_smt_snooze_delay = 30000; /* default value */
+		}
+	} else {
+		my_smt_snooze_delay = 0; /* default value */
+	}
+	_naca->smt_snooze_delay = my_smt_snooze_delay;
+	_naca->smt_state = my_smt_enabled;
+}
+
 #ifdef CONFIG_PPCDBG
 extern char *trace_names[];	/* defined in udbg.c -- need a better interface */
 
@@ -1359,7 +1475,6 @@
 	char *p, *d;
  	unsigned long phys;
         u32 getprop_rval;
-        struct naca_struct *_naca = RELOC(naca);
         struct systemcfg *_systemcfg = RELOC(systemcfg);
 	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
 	struct prom_t *_prom = PTRRELOC(&prom);
@@ -1532,12 +1647,13 @@
         /* Initialize some system info into the Naca early... */
         mem = prom_initialize_naca(mem);
 
+	smt_setup();
+
         /* If we are on an SMP machine, then we *MUST* do the
          * following, regardless of whether we have an SMP
          * kernel or not.
          */
-        if (_systemcfg->processorCount > 1)
-	        prom_hold_cpus(mem);
+	prom_hold_cpus(mem);
 
 #ifdef DEBUG_PROM
 	prom_print(RELOC("copying OF device tree...\n"));
@@ -1697,46 +1813,6 @@
 	return DOUBLEWORD_ALIGN(mem);
 }
 
-void
-virt_irq_init(void)
-{
-	int i;
-	for (i = 0; i < NR_IRQS; i++)
-		virt_irq_to_real_map[i] = UNDEFINED_IRQ;
-	for (i = 0; i < NR_HW_IRQS; i++)
-		real_irq_to_virt_map[i] = UNDEFINED_IRQ;
-}
-
-/* Create a mapping for a real_irq if it doesn't already exist.
- * Return the virtual irq as a convenience.
- */
-unsigned long
-virt_irq_create_mapping(unsigned long real_irq)
-{
-	unsigned long virq;
-	if (naca->interrupt_controller == IC_OPEN_PIC)
-		return real_irq;	/* no mapping for openpic (for now) */
-	virq = real_irq_to_virt(real_irq);
-	if (virq == UNDEFINED_IRQ) {
-		/* Assign a virtual IRQ number */
-		if (real_irq < NR_IRQS && virt_irq_to_real(real_irq) == UNDEFINED_IRQ) {
-			/* A 1-1 mapping will work. */
-			virq = real_irq;
-		} else {
-			while (last_virt_irq < NR_IRQS &&
-			       virt_irq_to_real(++last_virt_irq) != UNDEFINED_IRQ)
-				/* skip irq's in use */;
-			if (last_virt_irq >= NR_IRQS)
-				panic("Too many IRQs are required on this system.  NR_IRQS=%d\n", NR_IRQS);
-			virq = last_virt_irq;
-		}
-		virt_irq_to_real_map[virq] = real_irq;
-		real_irq_to_virt_map[real_irq] = virq;
-	}
-	return virq;
-}
-
-
 static int __init
 prom_next_node(phandle *nodep)
 {
@@ -1866,8 +1942,6 @@
 {
 	unsigned long mem = klimit;
 
-	virt_irq_init();
-
 	mem = finish_node(allnodes, mem, NULL, 0, 0);
 	dev_tree_size = mem - (unsigned long) allnodes;
 
@@ -1972,7 +2046,7 @@
 		np->n_intrs = ipsize / isize;
 		mem_start += np->n_intrs * sizeof(struct interrupt_info);
 		for (i = 0; i < np->n_intrs; ++i) {
-		    np->intrs[i].line = openpic_to_irq(virt_irq_create_mapping(*interrupts++));
+		    np->intrs[i].line = irq_offset_up(*interrupts++);
 		    np->intrs[i].sense = 1;
 		    if (isize > 1)
 		        np->intrs[i].sense = *interrupts++;
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/ras.c linux-2.4.24-pre2/arch/ppc64/kernel/ras.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/ras.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/ras.c	2003-12-22 11:34:34.000000000 -0800
@@ -73,7 +73,7 @@
 	   (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", 
 						&len))) {
 		for(i=0; i<(len / sizeof(*ireg)); i++) {
-			request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, 
+			request_irq(irq_offset_up(*(ireg)),
 				    &ras_error_interrupt, 0, 
 				    "RAS_ERROR", NULL);
 			ireg++;
@@ -84,7 +84,7 @@
 	   (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", 
 						&len))) {
 		for(i=0; i<(len / sizeof(*ireg)); i++) {
-			request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, 
+			request_irq(irq_offset_up(*(ireg)),
 				    &ras_epow_interrupt, 0, 
 				    "RAS_EPOW", NULL);
 			ireg++;
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/rtas-proc.c linux-2.4.24-pre2/arch/ppc64/kernel/rtas-proc.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/rtas-proc.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/rtas-proc.c	2003-12-22 11:34:34.000000000 -0800
@@ -273,12 +273,19 @@
 static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf,
 		size_t count, loff_t *ppos)
 {
+	char stkbuf[40];  /* its small, its on stack */
 	struct rtc_time tm;
 	unsigned long nowtime;
 	char *dest;
 	int error;
 
-	nowtime = simple_strtoul(buf, &dest, 10);
+	if (39 < count)
+		count = 39;
+	if (copy_from_user(stkbuf, buf, count))
+		return -EFAULT;
+
+	stkbuf[count] = 0;
+	nowtime = simple_strtoul(stkbuf, &dest, 10);
 	if (*dest != '\0' && *dest != '\n') {
 		printk("ppc_rtas_poweron_write: Invalid time\n");
 		return count;
@@ -299,18 +306,23 @@
 static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf,
 		size_t count, loff_t *ppos)
 {
+	char stkbuf[40];  /* its small, its on stack */
 	int n;
+
 	if (power_on_time == 0)
-		n = sprintf(buf, "Power on time not set\n");
+		n = snprintf(stkbuf, 40, "Power on time not set\n");
 	else
-		n = sprintf(buf, "%lu\n", power_on_time);
+		n = snprintf(stkbuf, 40, "%lu\n", power_on_time);
 
-	if (*ppos >= strlen(buf))
+	int sn = strlen(stkbuf) +1;
+	if (*ppos >= sn)
 		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
+	if (n > sn - *ppos)
+		n = sn - *ppos;
 	if (n > count)
 		n = count;
+	if (copy_to_user(buf, stkbuf + (*ppos), n))
+		return -EFAULT;
 	*ppos += n;
 	return n;
 }
@@ -323,11 +335,17 @@
 {
 	unsigned long hex;
 
-	strcpy(progress_led, buf); /* save the string */
+	if (count >= MAX_LINELENGTH)
+		count = MAX_LINELENGTH -1;
+	if (copy_from_user(progress_led, buf, count))
+		return -EFAULT;
+
+	progress_led[count] = 0;
+
 	/* Lets see if the user passed hexdigits */
-	hex = simple_strtoul(buf, NULL, 10);
-	
-	ppc_md.progress ((char *)buf, hex);
+	hex = simple_strtoul(progress_led, NULL, 10);
+
+	ppc_md.progress((char *)progress_led, hex);
 	return count;
 
 	/* clear the line */ /* ppc_md.progress("                   ", 0xffff);*/
@@ -336,15 +354,32 @@
 static ssize_t ppc_rtas_progress_read(struct file * file, char * buf,
 		size_t count, loff_t *ppos)
 {
-	int n = 0;
-	if (progress_led != NULL)
-		n = sprintf (buf, "%s\n", progress_led);
-	if (*ppos >= strlen(buf))
+	int n = 0, sn;
+	
+	if (progress_led == NULL)
 		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
+
+	char * tmpbuf = kmalloc(MAX_LINELENGTH, GFP_KERNEL);
+	if (!tmpbuf) {
+		printk(KERN_ERR "error: kmalloc failed\n");
+		return -ENOMEM;
+	}
+	n = sprintf (tmpbuf, "%s\n", progress_led);
+
+	sn = strlen (tmpbuf) +1;
+	if (*ppos >= sn) {
+		kfree(tmpbuf);
+		return 0;
+	}
+	if (n > sn - *ppos)
+		n = sn - *ppos;
 	if (n > count)
 		n = count;
+	if (copy_to_user(buf, tmpbuf + (*ppos), n)) {
+		kfree(tmpbuf);
+		return -EFAULT;
+	}
+	kfree(tmpbuf);
 	*ppos += n;
 	return n;
 }
@@ -355,12 +390,19 @@
 static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, 
 		size_t count, loff_t *ppos)
 {
+	char stkbuf[40];  /* its small, its on stack */
 	struct rtc_time tm;
 	unsigned long nowtime;
 	char *dest;
 	int error;
 
-	nowtime = simple_strtoul(buf, &dest, 10);
+	if (39 < count)
+		count = 39;
+	if (copy_from_user(stkbuf, buf, count))
+		return -EFAULT;
+
+	stkbuf[count] = 0;
+	nowtime = simple_strtoul(stkbuf, &dest, 10);
 	if (*dest != '\0' && *dest != '\n') {
 		printk("ppc_rtas_clock_write: Invalid time\n");
 		return count;
@@ -388,21 +430,27 @@
 	year = ret[0]; mon  = ret[1]; day  = ret[2];
 	hour = ret[3]; min  = ret[4]; sec  = ret[5];
 
+	char stkbuf[40];  /* its small, its on stack */
+
 	if (error != 0){
 		printk(KERN_WARNING "error: reading the clock returned: %s\n", 
 				ppc_rtas_process_error(error));
-		n = sprintf (buf, "0");
+		n = snprintf(stkbuf, 40, "0");
 	} else { 
-		n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec));
+		n = snprintf(stkbuf, 40, "%lu\n", mktime(year, mon, day, hour, min, sec));
 	}
 	kfree(ret);
 
-	if (*ppos >= strlen(buf))
+	int sn = strlen(stkbuf) +1;
+	if (*ppos >= sn)
 		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
+	if (n > sn - *ppos)
+		n = sn - *ppos;
 	if (n > count)
 		n = count;
+	if (copy_to_user(buf, stkbuf + (*ppos), n))
+		return -EFAULT;
+
 	*ppos += n;
 	return n;
 }
@@ -751,7 +799,7 @@
 		n += check_location_string(ret, buffer + n);
 		n += sprintf ( buffer+n, " ");
 		/* see how many characters we have printed */
-		sprintf ( t, "%s ", ret);
+		snprintf( t, 50, "%s ", ret);
 
 		pos += strlen(t);
 		if (pos >= llen) pos=0;
@@ -764,10 +812,18 @@
 static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf,
 		size_t count, loff_t *ppos)
 {
+	char stkbuf[40];  /* its small, its on stack */
 	unsigned long freq;
 	char *dest;
 	int error;
-	freq = simple_strtoul(buf, &dest, 10);
+
+	if (39 < count)
+		count = 39;
+	if (copy_from_user(stkbuf, buf, count))
+		return -EFAULT;
+
+	stkbuf[count] = 0;
+	freq = simple_strtoul(stkbuf, &dest, 10);
 	if (*dest != '\0' && *dest != '\n') {
 		printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n");
 		return count;
@@ -785,15 +841,21 @@
 static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf,
 		size_t count, loff_t *ppos)
 {
-	int n;
-	n = sprintf(buf, "%lu\n", rtas_tone_frequency);
+	int n, sn;
+	char stkbuf[40];  /* its small, its on stack */
 
-	if (*ppos >= strlen(buf))
+	n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_frequency);
+
+	sn = strlen(stkbuf) +1;
+	if (*ppos >= sn)
 		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
+	if (n > sn - *ppos)
+		n = sn - *ppos;
 	if (n > count)
 		n = count;
+	if (copy_to_user(buf, stkbuf + (*ppos), n))
+		return -EFAULT;
+
 	*ppos += n;
 	return n;
 }
@@ -803,10 +865,18 @@
 static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf,
 		size_t count, loff_t *ppos)
 {
+	char stkbuf[40];  /* its small, its on stack */
 	unsigned long volume;
 	char *dest;
 	int error;
-	volume = simple_strtoul(buf, &dest, 10);
+
+	if (39 < count)
+		count = 39;
+	if (copy_from_user(stkbuf, buf, count))
+		return -EFAULT;
+
+	stkbuf[count] = 0;
+	volume = simple_strtoul(stkbuf, &dest, 10);
 	if (*dest != '\0' && *dest != '\n') {
 		printk("ppc_rtas_tone_volume_write: Invalid tone volume\n");
 		return count;
@@ -826,15 +896,20 @@
 static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf,
 		size_t count, loff_t *ppos)
 {
-	int n;
-	n = sprintf(buf, "%lu\n", rtas_tone_volume);
+	int n, sn;
+	char stkbuf[40];  /* its small, its on stack */
 
-	if (*ppos >= strlen(buf))
+	n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_volume);
+	sn = strlen(stkbuf) +1;
+	if (*ppos >= sn)
 		return 0;
-	if (n > strlen(buf) - *ppos)
-		n = strlen(buf) - *ppos;
+	if (n > sn - *ppos)
+		n = sn - *ppos;
 	if (n > count)
 		n = count;
+	if (copy_to_user(buf, stkbuf + (*ppos), n))
+		return -EFAULT;
+
 	*ppos += n;
 	return n;
 }
@@ -864,7 +939,7 @@
 static ssize_t ppc_rtas_errinjct_write(struct file * file, const char * buf,
 				       size_t count, loff_t *ppos)
 {
- 
+ 	char * tmpbuf;
 	char * ei_token;
 	char * workspace = NULL;
 	size_t max_len;
@@ -878,16 +953,26 @@
 		max_len = ERRINJCT_TOKEN_LEN;
 	}
 
-	token_len = strnlen(buf, max_len);
+	tmpbuf = (char *) kmalloc(max_len, GFP_KERNEL);
+	if (!tmpbuf) {
+		printk(KERN_WARNING "error: kmalloc failed\n");
+		return -ENOMEM;
+	}
+	if (copy_from_user (tmpbuf, buf, max_len)) {
+		kfree(tmpbuf);
+		return -EFAULT;
+	}
+	token_len = strnlen(tmpbuf, max_len);
 	token_len++; /* Add one for the null termination */
     
 	ei_token = (char *)kmalloc(token_len, GFP_KERNEL);
 	if (!ei_token) {
 		printk(KERN_WARNING "error: kmalloc failed\n");
+		kfree(tmpbuf);
 		return -ENOMEM;
 	}
 
-	strncpy(ei_token, buf, token_len);
+	strncpy(ei_token, tmpbuf, token_len);
     
 	if (count > token_len + WORKSPACE_SIZE) {
 		count = token_len + WORKSPACE_SIZE;
@@ -907,11 +992,12 @@
 		workspace = (char *)kmalloc(max_len, GFP_KERNEL);
 		if (!workspace) {
 			printk(KERN_WARNING "error: failed kmalloc\n");
+			kfree(tmpbuf);
 			kfree(ei_token);
 			return -ENOMEM;
 		}
 	
-		memcpy(workspace, buf, max_len);
+		memcpy(workspace, tmpbuf, max_len);
 	}
 
 	rc = rtas_errinjct(open_token, ei_token, workspace);
@@ -920,6 +1006,7 @@
 		kfree(workspace);
 	}
 	kfree(ei_token);
+	kfree(tmpbuf);
 
 	return rc < 0 ? rc : count;
 }
@@ -940,32 +1027,36 @@
 				      size_t count, loff_t *ppos) 
 {
 	char * buffer;
-	int i;
+	int i, sn;
 	int n = 0;
 
-	buffer = (char *)kmalloc(MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1),
-				 GFP_KERNEL);
+	int m = MAX_ERRINJCT_TOKENS * (ERRINJCT_TOKEN_LEN+1);
+	buffer = (char *)kmalloc(m, GFP_KERNEL);
 	if (!buffer) {
 		printk(KERN_ERR "error: kmalloc failed\n");
 		return -ENOMEM;
 	}
 
 	for (i = 0; i < MAX_ERRINJCT_TOKENS && ei_token_list[i].value; i++) {
-		n += sprintf(buffer+n, ei_token_list[i].name);
-		n += sprintf(buffer+n, "\n");
+		n += snprintf(buffer+n, m-n, ei_token_list[i].name);
+		n += snprintf(buffer+n, m-n, "\n");
 	}
 
-	if (*ppos >= strlen(buffer)) {
+	sn = strlen(buffer) +1;
+	if (*ppos >= sn) {
 		kfree(buffer);
 		return 0;
 	}
-	if (n > strlen(buffer) - *ppos)
-		n = strlen(buffer) - *ppos;
+	if (n > sn - *ppos)
+		n = sn - *ppos;
 
 	if (n > count)
 		n = count;
 
-	memcpy(buf, buffer + *ppos, n);
+	if (copy_to_user(buf, buffer + *ppos, n)) {
+		kfree(buffer);
+		return -EFAULT;
+	}
 
 	*ppos += n;
 
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/rtc.c linux-2.4.24-pre2/arch/ppc64/kernel/rtc.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/rtc.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/rtc.c	2003-12-22 11:34:34.000000000 -0800
@@ -96,6 +96,7 @@
 	switch (cmd) {
 	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
 	{
+		memset(&wtime, 0, sizeof(struct rtc_time));
 		ppc_md.get_rtc_time(&wtime);
 		break;
 	}
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/scanlog.c linux-2.4.24-pre2/arch/ppc64/kernel/scanlog.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/scanlog.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/scanlog.c	2003-12-22 11:34:34.000000000 -0800
@@ -129,17 +129,25 @@
 static ssize_t scanlog_write(struct file * file, const char * buf,
 			     size_t count, loff_t *ppos)
 {
+	char stkbuf[20];
 	unsigned long status;
 
+	if (count > 19)
+		count = 19;
+	if (copy_from_user (stkbuf, buf, count))
+		return -EFAULT;
+
+	stkbuf[count] = 0;
+
 	if (buf) {
-		if (strncmp(buf, "reset", 5) == 0) {
+		if (strncmp(stkbuf, "reset", 5) == 0) {
 			DEBUG("reset scanlog\n");
 			status = rtas_call(ibm_scan_log_dump, 2, 1, NULL, NULL, 0);
 			DEBUG("rtas returns %ld\n", status);
-		} else if (strncmp(buf, "debugon", 7) == 0) {
+		} else if (strncmp(stkbuf, "debugon", 7) == 0) {
 			printk(KERN_ERR "scanlog: debug on\n");
 			scanlog_debug = 1;
-		} else if (strncmp(buf, "debugoff", 8) == 0) {
+		} else if (strncmp(stkbuf, "debugoff", 8) == 0) {
 			printk(KERN_ERR "scanlog: debug off\n");
 			scanlog_debug = 0;
 		}
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/setup.c linux-2.4.24-pre2/arch/ppc64/kernel/setup.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/setup.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/kernel/setup.c	2003-12-22 11:34:34.000000000 -0800
@@ -62,6 +62,8 @@
 extern void pSeries_init_early( void );
 extern void pSeriesLP_init_early(void);
 extern void mm_init_ppc64( void ); 
+extern void pseries_secondary_smp_init(unsigned long);
+extern void vpa_init(int cpu);
 
 unsigned long decr_overclock = 1;
 unsigned long decr_overclock_proc0 = 1;
@@ -107,6 +109,8 @@
 void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
 		  unsigned long r6, unsigned long r7)
 {
+	unsigned int ret, i;
+
 	/* This should be fixed properly in kernel/resource.c */
 	iomem_resource.end = MEM_SPACE_LIMIT;
 
@@ -143,7 +147,22 @@
 		udbg_printf("---- start early boot console ----\n");
 	}
 
-	printk("Starting Linux PPC64 %s\n", UTS_RELEASE);
+	if (systemcfg->platform & PLATFORM_PSERIES) {
+		finish_device_tree();
+		chrp_init(r3, r4, r5, r6, r7);
+
+		/* Start secondary threads on SMT systems */
+		for (i = 0; i < NR_CPUS; i++) {
+			if(cpu_available(i)  && !cpu_possible(i)) {
+				printk("%16.16lx : starting thread\n", i);
+				rtas_call(rtas_token("start-cpu"), 3, 1,
+					  (void *)&ret,
+					  i, *((unsigned long *)pseries_secondary_smp_init), i);
+				paca[i].active = 1;
+				systemcfg->processorCount++;
+			}
+		}
+	}
 
 	printk("-----------------------------------------------------\n");
 	printk("naca                          = 0x%p\n", naca);
@@ -160,13 +179,16 @@
 	printk("htab_data.num_ptegs           = 0x%lx\n", htab_data.htab_num_ptegs);
 	printk("-----------------------------------------------------\n");
 
-	if (systemcfg->platform & PLATFORM_PSERIES) {
-		finish_device_tree();
-		chrp_init(r3, r4, r5, r6, r7);
-	}
+	printk("Starting Linux PPC64 %s\n", UTS_RELEASE);
 
 	mm_init_ppc64();
 
+	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
+		vpa_init(0);
+	}
+
+	idle_setup();
+
 	switch (systemcfg->platform) {
 	    case PLATFORM_ISERIES_LPAR:
 		iSeries_init();
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/signal.c linux-2.4.24-pre2/arch/ppc64/kernel/signal.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/signal.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/signal.c	2003-12-22 11:34:34.000000000 -0800
@@ -296,7 +296,9 @@
 			newsp = (current->sas_ss_sp + current->sas_ss_size);
 	}
 
-        return (void *)((newsp - frame_size) & -8ul);
+	/* The ABI requires quadword alignment for the stack. */
+	return (void *)((newsp - frame_size) & -16ul);
+
 }
 
 static int
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/signal32.c linux-2.4.24-pre2/arch/ppc64/kernel/signal32.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/signal32.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/signal32.c	2003-12-22 11:34:34.000000000 -0800
@@ -761,7 +761,7 @@
 	memset (d, 0, sizeof(siginfo_t32));
 	d->si_signo = s->si_signo;
 	d->si_errno = s->si_errno;
-	d->si_code = s->si_code & 0xffff;
+	d->si_code = (short)s->si_code;
 	if (s->si_signo >= SIGRTMIN) {
 		d->si_pid = s->si_pid;
 		d->si_uid = s->si_uid;
@@ -1067,7 +1067,8 @@
 	if (ka->sa.sa_flags & SA_SIGINFO)
 	{
 		siginfo64to32(&siginfo32bit,info);
-		*newspp -= sizeof(*rt_stack_frame);
+		/* The ABI requires quadword alignment for the stack. */
+		*newspp = (*newspp - sizeof(*rt_stack_frame)) & -16ul;
 		rt_stack_frame = (struct rt_sigframe_32 *) (u64)(*newspp) ;
     
 		if (verify_area(VERIFY_WRITE, rt_stack_frame, sizeof(*rt_stack_frame)))
@@ -1095,7 +1096,7 @@
 		}
 	} else {
 		/* Put a sigcontext on the stack */
-		*newspp -= sizeof(*sc);
+		*newspp = (*newspp - sizeof(*sc)) & -16ul;
 		sc = (struct sigcontext32 *)(u64)*newspp;
 		if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
 			goto badframe;
@@ -1310,7 +1311,8 @@
 			newsp = (current->sas_ss_sp + current->sas_ss_size);
 		else
 			newsp = regs->gpr[1];
-		newsp = frame = newsp - sizeof(struct sigregs32);
+		/* The ABI requires quadword alignment for the stack. */
+		newsp = frame = (newsp - sizeof(struct sigregs32)) & -16ul;
 
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal32(signr, ka, &info, oldset, regs, &newsp, frame);
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/smp.c linux-2.4.24-pre2/arch/ppc64/kernel/smp.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/smp.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/smp.c	2003-12-22 11:34:34.000000000 -0800
@@ -28,7 +28,7 @@
 #define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
 #include <linux/init.h>
-/* #include <linux/openpic.h> */
+#include <linux/mm.h>
 #include <linux/spinlock.h>
 #include <linux/cache.h>
 
@@ -52,9 +52,10 @@
 #include <asm/ppcdebug.h>
 #include "open_pic.h"
 #include <asm/machdep.h>
+#include <asm/cputable.h>
 #if defined(CONFIG_DUMP) || defined(CONFIG_DUMP_MODULE)
 int (*dump_ipi_function_ptr)(struct pt_regs *);
-#include <linux/dump.h>
+#include <asm/dump.h>
 #endif
 
 #ifdef CONFIG_KDB
@@ -90,6 +91,9 @@
 void xics_setup_cpu(void);
 void xics_cause_IPI(int cpu);
 
+long h_register_vpa(unsigned long flags, unsigned long proc,
+		    unsigned long vpa);
+
 /*
  * XICS only has a single IPI, so encode the messages per CPU
  */
@@ -293,6 +297,17 @@
 	}
 }
 
+void vpa_init(int cpu)
+{
+	unsigned long flags;
+
+	/* Register the Virtual Processor Area (VPA) */
+	printk(KERN_INFO "register_vpa: cpu 0x%x\n", cpu);
+	flags = 1UL << (63 - 18);
+	paca[cpu].xLpPaca.xSLBCount = 64; /* SLB restore highwater mark */
+	register_vpa(flags, cpu, __pa((unsigned long)&(paca[cpu].xLpPaca)));
+}
+
 static void
 smp_chrp_setup_cpu(int cpu_nr)
 {
@@ -434,8 +449,17 @@
 
 void smp_send_reschedule(int cpu)
 {
+	if ((systemcfg->platform & PLATFORM_LPAR) &&
+	    (paca[cpu].yielded == 1)) {
+#ifdef CONFIG_PPC_ISERIES
+		HvCall_sendLpProd(cpu);
+#else
+		prod_processor(cpu);
+#endif
+	} else {
 	smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
 }
+}
 
 #ifdef CONFIG_XMON
 void smp_send_xmon_break(int cpu)
@@ -564,6 +588,7 @@
 	ret = 0;
 
  out:
+	call_data = NULL;
 	HMT_medium();
 	spin_unlock_bh(&call_lock);
 	return ret;
@@ -571,9 +596,20 @@
 
 void smp_call_function_interrupt(void)
 {
-	void (*func) (void *info) = call_data->func;
-	void *info = call_data->info;
-	int wait = call_data->wait;
+	void (*func) (void *info);
+	void *info;
+	int wait;
+
+
+	/* call_data will be NULL if the sender timed out while
+	 * waiting on us to receive the call.
+	 */
+	if (!call_data)
+		return;
+
+	func = call_data->func;
+	info = call_data->info;
+	wait = call_data->wait;
 
 	/*
 	 * Notify initiating CPU that I've grabbed the data and am
@@ -773,6 +809,12 @@
 	current->active_mm = &init_mm;
 	smp_callin();
 
+	get_paca()->yielded = 0;
+
+	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
+		vpa_init(cpu);
+	}
+
 	/* Go into the idle loop. */
 	return cpu_idle(NULL);
 }
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/stab.c linux-2.4.24-pre2/arch/ppc64/kernel/stab.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/stab.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/stab.c	2003-12-22 11:34:34.000000000 -0800
@@ -159,7 +159,6 @@
 inline void make_slbe(unsigned long esid, unsigned long vsid, int large)
 {
 	unsigned long entry, castout_entry;
-	slb_dword0 castout_esid_data;
 	union {
 		unsigned long word0;
 		slb_dword0    data;
@@ -217,23 +216,37 @@
 
 	PMC_SW_PROCESSOR(stab_capacity_castouts); 
 
+	/*
+	 * Never cast out the segment for our own stack. Since we
+	 * dont invalidate the ERAT we could have a valid translation
+	 * for our stack during the first part of exception exit
+	 * which gets invalidated due to a tlbie from another cpu at a
+	 * non recoverable point (after setting srr0/1) - Anton
+	 */
+
 	castout_entry = get_paca()->xStab_data.next_round_robin;
-	__asm__ __volatile__("slbmfee  %0,%1" 
-			     : "=r" (castout_esid_data) 
-			     : "r" (castout_entry)); 
-
-	entry = castout_entry; 
-	castout_entry++; 
-	if(castout_entry >= naca->slb_size) {
-		castout_entry = 1; 
-	}
+	do {
+		entry = castout_entry;
+		castout_entry++;
+		if (castout_entry >= naca->slb_size)
+			castout_entry = 1;
+		asm volatile("slbmfee  %0,%1" : "=r" (esid_data) : "r" (entry));
+	} while (esid_data.data.esid == GET_ESID((unsigned long)_get_SP()));
+	
 	get_paca()->xStab_data.next_round_robin = castout_entry;
 
-	/* Invalidate the old entry. */
-	castout_esid_data.v = 0; /* Set the class to 0 */
-	/* slbie not needed as the previous mapping is still valid. */
-	__asm__ __volatile__("slbie  %0" : : "r" (castout_esid_data)); 
-	
+	/* We're executing this code on the interrupt stack, so the
+	 * above code might pick the kernel stack segment as the victim.
+	 *
+	 * Because of this, we need to invalidate the old entry. We need
+	 * to do this since it'll otherwise be in the ERAT and might come
+	 * back and haunt us if it get's thrown out of there at the wrong
+	 * time (i.e. similar to throwing out our own stack above).
+	 */
+
+	esid_data.data.v = 0;
+	__asm__ __volatile__("slbie  %0" : : "r" (esid_data));
+
 	/* 
 	 * Write the new SLB entry.
 	 */
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/sys_ppc32.c linux-2.4.24-pre2/arch/ppc64/kernel/sys_ppc32.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/sys_ppc32.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/kernel/sys_ppc32.c	2003-12-22 11:34:34.000000000 -0800
@@ -104,11 +104,37 @@
 	return ret;
 }
 
+asmlinkage int sys32_ustat(__kernel_dev_t32 dev, struct ustat32 * ubuf)
+{
+
+	struct super_block *s;
+	struct ustat32 tmp;
+	struct statfs sbuf;
+	int err = -EINVAL;
+
+	s = get_super(to_kdev_t(dev));
+	if (s == NULL)
+		goto out;
+	err = vfs_statfs(s, &sbuf);
+	drop_super(s);
+	if (err)
+		goto out;
 
+	memset(&tmp,0,sizeof(struct ustat));
+	tmp.f_tfree = sbuf.f_bfree;
+	tmp.f_tinode = sbuf.f_ffree;
+
+	err = copy_to_user(ubuf, &tmp, sizeof(struct ustat32)) ? -EFAULT : 0;
+
+out:
+	return err;
+
+}
 
 struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
 
 typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
+typedef __kernel_ssize_t32 ssize_t32;
 
 static long do_readv_writev32(int type, struct file *file,
 			      const struct iovec32 *vector, u32 count)
@@ -149,6 +175,11 @@
 		ivp->iov_len = (__kernel_size_t) len;
 		vector++;
 		ivp++;
+		if ((len < 0) || (tot_len != (ssize_t32)tot_len)) {
+			if (iov != iovstack)
+				kfree(iov);
+			return -EINVAL;
+		}
 		i--;
 	}
 
@@ -467,7 +498,7 @@
 };
                                 
 
-extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
+extern asmlinkage long sys_quotactl(unsigned int cmd, const char *special, qid_t id, caddr_t addr);
 
 /* Note: it is necessary to treat cmd and id as unsigned ints, 
  * with the corresponding cast to a signed int to insure that the 
@@ -476,9 +507,9 @@
  */
 asmlinkage long sys32_quotactl(u32 cmd_parm, const char *special, u32 id_parm, caddr_t addr)
 {
-	int cmd = (int)cmd_parm;
-	int id  = (int)id_parm;
-	int cmds = cmd >> SUBCMDSHIFT;
+	unsigned int cmd = cmd_parm;
+	qid_t id  = (qid_t)id_parm;
+	unsigned int cmds = cmd >> SUBCMDSHIFT;
 	int err;
 	struct v1c_mem_dqblk d;
 	mm_segment_t old_fs;
@@ -995,19 +1026,21 @@
 
 static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
 {
-	int err;
-	
-	err = put_user (kbuf->f_type, &ubuf->f_type);
-	err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
-	err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
-	err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
-	err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
-	err |= __put_user (kbuf->f_files, &ubuf->f_files);
-	err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
-	err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
-	err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
-	err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
-	return err;
+	struct statfs32 tmp;
+	memset(&tmp, 0, sizeof(tmp));
+
+	tmp.f_type = kbuf->f_type;
+	tmp.f_bsize = kbuf->f_bsize;
+	tmp.f_blocks = kbuf->f_blocks;
+	tmp.f_bfree = kbuf->f_bfree;
+	tmp.f_bavail = kbuf->f_bavail;
+	tmp.f_files = kbuf->f_files;
+	tmp.f_ffree = kbuf->f_ffree;
+	tmp.f_namelen = kbuf->f_namelen;
+	tmp.f_fsid.val[0] = kbuf->f_fsid.val[0];
+	tmp.f_fsid.val[1] = kbuf->f_fsid.val[1];
+
+	return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
 
 extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
@@ -2567,7 +2600,7 @@
 	err = -EFAULT;
 	if (get_user(pad, (u32 *)uptr))
 		return err;
-	if (third == SETVAL)
+	if ((third & (~IPC_64)) == SETVAL)
 		fourth.val = (int)pad;
 	else
 		fourth.__pad = (void *)A(pad);
@@ -3488,7 +3521,7 @@
 	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
 		return -EFAULT;
 	if(kern_msg.msg_iovlen > UIO_MAXIOV)
-		return -EINVAL;
+		return -EMSGSIZE;
 	err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
 	if (err < 0)
 		goto out;
@@ -3726,7 +3759,7 @@
 	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
 		return -EFAULT;
 	if(kern_msg.msg_iovlen > UIO_MAXIOV)
-		return -EINVAL;
+		return -EMSGSIZE;
 
 	uaddr = kern_msg.msg_name;
 	uaddr_len = &user_msg->msg_namelen;
@@ -3987,8 +4020,10 @@
 	regs->nip = nip;
 	regs->gpr[1] = sp;
 	regs->msr = MSR_USER32;
+#ifndef CONFIG_SMP
 	if (last_task_used_math == current)
 		last_task_used_math = 0;
+#endif
 	current->thread.fpscr = 0;
 }
 
@@ -4607,8 +4642,6 @@
 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
 				     size_t count, loff_t pos);
 
-typedef __kernel_ssize_t32 ssize_t32;
-
 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
 				 __kernel_size_t32 count, u32 reg6, u32 poshi, u32 poslo)
 {
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/vio.c linux-2.4.24-pre2/arch/ppc64/kernel/vio.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/vio.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/kernel/vio.c	2003-12-22 11:34:34.000000000 -0800
@@ -0,0 +1,503 @@
+/*
+ * IBM PowerPC Virtual I/O Infrastructure Support.
+ *
+ * Dave Engebretsen engebret@us.ibm.com
+ *    Copyright (c) 2003 Dave Engebretsen
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/pci.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <asm/rtas.h>
+#include <asm/pci_dma.h>
+#include <asm/dma.h>
+#include <asm/ppcdebug.h>
+#include <asm/vio.h>
+#include <asm/hvcall.h>
+
+extern struct TceTable *build_tce_table(struct TceTable *tbl);
+
+extern dma_addr_t get_tces(struct TceTable *, unsigned order,
+			   void *page, unsigned numPages, int direction);
+extern void tce_free(struct TceTable *tbl, dma_addr_t dma_addr,
+		     unsigned order, unsigned num_pages);
+
+
+static struct vio_bus vio_bus;
+static LIST_HEAD(registered_vio_drivers);
+int vio_num_address_cells;
+EXPORT_SYMBOL(vio_num_address_cells);
+
+/**
+ * vio_register_driver: - Register a new vio driver
+ * @drv:	The vio_driver structure to be registered.
+ *
+ * Adds the driver structure to the list of registered drivers
+ * Returns the number of vio devices which were claimed by the driver
+ * during registration.  The driver remains registered even if the
+ * return value is zero.
+ */
+int vio_register_driver(struct vio_driver *drv)
+{
+	int count = 0;
+	struct vio_dev *dev;
+	const struct vio_device_id* id;
+	/*
+	 * Walk the vio_bus, find devices for this driver, and
+	 * call back into the driver probe interface.
+	 */
+
+	list_for_each_entry(dev, &vio_bus.devices, devices_list) {
+		id = vio_match_device(drv->id_table, dev);
+		if(drv && id) {
+			if (0 == drv->probe(dev, id)) {
+				dev->driver = drv;
+				count++;
+			}
+		}
+	}
+
+	list_add_tail(&drv->node, &registered_vio_drivers);
+
+	return count;
+}
+EXPORT_SYMBOL(vio_register_driver);
+
+/**
+ * vio_unregister_driver - Remove registration of vio driver.
+ * @driver:	The vio_driver struct to be removed form registration
+ *
+ * Searches for devices that are assigned to the driver and calls
+ * driver->remove() for each one.  Removes the driver from the list
+ * of registered drivers.  Returns the number of devices that were
+ * assigned to that driver.
+ */
+int vio_unregister_driver(struct vio_driver *driver)
+{
+	struct vio_dev *dev;
+	int devices_found = 0;
+
+	list_for_each_entry(dev, &vio_bus.devices, devices_list) {
+		if (dev->driver == driver) {
+			driver->remove(dev);
+			dev->driver = NULL;
+			devices_found++;
+		}
+	}
+
+	list_del(&driver->node);
+
+	return devices_found;
+}
+EXPORT_SYMBOL(vio_unregister_driver);
+
+/**
+ * vio_match_device: - Tell if a VIO device has a matching VIO device id structure.
+ * @ids: 	array of VIO device id structures to search in
+ * @dev: 	the VIO device structure to match against
+ *
+ * Used by a driver to check whether a VIO device present in the
+ * system is in its list of supported devices. Returns the matching
+ * vio_device_id structure or NULL if there is no match.
+ */
+const struct vio_device_id *
+vio_match_device(const struct vio_device_id *ids, const struct vio_dev *dev)
+{
+	while (ids->type) {
+		if ((strncmp(dev->archdata->type, ids->type, strlen(ids->type)) == 0) &&
+			device_is_compatible((struct device_node*)dev->archdata, ids->compat))
+			return ids;
+		ids++;
+	}
+	return NULL;
+}
+
+/**
+ * vio_bus_init: - Initialize the virtual IO bus
+ */
+int __init
+vio_bus_init(void)
+{
+	struct device_node *node_vroot, *node_vdev;
+
+	printk("vio_bus_init: start\n");
+
+	INIT_LIST_HEAD(&vio_bus.devices);
+
+	/*
+	 * Create device node entries for each virtual device
+	 * identified in the device tree.
+	 * Functionally takes the place of pci_scan_bus
+	 */
+	node_vroot = find_devices("vdevice");
+	if (!node_vroot) {
+		printk(KERN_WARNING "vio_bus_init: no /vdevice node\n");
+		return 0;
+	}
+
+	vio_num_address_cells = prom_n_addr_cells(node_vroot->child);
+
+	for (node_vdev = node_vroot->child;
+			node_vdev != NULL;
+			node_vdev = node_vdev->sibling) {
+		printk(KERN_INFO "vio_bus_init: processing %p\n", node_vdev);
+
+		vio_register_device(node_vdev);
+	}
+
+	printk(KERN_INFO "vio_bus_init: done\n");
+
+	return 0;
+}
+
+__initcall(vio_bus_init);
+
+
+/**
+ * vio_register_device: - Register a new vio device.
+ * @archdata:	The OF node for this device.
+ *
+ * Creates and initializes a vio_dev structure from the data in
+ * node_vdev (archdata) and adds it to the list of virtual devices.
+ * Returns a pointer to the created vio_dev or NULL if node has
+ * NULL device_type or compatible fields.
+*/
+struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev)
+{
+	struct vio_dev *dev;
+	unsigned int *unit_address;
+	unsigned int *irq_p;
+
+	/* guarantee all vio_devs have 'device_type' field*/
+	if ((NULL == node_vdev->type)) {
+		printk(KERN_WARNING "vio_register_device: node %s missing 'device_type' "
+			, node_vdev->name?node_vdev->name:"UNKNOWN");
+		return NULL;
+	}
+
+	unit_address = (unsigned int *)get_property(node_vdev, "reg", NULL);
+	if(!unit_address) {
+		printk(KERN_WARNING "Can't find %s reg property\n", node_vdev->name?node_vdev->name:"UNKNOWN_DEVICE");
+		return NULL;
+	}
+
+	/* allocate a vio_dev for this node */
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	memset(dev, 0, sizeof(*dev));
+
+	dev->archdata = (void*)node_vdev; /* to become of_get_node(node_vdev); */
+	dev->bus = &vio_bus;
+	dev->unit_address = *unit_address;
+	dev->tce_table = vio_build_tce_table(dev);
+
+	irq_p = (unsigned int *) get_property(node_vdev, "interrupts", 0);
+	if(irq_p) {
+		dev->irq = irq_offset_up(*irq_p);
+	} else {
+		dev->irq = (unsigned int) -1;
+	}
+
+	list_add_tail(&dev->devices_list, &vio_bus.devices);
+
+	return dev;
+}
+
+/**
+ * vio_find_driver: - Find driver for vio_dev.
+ * @dev:	Device to search for a driver.
+ *
+ * Walks the registered_vio_drivers list calling vio_match_device()
+ * for every driver in the list. If there is a match, calls the
+ * driver's probe().
+ * Returns a pointer to the matched driver or NULL if driver is not
+ * found.
+*/
+struct vio_driver * vio_find_driver(struct vio_dev* dev)
+{
+	struct vio_driver *driver;
+	list_for_each_entry(driver, &registered_vio_drivers, node) {
+		if(driver && vio_match_device(driver->id_table, dev)) {
+			if (0 < driver->probe(dev, NULL)) {
+				dev->driver = driver;
+				return driver;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * vio_get_attribute: - get attribute for virtual device
+ * @vdev:	The vio device to get property.
+ * @which:	The property/attribute to be extracted.
+ * @length:	Pointer to length of returned data size (unused if NULL).
+ *
+ * Calls prom.c's get_property() to return the value of the
+ * attribute specified by the preprocessor constant @which
+*/
+const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
+{
+	return get_property((struct device_node *)vdev->archdata, (char*)which, length);
+}
+EXPORT_SYMBOL(vio_get_attribute);
+
+/**
+ * vio_build_tce_table: - gets the dma information from OF and builds the TCE tree.
+ * @dev: the virtual device.
+ *
+ * Returns a pointer to the built tce tree, or NULL if it can't
+ * find property.
+*/
+struct TceTable * vio_build_tce_table(struct vio_dev *dev)
+{
+	unsigned int *dma_window;
+	struct TceTable *newTceTable;
+	unsigned long offset;
+	unsigned long size;
+	int dma_window_property_size;
+
+	dma_window = (unsigned int *) get_property((struct device_node *)dev->archdata, "ibm,my-dma-window", &dma_window_property_size);
+	if(!dma_window) {
+		return NULL;
+	}
+
+	newTceTable = (struct TceTable *) kmalloc(sizeof(struct TceTable), GFP_KERNEL);
+
+	/* RPA docs say that #address-cells is always 1 for virtual
+		devices, but some older boxes' OF returns 2.  This should
+		be removed by GA, unless there is legacy OFs that still
+		have 2 for #address-cells */
+	size = ((dma_window[1+vio_num_address_cells]
+		>> PAGE_SHIFT) << 3) >> PAGE_SHIFT;
+
+	/* This is just an ugly kludge. Remove as soon as the OF for all
+	machines actually follow the spec and encodes the offset field
+	as phys-encode (that is, #address-cells wide)*/
+	if (dma_window_property_size == 12) {
+		size = ((dma_window[1] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT;
+	} else if (dma_window_property_size == 20) {
+		size = ((dma_window[4] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT;
+	} else {
+		printk(KERN_WARNING "vio_build_tce_table: Invalid size of ibm,my-dma-window=%i, using 0x80 for size\n", dma_window_property_size);
+		size = 0x80;
+	}
+
+	/*  There should be some code to extract the phys-encoded offset
+		using prom_n_addr_cells(). However, according to a comment
+		on earlier versions, it's always zero, so we don't bother */
+	offset = dma_window[1] >>  PAGE_SHIFT;
+
+	/* TCE table size - measured in units of pages of tce table */
+	newTceTable->size = size;
+	/* offset for VIO should always be 0 */
+	newTceTable->startOffset = offset;
+	newTceTable->busNumber   = 0;
+	newTceTable->index       = (unsigned long)dma_window[0];
+	newTceTable->tceType     = TCE_VB;
+
+	return build_tce_table(newTceTable);
+}
+
+int vio_enable_interrupts(struct vio_dev *dev)
+{
+	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
+	if (rc != H_Success) {
+		printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
+	}
+	return rc;
+}
+EXPORT_SYMBOL(vio_enable_interrupts);
+
+int vio_disable_interrupts(struct vio_dev *dev)
+{
+	int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
+	if (rc != H_Success) {
+	printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
+	}
+	return rc;
+}
+EXPORT_SYMBOL(vio_disable_interrupts);
+
+dma_addr_t vio_map_single(struct vio_dev *dev, void *vaddr,
+			  size_t size, int direction )
+{
+	struct TceTable * tbl;
+	dma_addr_t dma_handle = NO_TCE;
+	unsigned long uaddr;
+	unsigned order, nPages;
+
+	if(direction == PCI_DMA_NONE) BUG();
+
+	uaddr = (unsigned long)vaddr;
+	nPages = PAGE_ALIGN( uaddr + size ) - ( uaddr & PAGE_MASK );
+	order = get_order( nPages & PAGE_MASK );
+	nPages >>= PAGE_SHIFT;
+
+	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+	if(order >= NUM_TCE_LEVELS) {
+		printk("VIO_DMA: vio_map_single size to large: 0x%lx \n",size);
+		return NO_TCE;
+	}
+
+	tbl = dev->tce_table;
+
+	if(tbl) {
+		dma_handle = get_tces(tbl, order, vaddr, nPages, direction);
+		dma_handle |= (uaddr & ~PAGE_MASK);
+	}
+
+	return dma_handle;
+}
+EXPORT_SYMBOL(vio_map_single);
+
+void vio_unmap_single(struct vio_dev *dev, dma_addr_t dma_handle,
+		      size_t size, int direction)
+{
+	struct TceTable * tbl;
+	unsigned order, nPages;
+
+	if (direction == PCI_DMA_NONE) BUG();
+
+	nPages = PAGE_ALIGN( dma_handle + size ) - ( dma_handle & PAGE_MASK );
+	order = get_order( nPages & PAGE_MASK );
+	nPages >>= PAGE_SHIFT;
+
+	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+	if(order >= NUM_TCE_LEVELS) {
+		printk("VIO_DMA: vio_unmap_single 0x%lx size to large: 0x%lx \n",(unsigned long)dma_handle,(unsigned long)size);
+		return;
+	}
+
+	tbl = dev->tce_table;
+	if(tbl) tce_free(tbl, dma_handle, order, nPages);
+}
+EXPORT_SYMBOL(vio_unmap_single);
+
+int vio_map_sg(struct vio_dev *vdev, struct scatterlist *sglist, int nelems,
+	       int direction)
+{
+	int i;
+
+	for (i = 0; i < nelems; i++) {
+
+		/* 2.4 scsi scatterlists use address field.
+		   Not sure about other subsystems. */
+		void *vaddr;
+		if (sglist->address)
+			vaddr = sglist->address;
+		else
+			vaddr = page_address(sglist->page) + sglist->offset;
+
+		sglist->dma_address = vio_map_single(vdev, vaddr,
+						     sglist->length,
+						     direction);
+		sglist->dma_length = sglist->length;
+		sglist++;
+	}
+
+	return nelems;
+}
+EXPORT_SYMBOL(vio_map_sg);
+
+void vio_unmap_sg(struct vio_dev *vdev, struct scatterlist *sglist, int nelems,
+		  int direction)
+{
+	while (nelems--) {
+		vio_unmap_single(vdev, sglist->dma_address,
+				 sglist->dma_length, direction);
+		sglist++;
+	}
+}
+
+void *vio_alloc_consistent(struct vio_dev *dev, size_t size,
+			   dma_addr_t *dma_handle)
+{
+	struct TceTable * tbl;
+	void *ret = NULL;
+	unsigned order, nPages;
+	dma_addr_t tce;
+
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+	nPages = 1 << order;
+
+	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+	if(order >= NUM_TCE_LEVELS) {
+		printk("VIO_DMA: vio_alloc_consistent size to large: 0x%lx \n",size);
+		return (void *)NO_TCE;
+	}
+
+	tbl = dev->tce_table;
+
+	if ( tbl ) {
+		/* Alloc enough pages (and possibly more) */
+		ret = (void *)__get_free_pages( GFP_ATOMIC, order );
+		if ( ret ) {
+			/* Page allocation succeeded */
+			memset(ret, 0, nPages << PAGE_SHIFT);
+			/* Set up tces to cover the allocated range */
+			tce = get_tces( tbl, order, ret, nPages, PCI_DMA_BIDIRECTIONAL );
+			if ( tce == NO_TCE ) {
+				PPCDBG(PPCDBG_TCE, "vio_alloc_consistent: get_tces failed\n" );
+				free_pages( (unsigned long)ret, order );
+				ret = NULL;
+			}
+			else
+				{
+					*dma_handle = tce;
+				}
+		}
+		else PPCDBG(PPCDBG_TCE, "vio_alloc_consistent: __get_free_pages failed for order = %d\n", order);
+	}
+	else PPCDBG(PPCDBG_TCE, "vio_alloc_consistent: get_tce_table failed for 0x%016lx\n", dev);
+
+	PPCDBG(PPCDBG_TCE, "\tvio_alloc_consistent: dma_handle = 0x%16.16lx\n", *dma_handle);
+	PPCDBG(PPCDBG_TCE, "\tvio_alloc_consistent: return     = 0x%16.16lx\n", ret);
+	return ret;
+}
+EXPORT_SYMBOL(vio_alloc_consistent);
+
+void vio_free_consistent(struct vio_dev *dev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	struct TceTable * tbl;
+	unsigned order, nPages;
+
+	PPCDBG(PPCDBG_TCE, "vio_free_consistent:\n");
+	PPCDBG(PPCDBG_TCE, "\tdev = 0x%16.16lx, size = 0x%16.16lx, dma_handle = 0x%16.16lx, vaddr = 0x%16.16lx\n", dev, size, dma_handle, vaddr);
+
+	size = PAGE_ALIGN(size);
+	order = get_order(size);
+	nPages = 1 << order;
+
+	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+	if(order >= NUM_TCE_LEVELS) {
+		printk("PCI_DMA: pci_free_consistent size to large: 0x%lx \n",size);
+		return;
+	}
+
+	tbl = dev->tce_table;
+
+	if ( tbl ) {
+		tce_free(tbl, dma_handle, order, nPages);
+		free_pages( (unsigned long)vaddr, order );
+	}
+}
+EXPORT_SYMBOL(vio_free_consistent);
+
+EXPORT_SYMBOL(plpar_hcall_norets);
+EXPORT_SYMBOL(plpar_hcall_8arg_2ret);
+
+
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/viopath.c linux-2.4.24-pre2/arch/ppc64/kernel/viopath.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/viopath.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/kernel/viopath.c	2003-12-22 11:34:34.000000000 -0800
@@ -0,0 +1,811 @@
+/* -*- linux-c -*-
+ *  arch/ppc64/viopath.c
+ *
+ *  iSeries Virtual I/O Message Path code
+ *
+ *  Authors: Dave Boutcher <boutcher@us.ibm.com>
+ *           Ryan Arnold <ryanarn@us.ibm.com>
+ *           Colin Devilbiss <devilbis@us.ibm.com>
+ *
+ * (C) Copyright 2000 IBM Corporation
+ *
+ * This code is used by the iSeries virtual disk, cd,
+ * tape, and console to communicate with OS/400 in another
+ * partition.
+ *
+ * This program is free software;  you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) anyu later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/config.h>
+#include <asm/uaccess.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/pci.h>
+#include <linux/wait.h>
+
+#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/HvLpEvent.h>
+#include <asm/iSeries/HvLpConfig.h>
+#include <asm/iSeries/HvCallCfg.h>
+#include <asm/iSeries/mf.h>
+#include <asm/iSeries/iSeries_proc.h>
+#include <asm/iSeries/vio.h>
+
+EXPORT_SYMBOL(viopath_hostLp);
+EXPORT_SYMBOL(viopath_ourLp);
+EXPORT_SYMBOL(vio_set_hostlp);
+EXPORT_SYMBOL(vio_lookup_rc);
+EXPORT_SYMBOL(viopath_open);
+EXPORT_SYMBOL(viopath_close);
+EXPORT_SYMBOL(viopath_isactive);
+EXPORT_SYMBOL(viopath_sourceinst);
+EXPORT_SYMBOL(viopath_targetinst);
+EXPORT_SYMBOL(vio_setHandler);
+EXPORT_SYMBOL(vio_clearHandler);
+EXPORT_SYMBOL(vio_get_event_buffer);
+EXPORT_SYMBOL(vio_free_event_buffer);
+
+extern struct pci_dev *iSeries_vio_dev;
+
+/* Status of the path to each other partition in the system.
+ * This is overkill, since we will only ever establish connections
+ * to our hosting partition and the primary partition on the system.
+ * But this allows for other support in the future.
+ */
+static struct viopathStatus {
+	int isOpen:1;		/* Did we open the path?            */
+	int isActive:1;		/* Do we have a mon msg outstanding */
+	int users[VIO_MAX_SUBTYPES];
+	HvLpInstanceId mSourceInst;
+	HvLpInstanceId mTargetInst;
+	int numberAllocated;
+} viopathStatus[HVMAXARCHITECTEDLPS];
+
+static spinlock_t statuslock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * For each kind of event we allocate a buffer that is
+ * guaranteed not to cross a page boundary
+ */
+static void *event_buffer[VIO_MAX_SUBTYPES] = { };
+static atomic_t event_buffer_available[VIO_MAX_SUBTYPES] = { };
+
+static void handleMonitorEvent(struct HvLpEvent *event);
+
+/* We use this structure to handle asynchronous responses.  The caller
+ * blocks on the semaphore and the handler posts the semaphore.
+ */
+struct doneAllocParms_t {
+	struct semaphore *sem;
+	int number;
+};
+
+/* Put a sequence number in each mon msg.  The value is not
+ * important.  Start at something other than 0 just for
+ * readability.  wrapping this is ok.
+ */
+static u8 viomonseq = 22;
+
+/* Our hosting logical partition.  We get this at startup
+ * time, and different modules access this variable directly.
+ */
+HvLpIndex viopath_hostLp = 0xff;	/* HvLpIndexInvalid */
+HvLpIndex viopath_ourLp = 0xff;
+
+/* For each kind of incoming event we set a pointer to a
+ * routine to call.
+ */
+static vio_event_handler_t *vio_handler[VIO_MAX_SUBTYPES];
+
+static unsigned char e2a(unsigned char x)
+{
+	switch (x) {
+	case 0xF0:
+		return '0';
+	case 0xF1:
+		return '1';
+	case 0xF2:
+		return '2';
+	case 0xF3:
+		return '3';
+	case 0xF4:
+		return '4';
+	case 0xF5:
+		return '5';
+	case 0xF6:
+		return '6';
+	case 0xF7:
+		return '7';
+	case 0xF8:
+		return '8';
+	case 0xF9:
+		return '9';
+	case 0xC1:
+		return 'A';
+	case 0xC2:
+		return 'B';
+	case 0xC3:
+		return 'C';
+	case 0xC4:
+		return 'D';
+	case 0xC5:
+		return 'E';
+	case 0xC6:
+		return 'F';
+	case 0xC7:
+		return 'G';
+	case 0xC8:
+		return 'H';
+	case 0xC9:
+		return 'I';
+	case 0xD1:
+		return 'J';
+	case 0xD2:
+		return 'K';
+	case 0xD3:
+		return 'L';
+	case 0xD4:
+		return 'M';
+	case 0xD5:
+		return 'N';
+	case 0xD6:
+		return 'O';
+	case 0xD7:
+		return 'P';
+	case 0xD8:
+		return 'Q';
+	case 0xD9:
+		return 'R';
+	case 0xE2:
+		return 'S';
+	case 0xE3:
+		return 'T';
+	case 0xE4:
+		return 'U';
+	case 0xE5:
+		return 'V';
+	case 0xE6:
+		return 'W';
+	case 0xE7:
+		return 'X';
+	case 0xE8:
+		return 'Y';
+	case 0xE9:
+		return 'Z';
+	}
+	return ' ';
+}
+
+/* Handle reads from the proc file system
+ */
+static int proc_read(char *buf, char **start, off_t offset,
+		     int blen, int *eof, void *data)
+{
+	HvLpEvent_Rc hvrc;
+	DECLARE_MUTEX_LOCKED(Semaphore);
+	dma_addr_t dmaa =
+	    pci_map_single(iSeries_vio_dev, buf, PAGE_SIZE,
+			   PCI_DMA_FROMDEVICE);
+	int len = PAGE_SIZE;
+
+	if (len > blen)
+		len = blen;
+
+	memset(buf, 0x00, len);
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+					     HvLpEvent_Type_VirtualIo,
+					     viomajorsubtype_config |
+					     vioconfigget,
+					     HvLpEvent_AckInd_DoAck,
+					     HvLpEvent_AckType_ImmediateAck,
+					     viopath_sourceinst
+					     (viopath_hostLp),
+					     viopath_targetinst
+					     (viopath_hostLp),
+					     (u64) (unsigned long)
+					     &Semaphore, VIOVERSION << 16,
+					     ((u64) dmaa) << 32, len, 0,
+					     0);
+	if (hvrc != HvLpEvent_Rc_Good) {
+		printk("viopath hv error on op %d\n", (int) hvrc);
+	}
+
+	down(&Semaphore);
+
+	pci_unmap_single(iSeries_vio_dev, dmaa, PAGE_SIZE,
+			 PCI_DMA_FROMDEVICE);
+
+	sprintf(buf + strlen(buf), "SRLNBR=");
+	buf[strlen(buf)] = e2a(xItExtVpdPanel.mfgID[2]);
+	buf[strlen(buf)] = e2a(xItExtVpdPanel.mfgID[3]);
+	buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[1]);
+	buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[2]);
+	buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[3]);
+	buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[4]);
+	buf[strlen(buf)] = e2a(xItExtVpdPanel.systemSerial[5]);
+	buf[strlen(buf)] = '\n';
+	*eof = 1;
+	return strlen(buf);
+}
+
+/* Handle writes to our proc file system
+ */
+static int proc_write(struct file *file, const char *buffer,
+		      unsigned long count, void *data)
+{
+	/* Doesn't do anything today!!!
+	 */
+	return count;
+}
+
+/* setup our proc file system entries
+ */
+static void vio_proc_init(struct proc_dir_entry *iSeries_proc)
+{
+	struct proc_dir_entry *ent;
+	ent = create_proc_entry("config", S_IFREG | S_IRUSR, iSeries_proc);
+	if (!ent)
+		return;
+	ent->nlink = 1;
+	ent->data = NULL;
+	ent->read_proc = proc_read;
+	ent->write_proc = proc_write;
+}
+
+/* See if a given LP is active.  Allow for invalid lps to be passed in
+ * and just return invalid
+ */
+int viopath_isactive(HvLpIndex lp)
+{
+	if (lp == HvLpIndexInvalid)
+		return 0;
+	if (lp < HVMAXARCHITECTEDLPS)
+		return viopathStatus[lp].isActive;
+	else
+		return 0;
+}
+
+/* We cache the source and target instance ids for each
+ * partition.  
+ */
+HvLpInstanceId viopath_sourceinst(HvLpIndex lp)
+{
+	return viopathStatus[lp].mSourceInst;
+}
+
+HvLpInstanceId viopath_targetinst(HvLpIndex lp)
+{
+	return viopathStatus[lp].mTargetInst;
+}
+
+/* Send a monitor message.  This is a message with the acknowledge
+ * bit on that the other side will NOT explicitly acknowledge.  When
+ * the other side goes down, the hypervisor will acknowledge any
+ * outstanding messages....so we will know when the other side dies.
+ */
+static void sendMonMsg(HvLpIndex remoteLp)
+{
+	HvLpEvent_Rc hvrc;
+
+	viopathStatus[remoteLp].mSourceInst =
+	    HvCallEvent_getSourceLpInstanceId(remoteLp,
+					      HvLpEvent_Type_VirtualIo);
+	viopathStatus[remoteLp].mTargetInst =
+	    HvCallEvent_getTargetLpInstanceId(remoteLp,
+					      HvLpEvent_Type_VirtualIo);
+
+	/* Deliberately ignore the return code here.  if we call this
+	 * more than once, we don't care.
+	 */
+	vio_setHandler(viomajorsubtype_monitor, handleMonitorEvent);
+
+	hvrc = HvCallEvent_signalLpEventFast(remoteLp,
+					     HvLpEvent_Type_VirtualIo,
+					     viomajorsubtype_monitor,
+					     HvLpEvent_AckInd_DoAck,
+					     HvLpEvent_AckType_DeferredAck,
+					     viopathStatus[remoteLp].
+					     mSourceInst,
+					     viopathStatus[remoteLp].
+					     mTargetInst, viomonseq++,
+					     0, 0, 0, 0, 0);
+
+	if (hvrc == HvLpEvent_Rc_Good) {
+		viopathStatus[remoteLp].isActive = 1;
+	} else {
+		printk(KERN_WARNING_VIO
+		       "could not connect to partition %d\n", remoteLp);
+		viopathStatus[remoteLp].isActive = 0;
+	}
+}
+
+static void handleMonitorEvent(struct HvLpEvent *event)
+{
+	HvLpIndex remoteLp;
+	int i;
+
+	/* This handler is _also_ called as part of the loop
+	 * at the end of this routine, so it must be able to
+	 * ignore NULL events...
+	 */
+	if (!event)
+		return;
+
+	/* First see if this is just a normal monitor message from the
+	 * other partition
+	 */
+	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+		remoteLp = event->xSourceLp;
+		if (!viopathStatus[remoteLp].isActive)
+			sendMonMsg(remoteLp);
+		return;
+	}
+
+	/* This path is for an acknowledgement; the other partition
+	 * died
+	 */
+	remoteLp = event->xTargetLp;
+	if ((event->xSourceInstanceId !=
+	     viopathStatus[remoteLp].mSourceInst)
+	    || (event->xTargetInstanceId !=
+		viopathStatus[remoteLp].mTargetInst)) {
+		printk(KERN_WARNING_VIO
+		       "ignoring ack....mismatched instances\n");
+		return;
+	}
+
+	printk(KERN_WARNING_VIO "partition %d ended\n", remoteLp);
+
+	viopathStatus[remoteLp].isActive = 0;
+
+	/* For each active handler, pass them a NULL
+	 * message to indicate that the other partition
+	 * died
+	 */
+	for (i = 0; i < VIO_MAX_SUBTYPES; i++) {
+		if (vio_handler[i] != NULL)
+			(*vio_handler[i]) (NULL);
+	}
+}
+
+int vio_setHandler(int subtype, vio_event_handler_t * beh)
+{
+	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+
+	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+		return -EINVAL;
+
+	if (vio_handler[subtype] != NULL)
+		return -EBUSY;
+
+	vio_handler[subtype] = beh;
+	return 0;
+}
+
+int vio_clearHandler(int subtype)
+{
+	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+
+	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+		return -EINVAL;
+
+	if (vio_handler[subtype] == NULL)
+		return -EAGAIN;
+
+	vio_handler[subtype] = NULL;
+	return 0;
+}
+
+static void handleConfig(struct HvLpEvent *event)
+{
+	if (!event)
+		return;
+	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+		printk(KERN_WARNING_VIO
+		       "unexpected config request from partition %d",
+		       event->xSourceLp);
+
+		if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
+		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+		return;
+	}
+
+	up((struct semaphore *) event->xCorrelationToken);
+}
+
+/* Initialization of the hosting partition
+ */
+void vio_set_hostlp(void)
+{
+	/* If this has already been set then we DON'T want to either change
+	 * it or re-register the proc file system
+	 */
+	if (viopath_hostLp != HvLpIndexInvalid)
+		return;
+
+	/* Figure out our hosting partition.  This isn't allowed to change
+	 * while we're active
+	 */
+	viopath_ourLp = HvLpConfig_getLpIndex();
+	viopath_hostLp = HvCallCfg_getHostingLpIndex(viopath_ourLp);
+
+	/* If we have a valid hosting LP, create a proc file system entry
+	 * for config information
+	 */
+	if (viopath_hostLp != HvLpIndexInvalid) {
+		iSeries_proc_callback(&vio_proc_init);
+		vio_setHandler(viomajorsubtype_config, handleConfig);
+	}
+}
+
+static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs)
+{
+	HvLpIndex remoteLp;
+	int subtype =
+	    (event->
+	     xSubtype & VIOMAJOR_SUBTYPE_MASK) >> VIOMAJOR_SUBTYPE_SHIFT;
+
+	if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
+		remoteLp = event->xSourceLp;
+		/* The isActive is checked because if the hosting partition
+		 * went down and came back up it would not be active but it would have
+		 * different source and target instances, in which case we'd want to
+		 * reset them.  This case really protects against an unauthorized
+		 * active partition sending interrupts or acks to this linux partition.
+		 */
+		if (viopathStatus[remoteLp].isActive
+		    && (event->xSourceInstanceId !=
+			viopathStatus[remoteLp].mTargetInst)) {
+			printk(KERN_WARNING_VIO
+			       "message from invalid partition. "
+			       "int msg rcvd, source inst (%d) doesnt match (%d)\n",
+			       viopathStatus[remoteLp].mTargetInst,
+			       event->xSourceInstanceId);
+			return;
+		}
+
+		if (viopathStatus[remoteLp].isActive
+		    && (event->xTargetInstanceId !=
+			viopathStatus[remoteLp].mSourceInst)) {
+			printk(KERN_WARNING_VIO
+			       "message from invalid partition. "
+			       "int msg rcvd, target inst (%d) doesnt match (%d)\n",
+			       viopathStatus[remoteLp].mSourceInst,
+			       event->xTargetInstanceId);
+			return;
+		}
+	} else {
+		remoteLp = event->xTargetLp;
+		if (event->xSourceInstanceId !=
+		    viopathStatus[remoteLp].mSourceInst) {
+			printk(KERN_WARNING_VIO
+			       "message from invalid partition. "
+			       "ack msg rcvd, source inst (%d) doesnt match (%d)\n",
+			       viopathStatus[remoteLp].mSourceInst,
+			       event->xSourceInstanceId);
+			return;
+		}
+
+		if (event->xTargetInstanceId !=
+		    viopathStatus[remoteLp].mTargetInst) {
+			printk(KERN_WARNING_VIO
+			       "message from invalid partition. "
+			       "viopath: ack msg rcvd, target inst (%d) doesnt match (%d)\n",
+			       viopathStatus[remoteLp].mTargetInst,
+			       event->xTargetInstanceId);
+			return;
+		}
+	}
+
+	if (vio_handler[subtype] == NULL) {
+		printk(KERN_WARNING_VIO
+		       "unexpected virtual io event subtype %d from partition %d\n",
+		       event->xSubtype, remoteLp);
+		/* No handler.  Ack if necessary
+		 */
+		if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
+		    (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+		return;
+	}
+
+	/* This innocuous little line is where all the real work happens
+	 */
+	(*vio_handler[subtype]) (event);
+}
+
+static void viopath_donealloc(void *parm, int number)
+{
+	struct doneAllocParms_t *doneAllocParmsp =
+	    (struct doneAllocParms_t *) parm;
+	doneAllocParmsp->number = number;
+	up(doneAllocParmsp->sem);
+}
+
+static int allocateEvents(HvLpIndex remoteLp, int numEvents)
+{
+	struct doneAllocParms_t doneAllocParms;
+	DECLARE_MUTEX_LOCKED(Semaphore);
+	doneAllocParms.sem = &Semaphore;
+
+	mf_allocateLpEvents(remoteLp, HvLpEvent_Type_VirtualIo, 250,	/* It would be nice to put a real number here! */
+			    numEvents,
+			    &viopath_donealloc, &doneAllocParms);
+
+	down(&Semaphore);
+
+	return doneAllocParms.number;
+}
+
+int viopath_open(HvLpIndex remoteLp, int subtype, int numReq)
+{
+	int i;
+	unsigned long flags;
+	void *tempEventBuffer = NULL;
+	int tempNumAllocated;
+
+	if ((remoteLp >= HvMaxArchitectedLps)
+	    || (remoteLp == HvLpIndexInvalid))
+		return -EINVAL;
+
+	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+		return -EINVAL;
+
+	/*
+	 * NOTE: If VIO_MAX_SUBTYPES exceeds 16 then we need
+	 * to allocate more than one page for the event_buffer.
+	 */
+	if (event_buffer[0] == NULL) {
+		if (VIO_MAX_SUBTYPES <= 16) {
+			tempEventBuffer =
+			    (void *) get_free_page(GFP_KERNEL);
+			if (tempEventBuffer == NULL)
+				return -ENOMEM;
+		} else {
+			printk(KERN_INFO_VIO
+			       "VIO_MAX_SUBTYPES > 16. Need more space.");
+			return -ENOMEM;
+		}
+	}
+
+	spin_lock_irqsave(&statuslock, flags);
+
+	/*
+	 * OK...we can fit 16 maximum-sized events (256 bytes) in
+	 * each page (4096).
+	 */
+	if (event_buffer[0] == NULL) {
+		event_buffer[0] = tempEventBuffer;
+		atomic_set(&event_buffer_available[0], 1);
+		/*
+		 * Start at the second element because we've already
+		 * set the pointer for the first element and set the
+		 * pointers for every 256 bytes in the page we
+		 * allocated earlier.
+		 */
+		for (i = 1; i < VIO_MAX_SUBTYPES; i++) {
+			event_buffer[i] = event_buffer[i - 1] + 256;
+			atomic_set(&event_buffer_available[i], 1);
+		}
+	} else {
+		/*
+		 * While we were fetching the pages, which shouldn't
+		 * be done in a spin lock, another call to viopath_open
+		 * decided to do the same thing and allocated storage
+		 * and set the event_buffer before we could so we'll
+		 * free the one that we allocated and continue with our
+		 * viopath_open operation.
+		 */
+		free_page((unsigned long) tempEventBuffer);
+	}
+
+	viopathStatus[remoteLp].users[subtype]++;
+
+	if (!viopathStatus[remoteLp].isOpen) {
+		viopathStatus[remoteLp].isOpen = 1;
+		HvCallEvent_openLpEventPath(remoteLp,
+					    HvLpEvent_Type_VirtualIo);
+
+		spin_unlock_irqrestore(&statuslock, flags);
+		/*
+		 * Don't hold the spinlock during an operation that
+		 * can sleep.
+		 */
+		tempNumAllocated = allocateEvents(remoteLp, 1);
+		spin_lock_irqsave(&statuslock, flags);
+
+		viopathStatus[remoteLp].numberAllocated +=
+		    tempNumAllocated;
+
+		if (viopathStatus[remoteLp].numberAllocated == 0) {
+			HvCallEvent_closeLpEventPath(remoteLp,
+						     HvLpEvent_Type_VirtualIo);
+
+			spin_unlock_irqrestore(&statuslock, flags);
+			return -ENOMEM;
+		}
+
+		viopathStatus[remoteLp].mSourceInst =
+		    HvCallEvent_getSourceLpInstanceId(remoteLp,
+						      HvLpEvent_Type_VirtualIo);
+		viopathStatus[remoteLp].mTargetInst =
+		    HvCallEvent_getTargetLpInstanceId(remoteLp,
+						      HvLpEvent_Type_VirtualIo);
+
+		HvLpEvent_registerHandler(HvLpEvent_Type_VirtualIo,
+					  &vio_handleEvent);
+
+		sendMonMsg(remoteLp);
+
+		printk(KERN_INFO_VIO
+		       "Opening connection to partition %d, setting sinst %d, tinst %d\n",
+		       remoteLp,
+		       viopathStatus[remoteLp].mSourceInst,
+		       viopathStatus[remoteLp].mTargetInst);
+	}
+
+	spin_unlock_irqrestore(&statuslock, flags);
+	tempNumAllocated = allocateEvents(remoteLp, numReq);
+	spin_lock_irqsave(&statuslock, flags);
+	viopathStatus[remoteLp].numberAllocated += tempNumAllocated;
+	spin_unlock_irqrestore(&statuslock, flags);
+
+	return 0;
+}
+
+int viopath_close(HvLpIndex remoteLp, int subtype, int numReq)
+{
+	unsigned long flags;
+	int i;
+	int numOpen;
+	struct doneAllocParms_t doneAllocParms;
+	DECLARE_MUTEX_LOCKED(Semaphore);
+	doneAllocParms.sem = &Semaphore;
+
+	if ((remoteLp >= HvMaxArchitectedLps)
+	    || (remoteLp == HvLpIndexInvalid))
+		return -EINVAL;
+
+	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+		return -EINVAL;
+
+	spin_lock_irqsave(&statuslock, flags);
+	/*
+	 * If the viopath_close somehow gets called before a
+	 * viopath_open it could decrement to -1 which is a non
+	 * recoverable state so we'll prevent this from
+	 * happening.
+	 */
+	if (viopathStatus[remoteLp].users[subtype] > 0) {
+		viopathStatus[remoteLp].users[subtype]--;
+	}
+	spin_unlock_irqrestore(&statuslock, flags);
+
+	mf_deallocateLpEvents(remoteLp, HvLpEvent_Type_VirtualIo,
+			      numReq, &viopath_donealloc, &doneAllocParms);
+	down(&Semaphore);
+
+	spin_lock_irqsave(&statuslock, flags);
+	for (i = 0, numOpen = 0; i < VIO_MAX_SUBTYPES; i++) {
+		numOpen += viopathStatus[remoteLp].users[i];
+	}
+
+	if ((viopathStatus[remoteLp].isOpen) && (numOpen == 0)) {
+		printk(KERN_INFO_VIO
+		       "Closing connection to partition %d", remoteLp);
+
+		HvCallEvent_closeLpEventPath(remoteLp,
+					     HvLpEvent_Type_VirtualIo);
+		viopathStatus[remoteLp].isOpen = 0;
+		viopathStatus[remoteLp].isActive = 0;
+
+		for (i = 0; i < VIO_MAX_SUBTYPES; i++) {
+			atomic_set(&event_buffer_available[i], 0);
+		}
+
+		/*
+		 * Precautionary check to make sure we don't
+		 * erroneously try to free a page that wasn't
+		 * allocated.
+		 */
+		if (event_buffer[0] != NULL) {
+			free_page((unsigned long) event_buffer[0]);
+			for (i = 0; i < VIO_MAX_SUBTYPES; i++) {
+				event_buffer[i] = NULL;
+			}
+		}
+
+	}
+	spin_unlock_irqrestore(&statuslock, flags);
+	return 0;
+}
+
+void *vio_get_event_buffer(int subtype)
+{
+	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES))
+		return NULL;
+
+	if (atomic_dec_if_positive(&event_buffer_available[subtype]) == 0)
+		return event_buffer[subtype];
+	else
+		return NULL;
+}
+
+void vio_free_event_buffer(int subtype, void *buffer)
+{
+	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
+	if ((subtype < 0) || (subtype >= VIO_MAX_SUBTYPES)) {
+		printk(KERN_WARNING_VIO
+		       "unexpected subtype %d freeing event buffer\n",
+		       subtype);
+		return;
+	}
+
+	if (atomic_read(&event_buffer_available[subtype]) != 0) {
+		printk(KERN_WARNING_VIO
+		       "freeing unallocated event buffer, subtype %d\n",
+		       subtype);
+		return;
+	}
+
+	if (buffer != event_buffer[subtype]) {
+		printk(KERN_WARNING_VIO
+		       "freeing invalid event buffer, subtype %d\n",
+		       subtype);
+	}
+
+	atomic_set(&event_buffer_available[subtype], 1);
+}
+
+static const struct vio_error_entry vio_no_error =
+    { 0, 0, "Non-VIO Error" };
+static const struct vio_error_entry vio_unknown_error =
+    { 0, EIO, "Unknown Error" };
+
+static const struct vio_error_entry vio_default_errors[] = {
+	{0x0001, EIO, "No Connection"},
+	{0x0002, EIO, "No Receiver"},
+	{0x0003, EIO, "No Buffer Available"},
+	{0x0004, EBADRQC, "Invalid Message Type"},
+	{0x0000, 0, NULL},
+};
+
+const struct vio_error_entry *vio_lookup_rc(const struct vio_error_entry
+					    *local_table, u16 rc)
+{
+	const struct vio_error_entry *cur;
+	if (!rc)
+		return &vio_no_error;
+	if (local_table)
+		for (cur = local_table; cur->rc; ++cur)
+			if (cur->rc == rc)
+				return cur;
+	for (cur = vio_default_errors; cur->rc; ++cur)
+		if (cur->rc == rc)
+			return cur;
+	return &vio_unknown_error;
+}
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/xics.c linux-2.4.24-pre2/arch/ppc64/kernel/xics.c
--- linux-2.4.24-pre1/arch/ppc64/kernel/xics.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/xics.c	2003-12-22 11:34:34.000000000 -0800
@@ -51,7 +51,6 @@
 };
 
 #define XICS_IPI		2
-#define XICS_IRQ_OFFSET		0x10
 #define XICS_IRQ_SPURIOUS	0
 
 /* Want a priority other than 0.  Various HW issues require this. */
@@ -136,17 +135,14 @@
 
 
 void
-xics_enable_irq(
-	u_int	virq
-	)
+xics_enable_irq(u_int virq)
 {
 	u_int		irq;
 	unsigned long	status;
 	long	        call_status;
 	unsigned int    interrupt_server = default_server;
 
-	virq -= XICS_IRQ_OFFSET;
-	irq = virt_irq_to_real(virq);
+	irq = irq_offset_down(virq);
 	if (irq == XICS_IPI)
 		return;
 
@@ -175,18 +171,14 @@
 }
 
 void
-xics_disable_irq(
-	u_int	virq
-	)
+xics_disable_irq(u_int virq)
 {
 	u_int		irq;
 	unsigned long 	status;
 	long 	        call_status;
 
-	virq -= XICS_IRQ_OFFSET;
-	irq = virt_irq_to_real(virq);
-	call_status = rtas_call(ibm_int_off, 1, 1, (unsigned long*)&status, 
-				irq);
+	irq = irq_offset_down(virq);
+	call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq);
 	if( call_status != 0 ) {
 		printk("xics_disable_irq: irq=%x: rtas_call failed, retn=%lx\n",
 		       irq, call_status);
@@ -195,16 +187,12 @@
 }
 
 void
-xics_end_irq(
-	u_int	irq
-	)
+xics_end_irq(u_int irq)
 {
 	int cpu = smp_processor_id();
 
-	ops->cppr_info(cpu, 0); /* actually the value overwritten by ack */
-	iosync();
-	ops->xirr_info_set(cpu, ((0xff<<24) | (virt_irq_to_real(irq-XICS_IRQ_OFFSET))));
 	iosync();
+	ops->xirr_info_set(cpu, (0xff<<24) | irq_offset_down(irq));
 }
 
 void
@@ -212,7 +200,7 @@
 {
 	int cpu = smp_processor_id();
 
-	if( irq < XICS_IRQ_OFFSET ) {
+	if (irq < irq_offset_value()) {
 		i8259_pic.ack(irq);
 		iosync();
 		ops->xirr_info_set(cpu, ((0xff<<24) | xics_irq_8259_cascade_real));
@@ -239,13 +227,13 @@
 		irq = i8259_irq(cpu);
 		if(irq == -1) {
 			/* Spurious cascaded interrupt.  Still must ack xics */
-                        xics_end_irq(XICS_IRQ_OFFSET + xics_irq_8259_cascade);
+			xics_end_irq(irq_offset_up(xics_irq_8259_cascade));
 			irq = -1;
 		}
 	} else if( vec == XICS_IRQ_SPURIOUS ) {
 		irq = -1;
 	} else {
-		irq = real_irq_to_virt(vec) + XICS_IRQ_OFFSET;
+		irq = irq_offset_up(vec);
 	}
 	return irq;
 }
@@ -290,6 +278,15 @@
 }
 #endif /* CONFIG_SMP */
 
+void xics_init_irq_desc(irq_desc_t *desc)
+{
+	/* Don't mess with the handler if already set.
+	 * This leaves the setup of isa handlers undisturbed.
+	 */
+	if (!desc->handler)
+		desc->handler = &xics_pic;
+}
+
 void
 xics_init_IRQ( void )
 {
@@ -373,7 +370,7 @@
 			while (1);
 		}
 		xics_irq_8259_cascade_real = *ireg;
-		xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real);
+		xics_irq_8259_cascade = xics_irq_8259_cascade_real;
 	}
 
 	if (systemcfg->platform == PLATFORM_PSERIES) {
@@ -398,36 +395,24 @@
 	xics_8259_pic.enable = i8259_pic.enable;
 	xics_8259_pic.disable = i8259_pic.disable;
 	for (i = 0; i < 16; ++i)
-		irq_desc[i].handler = &xics_8259_pic;
-	for (; i < NR_IRQS; ++i)
-		irq_desc[i].handler = &xics_pic;
+		real_irqdesc(i)->handler = &xics_8259_pic;
 
 	ops->cppr_info(0, 0xff);
 	iosync();
 	if (xics_irq_8259_cascade != -1) {
-		if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action,
-				0, "8259 cascade", 0))
+		if (request_irq(irq_offset_up(xics_irq_8259_cascade),
+				no_action, 0, "8259 cascade", 0))
 			printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
 		i8259_init();
 	}
 
 #ifdef CONFIG_SMP
-	real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] = XICS_IPI;
-	request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0);
-	irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU;
+	request_irq(irq_offset_up(XICS_IPI), xics_ipi_action, 0, "IPI", 0);
+	real_irqdesc(irq_offset_up(XICS_IPI))->status |= IRQ_PER_CPU;
 #endif
 	ppc64_boot_msg(0x21, "XICS Done");
 }
 
-void xics_isa_init(void)
-{
-	return;
-	if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action,
-			0, "8259 cascade", 0))
-		printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
-	i8259_init();
-}
-
 /*
  * Find first logical cpu and return its physical cpu number
  */
@@ -445,21 +430,19 @@
 	return default_distrib_server;
 }
 
-void xics_set_affinity(unsigned int virq, unsigned long cpumask)
+void xics_set_affinity(unsigned int irq, unsigned long cpumask)
 {
-        irq_desc_t *desc = irq_desc + virq;
-	unsigned int irq;
+	irq_desc_t *desc = irqdesc(irq);
 	unsigned long flags;
 	long status;
 	unsigned long xics_status[2];
 	u32 newmask;
 
-	virq -= XICS_IRQ_OFFSET;
-	irq = virt_irq_to_real(virq);
+	irq = irq_offset_down(irq);
 	if (irq == XICS_IPI)
 		return;
 
-        spin_lock_irqsave(&desc->lock, flags);
+	spin_lock_irqsave(&desc->lock, flags);
 
 	status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, irq);
 
@@ -485,5 +468,5 @@
 	}
 
 out:
-        spin_unlock_irqrestore(&desc->lock, flags);
+	spin_unlock_irqrestore(&desc->lock, flags);
 }
diff -urN linux-2.4.24-pre1/arch/ppc64/kernel/xics.h linux-2.4.24-pre2/arch/ppc64/kernel/xics.h
--- linux-2.4.24-pre1/arch/ppc64/kernel/xics.h	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/ppc64/kernel/xics.h	2003-12-22 11:34:34.000000000 -0800
@@ -18,7 +18,7 @@
 extern struct hw_interrupt_type xics_8259_pic;
 
 void xics_init_IRQ(void);
+void xics_init_irq_desc(irq_desc_t *);
 int xics_get_irq(struct pt_regs *);
-void xics_isa_init(void);
 
 #endif /* _PPC_KERNEL_XICS_H */
diff -urN linux-2.4.24-pre1/arch/ppc64/mm/fault.c linux-2.4.24-pre2/arch/ppc64/mm/fault.c
--- linux-2.4.24-pre1/arch/ppc64/mm/fault.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/ppc64/mm/fault.c	2003-12-22 11:34:34.000000000 -0800
@@ -59,6 +59,44 @@
 #endif
 
 /*
+ * Check whether the instruction at regs->nip is a store using
+ * an update addressing form which will update r1.
+ */
+static int store_updates_sp(struct pt_regs *regs)
+{
+	unsigned int inst;
+
+	if (get_user(inst, (unsigned int *)regs->nip))
+		return 0;
+	/* check for 1 in the rA field */
+	if (((inst >> 16) & 0x1f) != 1)
+		return 0;
+	/* check major opcode */
+	switch (inst >> 26) {
+	case 37:	/* stwu */
+	case 39:	/* stbu */
+	case 45:	/* sthu */
+	case 53:	/* stfsu */
+	case 55:	/* stfdu */
+		return 1;
+	case 62:	/* std or stdu */
+		return (inst & 3) == 1;
+	case 31:
+		/* check minor opcode */
+		switch ((inst >> 1) & 0x3ff) {
+		case 181:	/* stdux */
+		case 183:	/* stwux */
+		case 247:	/* stbux */
+		case 439:	/* sthux */
+		case 695:	/* stfsux */
+		case 759:	/* stfdux */
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
  * The error_code parameter is
  *  - DSISR for a non-SLB data access fault,
  *  - SRR1 & 0x08000000 for a non-SLB instruction access fault
@@ -115,7 +153,39 @@
 		PPCDBG(PPCDBG_MM, "\tdo_page_fault: vma->vm_flags = %lx, %lx\n", vma->vm_flags, VM_GROWSDOWN);
 		goto bad_area;
 	}
-	vma = find_vma_prev(mm, address, &prev_vma);
+
+	/*
+	 * N.B. The POWER/Open ABI allows programs to access up to
+	 * 288 bytes below the stack pointer.
+	 * The kernel signal delivery code writes up to about 1.5kB
+	 * below the stack pointer (r1) before decrementing it.
+	 * The exec code can write slightly over 640kB to the stack
+	 * before setting the user r1.  Thus we allow the stack to
+	 * expand to 1MB without further checks.
+	 */
+	if (address + 0x100000 < vma->vm_end) {
+		/* get user regs even if this fault is in kernel mode */
+		struct pt_regs *uregs = current->thread.regs;
+		if (uregs == NULL)
+			goto bad_area;
+
+		/*
+		 * A user-mode access to an address a long way below
+		 * the stack pointer is only valid if the instruction
+		 * is one which would update the stack pointer to the
+		 * address accessed if the instruction completed,
+		 * i.e. either stwu rs,n(r1) or stwux rs,r1,rb
+		 * (or the byte, halfword, float or double forms).
+		 *
+		 * If we don't check this then any write to the area
+		 * between the last mapped region and the stack will
+		 * expand the stack rather than segfaulting.
+		 */
+		if (address + 2048 < uregs->gpr[1]
+		    && (!user_mode(regs) || !store_updates_sp(regs)))
+			goto bad_area;
+	}
+
 	if (expand_stack(vma, address)) {
 		PPCDBG(PPCDBG_MM, "\tdo_page_fault: expand_stack\n");
 		goto bad_area;
diff -urN linux-2.4.24-pre1/arch/sparc/kernel/devices.c linux-2.4.24-pre2/arch/sparc/kernel/devices.c
--- linux-2.4.24-pre1/arch/sparc/kernel/devices.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/sparc/kernel/devices.c	2003-12-22 11:34:34.000000000 -0800
@@ -72,7 +72,7 @@
 		if (linux_num_cpus == 0) {
 			printk("No CPU nodes found, cannot continue.\n");
 			/* Probably a sun4e, Sun is trying to trick us ;-) */
-			halt();
+			prom_halt();
 		}
 		printk("Found %d CPU prom device tree node(s).\n", linux_num_cpus);
 	}
diff -urN linux-2.4.24-pre1/arch/sparc/kernel/ioport.c linux-2.4.24-pre2/arch/sparc/kernel/ioport.c
--- linux-2.4.24-pre1/arch/sparc/kernel/ioport.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.24-pre2/arch/sparc/kernel/ioport.c	2003-12-22 11:34:34.000000000 -0800
@@ -760,7 +760,7 @@
 	default:
 		printk("ioport_init: cpu type %d is unknown.\n",
 		    sparc_cpu_model);
-		halt();
+		prom_halt();
 	};
 
 }
diff -urN linux-2.4.24-pre1/arch/sparc64/kernel/ebus.c linux-2.4.24-pre2/arch/sparc64/kernel/ebus.c
--- linux-2.4.24-pre1/arch/sparc64/kernel/ebus.c	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.24-pre2/arch/sparc64/kernel/ebus.c	2003-12-22 11:34:34.000000000 -0800
@@ -177,7 +177,8 @@
 
 static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
 {
-	if (!strcmp(dev->prom_name, "i2c"))
+	if (!strcmp(dev->prom_name, "i2c") ||
+	    !strcmp(dev->prom_name, "SUNW,lombus"))
 		return 1;
 	return 0;
 }
diff -urN linux-2.4.24-pre1/arch/x86_64/kernel/acpi.c linux-2.4.24-pre2/arch/x86_64/kernel/acpi.c
--- linux-2.4.24-pre1/arch/x86_64/kernel/acpi.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/arch/x86_64/kernel/acpi.c	2003-12-22 11:34:34.000000000 -0800
@@ -411,8 +411,10 @@
 	 * Initialize the ACPI boot-time table parser.
 	 */
 	result = acpi_table_init();
-	if (result)
+	if (result) {
+		acpi_disabled = 1;
 		return result;
+	}
 
 #ifdef CONFIG_X86_LOCAL_APIC
 
diff -urN linux-2.4.24-pre1/drivers/acorn/char/i2c.c linux-2.4.24-pre2/drivers/acorn/char/i2c.c
--- linux-2.4.24-pre1/drivers/acorn/char/i2c.c	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acorn/char/i2c.c	2003-12-22 11:34:34.000000000 -0800
@@ -166,6 +166,7 @@
 		break;
 
 	case RTC_RD_TIME:
+		memset(&rtctm, 0, sizeof(struct rtc_time));
 		get_rtc_time(&rtc_raw, &year);
 		rtctm.tm_sec  = rtc_raw.secs;
 		rtctm.tm_min  = rtc_raw.mins;
diff -urN linux-2.4.24-pre1/drivers/acpi/Config.in linux-2.4.24-pre2/drivers/acpi/Config.in
--- linux-2.4.24-pre1/drivers/acpi/Config.in	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/Config.in	2003-12-22 11:34:34.000000000 -0800
@@ -32,7 +32,7 @@
     tristate     '  Toshiba Laptop Extras'	CONFIG_ACPI_TOSHIBA
     bool         '  Debug Statements'	CONFIG_ACPI_DEBUG
     bool         '  Relaxed AML Checking'	CONFIG_ACPI_RELAXED_AML
-  else 
+  else
     if [ "$CONFIG_SMP" = "y" ]; then
       define_bool CONFIG_ACPI_BOOT		y
     fi
diff -urN linux-2.4.24-pre1/drivers/acpi/bus.c linux-2.4.24-pre2/drivers/acpi/bus.c
--- linux-2.4.24-pre1/drivers/acpi/bus.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/bus.c	2003-12-22 11:34:34.000000000 -0800
@@ -2047,8 +2047,10 @@
 #endif
 
 	result = acpi_bus_init();
-	if (result)
+	if (result) {
+		acpi_disabled = 1;
 		return_VALUE(result);
+	}
 
 #ifdef CONFIG_PM
 	pm_active = 1;
diff -urN linux-2.4.24-pre1/drivers/acpi/dispatcher/dsinit.c linux-2.4.24-pre2/drivers/acpi/dispatcher/dsinit.c
--- linux-2.4.24-pre1/drivers/acpi/dispatcher/dsinit.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/dispatcher/dsinit.c	2003-12-22 11:34:34.000000000 -0800
@@ -106,7 +106,7 @@
 		status = acpi_ds_initialize_region (obj_handle);
 		if (ACPI_FAILURE (status)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n",
-				obj_handle, ((struct acpi_namespace_node *) obj_handle)->name.ascii,
+				obj_handle, acpi_ut_get_node_name (obj_handle),
 				acpi_format_exception (status)));
 		}
 
@@ -141,7 +141,7 @@
 		status = acpi_ds_parse_method (obj_handle);
 		if (ACPI_FAILURE (status)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
-				obj_handle, ((struct acpi_namespace_node *) obj_handle)->name.ascii,
+				obj_handle, acpi_ut_get_node_name (obj_handle),
 				acpi_format_exception (status)));
 
 			/* This parse failed, but we will continue parsing more methods */
diff -urN linux-2.4.24-pre1/drivers/acpi/dispatcher/dsmethod.c linux-2.4.24-pre2/drivers/acpi/dispatcher/dsmethod.c
--- linux-2.4.24-pre1/drivers/acpi/dispatcher/dsmethod.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/dispatcher/dsmethod.c	2003-12-22 11:34:34.000000000 -0800
@@ -94,7 +94,7 @@
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n",
-		((struct acpi_namespace_node *) obj_handle)->name.ascii, obj_handle));
+		acpi_ut_get_node_name (obj_handle), obj_handle));
 
 	/* Extract the method object from the method Node */
 
@@ -169,7 +169,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
 		"**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
-		((struct acpi_namespace_node *) obj_handle)->name.ascii, obj_handle, op));
+		acpi_ut_get_node_name (obj_handle), obj_handle, op));
 
 	acpi_ps_delete_parse_tree (op);
 	return_ACPI_STATUS (status);
diff -urN linux-2.4.24-pre1/drivers/acpi/dispatcher/dsmthdat.c linux-2.4.24-pre2/drivers/acpi/dispatcher/dsmthdat.c
--- linux-2.4.24-pre1/drivers/acpi/dispatcher/dsmthdat.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/dispatcher/dsmthdat.c	2003-12-22 11:34:34.000000000 -0800
@@ -567,13 +567,13 @@
 	acpi_status                     status;
 	struct acpi_namespace_node      *node;
 	union acpi_operand_object       *current_obj_desc;
+	union acpi_operand_object       *new_obj_desc;
 
 
 	ACPI_FUNCTION_TRACE ("ds_store_object_to_local");
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n",
 		opcode, index, obj_desc));
 
-
 	/* Parameter validation */
 
 	if (!obj_desc) {
@@ -595,6 +595,19 @@
 	}
 
 	/*
+	 * If the reference count on the object is more than one, we must
+	 * take a copy of the object before we store.
+	 */
+	new_obj_desc = obj_desc;
+	if (obj_desc->common.reference_count > 1) {
+		status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state);
+		new_obj_desc;
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
 	 * If there is an object already in this slot, we either
 	 * have to delete it, or if this is an argument and there
 	 * is an object reference stored there, we have to do
@@ -624,8 +637,8 @@
 			 * operand objects of type Reference.
 			 */
 			if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) {
-				ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: %X\n",
-					current_obj_desc->common.type));
+				ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n",
+						acpi_ut_get_descriptor_name (current_obj_desc)));
 				return_ACPI_STATUS (AE_AML_INTERNAL);
 			}
 
@@ -636,15 +649,21 @@
 			if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
 				(current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
-					"Arg (%p) is an obj_ref(Node), storing in node %p\n",
-					obj_desc, current_obj_desc));
+						"Arg (%p) is an obj_ref(Node), storing in node %p\n",
+						new_obj_desc, current_obj_desc));
 
 				/*
 				 * Store this object to the Node
 				 * (perform the indirect store)
 				 */
-				status = acpi_ex_store_object_to_node (obj_desc,
+				status = acpi_ex_store_object_to_node (new_obj_desc,
 						 current_obj_desc->reference.object, walk_state);
+
+				/* Remove local reference if we copied the object above */
+
+				if (new_obj_desc != obj_desc) {
+					acpi_ut_remove_reference (new_obj_desc);
+				}
 				return_ACPI_STATUS (status);
 			}
 		}
@@ -657,12 +676,18 @@
 	}
 
 	/*
-	 * Install the obj_stack descriptor (*obj_desc) into
+	 * Install the Obj descriptor (*new_obj_desc) into
 	 * the descriptor for the Arg or Local.
-	 * Install the new object in the stack entry
 	 * (increments the object reference count by one)
 	 */
-	status = acpi_ds_method_data_set_value (opcode, index, obj_desc, walk_state);
+	status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state);
+
+	/* Remove local reference if we copied the object above */
+
+	if (new_obj_desc != obj_desc) {
+		acpi_ut_remove_reference (new_obj_desc);
+	}
+
 	return_ACPI_STATUS (status);
 }
 
diff -urN linux-2.4.24-pre1/drivers/acpi/dispatcher/dsopcode.c linux-2.4.24-pre2/drivers/acpi/dispatcher/dsopcode.c
--- linux-2.4.24-pre1/drivers/acpi/dispatcher/dsopcode.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/dispatcher/dsopcode.c	2003-12-22 11:34:34.000000000 -0800
@@ -201,7 +201,7 @@
 
 	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL));
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n",
-		node->name.ascii));
+		acpi_ut_get_node_name (node)));
 
 	/* Execute the AML code for the term_arg arguments */
 
@@ -346,7 +346,7 @@
 	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n",
-		node->name.ascii, extra_desc->extra.aml_start));
+		acpi_ut_get_node_name (node), extra_desc->extra.aml_start));
 
 	/* Execute the argument AML */
 
@@ -438,8 +438,8 @@
 	 * after resolution in acpi_ex_resolve_operands().
 	 */
 	if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination must be a NS Node\n",
-			acpi_ps_get_opcode_name (aml_opcode)));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n",
+				acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc)));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
@@ -514,14 +514,16 @@
 		goto cleanup;
 	}
 
-
 	/* Entire field must fit within the current length of the buffer */
 
 	if ((bit_offset + bit_count) >
 		(8 * (u32) buffer_desc->buffer.length)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Field size %d exceeds Buffer size %d (bits)\n",
-			 bit_offset + bit_count, 8 * (u32) buffer_desc->buffer.length));
+			"Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
+			 acpi_ut_get_node_name (result_desc),
+			 bit_offset + bit_count,
+			 acpi_ut_get_node_name (buffer_desc->buffer.node),
+			 8 * (u32) buffer_desc->buffer.length));
 		status = AE_AML_BUFFER_LIMIT;
 		goto cleanup;
 	}
@@ -742,7 +744,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
 		obj_desc,
-		ACPI_HIDWORD (obj_desc->region.address), ACPI_LODWORD (obj_desc->region.address),
+		ACPI_FORMAT_UINT64 (obj_desc->region.address),
 		obj_desc->region.length));
 
 	/* Now the address and length are valid for this opregion */
diff -urN linux-2.4.24-pre1/drivers/acpi/dispatcher/dswexec.c linux-2.4.24-pre2/drivers/acpi/dispatcher/dswexec.c
--- linux-2.4.24-pre1/drivers/acpi/dispatcher/dswexec.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/dispatcher/dswexec.c	2003-12-22 11:34:34.000000000 -0800
@@ -416,10 +416,24 @@
 			status = acpi_gbl_op_type_dispatch [op_type] (walk_state);
 		}
 		else {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-				"[%s]: Could not resolve operands, %s\n",
-				acpi_ps_get_opcode_name (walk_state->opcode),
-				acpi_format_exception (status)));
+			/*
+			 * Treat constructs of the form "Store(local_x,local_x)" as noops when the
+			 * Local is uninitialized.
+			 */
+			if  ((status == AE_AML_UNINITIALIZED_LOCAL) &&
+				(walk_state->opcode == AML_STORE_OP) &&
+				(walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+				(walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+				(walk_state->operands[0]->reference.opcode ==
+				 walk_state->operands[1]->reference.opcode)) {
+				status = AE_OK;
+			}
+			else {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"[%s]: Could not resolve operands, %s\n",
+					acpi_ps_get_opcode_name (walk_state->opcode),
+					acpi_format_exception (status)));
+			}
 		}
 
 		/* Always delete the argument objects and clear the operand stack */
diff -urN linux-2.4.24-pre1/drivers/acpi/dispatcher/dswload.c linux-2.4.24-pre2/drivers/acpi/dispatcher/dswload.c
--- linux-2.4.24-pre1/drivers/acpi/dispatcher/dswload.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/dispatcher/dswload.c	2003-12-22 11:34:34.000000000 -0800
@@ -167,7 +167,7 @@
 	object_type = walk_state->op_info->object_type;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-		"State=%p Op=%p [%s] ", walk_state, op, acpi_ut_get_type_name (object_type)));
+		"State=%p Op=%p [%s]\n", walk_state, op, acpi_ut_get_type_name (object_type)));
 
 	switch (walk_state->opcode) {
 	case AML_SCOPE_OP:
@@ -260,10 +260,12 @@
 		if ((walk_state->opcode != AML_SCOPE_OP) &&
 			(!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
 			flags |= ACPI_NS_ERROR_IF_FOUND;
-			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Cannot already exist\n"));
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
+					acpi_ut_get_type_name (object_type)));
 		}
 		else {
-			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Both Find or Create allowed\n"));
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n",
+					acpi_ut_get_type_name (object_type)));
 		}
 
 		/*
diff -urN linux-2.4.24-pre1/drivers/acpi/dispatcher/dswscope.c linux-2.4.24-pre2/drivers/acpi/dispatcher/dswscope.c
--- linux-2.4.24-pre1/drivers/acpi/dispatcher/dswscope.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/dispatcher/dswscope.c	2003-12-22 11:34:34.000000000 -0800
@@ -146,7 +146,7 @@
 	if (old_scope_info) {
 		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
 			"[%4.4s] (%s)",
-			old_scope_info->scope.node->name.ascii,
+			acpi_ut_get_node_name (old_scope_info->scope.node),
 			acpi_ut_get_type_name (old_scope_info->common.value)));
 	}
 	else {
@@ -156,7 +156,7 @@
 
 	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
 		", New scope -> [%4.4s] (%s)\n",
-		scope_info->scope.node->name.ascii,
+		acpi_ut_get_node_name (scope_info->scope.node),
 		acpi_ut_get_type_name (scope_info->common.value)));
 
 	/* Push new scope object onto stack */
@@ -207,14 +207,14 @@
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 		"[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
 		(u32) walk_state->scope_depth,
-		scope_info->scope.node->name.ascii,
+		acpi_ut_get_node_name (scope_info->scope.node),
 		acpi_ut_get_type_name (scope_info->common.value)));
 
 	new_scope_info = walk_state->scope_info;
 	if (new_scope_info) {
 		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
 			"[%4.4s] (%s)\n",
-			new_scope_info->scope.node->name.ascii,
+			acpi_ut_get_node_name (new_scope_info->scope.node),
 			acpi_ut_get_type_name (new_scope_info->common.value)));
 	}
 	else {
diff -urN linux-2.4.24-pre1/drivers/acpi/events/evgpe.c linux-2.4.24-pre2/drivers/acpi/events/evgpe.c
--- linux-2.4.24-pre1/drivers/acpi/events/evgpe.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/events/evgpe.c	2003-12-22 11:34:34.000000000 -0800
@@ -139,12 +139,10 @@
 {
 	u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
 	u8                              enabled_status_byte;
-	u8                              bit_mask;
 	struct acpi_gpe_register_info   *gpe_register_info;
 	u32                             in_value;
 	acpi_status                     status;
 	struct acpi_gpe_block_info      *gpe_block;
-	u32                             gpe_number;
 	u32                             i;
 	u32                             j;
 
@@ -187,11 +185,9 @@
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
 				"GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n",
-				ACPI_HIDWORD (gpe_register_info->status_address.address),
-				ACPI_LODWORD (gpe_register_info->status_address.address),
+				ACPI_FORMAT_UINT64 (gpe_register_info->status_address.address),
 				gpe_register_info->status,
-				ACPI_HIDWORD (gpe_register_info->enable_address.address),
-				ACPI_LODWORD (gpe_register_info->enable_address.address),
+				ACPI_FORMAT_UINT64 (gpe_register_info->enable_address.address),
 				gpe_register_info->enable));
 
 			/* First check if there is anything active at all in this register */
@@ -206,18 +202,16 @@
 
 			/* Now look at the individual GPEs in this byte register */
 
-			for (j = 0, bit_mask = 1; j < ACPI_GPE_REGISTER_WIDTH; j++, bit_mask <<= 1) {
+			for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
 				/* Examine one GPE bit */
 
-				if (enabled_status_byte & bit_mask) {
+				if (enabled_status_byte & acpi_gbl_decode_to8bit[j]) {
 					/*
 					 * Found an active GPE. Dispatch the event to a handler
 					 * or method.
 					 */
-					gpe_number = (i * ACPI_GPE_REGISTER_WIDTH) + j;
-
 					int_status |= acpi_ev_gpe_dispatch (
-							  &gpe_block->event_info[gpe_number],
+							  &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
 							  j + gpe_register_info->base_gpe_number);
 				}
 			}
@@ -294,7 +288,7 @@
 		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n",
 				acpi_format_exception (status),
-				local_gpe_event_info.method_node->name.ascii, gpe_number));
+				acpi_ut_get_node_name (local_gpe_event_info.method_node), gpe_number));
 		}
 	}
 
@@ -367,6 +361,18 @@
 		/* Invoke the installed handler (at interrupt level) */
 
 		gpe_event_info->handler (gpe_event_info->context);
+
+		/* It is now safe to clear level-triggered events. */
+
+		if (gpe_event_info->flags & ACPI_EVENT_LEVEL_TRIGGERED) {
+			status = acpi_hw_clear_gpe (gpe_event_info);
+			if (ACPI_FAILURE (status)) {
+				ACPI_REPORT_ERROR ((
+					"acpi_ev_gpe_dispatch: Unable to clear GPE[%2X]\n",
+					gpe_number));
+				return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
+			}
+		}
 	}
 	else if (gpe_event_info->method_node) {
 		/*
@@ -375,13 +381,16 @@
 		 */
 		status = acpi_hw_disable_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
+			ACPI_REPORT_ERROR ((
+				"acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
 				gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
 
-		/* Execute the method associated with the GPE. */
-
+		/*
+		 * Execute the method associated with the GPE
+		 * NOTE: Level-triggered GPEs are cleared after the method completes.
+		 */
 		if (ACPI_FAILURE (acpi_os_queue_for_execution (OSD_PRIORITY_GPE,
 				 acpi_ev_asynch_execute_gpe_method,
 				 gpe_event_info))) {
@@ -399,22 +408,12 @@
 
 		/*
 		 * Disable the GPE.  The GPE will remain disabled until the ACPI
-		 * Core Subsystem is restarted, or the handler is reinstalled.
+		 * Core Subsystem is restarted, or a handler is installed.
 		 */
 		status = acpi_hw_disable_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
-				gpe_number));
-			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
-		}
-	}
-
-	/* It is now safe to clear level-triggered events. */
-
-	if (gpe_event_info->flags & ACPI_EVENT_LEVEL_TRIGGERED) {
-		status = acpi_hw_clear_gpe (gpe_event_info);
-		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: Unable to clear GPE[%2X]\n",
+			ACPI_REPORT_ERROR ((
+				"acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
 				gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
diff -urN linux-2.4.24-pre1/drivers/acpi/events/evgpeblk.c linux-2.4.24-pre2/drivers/acpi/events/evgpeblk.c
--- linux-2.4.24-pre1/drivers/acpi/events/evgpeblk.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/events/evgpeblk.c	2003-12-22 11:34:34.000000000 -0800
@@ -477,7 +477,7 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Install new GPE block with mutex support
+ * DESCRIPTION: Remove a GPE block
  *
  ******************************************************************************/
 
@@ -743,8 +743,7 @@
 				((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
 		gpe_device->name.ascii,
 		gpe_block->register_count,
-		ACPI_HIDWORD (gpe_block->block_address.address),
-		ACPI_LODWORD (gpe_block->block_address.address),
+		ACPI_FORMAT_UINT64 (gpe_block->block_address.address),
 		interrupt_level));
 
 	/* Find all GPE methods (_Lxx, _Exx) for this block */
diff -urN linux-2.4.24-pre1/drivers/acpi/events/evmisc.c linux-2.4.24-pre2/drivers/acpi/events/evmisc.c
--- linux-2.4.24-pre1/drivers/acpi/events/evmisc.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/events/evmisc.c	2003-12-22 11:34:34.000000000 -0800
@@ -195,7 +195,8 @@
 		/* There is no per-device notify handler for this device */
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-			"No notify handler for [%4.4s] node %p\n", node->name.ascii, node));
+			"No notify handler for [%4.4s] node %p\n",
+			acpi_ut_get_node_name (node), node));
 	}
 
 	return (status);
diff -urN linux-2.4.24-pre1/drivers/acpi/events/evregion.c linux-2.4.24-pre2/drivers/acpi/events/evregion.c
--- linux-2.4.24-pre1/drivers/acpi/events/evregion.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/events/evregion.c	2003-12-22 11:34:34.000000000 -0800
@@ -136,7 +136,7 @@
  *
  ******************************************************************************/
 
-static acpi_status
+acpi_status
 acpi_ev_execute_reg_method (
 	union acpi_operand_object      *region_obj,
 	u32                             function)
@@ -202,7 +202,7 @@
  *
  * FUNCTION:    acpi_ev_address_space_dispatch
  *
- * PARAMETERS:  region_obj          - internal region object
+ * PARAMETERS:  region_obj          - Internal region object
  *              space_id            - ID of the address space (0-255)
  *              Function            - Read or Write operation
  *              Address             - Where in the space to read or write
@@ -243,9 +243,11 @@
 
 	/* Ensure that there is a handler associated with this region */
 
-	handler_desc = region_obj->region.address_space;
+	handler_desc = region_obj->region.handler;
 	if (!handler_desc) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"No handler for Region [%4.4s] (%p) [%s]\n",
+			acpi_ut_get_node_name (region_obj->region.node),
 			region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
 
 		return_ACPI_STATUS (AE_NOT_EXIST);
@@ -320,8 +322,8 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 		"Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
-		&region_obj->region.address_space->address_space, handler,
-		ACPI_HIDWORD (address), ACPI_LODWORD (address),
+		&region_obj->region.handler->address_space, handler,
+		ACPI_FORMAT_UINT64 (address),
 		acpi_ut_get_region_name (region_obj->region.space_id)));
 
 	if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
@@ -359,6 +361,7 @@
 	return_ACPI_STATUS (status);
 }
 
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_detach_region
@@ -398,7 +401,7 @@
 
 	/* Get the address handler from the region object */
 
-	handler_obj = region_obj->region.address_space;
+	handler_obj = region_obj->region.handler;
 	if (!handler_obj) {
 		/* This region has no handler, all done */
 
@@ -472,7 +475,7 @@
 			 * If the region is on the handler's list
 			 * this better be the region's handler
 			 */
-			region_obj->region.address_space = NULL;
+			region_obj->region.handler = NULL;
 			acpi_ut_remove_reference (handler_obj);
 
 			return_VOID;
@@ -515,17 +518,15 @@
 	union acpi_operand_object       *region_obj,
 	u8                              acpi_ns_is_locked)
 {
-	acpi_status                     status;
-	acpi_status                     status2;
-
 
 	ACPI_FUNCTION_TRACE ("ev_attach_region");
 
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
-		"Adding Region %p to address handler %p [%s]\n",
-		region_obj, handler_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
-
+		"Adding Region [%4.4s] %p to address handler %p [%s]\n",
+		acpi_ut_get_node_name (region_obj->region.node),
+		region_obj, handler_obj,
+		acpi_ut_get_region_name (region_obj->region.space_id)));
 
 	/* Link this region to the front of the handler's list */
 
@@ -534,34 +535,14 @@
 
 	/* Install the region's handler */
 
-	if (region_obj->region.address_space) {
+	if (region_obj->region.handler) {
 		return_ACPI_STATUS (AE_ALREADY_EXISTS);
 	}
 
-	region_obj->region.address_space = handler_obj;
+	region_obj->region.handler = handler_obj;
 	acpi_ut_add_reference (handler_obj);
 
-	/*
-	 * Tell all users that this region is usable by running the _REG
-	 * method
-	 */
-	if (acpi_ns_is_locked) {
-		status2 = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
-		if (ACPI_FAILURE (status2)) {
-			return_ACPI_STATUS (status2);
-		}
-	}
-
-	status = acpi_ev_execute_reg_method (region_obj, 1);
-
-	if (acpi_ns_is_locked) {
-		status2 = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
-		if (ACPI_FAILURE (status2)) {
-			return_ACPI_STATUS (status2);
-		}
-	}
-
-	return_ACPI_STATUS (status);
+	return_ACPI_STATUS (AE_OK);
 }
 
 
@@ -569,9 +550,7 @@
  *
  * FUNCTION:    acpi_ev_install_handler
  *
- * PARAMETERS:  Handle              - Node to be dumped
- *              Level               - Nesting level of the handle
- *              Context             - Passed into acpi_ns_walk_namespace
+ * PARAMETERS:  walk_namespace callback
  *
  * DESCRIPTION: This routine installs an address handler into objects that are
  *              of type Region or Device.
@@ -640,7 +619,7 @@
 	if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) {
 		/* Check if this Device already has a handler for this address space */
 
-		next_handler_obj = obj_desc->device.address_space;
+		next_handler_obj = obj_desc->device.handler;
 		while (next_handler_obj) {
 			/* Found a handler, is it for the same address space? */
 
@@ -697,4 +676,77 @@
 	return (status);
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_reg_run
+ *
+ * PARAMETERS:  walk_namespace callback
+ *
+ * DESCRIPTION: Run _REg method for region objects of the requested space_iD
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_reg_run (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value)
+{
+	union acpi_operand_object       *handler_obj;
+	union acpi_operand_object       *obj_desc;
+	struct acpi_namespace_node      *node;
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_NAME ("ev_reg_run");
+
+
+	handler_obj = (union acpi_operand_object   *) context;
+
+	/* Parameter validation */
+
+	if (!handler_obj) {
+		return (AE_OK);
+	}
+
+	/* Convert and validate the device handle */
+
+	node = acpi_ns_map_handle_to_node (obj_handle);
+	if (!node) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	/*
+	 * We only care about regions.and objects
+	 * that are allowed to have address space handlers
+	 */
+	if ((node->type != ACPI_TYPE_REGION) &&
+		(node != acpi_gbl_root_node)) {
+		return (AE_OK);
+	}
+
+	/* Check for an existing internal object */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (!obj_desc) {
+		/* No object, just exit */
+
+		return (AE_OK);
+	}
+
+
+	/* Object is a Region */
+
+	if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
+		/*
+		 * This region is for a different address space
+		 * -- just ignore it
+		 */
+		return (AE_OK);
+	}
+
+	status = acpi_ev_execute_reg_method (obj_desc, 1);
+	return (status);
+}
 
diff -urN linux-2.4.24-pre1/drivers/acpi/events/evrgnini.c linux-2.4.24-pre2/drivers/acpi/events/evrgnini.c
--- linux-2.4.24-pre1/drivers/acpi/events/evrgnini.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/events/evrgnini.c	2003-12-22 11:34:34.000000000 -0800
@@ -177,7 +177,7 @@
 	ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup");
 
 
-	handler_obj = region_obj->region.address_space;
+	handler_obj = region_obj->region.handler;
 	if (!handler_obj) {
 		/*
 		 * No installed handler. This shouldn't happen because the dispatch
@@ -239,7 +239,7 @@
 						else {
 							ACPI_REPORT_ERROR ((
 								"Could not install pci_config handler for Root Bridge %4.4s, %s\n",
-								pci_root_node->name.ascii, acpi_format_exception (status)));
+								acpi_ut_get_node_name (pci_root_node), acpi_format_exception (status)));
 						}
 					}
 					break;
@@ -469,7 +469,7 @@
 
 	/* Setup defaults */
 
-	region_obj->region.address_space = NULL;
+	region_obj->region.handler = NULL;
 	region_obj2->extra.method_REG = NULL;
 	region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
 	region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
@@ -502,17 +502,17 @@
 			switch (node->type) {
 			case ACPI_TYPE_DEVICE:
 
-				handler_obj = obj_desc->device.address_space;
+				handler_obj = obj_desc->device.handler;
 				break;
 
 			case ACPI_TYPE_PROCESSOR:
 
-				handler_obj = obj_desc->processor.address_space;
+				handler_obj = obj_desc->processor.handler;
 				break;
 
 			case ACPI_TYPE_THERMAL:
 
-				handler_obj = obj_desc->thermal_zone.address_space;
+				handler_obj = obj_desc->thermal_zone.handler;
 				break;
 
 			default:
@@ -533,6 +533,26 @@
 					status = acpi_ev_attach_region (handler_obj, region_obj,
 							 acpi_ns_locked);
 
+					/*
+					 * Tell all users that this region is usable by running the _REG
+					 * method
+					 */
+					if (acpi_ns_locked) {
+						status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+						if (ACPI_FAILURE (status)) {
+							return_ACPI_STATUS (status);
+						}
+					}
+
+					status = acpi_ev_execute_reg_method (region_obj, 1);
+
+					if (acpi_ns_locked) {
+						status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+						if (ACPI_FAILURE (status)) {
+							return_ACPI_STATUS (status);
+						}
+					}
+
 					return_ACPI_STATUS (AE_OK);
 				}
 
diff -urN linux-2.4.24-pre1/drivers/acpi/events/evxfregn.c linux-2.4.24-pre2/drivers/acpi/events/evxfregn.c
--- linux-2.4.24-pre1/drivers/acpi/events/evxfregn.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/events/evxfregn.c	2003-12-22 11:34:34.000000000 -0800
@@ -173,7 +173,7 @@
 		 * The attached device object already exists.
 		 * Make sure the handler is not already installed.
 		 */
-		handler_obj = obj_desc->device.address_space;
+		handler_obj = obj_desc->device.handler;
 
 		/* Walk the handler list for this device */
 
@@ -240,7 +240,8 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
 		"Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
-		acpi_ut_get_region_name (space_id), space_id, node->name.ascii, node, obj_desc));
+		acpi_ut_get_region_name (space_id), space_id,
+		acpi_ut_get_node_name (node), node, obj_desc));
 
 	/*
 	 * Install the handler
@@ -267,13 +268,13 @@
 
 	/* Install at head of Device.address_space list */
 
-	handler_obj->address_space.next      = obj_desc->device.address_space;
+	handler_obj->address_space.next      = obj_desc->device.handler;
 
 	/*
 	 * The Device object is the first reference on the handler_obj.
 	 * Each region that uses the handler adds a reference.
 	 */
-	obj_desc->device.address_space = handler_obj;
+	obj_desc->device.handler = handler_obj;
 
 	/*
 	 * Walk the namespace finding all of the regions this
@@ -291,6 +292,17 @@
 			  ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
 			  handler_obj, NULL);
 
+	/*
+	 * Now we can run the _REG methods for all Regions for this
+	 * space ID.  This is a separate walk in order to handle any
+	 * interdependencies between regions and _REG methods.  (i.e. handlers
+	 * must be installed for all regions of this Space ID before we
+	 * can run any _REG methods.
+	 */
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
+			  ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
+			  handler_obj, NULL);
+
 unlock_and_exit:
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return_ACPI_STATUS (status);
@@ -357,8 +369,8 @@
 
 	/* Find the address handler the user requested */
 
-	handler_obj = obj_desc->device.address_space;
-	last_obj_ptr = &obj_desc->device.address_space;
+	handler_obj = obj_desc->device.handler;
+	last_obj_ptr = &obj_desc->device.handler;
 	while (handler_obj) {
 		/* We have a handler, see if user requested this one */
 
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exdump.c linux-2.4.24-pre2/drivers/acpi/executer/exdump.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exdump.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/executer/exdump.c	2003-12-22 11:34:34.000000000 -0800
@@ -89,27 +89,27 @@
 
 	if (!obj_desc) {
 		/*
-		 * This usually indicates that something serious is wrong --
-		 * since most (if not all)
-		 * code that dumps the stack expects something to be there!
+		 * This usually indicates that something serious is wrong
 		 */
-		acpi_os_printf ("Null stack entry ptr\n");
+		acpi_os_printf ("Null Object Descriptor\n");
 		return;
 	}
 
 	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p NS Node: ", obj_desc));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is a NS Node: ", obj_desc));
 		ACPI_DUMP_ENTRY (obj_desc, ACPI_LV_EXEC);
 		return;
 	}
 
 	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p is not a local object\n", obj_desc));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+				"%p is not a node or operand object: [%s]\n",
+				obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
 		ACPI_DUMP_BUFFER (obj_desc, sizeof (union acpi_operand_object));
 		return;
 	}
 
-	/*  obj_desc is a valid object */
+	/* obj_desc is a valid object */
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
 
@@ -151,11 +151,10 @@
 					 obj_desc->reference.offset);
 
 			if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
-				/* Value is a Number */
+				/* Value is an Integer */
 
 				acpi_os_printf (" value is [%8.8X%8.8x]",
-						 ACPI_HIDWORD(obj_desc->integer.value),
-						 ACPI_LODWORD(obj_desc->integer.value));
+						 ACPI_FORMAT_UINT64 (obj_desc->integer.value));
 			}
 
 			acpi_os_printf ("\n");
@@ -169,11 +168,10 @@
 
 			if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 
-				/* Value is a Number */
+				/* Value is an Integer */
 
 				acpi_os_printf (" value is [%8.8X%8.8x]",
-						 ACPI_HIDWORD(obj_desc->integer.value),
-						 ACPI_LODWORD(obj_desc->integer.value));
+						 ACPI_FORMAT_UINT64 (obj_desc->integer.value));
 			}
 
 			acpi_os_printf ("\n");
@@ -189,7 +187,7 @@
 
 		default:
 
-			/*  unknown opcode  */
+			/* Unknown opcode */
 
 			acpi_os_printf ("Unknown Reference opcode=%X\n",
 				obj_desc->reference.opcode);
@@ -229,8 +227,7 @@
 	case ACPI_TYPE_INTEGER:
 
 		acpi_os_printf ("Integer %8.8X%8.8X\n",
-				 ACPI_HIDWORD (obj_desc->integer.value),
-				 ACPI_LODWORD (obj_desc->integer.value));
+				 ACPI_FORMAT_UINT64 (obj_desc->integer.value));
 		break;
 
 
@@ -271,8 +268,7 @@
 		}
 		else {
 			acpi_os_printf (" base %8.8X%8.8X Length %X\n",
-				ACPI_HIDWORD (obj_desc->region.address),
-				ACPI_LODWORD (obj_desc->region.address),
+				ACPI_FORMAT_UINT64 (obj_desc->region.address),
 				obj_desc->region.length);
 		}
 		break;
@@ -494,7 +490,7 @@
 	acpi_os_printf ("%20s : %p\n", title, value);
 #else
 	acpi_os_printf ("%20s : %8.8X%8.8X\n", title,
-			 ACPI_HIDWORD (value), ACPI_LODWORD (value));
+			 ACPI_FORMAT_UINT64 (value));
 #endif
 }
 
@@ -525,7 +521,7 @@
 		}
 	}
 
-	acpi_os_printf ("%20s : %4.4s\n",     "Name", node->name.ascii);
+	acpi_os_printf ("%20s : %4.4s\n",     "Name", acpi_ut_get_node_name (node));
 	acpi_ex_out_string ("Type",           acpi_ut_get_type_name (node->type));
 	acpi_ex_out_integer ("Flags",         node->flags);
 	acpi_ex_out_integer ("Owner Id",      node->owner_id);
@@ -573,7 +569,8 @@
 	}
 
 	if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
-		acpi_os_printf ("ex_dump_object_descriptor: %p is not a valid ACPI object\n", obj_desc);
+		acpi_os_printf ("ex_dump_object_descriptor: %p is not an ACPI operand object: [%s]\n",
+				obj_desc, acpi_ut_get_descriptor_name (obj_desc));
 		return_VOID;
 	}
 
@@ -589,8 +586,7 @@
 	case ACPI_TYPE_INTEGER:
 
 		acpi_os_printf ("%20s : %8.8X%8.8X\n", "Value",
-				  ACPI_HIDWORD (obj_desc->integer.value),
-				  ACPI_LODWORD (obj_desc->integer.value));
+				ACPI_FORMAT_UINT64 (obj_desc->integer.value));
 		break;
 
 
@@ -635,7 +631,7 @@
 
 	case ACPI_TYPE_DEVICE:
 
-		acpi_ex_out_pointer ("address_space", obj_desc->device.address_space);
+		acpi_ex_out_pointer ("Handler",     obj_desc->device.handler);
 		acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify);
 		acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify);
 		break;
@@ -673,7 +669,7 @@
 		acpi_ex_out_integer ("Flags",        obj_desc->region.flags);
 		acpi_ex_out_address ("Address",      obj_desc->region.address);
 		acpi_ex_out_integer ("Length",       obj_desc->region.length);
-		acpi_ex_out_pointer ("address_space", obj_desc->region.address_space);
+		acpi_ex_out_pointer ("Handler",      obj_desc->region.handler);
 		acpi_ex_out_pointer ("Next",         obj_desc->region.next);
 		break;
 
@@ -694,7 +690,7 @@
 		acpi_ex_out_address ("Address",      (acpi_physical_address) obj_desc->processor.address);
 		acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify);
 		acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify);
-		acpi_ex_out_pointer ("address_space", obj_desc->processor.address_space);
+		acpi_ex_out_pointer ("Handler",      obj_desc->processor.handler);
 		break;
 
 
@@ -702,7 +698,7 @@
 
 		acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify);
 		acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify);
-		acpi_ex_out_pointer ("address_space", obj_desc->thermal_zone.address_space);
+		acpi_ex_out_pointer ("Handler",      obj_desc->thermal_zone.handler);
 		break;
 
 
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exfldio.c linux-2.4.24-pre2/drivers/acpi/executer/exfldio.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exfldio.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/executer/exfldio.c	2003-12-22 11:34:34.000000000 -0800
@@ -138,8 +138,9 @@
 			 */
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
-				obj_desc->common_field.node->name.ascii, obj_desc->common_field.access_byte_width,
-				rgn_desc->region.node->name.ascii, rgn_desc->region.length));
+				acpi_ut_get_node_name (obj_desc->common_field.node),
+				obj_desc->common_field.access_byte_width,
+				acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
 		}
 
 		/*
@@ -148,9 +149,10 @@
 		 */
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Field [%4.4s] Base+Offset+Width %X+%X+%X is beyond end of region [%4.4s] (length %X)\n",
-			obj_desc->common_field.node->name.ascii, obj_desc->common_field.base_byte_offset,
+			acpi_ut_get_node_name (obj_desc->common_field.node),
+			obj_desc->common_field.base_byte_offset,
 			field_datum_byte_offset, obj_desc->common_field.access_byte_width,
-			rgn_desc->region.node->name.ascii, rgn_desc->region.length));
+			acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
 
 		#ifdef CONFIG_ACPI_RELAXED_AML
 		{
@@ -261,7 +263,7 @@
 		obj_desc->common_field.access_byte_width,
 		obj_desc->common_field.base_byte_offset,
 		field_datum_byte_offset,
-		ACPI_HIDWORD (address), ACPI_LODWORD (address)));
+		ACPI_FORMAT_UINT64 (address)));
 
 	/* Invoke the appropriate address_space/op_region handler */
 
@@ -514,12 +516,12 @@
 	if (ACPI_SUCCESS (status)) {
 		if (read_write == ACPI_READ) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n",
-					   ACPI_HIDWORD (*value), ACPI_LODWORD (*value),
+					   ACPI_FORMAT_UINT64 (*value),
 					   obj_desc->common_field.access_byte_width));
 		}
 		else {
 			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n",
-					   ACPI_HIDWORD (*value), ACPI_LODWORD (*value),
+					   ACPI_FORMAT_UINT64 (*value),
 					   obj_desc->common_field.access_byte_width));
 		}
 	}
@@ -612,11 +614,11 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 		"Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n",
-		ACPI_HIDWORD (mask), ACPI_LODWORD (mask),
+		ACPI_FORMAT_UINT64 (mask),
 		field_datum_byte_offset,
 		obj_desc->common_field.access_byte_width,
-		ACPI_HIDWORD (field_value), ACPI_LODWORD (field_value),
-		ACPI_HIDWORD (merged_value),ACPI_LODWORD (merged_value)));
+		ACPI_FORMAT_UINT64 (field_value),
+		ACPI_FORMAT_UINT64 (merged_value)));
 
 	/* Write the merged value */
 
@@ -784,12 +786,13 @@
 {
 	acpi_status                     status;
 	u32                             field_datum_byte_offset;
-	u32                             datum_offset;
-	acpi_integer                    previous_raw_datum;
+	u32                             buffer_datum_offset;
+	acpi_integer                    previous_raw_datum = 0;
 	acpi_integer                    this_raw_datum = 0;
 	acpi_integer                    merged_datum = 0;
 	u32                             byte_field_length;
 	u32                             datum_count;
+	u32                             i;
 
 
 	ACPI_FUNCTION_TRACE ("ex_extract_from_field");
@@ -812,77 +815,74 @@
 	datum_count = ACPI_ROUND_UP_TO (byte_field_length,
 			   obj_desc->common_field.access_byte_width);
 
+	/*
+	 * If the field is not aligned on a datum boundary and does not
+	 * fit within a single datum, we must read an extra datum.
+	 *
+	 * We could just split the aligned and non-aligned cases since the
+	 * aligned case is so very simple, but this would require more code.
+	 */
+	if ((obj_desc->common_field.end_field_valid_bits != 0)    &&
+		(!(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM))) {
+		datum_count++;
+	}
+
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 		"byte_len %X, datum_len %X, byte_gran %X\n",
 		byte_field_length, datum_count,obj_desc->common_field.access_byte_width));
 
 	/*
 	 * Clear the caller's buffer (the whole buffer length as given)
-	 * This is very important, especially in the cases where a byte is read,
-	 * but the buffer is really a u32 (4 bytes).
+	 * This is very important, especially in the cases where the buffer
+	 * is longer than the size of the field.
 	 */
 	ACPI_MEMSET (buffer, 0, buffer_length);
 
-	/* Read the first raw datum to prime the loop */
-
 	field_datum_byte_offset = 0;
-	datum_offset= 0;
-
-	status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
-			  &previous_raw_datum, ACPI_READ);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
-
+	buffer_datum_offset= 0;
 
-	/* We might actually be done if the request fits in one datum */
+	/* Read the entire field */
 
-	if ((datum_count == 1) &&
-		(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) {
-		/* 1) Shift the valid data bits down to start at bit 0 */
+	for (i = 0; i < datum_count; i++) {
+		status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
+				  &this_raw_datum, ACPI_READ);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
 
-		merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset);
+		/* We might actually be done if the request fits in one datum */
 
-		/* 2) Mask off any upper unused bits (bits not part of the field) */
+		if ((datum_count == 1) &&
+			(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM)) {
+			/* 1) Shift the valid data bits down to start at bit 0 */
 
-		if (obj_desc->common_field.end_buffer_valid_bits) {
-			merged_datum &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits);
-		}
+			merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset);
 
-		/* Store the datum to the caller buffer */
+			/* 2) Mask off any upper unused bits (bits not part of the field) */
 
-		acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
-				obj_desc->common_field.access_byte_width, datum_offset);
+			if (obj_desc->common_field.end_buffer_valid_bits) {
+				merged_datum &= ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits);
+			}
 
-		return_ACPI_STATUS (AE_OK);
-	}
+			/* Store the datum to the caller buffer */
 
+			acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
+					obj_desc->common_field.access_byte_width, buffer_datum_offset);
 
-	/* We need to get more raw data to complete one or more field data */
+			return_ACPI_STATUS (AE_OK);
+		}
 
-	while (datum_offset < datum_count) {
-		field_datum_byte_offset += obj_desc->common_field.access_byte_width;
+		/* Special handling for the last datum to ignore extra bits */
 
-		/*
-		 * If the field is aligned on a byte boundary, we don't want
-		 * to perform a final read, since this would potentially read
-		 * past the end of the region.
-		 *
-		 * We could just split the aligned and non-aligned cases since the
-		 * aligned case is so very simple, but this would require more code.
-		 */
-		if ((obj_desc->common_field.start_field_bit_offset != 0) ||
-			((obj_desc->common_field.start_field_bit_offset == 0) &&
-			(datum_offset < (datum_count -1)))) {
+		if ((i >= (datum_count -1))          &&
+			(obj_desc->common_field.end_field_valid_bits)) {
 			/*
-			 * Get the next raw datum, it contains some or all bits
-			 * of the current field datum
+			 * This is the last iteration of the loop.  We need to clear
+			 * any unused bits (bits that are not part of this field) before
+			 * we store the final merged datum into the caller buffer.
 			 */
-			status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset,
-					  &this_raw_datum, ACPI_READ);
-			if (ACPI_FAILURE (status)) {
-				return_ACPI_STATUS (status);
-			}
+			this_raw_datum &=
+				ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits);
 		}
 
 		/*
@@ -891,48 +891,48 @@
 		if (obj_desc->common_field.start_field_bit_offset == 0) {
 			/* Field is not skewed and we can just copy the datum */
 
-			merged_datum = previous_raw_datum;
+			acpi_ex_set_buffer_datum (this_raw_datum, buffer, buffer_length,
+					obj_desc->common_field.access_byte_width, buffer_datum_offset);
+			buffer_datum_offset++;
 		}
 		else {
-			/*
-			 * Put together the appropriate bits of the two raw data to make a
-			 * single complete field datum
-			 *
-			 * 1) Normalize the first datum down to bit 0
-			 */
-			merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset);
-
-			/* 2) Insert the second datum "above" the first datum */
+			/* Not aligned -- on the first iteration, just save the datum */
 
-			merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits);
-
-			if ((datum_offset >= (datum_count -1))) {
+			if (i != 0) {
 				/*
-				 * This is the last iteration of the loop.  We need to clear
-				 * any unused bits (bits that are not part of this field) that
-				 * came from the last raw datum before we store the final
-				 * merged datum into the caller buffer.
+				 * Put together the appropriate bits of the two raw data to make a
+				 * single complete field datum
+				 *
+				 * 1) Normalize the first datum down to bit 0
 				 */
-				if (obj_desc->common_field.end_buffer_valid_bits) {
-					merged_datum &=
-						ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_buffer_valid_bits);
-				}
+				merged_datum = (previous_raw_datum >> obj_desc->common_field.start_field_bit_offset);
+
+				/* 2) Insert the second datum "above" the first datum */
+
+				merged_datum |= (this_raw_datum << obj_desc->common_field.datum_valid_bits);
+
+				acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
+						obj_desc->common_field.access_byte_width, buffer_datum_offset);
+				buffer_datum_offset++;
 			}
+
+			/*
+			 * Save the raw datum that was just acquired since it may contain bits
+			 * of the *next* field datum
+			 */
+			previous_raw_datum = this_raw_datum;
 		}
 
-		/*
-		 * Store the merged field datum in the caller's buffer, according to
-		 * the granularity of the field (size of each datum).
-		 */
-		acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
-				obj_desc->common_field.access_byte_width, datum_offset);
+		field_datum_byte_offset += obj_desc->common_field.access_byte_width;
+	}
 
-		/*
-		 * Save the raw datum that was just acquired since it may contain bits
-		 * of the *next* field datum.  Update offsets
-		 */
-		previous_raw_datum = this_raw_datum;
-		datum_offset++;
+	/* For non-aligned case, there is one last datum to insert */
+
+	if (obj_desc->common_field.start_field_bit_offset != 0) {
+		merged_datum = (this_raw_datum >> obj_desc->common_field.start_field_bit_offset);
+
+		acpi_ex_set_buffer_datum (merged_datum, buffer, buffer_length,
+				obj_desc->common_field.access_byte_width, buffer_datum_offset);
 	}
 
 	return_ACPI_STATUS (AE_OK);
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exmisc.c linux-2.4.24-pre2/drivers/acpi/executer/exmisc.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exmisc.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/executer/exmisc.c	2003-12-22 11:34:34.000000000 -0800
@@ -121,8 +121,8 @@
 
 	default:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type %X in %p\n",
-			ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p has invalid descriptor [%s]\n",
+				obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
 		return_ACPI_STATUS (AE_TYPE);
 	}
 
@@ -139,7 +139,7 @@
 	*return_desc = reference_obj;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n",
-		obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
+			obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
 
 	return_ACPI_STATUS (AE_OK);
 }
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exmutex.c linux-2.4.24-pre2/drivers/acpi/executer/exmutex.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exmutex.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/executer/exmutex.c	2003-12-22 11:34:34.000000000 -0800
@@ -159,7 +159,7 @@
 
 	if (!walk_state->thread) {
 		ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], null thread info\n",
-				obj_desc->mutex.node->name.ascii));
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
 		return_ACPI_STATUS (AE_AML_INTERNAL);
 	}
 
@@ -169,7 +169,7 @@
 	 */
 	if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
 		ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], incorrect sync_level\n",
-				obj_desc->mutex.node->name.ascii));
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
 		return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
 	}
 
@@ -242,7 +242,7 @@
 
 	if (!obj_desc->mutex.owner_thread) {
 		ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], not acquired\n",
-				obj_desc->mutex.node->name.ascii));
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
 		return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
 	}
 
@@ -250,7 +250,7 @@
 
 	if (!walk_state->thread) {
 		ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], null thread info\n",
-				obj_desc->mutex.node->name.ascii));
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
 		return_ACPI_STATUS (AE_AML_INTERNAL);
 	}
 
@@ -260,7 +260,7 @@
 		ACPI_REPORT_ERROR ((
 			"Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n",
 			walk_state->thread->thread_id,
-			obj_desc->mutex.node->name.ascii,
+			acpi_ut_get_node_name (obj_desc->mutex.node),
 			obj_desc->mutex.owner_thread->thread_id));
 		return_ACPI_STATUS (AE_AML_NOT_OWNER);
 	}
@@ -271,7 +271,7 @@
 	 */
 	if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
 		ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], incorrect sync_level\n",
-				obj_desc->mutex.node->name.ascii));
+				acpi_ut_get_node_name (obj_desc->mutex.node)));
 		return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
 	}
 
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exoparg1.c linux-2.4.24-pre2/drivers/acpi/executer/exoparg1.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exoparg1.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/executer/exoparg1.c	2003-12-22 11:34:34.000000000 -0800
@@ -351,8 +351,7 @@
 
 			if (digit > 0) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Integer too large to convert to BCD: %8.8X%8.8X\n",
-					ACPI_HIDWORD(operand[0]->integer.value),
-					ACPI_LODWORD(operand[0]->integer.value)));
+						ACPI_FORMAT_UINT64 (operand[0]->integer.value)));
 				status = AE_AML_NUMERIC_OVERFLOW;
 				goto cleanup;
 			}
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exoparg3.c linux-2.4.24-pre2/drivers/acpi/executer/exoparg3.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exoparg3.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/executer/exoparg3.c	2003-12-22 11:34:34.000000000 -0800
@@ -101,15 +101,14 @@
 
 
 	switch (walk_state->opcode) {
-
 	case AML_FATAL_OP:          /* Fatal (fatal_type fatal_code fatal_arg)   */
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 			"fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
-			(u32) operand[0]->integer.value, (u32) operand[1]->integer.value,
+			(u32) operand[0]->integer.value,
+			(u32) operand[1]->integer.value,
 			(u32) operand[2]->integer.value));
 
-
 		fatal = ACPI_MEM_ALLOCATE (sizeof (struct acpi_signal_fatal_info));
 		if (fatal) {
 			fatal->type     = (u32) operand[0]->integer.value;
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exprep.c linux-2.4.24-pre2/drivers/acpi/executer/exprep.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exprep.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/executer/exprep.c	2003-12-22 11:34:34.000000000 -0800
@@ -351,7 +351,7 @@
 	 */
 	nearest_byte_address =
 			ACPI_ROUND_BITS_DOWN_TO_BYTES (field_bit_position);
-	obj_desc->common_field.base_byte_offset =
+	obj_desc->common_field.base_byte_offset = (u32)
 			ACPI_ROUND_DOWN (nearest_byte_address, byte_alignment);
 
 	/*
@@ -539,7 +539,7 @@
 			  acpi_ns_get_type (info->field_node));
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set named_obj %p [%4.4s], obj_desc %p\n",
-			info->field_node, info->field_node->name.ascii, obj_desc));
+			info->field_node, acpi_ut_get_node_name (info->field_node), obj_desc));
 
 	/* Remove local reference to the object */
 
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exregion.c linux-2.4.24-pre2/drivers/acpi/executer/exregion.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exregion.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/executer/exregion.c	2003-12-22 11:34:34.000000000 -0800
@@ -161,7 +161,7 @@
 				  (void **) &mem_info->mapped_logical_address);
 		if (ACPI_FAILURE (status)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n",
-				ACPI_HIDWORD (address), ACPI_LODWORD (address), (u32) window_size));
+					ACPI_FORMAT_UINT64 (address), (u32) window_size));
 			mem_info->mapped_length = 0;
 			return_ACPI_STATUS (status);
 		}
@@ -180,8 +180,8 @@
 			  ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address);
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-		"system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
-		ACPI_HIDWORD (address), ACPI_LODWORD (address)));
+			"system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
+			ACPI_FORMAT_UINT64 (address)));
 
    /*
 	* Perform the memory read or write
@@ -290,8 +290,8 @@
 
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-		"system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
-		ACPI_HIDWORD (address), ACPI_LODWORD (address)));
+			"system_iO %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
+			ACPI_FORMAT_UINT64 (address)));
 
 	/* Decode the function parameter */
 
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exresolv.c linux-2.4.24-pre2/drivers/acpi/executer/exresolv.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exresolv.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/executer/exresolv.c	2003-12-22 11:34:34.000000000 -0800
@@ -349,6 +349,8 @@
 			/* All "References" point to a NS node */
 
 			if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
+				ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
+						node, acpi_ut_get_descriptor_name (node)));
 				return_ACPI_STATUS (AE_AML_INTERNAL);
 			}
 
@@ -399,7 +401,9 @@
 			/* All "References" point to a NS node */
 
 			if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
-				return_ACPI_STATUS (AE_AML_INTERNAL);
+				ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
+						node, acpi_ut_get_descriptor_name (node)));
+			   return_ACPI_STATUS (AE_AML_INTERNAL);
 			}
 
 			/* Get the attached object */
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exresop.c linux-2.4.24-pre2/drivers/acpi/executer/exresop.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exresop.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/executer/exresop.c	2003-12-22 11:34:34.000000000 -0800
@@ -247,8 +247,8 @@
 			/* Invalid descriptor */
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-				"Bad descriptor type %X in Obj %p\n",
-				ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc));
+					"Invalid descriptor %p [%s]\n",
+					obj_desc, acpi_ut_get_descriptor_name (obj_desc)));
 
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exstore.c linux-2.4.24-pre2/drivers/acpi/executer/exstore.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exstore.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/executer/exstore.c	2003-12-22 11:34:34.000000000 -0800
@@ -190,8 +190,7 @@
 		case ACPI_TYPE_INTEGER:
 
 			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%8.8X%8.8X\n",
-					ACPI_HIDWORD (source_desc->integer.value),
-					ACPI_LODWORD (source_desc->integer.value)));
+					ACPI_FORMAT_UINT64 (source_desc->integer.value)));
 			break;
 
 
diff -urN linux-2.4.24-pre1/drivers/acpi/executer/exsystem.c linux-2.4.24-pre2/drivers/acpi/executer/exsystem.c
--- linux-2.4.24-pre1/drivers/acpi/executer/exsystem.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/executer/exsystem.c	2003-12-22 11:34:34.000000000 -0800
@@ -111,11 +111,16 @@
  *
  * FUNCTION:    acpi_ex_system_do_stall
  *
- * PARAMETERS:  how_long            - The amount of time to stall
+ * PARAMETERS:  how_long            - The amount of time to stall,
+ *                                    in microseconds
  *
  * RETURN:      Status
  *
  * DESCRIPTION: Suspend running thread for specified amount of time.
+ *              Note: ACPI specification requires that Stall() does not
+ *              relinquish the processor, and delays longer than 100 usec
+ *              should use Sleep() instead.  We allow stalls up to 255 usec
+ *              for compatibility with other interpreters and existing BIOSs.
  *
  ******************************************************************************/
 
@@ -129,12 +134,15 @@
 	ACPI_FUNCTION_ENTRY ();
 
 
-	if (how_long > 100) /* 100 microseconds */ {
+	if (how_long > 255) /* 255 microseconds */ {
 		/*
-		 * Longer than 100 usec, use sleep instead
-		 * (according to ACPI specification)
+		 * Longer than 255 usec, this is an error
+		 *
+		 * (ACPI specifies 100 usec as max, but this gives some slack in
+		 * order to support existing BIOSs)
 		 */
-		status = acpi_ex_system_do_suspend ((how_long / 1000) + 1);
+		ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long));
+		status = AE_AML_OPERAND_VALUE;
 	}
 	else {
 		acpi_os_stall (how_long);
@@ -148,7 +156,8 @@
  *
  * FUNCTION:    acpi_ex_system_do_suspend
  *
- * PARAMETERS:  how_long            - The amount of time to suspend
+ * PARAMETERS:  how_long            - The amount of time to suspend,
+ *                                    in milliseconds
  *
  * RETURN:      None
  *
diff -urN linux-2.4.24-pre1/drivers/acpi/hardware/hwacpi.c linux-2.4.24-pre2/drivers/acpi/hardware/hwacpi.c
--- linux-2.4.24-pre1/drivers/acpi/hardware/hwacpi.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/hardware/hwacpi.c	2003-12-22 11:34:34.000000000 -0800
@@ -119,7 +119,7 @@
 	 * system does not support mode transition.
 	 */
 	if (!acpi_gbl_FADT->smi_cmd) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No SMI_CMD in FADT, mode transition failed.\n"));
+		ACPI_REPORT_ERROR (("No SMI_CMD in FADT, mode transition failed.\n"));
 		return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
 	}
 
@@ -131,7 +131,7 @@
 	 * transitions are not supported.
 	 */
 	if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "No mode transition supported in this system.\n"));
+		ACPI_REPORT_ERROR (("No ACPI mode transition supported in this system (enable/disable both zero)\n"));
 		return_ACPI_STATUS (AE_OK);
 	}
 
@@ -162,6 +162,7 @@
 	}
 
 	if (ACPI_FAILURE (status)) {
+		ACPI_REPORT_ERROR (("Could not write mode change, %s\n", acpi_format_exception (status)));
 		return_ACPI_STATUS (status);
 	}
 
@@ -171,18 +172,16 @@
 	 */
 	retry = 3000;
 	while (retry) {
-		status = AE_NO_HARDWARE_RESPONSE;
-
 		if (acpi_hw_get_mode() == mode) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode));
-			status = AE_OK;
-			break;
+			return_ACPI_STATUS (AE_OK);
 		}
 		acpi_os_stall(1000);
 		retry--;
 	}
 
-	return_ACPI_STATUS (status);
+	ACPI_REPORT_ERROR (("Hardware never changed modes\n"));
+	return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
 }
 
 
diff -urN linux-2.4.24-pre1/drivers/acpi/hardware/hwregs.c linux-2.4.24-pre2/drivers/acpi/hardware/hwregs.c
--- linux-2.4.24-pre1/drivers/acpi/hardware/hwregs.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/hardware/hwregs.c	2003-12-22 11:34:34.000000000 -0800
@@ -418,16 +418,14 @@
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n",
 			register_value,
-			ACPI_HIDWORD (acpi_gbl_FADT->xpm2_cnt_blk.address),
-			ACPI_LODWORD (acpi_gbl_FADT->xpm2_cnt_blk.address)));
+			ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address)));
 
 		ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position,
 				bit_reg_info->access_bit_mask, value);
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n",
 			register_value,
-			ACPI_HIDWORD (acpi_gbl_FADT->xpm2_cnt_blk.address),
-			ACPI_LODWORD (acpi_gbl_FADT->xpm2_cnt_blk.address)));
+			ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address)));
 
 		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
 				   ACPI_REGISTER_PM2_CONTROL, (u8) (register_value));
@@ -763,8 +761,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
 			*value, width,
-			ACPI_HIDWORD (reg->address),
-			ACPI_LODWORD (reg->address),
+			ACPI_FORMAT_UINT64 (reg->address),
 			acpi_ut_get_region_name (reg->address_space_id)));
 
 	return (status);
@@ -850,8 +847,7 @@
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
 			value, width,
-			ACPI_HIDWORD (reg->address),
-			ACPI_LODWORD (reg->address),
+			ACPI_FORMAT_UINT64 (reg->address),
 			acpi_ut_get_region_name (reg->address_space_id)));
 
 	return (status);
diff -urN linux-2.4.24-pre1/drivers/acpi/hardware/hwsleep.c linux-2.4.24-pre2/drivers/acpi/hardware/hwsleep.c
--- linux-2.4.24-pre1/drivers/acpi/hardware/hwsleep.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/hardware/hwsleep.c	2003-12-22 11:34:34.000000000 -0800
@@ -181,6 +181,13 @@
 		return_ACPI_STATUS (status);
 	}
 
+	/* Set the system indicators to show the desired sleep state. */
+
+	status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL);
+	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+		 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+	}
+
 	return_ACPI_STATUS (AE_OK);
 }
 
@@ -220,27 +227,28 @@
 		return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
 	}
 
-
 	sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
 	sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
 
-	/* Clear wake status */
+	if (sleep_state != ACPI_STATE_S5) {
+		/* Clear wake status */
 
-	status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
+		status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
 
-	status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
+		status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
 
-	/* Disable BM arbitration */
+		/* Disable BM arbitration */
 
-	status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
+		status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
 	}
 
 	status = acpi_hw_disable_non_wakeup_gpes();
@@ -297,11 +305,13 @@
 		return_ACPI_STATUS (status);
 	}
 
-	/*
-	 * Wait a second, then try again. This is to get S4/5 to work on all machines.
-	 */
 	if (sleep_state > ACPI_STATE_S3) {
 		/*
+		 * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that
+		 * we are still executing!)
+		 *
+		 * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines.
+		 *
 		 * We wait so long to allow chipsets that poll this reg very slowly to
 		 * still read the right value. Ideally, this entire block would go
 		 * away entirely.
@@ -354,6 +364,7 @@
 
 	ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios");
 
+
 	acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
 	acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK);
 
@@ -389,15 +400,38 @@
 
 acpi_status
 acpi_leave_sleep_state (
-	u8                          sleep_state)
+	u8                              sleep_state)
 {
-	struct acpi_object_list     arg_list;
-	union acpi_object           arg;
-	acpi_status                 status;
+	struct acpi_object_list         arg_list;
+	union acpi_object               arg;
+	acpi_status                     status;
+	struct acpi_bit_register_info   *sleep_type_reg_info;
+	struct acpi_bit_register_info   *sleep_enable_reg_info;
+	u32                             pm1x_control;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state");
 
+	/* Some machines require SLP_TYPE and SLP_EN to be cleared */
+
+	sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
+	sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
+
+	/* Get current value of PM1A control */
+
+	status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
+			 ACPI_REGISTER_PM1_CONTROL, &pm1x_control);
+	if (ACPI_SUCCESS (status)) {
+		/* Clear SLP_TYP and SLP_EN */
+
+		pm1x_control &= ~(sleep_type_reg_info->access_bit_mask |
+				   sleep_enable_reg_info->access_bit_mask);
+
+		acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+				ACPI_REGISTER_PM1A_CONTROL, pm1x_control);
+		acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+				ACPI_REGISTER_PM1B_CONTROL, pm1x_control);
+	}
 
 	/* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
 
@@ -407,12 +441,17 @@
 
 	arg_list.count = 1;
 	arg_list.pointer = &arg;
-
 	arg.type = ACPI_TYPE_INTEGER;
-	arg.integer.value = sleep_state;
 
 	/* Ignore any errors from these methods */
 
+	arg.integer.value = 0;
+	status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL);
+	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
+		ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+	}
+
+	arg.integer.value = sleep_state;
 	status = acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL);
 	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
 		ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status)));
@@ -430,8 +469,8 @@
 		return_ACPI_STATUS (status);
 	}
 
-	/* Disable BM arbitration */
-	status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK);
+	/* Enable BM arbitration */
 
+	status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK);
 	return_ACPI_STATUS (status);
 }
diff -urN linux-2.4.24-pre1/drivers/acpi/namespace/nsaccess.c linux-2.4.24-pre2/drivers/acpi/namespace/nsaccess.c
--- linux-2.4.24-pre1/drivers/acpi/namespace/nsaccess.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/namespace/nsaccess.c	2003-12-22 11:34:34.000000000 -0800
@@ -314,8 +314,8 @@
 	else {
 		prefix_node = scope_info->scope.node;
 		if (ACPI_GET_DESCRIPTOR_TYPE (prefix_node) != ACPI_DESC_TYPE_NAMED) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "[%p] Not a namespace node\n",
-				prefix_node));
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p Not a namespace node [%s]\n",
+					prefix_node, acpi_ut_get_descriptor_name (prefix_node)));
 			return_ACPI_STATUS (AE_AML_INTERNAL);
 		}
 
@@ -379,7 +379,7 @@
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 				"Searching relative to prefix scope [%4.4s] (%p)\n",
-				prefix_node->name.ascii, prefix_node));
+				acpi_ut_get_node_name (prefix_node), prefix_node));
 
 			/*
 			 * Handle multiple Parent Prefixes (carat) by just getting
@@ -413,7 +413,7 @@
 			if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 					"Search scope is [%4.4s], path has %d carat(s)\n",
-					this_node->name.ascii, num_carats));
+					acpi_ut_get_node_name (this_node), num_carats));
 			}
 		}
 
diff -urN linux-2.4.24-pre1/drivers/acpi/namespace/nsalloc.c linux-2.4.24-pre2/drivers/acpi/namespace/nsalloc.c
--- linux-2.4.24-pre1/drivers/acpi/namespace/nsalloc.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/namespace/nsalloc.c	2003-12-22 11:34:34.000000000 -0800
@@ -271,7 +271,7 @@
 		 * alphabetic placement.
 		 */
 		previous_child_node = NULL;
-		while (acpi_ns_compare_names (child_node->name.ascii, node->name.ascii) < 0) {
+		while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node), acpi_ut_get_node_name (node)) < 0) {
 			if (child_node->flags & ANOBJ_END_OF_PEER_LIST) {
 				/* Last peer;  Clear end-of-list flag */
 
@@ -335,8 +335,9 @@
 	node->type = (u8) type;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n",
-		node->name.ascii, acpi_ut_get_type_name (node->type),
-		parent_node->name.ascii, acpi_ut_get_type_name (parent_node->type), parent_node, node));
+		acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type),
+		acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type),
+		parent_node, node));
 
 	/*
 	 * Increment the reference count(s) of all parents up to
diff -urN linux-2.4.24-pre1/drivers/acpi/namespace/nsdump.c linux-2.4.24-pre2/drivers/acpi/namespace/nsdump.c
--- linux-2.4.24-pre1/drivers/acpi/namespace/nsdump.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/namespace/nsdump.c	2003-12-22 11:34:34.000000000 -0800
@@ -50,8 +50,8 @@
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsdump")
 
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 
 /*******************************************************************************
  *
@@ -76,7 +76,7 @@
 		return;
 	}
 
-		/* Print the entire name */
+	/* Print the entire name */
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "["));
 
@@ -205,7 +205,7 @@
 	 * Now we can print out the pertinent information
 	 */
 	acpi_os_printf ("%4.4s %-12s %p ",
-			this_node->name.ascii, acpi_ut_get_type_name (type), this_node);
+			acpi_ut_get_node_name (this_node), acpi_ut_get_type_name (type), this_node);
 
 	dbg_level = acpi_dbg_level;
 	acpi_dbg_level = 0;
@@ -250,8 +250,7 @@
 		case ACPI_TYPE_INTEGER:
 
 			acpi_os_printf ("= %8.8X%8.8X\n",
-					 ACPI_HIDWORD (obj_desc->integer.value),
-					 ACPI_LODWORD (obj_desc->integer.value));
+					 ACPI_FORMAT_UINT64 (obj_desc->integer.value));
 			break;
 
 
@@ -302,8 +301,7 @@
 			acpi_os_printf ("[%s]", acpi_ut_get_region_name (obj_desc->region.space_id));
 			if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
 				acpi_os_printf (" Addr %8.8X%8.8X Len %.4X\n",
-						 ACPI_HIDWORD (obj_desc->region.address),
-						 ACPI_LODWORD (obj_desc->region.address),
+						 ACPI_FORMAT_UINT64 (obj_desc->region.address),
 						 obj_desc->region.length);
 			}
 			else {
@@ -324,7 +322,7 @@
 			if (obj_desc->buffer_field.buffer_obj &&
 				obj_desc->buffer_field.buffer_obj->buffer.node) {
 				acpi_os_printf ("Buf [%4.4s]",
-						obj_desc->buffer_field.buffer_obj->buffer.node->name.ascii);
+						acpi_ut_get_node_name (obj_desc->buffer_field.buffer_obj->buffer.node));
 			}
 			break;
 
@@ -332,29 +330,29 @@
 		case ACPI_TYPE_LOCAL_REGION_FIELD:
 
 			acpi_os_printf ("Rgn [%4.4s]",
-					obj_desc->common_field.region_obj->region.node->name.ascii);
+					acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node));
 			break;
 
 
 		case ACPI_TYPE_LOCAL_BANK_FIELD:
 
 			acpi_os_printf ("Rgn [%4.4s] Bnk [%4.4s]",
-					obj_desc->common_field.region_obj->region.node->name.ascii,
-					obj_desc->bank_field.bank_obj->common_field.node->name.ascii);
+					acpi_ut_get_node_name (obj_desc->common_field.region_obj->region.node),
+					acpi_ut_get_node_name (obj_desc->bank_field.bank_obj->common_field.node));
 			break;
 
 
 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
 
 			acpi_os_printf ("Idx [%4.4s] Dat [%4.4s]",
-					obj_desc->index_field.index_obj->common_field.node->name.ascii,
-					obj_desc->index_field.data_obj->common_field.node->name.ascii);
+					acpi_ut_get_node_name (obj_desc->index_field.index_obj->common_field.node),
+					acpi_ut_get_node_name (obj_desc->index_field.data_obj->common_field.node));
 			break;
 
 
 		case ACPI_TYPE_LOCAL_ALIAS:
 
-			acpi_os_printf ("Target %4.4s (%p)\n", ((struct acpi_namespace_node *) obj_desc)->name.ascii, obj_desc);
+			acpi_os_printf ("Target %4.4s (%p)\n", acpi_ut_get_node_name (obj_desc), obj_desc);
 			break;
 
 		default:
@@ -371,7 +369,7 @@
 		case ACPI_TYPE_LOCAL_BANK_FIELD:
 		case ACPI_TYPE_LOCAL_INDEX_FIELD:
 
-			acpi_os_printf ("Off %.2X Len %.2X Acc %.2hd\n",
+			acpi_os_printf (" Off %.3X Len %.2X Acc %.2hd\n",
 					(obj_desc->common_field.base_byte_offset * 8)
 						+ obj_desc->common_field.start_field_bit_offset,
 					obj_desc->common_field.bit_length,
@@ -408,8 +406,8 @@
 
 		case ACPI_TYPE_INTEGER:
 
-			acpi_os_printf (" N:%X%X\n", ACPI_HIDWORD(obj_desc->integer.value),
-					 ACPI_LODWORD(obj_desc->integer.value));
+			acpi_os_printf (" I:%8.8X8.8%X\n",
+					ACPI_FORMAT_UINT64 (obj_desc->integer.value));
 			break;
 
 		case ACPI_TYPE_STRING:
@@ -485,7 +483,8 @@
 
 		default:
 
-			acpi_os_printf ("(String or Buffer ptr - not an object descriptor)\n");
+			acpi_os_printf ("(String or Buffer ptr - not an object descriptor) [%s]\n",
+					acpi_ut_get_descriptor_name (obj_desc));
 			bytes_to_dump = 16;
 			break;
 		}
@@ -581,7 +580,6 @@
 	info.owner_id = owner_id;
 	info.display_type = display_type;
 
-
 	(void) acpi_ns_walk_namespace (type, start_handle, max_depth,
 			 ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object,
 			 (void *) &info, NULL);
@@ -628,7 +626,6 @@
 		ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n"));
 	}
 
-
 	acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth,
 			ACPI_UINT32_MAX, search_handle);
 	return_VOID;
diff -urN linux-2.4.24-pre1/drivers/acpi/namespace/nsdumpdv.c linux-2.4.24-pre2/drivers/acpi/namespace/nsdumpdv.c
--- linux-2.4.24-pre1/drivers/acpi/namespace/nsdumpdv.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/namespace/nsdumpdv.c	2003-12-22 11:34:34.000000000 -0800
@@ -93,7 +93,7 @@
 
 		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "    HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
 				  info->hardware_id.value,
-				  ACPI_HIDWORD (info->address), ACPI_LODWORD (info->address),
+				  ACPI_FORMAT_UINT64 (info->address),
 				  info->current_status));
 		ACPI_MEM_FREE (info);
 	}
diff -urN linux-2.4.24-pre1/drivers/acpi/namespace/nsinit.c linux-2.4.24-pre2/drivers/acpi/namespace/nsinit.c
--- linux-2.4.24-pre1/drivers/acpi/namespace/nsinit.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/namespace/nsinit.c	2003-12-22 11:34:34.000000000 -0800
@@ -144,10 +144,17 @@
 
 	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Executing all Device _STA and_INI methods:"));
 
-	/* Walk namespace for all objects of type Device */
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Walk namespace for all objects of type Device or Processor */
 
-	status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-			  ACPI_UINT32_MAX, FALSE, acpi_ns_init_one_device, &info, NULL);
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
+			  ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL);
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 	if (ACPI_FAILURE (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed! %s\n",
@@ -290,7 +297,8 @@
 		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n"));
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Could not execute arguments for [%4.4s] (%s), %s\n",
-				node->name.ascii, acpi_ut_get_type_name (type), acpi_format_exception (status)));
+				acpi_ut_get_node_name (node), acpi_ut_get_type_name (type),
+				acpi_format_exception (status)));
 	}
 
 	/* Print a dot for each object unless we are going to print the entire pathname */
@@ -338,45 +346,48 @@
 	ACPI_FUNCTION_TRACE ("ns_init_one_device");
 
 
-	if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) {
-		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
-	}
-
-	info->device_count++;
-
-	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
-
 	node = acpi_ns_map_handle_to_node (obj_handle);
 	if (!node) {
-		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
+	/*
+	 * We will run _STA/_INI on Devices and Processors only
+	 */
+	if ((node->type != ACPI_TYPE_DEVICE) &&
+		(node->type != ACPI_TYPE_PROCESSOR)) {
+		return_ACPI_STATUS (AE_OK);
 	}
 
+	if ((acpi_dbg_level <= ACPI_LV_ALL_EXCEPTIONS) && (!(acpi_dbg_level & ACPI_LV_INFO))) {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
+	}
+
+	info->device_count++;
+
 	/*
 	 * Run _STA to determine if we can run _INI on the device.
 	 */
 	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, node, "_STA"));
 	status = acpi_ut_execute_STA (node, &flags);
+
 	if (ACPI_FAILURE (status)) {
-		/* Ignore error and move on to next device */
+		if (node->type == ACPI_TYPE_DEVICE) {
+			/* Ignore error and move on to next device */
 
-		return_ACPI_STATUS (AE_OK);
-	}
+			return_ACPI_STATUS (AE_OK);
+		}
 
-	info->num_STA++;
+		/* _STA is not required for Processor objects */
+	}
+	else {
+		info->num_STA++;
 
-	if (!(flags & 0x01)) {
-		/* don't look at children of a not present device */
+		if (!(flags & 0x01)) {
+			/* Don't look at children of a not present device */
 
-		return_ACPI_STATUS(AE_CTRL_DEPTH);
+			return_ACPI_STATUS(AE_CTRL_DEPTH);
+		}
 	}
 
 	/*
diff -urN linux-2.4.24-pre1/drivers/acpi/namespace/nsobject.c linux-2.4.24-pre2/drivers/acpi/namespace/nsobject.c
--- linux-2.4.24-pre1/drivers/acpi/namespace/nsobject.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/namespace/nsobject.c	2003-12-22 11:34:34.000000000 -0800
@@ -104,7 +104,8 @@
 	if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
 		/* Not a name handle */
 
-		ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle\n"));
+		ACPI_REPORT_ERROR (("ns_attach_object: Invalid handle %p [%s]\n",
+				node, acpi_ut_get_descriptor_name (node)));
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
@@ -151,7 +152,7 @@
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Installing %p into Node %p [%4.4s]\n",
-		obj_desc, node, node->name.ascii));
+		obj_desc, node, acpi_ut_get_node_name (node)));
 
 	/* Detach an existing attached object if present */
 
@@ -234,7 +235,7 @@
 	node->type = ACPI_TYPE_ANY;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Node %p [%4.4s] Object %p\n",
-		node, node->name.ascii, obj_desc));
+		node, acpi_ut_get_node_name (node), obj_desc));
 
 	/* Remove one reference on the object (and all subobjects) */
 
diff -urN linux-2.4.24-pre1/drivers/acpi/namespace/nssearch.c linux-2.4.24-pre2/drivers/acpi/namespace/nssearch.c
--- linux-2.4.24-pre1/drivers/acpi/namespace/nssearch.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/namespace/nssearch.c	2003-12-22 11:34:34.000000000 -0800
@@ -119,7 +119,7 @@
 			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 				"Name [%4.4s] (%s) %p found in scope [%4.4s] %p\n",
 				(char *) &target_name, acpi_ut_get_type_name (next_node->type),
-				next_node, node->name.ascii, node));
+				next_node, acpi_ut_get_node_name (node), node));
 
 			*return_node = next_node;
 			return_ACPI_STATUS (AE_OK);
@@ -145,7 +145,7 @@
 	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
 		"Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
 		(char *) &target_name, acpi_ut_get_type_name (type),
-		node->name.ascii, node, node->child));
+		acpi_ut_get_node_name (node), node, node->child));
 
 	return_ACPI_STATUS (AE_NOT_FOUND);
 }
diff -urN linux-2.4.24-pre1/drivers/acpi/namespace/nsutils.c linux-2.4.24-pre2/drivers/acpi/namespace/nsutils.c
--- linux-2.4.24-pre1/drivers/acpi/namespace/nsutils.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/namespace/nsutils.c	2003-12-22 11:34:34.000000000 -0800
@@ -977,8 +977,8 @@
 		parent_node = acpi_ns_get_parent_node (child_node);
 		if (parent_node) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Parent of %p [%4.4s] is %p [%4.4s]\n",
-				child_node, child_node->name.ascii,
-				parent_node, parent_node->name.ascii));
+				child_node, acpi_ut_get_node_name (child_node),
+				parent_node, acpi_ut_get_node_name (parent_node)));
 
 			if (parent_node->name.integer) {
 				return_VALUE ((acpi_name) parent_node->name.integer);
@@ -986,7 +986,7 @@
 		}
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "unable to find parent of %p (%4.4s)\n",
-			child_node, child_node->name.ascii));
+			child_node, acpi_ut_get_node_name (child_node)));
 	}
 
 	return_VALUE (ACPI_UNKNOWN_NAME);
diff -urN linux-2.4.24-pre1/drivers/acpi/namespace/nsxfname.c linux-2.4.24-pre2/drivers/acpi/namespace/nsxfname.c
--- linux-2.4.24-pre1/drivers/acpi/namespace/nsxfname.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/namespace/nsxfname.c	2003-12-22 11:34:34.000000000 -0800
@@ -199,7 +199,7 @@
 
 	/* Just copy the ACPI name from the Node and zero terminate it */
 
-	ACPI_STRNCPY (buffer->pointer, node->name.ascii,
+	ACPI_STRNCPY (buffer->pointer, acpi_ut_get_node_name (node),
 			 ACPI_NAME_SIZE);
 	((char *) buffer->pointer) [ACPI_NAME_SIZE] = 0;
 	status = AE_OK;
diff -urN linux-2.4.24-pre1/drivers/acpi/parser/psargs.c linux-2.4.24-pre2/drivers/acpi/parser/psargs.c
--- linux-2.4.24-pre1/drivers/acpi/parser/psargs.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/parser/psargs.c	2003-12-22 11:34:34.000000000 -0800
@@ -490,7 +490,7 @@
 acpi_ps_get_next_field (
 	struct acpi_parse_state         *parser_state)
 {
-	u32                             aml_offset = ACPI_PTR_DIFF (parser_state->aml,
+	u32                             aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
 			 parser_state->aml_start);
 	union acpi_parse_object         *field;
 	u16                             opcode;
@@ -677,7 +677,7 @@
 
 			/* Fill in bytelist data */
 
-			arg->common.value.size = ACPI_PTR_DIFF (parser_state->pkg_end,
+			arg->common.value.size = (u32) ACPI_PTR_DIFF (parser_state->pkg_end,
 					  parser_state->aml);
 			arg->named.data = parser_state->aml;
 
diff -urN linux-2.4.24-pre1/drivers/acpi/parser/psparse.c linux-2.4.24-pre2/drivers/acpi/parser/psparse.c
--- linux-2.4.24-pre1/drivers/acpi/parser/psparse.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/parser/psparse.c	2003-12-22 11:34:34.000000000 -0800
@@ -498,7 +498,7 @@
 		if (!op) {
 			/* Get the next opcode from the AML stream */
 
-			walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml,
+			walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
 					   parser_state->aml_start);
 			walk_state->opcode   = acpi_ps_peek_opcode (parser_state);
 
@@ -710,7 +710,7 @@
 
 				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
 						!walk_state->arg_count) {
-					walk_state->aml_offset = ACPI_PTR_DIFF (parser_state->aml,
+					walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
 							   parser_state->aml_start);
 					status = acpi_ps_get_next_arg (walk_state, parser_state,
 							 GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
diff -urN linux-2.4.24-pre1/drivers/acpi/parser/psxface.c linux-2.4.24-pre2/drivers/acpi/parser/psxface.c
--- linux-2.4.24-pre1/drivers/acpi/parser/psxface.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/parser/psxface.c	2003-12-22 11:34:34.000000000 -0800
@@ -127,7 +127,8 @@
 
 	op = acpi_ps_create_scope_op ();
 	if (!op) {
-		return_ACPI_STATUS (AE_NO_MEMORY);
+		status = AE_NO_MEMORY;
+		goto cleanup1;
 	}
 
 	/*
@@ -142,20 +143,24 @@
 	walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
 			   NULL, NULL, NULL);
 	if (!walk_state) {
-		return_ACPI_STATUS (AE_NO_MEMORY);
+		status = AE_NO_MEMORY;
+		goto cleanup2;
 	}
 
 	status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
 			  obj_desc->method.aml_length, NULL, NULL, 1);
 	if (ACPI_FAILURE (status)) {
-		acpi_ds_delete_walk_state (walk_state);
-		return_ACPI_STATUS (status);
+		goto cleanup3;
 	}
 
 	/* Parse the AML */
 
 	status = acpi_ps_parse_aml (walk_state);
 	acpi_ps_delete_parse_tree (op);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup1; /* Walk state is already deleted */
+
+	}
 
 	/*
 	 * 2) Execute the method.  Performs second pass parse simultaneously
@@ -168,7 +173,8 @@
 
 	op = acpi_ps_create_scope_op ();
 	if (!op) {
-		return_ACPI_STATUS (AE_NO_MEMORY);
+		status = AE_NO_MEMORY;
+		goto cleanup1;
 	}
 
 	/* Init new op with the method name and pointer back to the NS node */
@@ -180,22 +186,30 @@
 
 	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
 	if (!walk_state) {
-		return_ACPI_STATUS (AE_NO_MEMORY);
+		status = AE_NO_MEMORY;
+		goto cleanup2;
 	}
 
 	status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
 			  obj_desc->method.aml_length, params, return_obj_desc, 3);
 	if (ACPI_FAILURE (status)) {
-		acpi_ds_delete_walk_state (walk_state);
-		return_ACPI_STATUS (status);
+		goto cleanup3;
 	}
 
 	/*
 	 * The walk of the parse tree is where we actually execute the method
 	 */
 	status = acpi_ps_parse_aml (walk_state);
+	goto cleanup2; /* Walk state already deleted */
+
+
+cleanup3:
+	acpi_ds_delete_walk_state (walk_state);
+
+cleanup2:
 	acpi_ps_delete_parse_tree (op);
 
+cleanup1:
 	if (params) {
 		/* Take away the extra reference that we gave the parameters above */
 
@@ -206,6 +220,10 @@
 		}
 	}
 
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
 	/*
 	 * If the method has returned an object, signal this to the caller with
 	 * a control exception code
diff -urN linux-2.4.24-pre1/drivers/acpi/pci_root.c linux-2.4.24-pre2/drivers/acpi/pci_root.c
--- linux-2.4.24-pre1/drivers/acpi/pci_root.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/pci_root.c	2003-12-22 11:34:34.000000000 -0800
@@ -61,8 +61,6 @@
 	acpi_handle		handle;
 	struct acpi_pci_id	id;
 	struct pci_bus		*bus;
-	u64			mem_tra;
-	u64			io_tra;
 };
 
 static LIST_HEAD(acpi_pci_roots);
@@ -114,97 +112,6 @@
 	}
 }
 
-void
-acpi_pci_get_translations (
-	struct acpi_pci_id	*id,
-	u64			*mem_tra,
-	u64			*io_tra)
-{
-	struct list_head	*node = NULL;
-	struct acpi_pci_root	*entry;
-
-	/* TBD: Locking */
-	list_for_each(node, &acpi_pci_roots) {
-		entry = list_entry(node, struct acpi_pci_root, node);
-		if ((id->segment == entry->id.segment)
-			&& (id->bus == entry->id.bus)) {
-			*mem_tra = entry->mem_tra;
-			*io_tra = entry->io_tra;
-			return;
-		}
-	}
-
-	*mem_tra = 0;
-	*io_tra = 0;
-}
-
-
-static u64
-acpi_pci_root_bus_tra (
-       struct acpi_resource	*resource,
-       int			type)
-{
-	struct acpi_resource_address16 *address16;
-	struct acpi_resource_address32 *address32;
-	struct acpi_resource_address64 *address64;
-
-	while (1) {
-		switch (resource->id) {
-		case ACPI_RSTYPE_END_TAG:
-			return 0;
-
-		case ACPI_RSTYPE_ADDRESS16:
-			address16 = (struct acpi_resource_address16 *) &resource->data;
-			if (type == address16->resource_type) {
-				return address16->address_translation_offset;
-			}
-			break;
-
-		case ACPI_RSTYPE_ADDRESS32:
-			address32 = (struct acpi_resource_address32 *) &resource->data;
-			if (type == address32->resource_type) {
-				return address32->address_translation_offset;
-			}
-			break;
-
-		case ACPI_RSTYPE_ADDRESS64:
-			address64 = (struct acpi_resource_address64 *) &resource->data;
-			if (type == address64->resource_type) {
-				return address64->address_translation_offset;
-			}
-			break;
-		}
-		resource = ACPI_PTR_ADD (struct acpi_resource,
-				resource, resource->length);
-	}
-
-	return 0;
-}
-
-
-static int
-acpi_pci_evaluate_crs (
-	struct acpi_pci_root	*root)
-{
-	acpi_status		status;
-	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-
-	ACPI_FUNCTION_TRACE("acpi_pci_evaluate_crs");
-
-	status = acpi_get_current_resources (root->handle, &buffer);
-	if (ACPI_FAILURE(status))
-		return_VALUE(-ENODEV);
-
-	root->io_tra = acpi_pci_root_bus_tra ((struct acpi_resource *)
-			buffer.pointer, ACPI_IO_RANGE);
-	root->mem_tra = acpi_pci_root_bus_tra ((struct acpi_resource *)
-			buffer.pointer, ACPI_MEMORY_RANGE);
-
-	acpi_os_free(buffer.pointer);
-	return_VALUE(0);
-}
-
-
 static int
 acpi_pci_root_add (
 	struct acpi_device	*device)
@@ -289,10 +196,8 @@
 	root->id.function = device->pnp.bus_address & 0xFFFF;
 
 	/*
-	 * Evaluate _CRS to get root bridge resources
 	 * TBD: Need PCI interface for enumeration/configuration of roots.
 	 */
- 	acpi_pci_evaluate_crs(root);
 
  	/* TBD: Locking */
  	list_add_tail(&root->node, &acpi_pci_roots);
diff -urN linux-2.4.24-pre1/drivers/acpi/processor.c linux-2.4.24-pre2/drivers/acpi/processor.c
--- linux-2.4.24-pre1/drivers/acpi/processor.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/processor.c	2003-12-22 11:34:34.000000000 -0800
@@ -144,6 +144,8 @@
 	int			platform_limit;
 	u16			control_register;
 	u16			status_register;
+	u8			control_register_bit_width;
+	u8			status_register_bit_width;
 	int			state_count;
 	struct acpi_processor_px states[ACPI_PROCESSOR_MAX_PERFORMANCE];
 };
@@ -902,7 +904,7 @@
 	}
 
 	pr->performance.control_register = (u16) reg->address;
-
+	pr->performance.control_register_bit_width = reg->bit_width;
 	/*
 	 * status_register
 	 */
@@ -929,6 +931,7 @@
 	}
 
 	pr->performance.status_register = (u16) reg->address;
+	pr->performance.status_register_bit_width = reg->bit_width;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"control_register[0x%04x] status_register[0x%04x]\n",
@@ -1018,6 +1021,42 @@
 	return_VALUE(result);
 }
 
+static int
+acpi_processor_write_port(
+	u16	port,
+	u8	bit_width,
+	u32	value)
+{
+	if (bit_width <= 8) {
+		outb(value, port);
+	} else if (bit_width <= 16) {
+		outw(value, port);
+	} else if (bit_width <= 32) {
+		outl(value, port);
+	} else {
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int
+acpi_processor_read_port(
+	u16	port,
+	u8	bit_width,
+	u32	*ret)
+{
+	*ret = 0;
+	if (bit_width <= 8) {
+		*ret = inb(port);
+	} else if (bit_width <= 16) {
+		*ret = inw(port);
+	} else if (bit_width <= 32) {
+		*ret = inl(port);
+	} else {
+		return -ENODEV;
+	}
+	return 0;
+}
 
 static int
 acpi_processor_set_performance (
@@ -1025,7 +1064,9 @@
 	int			state)
 {
 	u16			port = 0;
-	u8			value = 0;
+	u8			bit_width = 0;
+	int			ret = 0;
+	u32			value = 0;
 	int			i = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_processor_set_performance");
@@ -1064,12 +1105,18 @@
 	 */
 
 	port = pr->performance.control_register;
-	value = (u16) pr->performance.states[state].control;
+	value = (u32) pr->performance.states[state].control;
+	bit_width = pr->performance.control_register_bit_width;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-		"Writing 0x%02x to port 0x%04x\n", value, port));
+		"Writing 0x%08x to port 0x%04x\n", value, port));
 
-	outb(value, port); 
+	ret = acpi_processor_write_port(port, bit_width, value);
+	if (ret) {
+		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+			"Invalid port width 0x%04x\n", bit_width));
+		return_VALUE(ret);
+	}
 
 	/*
 	 * Then we read the 'status_register' and compare the value with the
@@ -1079,19 +1126,25 @@
 	 */
 
 	port = pr->performance.status_register;
+	bit_width = pr->performance.status_register_bit_width;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
-		"Looking for 0x%02x from port 0x%04x\n",
-		(u8) pr->performance.states[state].status, port));
+		"Looking for 0x%08x from port 0x%04x\n",
+		(u32) pr->performance.states[state].status, port));
 
 	for (i=0; i<100; i++) {
-		value = inb(port);
-		if (value == (u8) pr->performance.states[state].status)
+		ret = acpi_processor_read_port(port, bit_width, &value);
+		if (ret) {	
+			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+				"Invalid port width 0x%04x\n", bit_width));
+			return_VALUE(ret);
+		}
+		if (value == (u32) pr->performance.states[state].status)
 			break;
 		udelay(10);
 	}
 
-	if (value != pr->performance.states[state].status) {
+	if (value != (u32) pr->performance.states[state].status) {
 		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n"));
 		return_VALUE(-ENODEV);
 	}
diff -urN linux-2.4.24-pre1/drivers/acpi/resources/rscalc.c linux-2.4.24-pre2/drivers/acpi/resources/rscalc.c
--- linux-2.4.24-pre1/drivers/acpi/resources/rscalc.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/resources/rscalc.c	2003-12-22 11:34:34.000000000 -0800
@@ -696,7 +696,7 @@
 		default:
 			/*
 			 * If we get here, everything is out of sync,
-			 *  so exit with an error
+			 * exit with an error
 			 */
 			return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
 		}
@@ -704,7 +704,7 @@
 		/*
 		 * Update the return value and counter
 		 */
-		buffer_size += ACPI_ALIGN_RESOURCE_SIZE(structure_size);
+		buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE (structure_size);
 		bytes_parsed += bytes_consumed;
 
 		/*
diff -urN linux-2.4.24-pre1/drivers/acpi/resources/rscreate.c linux-2.4.24-pre2/drivers/acpi/resources/rscreate.c
--- linux-2.4.24-pre1/drivers/acpi/resources/rscreate.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/resources/rscreate.c	2003-12-22 11:34:34.000000000 -0800
@@ -331,7 +331,7 @@
 
 		/* Now align the current length */
 
-		user_prt->length = ACPI_ROUND_UP_to_64_bITS (user_prt->length);
+		user_prt->length = (u32) ACPI_ROUND_UP_to_64_bITS (user_prt->length);
 
 		/*
 		 * 4) Fourth subobject: Dereference the PRT.source_index
diff -urN linux-2.4.24-pre1/drivers/acpi/resources/rsdump.c linux-2.4.24-pre2/drivers/acpi/resources/rsdump.c
--- linux-2.4.24-pre1/drivers/acpi/resources/rsdump.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/resources/rsdump.c	2003-12-22 11:34:34.000000000 -0800
@@ -899,24 +899,19 @@
 			 "" : "not ");
 
 	acpi_os_printf ("  Granularity: %8.8X%8.8X\n",
-			 ACPI_HIDWORD (address64_data->granularity),
-			 ACPI_LODWORD (address64_data->granularity));
+			 ACPI_FORMAT_UINT64 (address64_data->granularity));
 
 	acpi_os_printf ("  Address range min: %8.8X%8.8X\n",
-			 ACPI_HIDWORD (address64_data->min_address_range),
-			 ACPI_HIDWORD (address64_data->min_address_range));
+			 ACPI_FORMAT_UINT64 (address64_data->min_address_range));
 
 	acpi_os_printf ("  Address range max: %8.8X%8.8X\n",
-			 ACPI_HIDWORD (address64_data->max_address_range),
-			 ACPI_HIDWORD (address64_data->max_address_range));
+			 ACPI_FORMAT_UINT64 (address64_data->max_address_range));
 
 	acpi_os_printf ("  Address translation offset: %8.8X%8.8X\n",
-			 ACPI_HIDWORD (address64_data->address_translation_offset),
-			 ACPI_HIDWORD (address64_data->address_translation_offset));
+			 ACPI_FORMAT_UINT64 (address64_data->address_translation_offset));
 
 	acpi_os_printf ("  Address Length: %8.8X%8.8X\n",
-			 ACPI_HIDWORD (address64_data->address_length),
-			 ACPI_HIDWORD (address64_data->address_length));
+			 ACPI_FORMAT_UINT64 (address64_data->address_length));
 
 	if(0xFF != address64_data->resource_source.index) {
 		acpi_os_printf ("  Resource Source Index: %X\n",
@@ -1126,8 +1121,7 @@
 			acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++);
 
 			acpi_os_printf ("  Address: %8.8X%8.8X\n",
-					 ACPI_HIDWORD (prt_element->address),
-					 ACPI_LODWORD (prt_element->address));
+					 ACPI_FORMAT_UINT64 (prt_element->address));
 
 			acpi_os_printf ("  Pin: %X\n", prt_element->pin);
 
diff -urN linux-2.4.24-pre1/drivers/acpi/resources/rsirq.c linux-2.4.24-pre2/drivers/acpi/resources/rsirq.c
--- linux-2.4.24-pre1/drivers/acpi/resources/rsirq.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/resources/rsirq.c	2003-12-22 11:34:34.000000000 -0800
@@ -132,26 +132,28 @@
 		temp8 = *buffer;
 
 		/*
-		 * Check for HE, LL or HL
+		 * Check for HE, LL interrupts
 		 */
-		if (temp8 & 0x01) {
+		switch (temp8 & 0x09) {
+		case 0x01: /* HE */
 			output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
 			output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH;
-		}
-		else {
-			if (temp8 & 0x8) {
-				output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE;
-				output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW;
-			}
-			else {
-				/*
-				 * Only _LL and _HE polarity/trigger interrupts
-				 * are allowed (ACPI spec v1.0b ection 6.4.2.1),
-				 * so an error will occur if we reach this point
-				 */
-				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid interrupt polarity/trigger in resource list\n"));
-				return_ACPI_STATUS (AE_BAD_DATA);
-			}
+			break;
+
+		case 0x08: /* LL */
+			output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE;
+			output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW;
+			break;
+
+		default:
+			/*
+			 * Only _LL and _HE polarity/trigger interrupts
+			 * are allowed (ACPI spec, section "IRQ Format")
+			 * so 0x00 and 0x09 are illegal.
+			 */
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Invalid interrupt polarity/trigger in resource list, %X\n", temp8));
+			return_ACPI_STATUS (AE_BAD_DATA);
 		}
 
 		/*
@@ -419,7 +421,7 @@
 		 * Point the String pointer to the end of this structure.
 		 */
 		output_struct->data.extended_irq.resource_source.string_ptr =
-				(char *)(output_struct + struct_size);
+				(char *)((char *) output_struct + struct_size);
 
 		temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr;
 
diff -urN linux-2.4.24-pre1/drivers/acpi/resources/rslist.c linux-2.4.24-pre2/drivers/acpi/resources/rslist.c
--- linux-2.4.24-pre1/drivers/acpi/resources/rslist.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/resources/rslist.c	2003-12-22 11:34:34.000000000 -0800
@@ -312,8 +312,8 @@
 		 * Set the Buffer to the next structure
 		 */
 		resource = ACPI_CAST_PTR (struct acpi_resource, buffer);
-		resource->length = ACPI_ALIGN_RESOURCE_SIZE(resource->length);
-		buffer += ACPI_ALIGN_RESOURCE_SIZE(structure_size);
+		resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length);
+		buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size);
 
 	} /*  end while */
 
diff -urN linux-2.4.24-pre1/drivers/acpi/tables/tbget.c linux-2.4.24-pre2/drivers/acpi/tables/tbget.c
--- linux-2.4.24-pre1/drivers/acpi/tables/tbget.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/tables/tbget.c	2003-12-22 11:34:34.000000000 -0800
@@ -148,8 +148,7 @@
 				  (void *) &header);
 		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n",
-				ACPI_HIDWORD (address->pointer.physical),
-				ACPI_LODWORD (address->pointer.physical),
+				ACPI_FORMAT_UINT64 (address->pointer.physical),
 				sizeof (struct acpi_table_header)));
 			return_ACPI_STATUS (status);
 		}
@@ -365,8 +364,7 @@
 		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
 				header->signature,
-				ACPI_HIDWORD (address->pointer.physical),
-				ACPI_LODWORD (address->pointer.physical), header->length));
+				ACPI_FORMAT_UINT64 (address->pointer.physical), header->length));
 			return (status);
 		}
 
@@ -408,8 +406,7 @@
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 		"Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
 		full_table->signature,
-		ACPI_HIDWORD (address->pointer.physical),
-		ACPI_LODWORD (address->pointer.physical), full_table));
+		ACPI_FORMAT_UINT64 (address->pointer.physical), full_table));
 
 	return_ACPI_STATUS (status);
 }
@@ -458,6 +455,7 @@
 	if (instance == 1) {
 		/* Get the first */
 
+		*table_ptr_loc = NULL;
 		if (acpi_gbl_table_lists[table_type].next) {
 			*table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer;
 		}
diff -urN linux-2.4.24-pre1/drivers/acpi/tables/tbgetall.c linux-2.4.24-pre2/drivers/acpi/tables/tbgetall.c
--- linux-2.4.24-pre1/drivers/acpi/tables/tbgetall.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/tables/tbgetall.c	2003-12-22 11:34:34.000000000 -0800
@@ -240,8 +240,7 @@
 		if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) {
 			ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n",
 				acpi_format_exception (status),
-				ACPI_HIDWORD (address.pointer.value),
-				ACPI_LODWORD (address.pointer.value)));
+				ACPI_FORMAT_UINT64 (address.pointer.value)));
 		}
 	}
 
diff -urN linux-2.4.24-pre1/drivers/acpi/tables/tbrsdt.c linux-2.4.24-pre2/drivers/acpi/tables/tbrsdt.c
--- linux-2.4.24-pre1/drivers/acpi/tables/tbrsdt.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/tables/tbrsdt.c	2003-12-22 11:34:34.000000000 -0800
@@ -278,8 +278,7 @@
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 		"RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
 		acpi_gbl_RSDP,
-		ACPI_HIDWORD (address.pointer.value),
-		ACPI_LODWORD (address.pointer.value)));
+		ACPI_FORMAT_UINT64 (address.pointer.value)));
 
 	/* Check the RSDT or XSDT signature */
 
diff -urN linux-2.4.24-pre1/drivers/acpi/tables/tbxface.c linux-2.4.24-pre2/drivers/acpi/tables/tbxface.c
--- linux-2.4.24-pre1/drivers/acpi/tables/tbxface.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/tables/tbxface.c	2003-12-22 11:34:34.000000000 -0800
@@ -251,7 +251,7 @@
 	/* Find all tables of the requested type */
 
 	table_desc = acpi_gbl_table_lists[table_type].next;
-	while (table_desc); {
+	while (table_desc) {
 		/*
 		 * Delete all namespace entries owned by this table.  Note that these
 		 * entries can appear anywhere in the namespace by virtue of the AML
diff -urN linux-2.4.24-pre1/drivers/acpi/tables/tbxfroot.c linux-2.4.24-pre2/drivers/acpi/tables/tbxfroot.c
--- linux-2.4.24-pre1/drivers/acpi/tables/tbxfroot.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/tables/tbxfroot.c	2003-12-22 11:34:34.000000000 -0800
@@ -211,8 +211,7 @@
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 		"RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
 		acpi_gbl_RSDP,
-		ACPI_HIDWORD (address.pointer.value),
-		ACPI_LODWORD (address.pointer.value)));
+		ACPI_FORMAT_UINT64 (address.pointer.value)));
 
 	/* Insert processor_mode flags */
 
diff -urN linux-2.4.24-pre1/drivers/acpi/tables.c linux-2.4.24-pre2/drivers/acpi/tables.c
--- linux-2.4.24-pre1/drivers/acpi/tables.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/tables.c	2003-12-22 11:34:34.000000000 -0800
@@ -60,6 +60,9 @@
 	[ACPI_HPET]		= "HPET",
 };
 
+static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
+static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
+
 /* System Description Table (RSDT/XSDT) */
 struct acpi_table_sdt {
 	unsigned long		pa;
@@ -136,8 +139,14 @@
 	{
 		struct acpi_table_int_src_ovr *p =
 			(struct acpi_table_int_src_ovr*) header;
-		printk(KERN_INFO PREFIX "INT_SRC_OVR (bus[%d] irq[0x%x] global_irq[0x%x] polarity[0x%x] trigger[0x%x])\n",
-			p->bus, p->bus_irq, p->global_irq, p->flags.polarity, p->flags.trigger);
+		printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
+			p->bus, p->bus_irq, p->global_irq,
+			mps_inti_flags_polarity[p->flags.polarity],
+			mps_inti_flags_trigger[p->flags.trigger]);
+		if(p->flags.reserved)
+			printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n",
+				p->flags.reserved);
+
 	}
 		break;
 
@@ -145,8 +154,9 @@
 	{
 		struct acpi_table_nmi_src *p =
 			(struct acpi_table_nmi_src*) header;
-		printk(KERN_INFO PREFIX "NMI_SRC (polarity[0x%x] trigger[0x%x] global_irq[0x%x])\n",
-			p->flags.polarity, p->flags.trigger, p->global_irq);
+		printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n",
+			mps_inti_flags_polarity[p->flags.polarity],
+			mps_inti_flags_trigger[p->flags.trigger], p->global_irq);
 	}
 		break;
 
@@ -154,8 +164,10 @@
 	{
 		struct acpi_table_lapic_nmi *p =
 			(struct acpi_table_lapic_nmi*) header;
-		printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] polarity[0x%x] trigger[0x%x] lint[0x%x])\n",
-			p->acpi_id, p->flags.polarity, p->flags.trigger, p->lint);
+		printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
+			p->acpi_id,
+			mps_inti_flags_polarity[p->flags.polarity],
+			mps_inti_flags_trigger[p->flags.trigger], p->lint);
 	}
 		break;
 
@@ -190,8 +202,10 @@
 	{
 		struct acpi_table_plat_int_src *p =
 			(struct acpi_table_plat_int_src*) header;
-		printk(KERN_INFO PREFIX "PLAT_INT_SRC (polarity[0x%x] trigger[0x%x] type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
-			p->flags.polarity, p->flags.trigger, p->type, p->id, p->eid, p->iosapic_vector, p->global_irq);
+		printk(KERN_INFO PREFIX "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
+			mps_inti_flags_polarity[p->flags.polarity],
+			mps_inti_flags_trigger[p->flags.trigger],
+			p->type, p->id, p->eid, p->iosapic_vector, p->global_irq);
 	}
 		break;
 
diff -urN linux-2.4.24-pre1/drivers/acpi/thermal.c linux-2.4.24-pre2/drivers/acpi/thermal.c
--- linux-2.4.24-pre1/drivers/acpi/thermal.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/thermal.c	2003-12-22 11:34:34.000000000 -0800
@@ -405,6 +405,7 @@
 	if (result)
 		return_VALUE(result);
 
+	printk(KERN_EMERG "Critical temperature reached (%ld C), shutting down.\n", KELVIN_TO_CELSIUS(tz->temperature));
 	acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled);
 
 	acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF);
diff -urN linux-2.4.24-pre1/drivers/acpi/utilities/utalloc.c linux-2.4.24-pre2/drivers/acpi/utilities/utalloc.c
--- linux-2.4.24-pre1/drivers/acpi/utilities/utalloc.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/utilities/utalloc.c	2003-12-22 11:34:34.000000000 -0800
@@ -902,71 +902,30 @@
 
 			descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
 			if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
-				acpi_os_printf ("%p Len %04X %9.9s-%d ",
+				acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
 						 descriptor, element->size, element->module,
-						 element->line);
+						 element->line, acpi_ut_get_descriptor_name (descriptor));
 
-				/* Most of the elements will be internal objects. */
+				/* Most of the elements will be Operand objects. */
 
 				switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
 				case ACPI_DESC_TYPE_OPERAND:
-					acpi_os_printf ("obj_type %12.12s R%hd",
+					acpi_os_printf ("%12.12s R%hd",
 							acpi_ut_get_type_name (descriptor->object.common.type),
 							descriptor->object.common.reference_count);
 					break;
 
 				case ACPI_DESC_TYPE_PARSER:
-					acpi_os_printf ("parse_obj aml_opcode %04hX",
+					acpi_os_printf ("aml_opcode %04hX",
 							descriptor->op.asl.aml_opcode);
 					break;
 
 				case ACPI_DESC_TYPE_NAMED:
-					acpi_os_printf ("Node %4.4s",
-							descriptor->node.name.ascii);
-					break;
-
-				case ACPI_DESC_TYPE_STATE:
-					acpi_os_printf ("Untyped state_obj");
-					break;
-
-				case ACPI_DESC_TYPE_STATE_UPDATE:
-					acpi_os_printf ("UPDATE state_obj");
-					break;
-
-				case ACPI_DESC_TYPE_STATE_PACKAGE:
-					acpi_os_printf ("PACKAGE state_obj");
-					break;
-
-				case ACPI_DESC_TYPE_STATE_CONTROL:
-					acpi_os_printf ("CONTROL state_obj");
-					break;
-
-				case ACPI_DESC_TYPE_STATE_RPSCOPE:
-					acpi_os_printf ("ROOT-PARSE-SCOPE state_obj");
-					break;
-
-				case ACPI_DESC_TYPE_STATE_PSCOPE:
-					acpi_os_printf ("PARSE-SCOPE state_obj");
-					break;
-
-				case ACPI_DESC_TYPE_STATE_WSCOPE:
-					acpi_os_printf ("WALK-SCOPE state_obj");
-					break;
-
-				case ACPI_DESC_TYPE_STATE_RESULT:
-					acpi_os_printf ("RESULT state_obj");
-					break;
-
-				case ACPI_DESC_TYPE_STATE_NOTIFY:
-					acpi_os_printf ("NOTIFY state_obj");
-					break;
-
-				case ACPI_DESC_TYPE_STATE_THREAD:
-					acpi_os_printf ("THREAD state_obj");
+					acpi_os_printf ("%4.4s",
+							acpi_ut_get_node_name (&descriptor->node));
 					break;
 
 				default:
-					/* All types should appear above */
 					break;
 				}
 
diff -urN linux-2.4.24-pre1/drivers/acpi/utilities/utdebug.c linux-2.4.24-pre2/drivers/acpi/utilities/utdebug.c
--- linux-2.4.24-pre1/drivers/acpi/utilities/utdebug.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/utilities/utdebug.c	2003-12-22 11:34:34.000000000 -0800
@@ -447,7 +447,7 @@
 
 	acpi_ut_debug_print (ACPI_LV_FUNCTIONS, line_number, dbg_info,
 			"%s %8.8X%8.8X\n", acpi_gbl_fn_exit_str,
-			ACPI_HIDWORD (value), ACPI_LODWORD (value));
+			ACPI_FORMAT_UINT64 (value));
 
 	acpi_gbl_nesting_level--;
 }
diff -urN linux-2.4.24-pre1/drivers/acpi/utilities/utdelete.c linux-2.4.24-pre2/drivers/acpi/utilities/utdelete.c
--- linux-2.4.24-pre1/drivers/acpi/utilities/utdelete.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/utilities/utdelete.c	2003-12-22 11:34:34.000000000 -0800
@@ -140,7 +140,7 @@
 
 		/* Walk the handler list for this device */
 
-		handler_desc = object->device.address_space;
+		handler_desc = object->device.handler;
 		while (handler_desc) {
 			next_desc = handler_desc->address_space.next;
 			acpi_ut_remove_reference (handler_desc);
@@ -193,7 +193,7 @@
 			 * default handlers -- and therefore, we created the context object
 			 * locally, it was not created by an external caller.
 			 */
-			handler_desc = object->region.address_space;
+			handler_desc = object->region.handler;
 			if (handler_desc) {
 				if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
 					obj_pointer = second_desc->extra.region_context;
diff -urN linux-2.4.24-pre1/drivers/acpi/utilities/uteval.c linux-2.4.24-pre2/drivers/acpi/utilities/uteval.c
--- linux-2.4.24-pre1/drivers/acpi/utilities/uteval.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/utilities/uteval.c	2003-12-22 11:34:34.000000000 -0800
@@ -91,7 +91,7 @@
 	if (ACPI_FAILURE (status)) {
 		if (status == AE_NOT_FOUND) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
-				prefix_node->name.ascii, path));
+				acpi_ut_get_node_name (prefix_node), path));
 		}
 		else {
 			ACPI_REPORT_METHOD_ERROR ("Method execution failed",
@@ -544,7 +544,7 @@
 		if (AE_NOT_FOUND == status) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 				"_STA on %4.4s was not found, assuming device is present\n",
-				device_node->name.ascii));
+				acpi_ut_get_node_name (device_node)));
 
 			*flags = 0x0F;
 			status = AE_OK;
diff -urN linux-2.4.24-pre1/drivers/acpi/utilities/utglobal.c linux-2.4.24-pre2/drivers/acpi/utilities/utglobal.c
--- linux-2.4.24-pre1/drivers/acpi/utilities/utglobal.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/acpi/utilities/utglobal.c	2003-12-22 11:34:34.000000000 -0800
@@ -358,7 +358,7 @@
 	/* ACPI_EVENT_GLOBAL        */  {ACPI_BITREG_GLOBAL_LOCK_STATUS,    ACPI_BITREG_GLOBAL_LOCK_ENABLE,  ACPI_BITMASK_GLOBAL_LOCK_STATUS,    ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
 	/* ACPI_EVENT_POWER_BUTTON  */  {ACPI_BITREG_POWER_BUTTON_STATUS,   ACPI_BITREG_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_STATUS,   ACPI_BITMASK_POWER_BUTTON_ENABLE},
 	/* ACPI_EVENT_SLEEP_BUTTON  */  {ACPI_BITREG_SLEEP_BUTTON_STATUS,   ACPI_BITREG_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_STATUS,   ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
-	/* ACPI_EVENT_RTC           */  {ACPI_BITREG_RT_CLOCK_STATUS,       ACPI_BITREG_RT_CLOCK_ENABLE,     0,                                  0},
+	/* ACPI_EVENT_RTC           */  {ACPI_BITREG_RT_CLOCK_STATUS,       ACPI_BITREG_RT_CLOCK_ENABLE,     ACPI_BITMASK_RT_CLOCK_STATUS,       ACPI_BITMASK_RT_CLOCK_ENABLE},
 };
 
 /*****************************************************************************
@@ -534,6 +534,99 @@
 }
 
 
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_node_name
+ *
+ * PARAMETERS:  Object               - A namespace node
+ *
+ * RETURN:      Pointer to a string
+ *
+ * DESCRIPTION: Validate the node and return the node's ACPI name.
+ *
+ ****************************************************************************/
+
+char *
+acpi_ut_get_node_name (
+	void                            *object)
+{
+	struct acpi_namespace_node      *node;
+
+
+	if (!object)
+	{
+		return ("NULL NODE");
+	}
+
+	node = (struct acpi_namespace_node *) object;
+
+	if (node->descriptor != ACPI_DESC_TYPE_NAMED)
+	{
+		return ("****");
+	}
+
+	if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii))
+	{
+		return ("----");
+	}
+
+	return (node->name.ascii);
+}
+
+
+/*****************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_descriptor_name
+ *
+ * PARAMETERS:  Object               - An ACPI object
+ *
+ * RETURN:      Pointer to a string
+ *
+ * DESCRIPTION: Validate object and return the descriptor type
+ *
+ ****************************************************************************/
+
+static const char                   *acpi_gbl_desc_type_names[] = /* printable names of descriptor types */
+{
+	/* 00 */ "Invalid",
+	/* 01 */ "Cached",
+	/* 02 */ "State-Generic",
+	/* 03 */ "State-Update",
+	/* 04 */ "State-Package",
+	/* 05 */ "State-Control",
+	/* 06 */ "State-root_parse_scope",
+	/* 07 */ "State-parse_scope",
+	/* 08 */ "State-walk_scope",
+	/* 09 */ "State-Result",
+	/* 10 */ "State-Notify",
+	/* 11 */ "State-Thread",
+	/* 12 */ "Walk",
+	/* 13 */ "Parser",
+	/* 14 */ "Operand",
+	/* 15 */ "Node"
+};
+
+
+char *
+acpi_ut_get_descriptor_name (
+	void                            *object)
+{
+
+	if (!object)
+	{
+		return ("NULL OBJECT");
+	}
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (object) > ACPI_DESC_TYPE_MAX)
+	{
+		return ((char *) acpi_gbl_bad_type);
+	}
+
+	return ((char *) acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE (object)]);
+
+}
+
+
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 /*
  * Strings and procedures used for debug only
diff -urN linux-2.4.24-pre1/drivers/acpi/utilities/utobject.c linux-2.4.24-pre2/drivers/acpi/utilities/utobject.c
--- linux-2.4.24-pre1/drivers/acpi/utilities/utobject.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/acpi/utilities/utobject.c	2003-12-22 11:34:34.000000000 -0800
@@ -223,29 +223,10 @@
 
 		return (TRUE);
 
-	case ACPI_DESC_TYPE_NAMED:
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-			"**** Obj %p is a named obj, not ACPI obj\n", object));
-		break;
-
-	case ACPI_DESC_TYPE_PARSER:
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-			"**** Obj %p is a parser obj, not ACPI obj\n", object));
-		break;
-
-	case ACPI_DESC_TYPE_CACHED:
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"**** Obj %p has already been released to internal cache\n", object));
-		break;
-
 	default:
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"**** Obj %p has unknown descriptor type %X\n", object,
-			ACPI_GET_DESCRIPTOR_TYPE (object)));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+				"%p is not not an ACPI operand obj [%s]\n",
+				object, acpi_ut_get_descriptor_name (object)));
 		break;
 	}
 
@@ -322,7 +303,8 @@
 
 	if (ACPI_GET_DESCRIPTOR_TYPE (object) != ACPI_DESC_TYPE_OPERAND) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Obj %p is not an ACPI object\n", object));
+				"%p is not an ACPI Operand object [%s]\n", object,
+				acpi_ut_get_descriptor_name (object)));
 		return_VOID;
 	}
 
diff -urN linux-2.4.24-pre1/drivers/block/cciss.c linux-2.4.24-pre2/drivers/block/cciss.c
--- linux-2.4.24-pre1/drivers/block/cciss.c	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/block/cciss.c	2003-12-22 11:34:34.000000000 -0800
@@ -2537,8 +2537,8 @@
 static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 {
 	ushort subsystem_vendor_id, subsystem_device_id, command;
-	unchar irq = pdev->irq;
-	__u32 board_id;
+	unchar irq = pdev->irq, ready = 0;
+	__u32 board_id, scratchpad;
 	__u64 cfg_offset;
 	__u32 cfg_base_addr;
 	__u64 cfg_base_addr_index;
@@ -2609,10 +2609,24 @@
 	printk("address 0 = %x\n", c->paddr);
 #endif /* CCISS_DEBUG */ 
 	c->vaddr = remap_pci_mem(c->paddr, 200);
+	/* Wait for the board to become ready.  (PCI hotplug needs this.)
+	 * We poll for up to 120 secs, once per 100ms. */
+	for (i=0; i < 1200; i++) {
+		scratchpad = readl(c->vaddr + SA5_SCRATCHPAD_OFFSET);
+		if (scratchpad == 0xffff0000) {
+			ready = 1;
+			break;
+		}
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ / 10); /* wait 100ms */
+	}
+	if (!ready) {
+		printk(KERN_WARNING "cciss: Board not ready.  Timed out.\n");
+		return -1;
+	}
 
 	/* get the address index number */
 	cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET);
-	/* I am not prepared to deal with a 64 bit address value */
 	cfg_base_addr &= (__u32) 0x0000ffff;
 #ifdef CCISS_DEBUG
 	printk("cfg base address = %x\n", cfg_base_addr);
@@ -2624,7 +2638,7 @@
 #endif /* CCISS_DEBUG */
 	if (cfg_base_addr_index == -1) {
 		printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n");
-		release_io_mem(hba[i]);
+		release_io_mem(c);
 		return -1;
 	}
 
@@ -2661,6 +2675,15 @@
 		printk("Does not appear to be a valid CISS config table\n");
 		return -1;
 	}
+
+#ifdef CONFIG_X86
+	/* Need to enable prefetch in the SCSI core for 6400 in x86 */
+	__u32 prefetch;
+	prefetch = readl(&(c->cfgtable->SCSI_Prefetch));
+	prefetch |= 0x100;
+	writel(prefetch, &(c->cfgtable->SCSI_Prefetch));
+#endif
+
 #ifdef CCISS_DEBUG
 	printk("Trying to put board into Simple mode\n");
 #endif /* CCISS_DEBUG */ 
diff -urN linux-2.4.24-pre1/drivers/block/cciss.h linux-2.4.24-pre2/drivers/block/cciss.h
--- linux-2.4.24-pre1/drivers/block/cciss.h	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/block/cciss.h	2003-12-22 11:34:34.000000000 -0800
@@ -137,6 +137,7 @@
 #define SA5_REPLY_INTR_MASK_OFFSET	0x34
 #define SA5_REPLY_PORT_OFFSET		0x44
 #define SA5_INTR_STATUS		0x30
+#define SA5_SCRATCHPAD_OFFSET	0xB0
 
 #define SA5_CTCFG_OFFSET	0xB4
 #define SA5_CTMEM_OFFSET	0xB8
diff -urN linux-2.4.24-pre1/drivers/block/cciss_cmd.h linux-2.4.24-pre2/drivers/block/cciss_cmd.h
--- linux-2.4.24-pre1/drivers/block/cciss_cmd.h	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.24-pre2/drivers/block/cciss_cmd.h	2003-12-22 11:34:34.000000000 -0800
@@ -266,6 +266,7 @@
   DWORD            Reserved; 
   BYTE             ServerName[16];
   DWORD            HeartBeat;
+  DWORD            SCSI_Prefetch;
 } CfgTable_struct;
 #pragma pack()	 
 #endif /* CCISS_CMD_H */
diff -urN linux-2.4.24-pre1/drivers/bluetooth/Config.in linux-2.4.24-pre2/drivers/bluetooth/Config.in
--- linux-2.4.24-pre1/drivers/bluetooth/Config.in	2003-11-28 10:26:19.000000000 -0800
+++ linux-2.4.24-pre2/drivers/bluetooth/Config.in	2003-12-22 11:34:34.000000000 -0800
@@ -7,7 +7,7 @@
 
 dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
 if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then
-   bool '  SCO (voice) support'  CONFIG_BLUEZ_USB_SCO
+   bool '  SCO (voice) support'  CONFIG_BLUEZ_HCIUSB_SCO
 fi
 
 dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
diff -urN linux-2.4.24-pre1/drivers/bluetooth/hci_usb.c linux-2.4.24-pre2/drivers/bluetooth/hci_usb.c
--- linux-2.4.24-pre1/drivers/bluetooth/hci_usb.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/bluetooth/hci_usb.c	2003-12-22 11:34:34.000000000 -0800
@@ -62,7 +62,7 @@
 #define BT_DMP( A... )
 #endif
 
-#ifndef CONFIG_BLUEZ_USB_ZERO_PACKET
+#ifndef CONFIG_BLUEZ_HCIUSB_ZERO_PACKET
 #undef  USB_ZERO_PACKET
 #define USB_ZERO_PACKET 0
 #endif
@@ -139,6 +139,7 @@
 	return _urb_dequeue(__completed_q(husb, type)); 
 }
 
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
 {
 	int offset = 0, i;
@@ -158,6 +159,7 @@
 	}
 	urb->number_of_packets = i;
 }
+#endif
 
 static int hci_usb_intr_rx_submit(struct hci_usb *husb)
 {
@@ -235,7 +237,7 @@
 	return err;
 }
 
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
 {
 	struct _urb *_urb;
@@ -306,7 +308,7 @@
 		for (i = 0; i < HCI_MAX_BULK_RX; i++)
 			hci_usb_bulk_rx_submit(husb);
 
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 		if (husb->isoc_iface)
 			for (i = 0; i < HCI_MAX_ISOC_RX; i++)
 				hci_usb_isoc_rx_submit(husb);
@@ -475,7 +477,7 @@
 	return __tx_submit(husb, _urb);
 }
 
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
 {
 	struct _urb *_urb = __get_completed(husb, skb->pkt_type);
@@ -526,7 +528,7 @@
 				skb_queue_head(q, skb);
 		}
 
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 		/* Process SCO queue */
 		q = __transmit_q(husb, HCI_SCODATA_PKT);
 		if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
@@ -585,7 +587,7 @@
 		hdev->stat.acl_tx++;
 		break;
 
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 	case HCI_SCODATA_PKT:
 		hdev->stat.sco_tx++;
 		break;
@@ -635,7 +637,7 @@
 				} else
 					return -EILSEQ;
 				break;
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 			case HCI_SCODATA_PKT:
 				if (count >= HCI_SCO_HDR_SIZE) {
 					hci_sco_hdr *h = data;
@@ -700,7 +702,7 @@
 		goto resubmit;
 
 	if (_urb->type == HCI_SCODATA_PKT) {
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 		int i;
 		for (i=0; i < urb->number_of_packets; i++) {
 			BT_DBG("desc %d status %d offset %d len %d", i,
@@ -835,7 +837,7 @@
 						bulk_out_ep[i] = ep;
 					break;
 
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 				case USB_ENDPOINT_XFER_ISOC:
 					if (ep->wMaxPacketSize < size || a > 2)
 						break;
@@ -861,7 +863,7 @@
 		goto done;
 	}
 
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 	if (!isoc_in_ep[1] || !isoc_out_ep[1]) {
 		BT_DBG("Isoc endpoints not found");
 		isoc_iface = NULL;
@@ -885,7 +887,7 @@
 	else
 		husb->ctrl_req = HCI_CTRL_REQ;
 
-#ifdef CONFIG_BLUEZ_USB_SCO
+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
 	if (isoc_iface) {
 		BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
 		if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
diff -urN linux-2.4.24-pre1/drivers/char/Config.in linux-2.4.24-pre2/drivers/char/Config.in
--- linux-2.4.24-pre1/drivers/char/Config.in	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/Config.in	2003-12-22 11:34:34.000000000 -0800
@@ -165,6 +165,9 @@
    fi
    bool 'Enable Smart Card Reader 0 Support ' CONFIG_IT8172_SCR0
 fi
+if [ "$CONFIG_CPU_VR41XX" = "y" ]; then
+   bool 'NEC VR4100 series Keyboard Interface Unit Support ' CONFIG_VR41XX_KIU
+fi
 bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
 if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
    int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
@@ -267,7 +270,9 @@
       fi
    fi
    tristate '  ZF MachZ Watchdog' CONFIG_MACHZ_WDT
-   dep_tristate '  Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22
+   if [ "$CONFIG_SGI_IP22" = "y" ]; then
+      dep_tristate '  Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22
+   fi
    dep_tristate '  AMD 766/768 TCO Timer/Watchdog' CONFIG_AMD7XX_TCO $CONFIG_EXPERIMENTAL
 fi
 endmenu
@@ -387,4 +392,9 @@
 if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
   tristate ' ITE GPIO' CONFIG_ITE_GPIO
 fi
+
+if [ "$CONFIG_X86" = "y" ]; then
+   tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE
+fi
+
 endmenu
diff -urN linux-2.4.24-pre1/drivers/char/Makefile linux-2.4.24-pre2/drivers/char/Makefile
--- linux-2.4.24-pre1/drivers/char/Makefile	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/Makefile	2003-12-22 11:34:34.000000000 -0800
@@ -47,6 +47,10 @@
   ifneq ($(CONFIG_PC_KEYB),y)
     KEYBD    =
   endif
+  ifeq ($(CONFIG_VR41XX_KIU),y)
+    KEYMAP   =
+    KEYBD    = vr41xx_keyb.o
+  endif
 endif
 
 ifeq ($(ARCH),s390x)
diff -urN linux-2.4.24-pre1/drivers/char/drm/drmP.h linux-2.4.24-pre2/drivers/char/drm/drmP.h
--- linux-2.4.24-pre1/drivers/char/drm/drmP.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/drmP.h	2003-12-22 11:34:34.000000000 -0800
@@ -328,16 +328,16 @@
    if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; }
 
 				/* Mapping helper macros */
-#define DRM_IOREMAP(map)						\
-	(map)->handle = DRM(ioremap)( (map)->offset, (map)->size )
+#define DRM_IOREMAP(map, dev)					\
+	(map)->handle = DRM(ioremap)((map)->offset, (map)->size, (dev) )
 
-#define DRM_IOREMAP_NOCACHE(map)					\
-	(map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size)
+#define DRM_IOREMAP_NOCACHE(map, dev)					\
+	(map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size, (dev) )
 
-#define DRM_IOREMAPFREE(map)						\
+#define DRM_IOREMAPFREE(map, dev)						\
 	do {								\
 		if ( (map)->handle && (map)->size )			\
-			DRM(ioremapfree)( (map)->handle, (map)->size );	\
+			DRM(ioremapfree)( (map)->handle, (map)->size, (dev) );	\
 	} while (0)
 
 #define DRM_FIND_MAP(_map, _o)						\
@@ -789,9 +789,9 @@
 extern unsigned long DRM(alloc_pages)(int order, int area);
 extern void	     DRM(free_pages)(unsigned long address, int order,
 				     int area);
-extern void	     *DRM(ioremap)(unsigned long offset, unsigned long size);
-extern void	     *DRM(ioremap_nocache)(unsigned long offset, unsigned long size);
-extern void	     DRM(ioremapfree)(void *pt, unsigned long size);
+extern void	     *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev);
+extern void	     *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev);
+extern void	     DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev);
 
 #if __REALLY_HAVE_AGP
 extern agp_memory    *DRM(alloc_agp)(int pages, u32 type);
diff -urN linux-2.4.24-pre1/drivers/char/drm/drm_bufs.h linux-2.4.24-pre2/drivers/char/drm/drm_bufs.h
--- linux-2.4.24-pre1/drivers/char/drm/drm_bufs.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/drm_bufs.h	2003-12-22 11:34:34.000000000 -0800
@@ -123,7 +123,7 @@
 					      MTRR_TYPE_WRCOMB, 1 );
 		}
 #endif
-		map->handle = DRM(ioremap)( map->offset, map->size );
+		map->handle = DRM(ioremap)( map->offset, map->size, dev );
 		break;
 
 	case _DRM_SHM:
@@ -245,7 +245,7 @@
 				DRM_DEBUG("mtrr_del = %d\n", retcode);
 			}
 #endif
-			DRM(ioremapfree)(map->handle, map->size);
+			DRM(ioremapfree)(map->handle, map->size, dev);
 			break;
 		case _DRM_SHM:
 			vfree(map->handle);
diff -urN linux-2.4.24-pre1/drivers/char/drm/drm_drv.h linux-2.4.24-pre2/drivers/char/drm/drm_drv.h
--- linux-2.4.24-pre1/drivers/char/drm/drm_drv.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/drm_drv.h	2003-12-22 11:34:34.000000000 -0800
@@ -443,7 +443,7 @@
 					DRM_DEBUG( "mtrr_del=%d\n", retcode );
 				}
 #endif
-				DRM(ioremapfree)( map->handle, map->size );
+				DRM(ioremapfree)( map->handle, map->size, dev );
 				break;
 			case _DRM_SHM:
 				vfree(map->handle);
diff -urN linux-2.4.24-pre1/drivers/char/drm/drm_memory.h linux-2.4.24-pre2/drivers/char/drm/drm_memory.h
--- linux-2.4.24-pre1/drivers/char/drm/drm_memory.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/drm_memory.h	2003-12-22 11:34:34.000000000 -0800
@@ -290,7 +290,7 @@
 	}
 }
 
-void *DRM(ioremap)(unsigned long offset, unsigned long size)
+void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
 {
 	void *pt;
 
@@ -313,7 +313,7 @@
 	return pt;
 }
 
-void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size)
+void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
 {
 	void *pt;
 
@@ -336,7 +336,7 @@
 	return pt;
 }
 
-void DRM(ioremapfree)(void *pt, unsigned long size)
+void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
 {
 	int alloc_count;
 	int free_count;
diff -urN linux-2.4.24-pre1/drivers/char/drm/drm_vm.h linux-2.4.24-pre2/drivers/char/drm/drm_vm.h
--- linux-2.4.24-pre1/drivers/char/drm/drm_vm.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/drm_vm.h	2003-12-22 11:34:34.000000000 -0800
@@ -206,7 +206,7 @@
 					DRM_DEBUG("mtrr_del = %d\n", retcode);
 				}
 #endif
-				DRM(ioremapfree)(map->handle, map->size);
+				DRM(ioremapfree)(map->handle, map->size, dev);
 				break;
 			case _DRM_SHM:
 				vfree(map->handle);
diff -urN linux-2.4.24-pre1/drivers/char/drm/gamma_dma.c linux-2.4.24-pre2/drivers/char/drm/gamma_dma.c
--- linux-2.4.24-pre1/drivers/char/drm/gamma_dma.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/gamma_dma.c	2003-12-22 11:34:34.000000000 -0800
@@ -638,7 +638,7 @@
 	} else {
 		DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
 
-		DRM_IOREMAP( dev_priv->buffers );
+		DRM_IOREMAP( dev_priv->buffers, dev );
 
 		buf = dma->buflist[GLINT_DRI_BUF_COUNT];
 		pgt = buf->address;
@@ -668,7 +668,7 @@
 	if ( dev->dev_private ) {
 		drm_gamma_private_t *dev_priv = dev->dev_private;
 
-		DRM_IOREMAPFREE( dev_priv->buffers );
+		DRM_IOREMAPFREE( dev_priv->buffers, dev );
 
 		DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t),
 			   DRM_MEM_DRIVER );
diff -urN linux-2.4.24-pre1/drivers/char/drm/i810_dma.c linux-2.4.24-pre2/drivers/char/drm/i810_dma.c
--- linux-2.4.24-pre1/drivers/char/drm/i810_dma.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/i810_dma.c	2003-12-22 11:34:34.000000000 -0800
@@ -276,7 +276,7 @@
 
 	   	if(dev_priv->ring.virtual_start) {
 		   	DRM(ioremapfree)((void *) dev_priv->ring.virtual_start,
-					 dev_priv->ring.Size);
+					 dev_priv->ring.Size, dev);
 		}
 	   	if(dev_priv->hw_status_page != 0UL) {
 		   	pci_free_consistent(dev->pdev, PAGE_SIZE,
@@ -292,7 +292,7 @@
 		for (i = 0; i < dma->buf_count; i++) {
 			drm_buf_t *buf = dma->buflist[ i ];
 			drm_i810_buf_priv_t *buf_priv = buf->dev_private;
-			DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total);
+			DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev);
 		}
 	}
    	return 0;
@@ -362,7 +362,7 @@
 	   	*buf_priv->in_use = I810_BUF_FREE;
 
 		buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address,
-							buf->total);
+							buf->total, dev);
 	}
 	return 0;
 }
@@ -415,7 +415,7 @@
 
    	dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base +
 						    init->ring_start,
-						    init->ring_size);
+						    init->ring_size, dev);
 
    	if (dev_priv->ring.virtual_start == NULL) {
 		dev->dev_private = (void *) dev_priv;
diff -urN linux-2.4.24-pre1/drivers/char/drm/i830_dma.c linux-2.4.24-pre2/drivers/char/drm/i830_dma.c
--- linux-2.4.24-pre1/drivers/char/drm/i830_dma.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/i830_dma.c	2003-12-22 11:34:34.000000000 -0800
@@ -252,7 +252,7 @@
 	   
 	   	if(dev_priv->ring.virtual_start) {
 		   	DRM(ioremapfree)((void *) dev_priv->ring.virtual_start,
-					 dev_priv->ring.Size);
+					 dev_priv->ring.Size, dev);
 		}
 	   	if(dev_priv->hw_status_page != 0UL) {
 			pci_free_consistent(dev->pdev, PAGE_SIZE,
@@ -277,7 +277,7 @@
 		for (i = 0; i < dma->buf_count; i++) {
 			drm_buf_t *buf = dma->buflist[ i ];
 			drm_i830_buf_priv_t *buf_priv = buf->dev_private;
-			DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total);
+			DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev);
 		}
 	}
    	return 0;
@@ -353,7 +353,7 @@
 	   	*buf_priv->in_use = I830_BUF_FREE;
 
 		buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, 
-							buf->total);
+							buf->total, dev);
 	}
 	return 0;
 }
@@ -407,7 +407,7 @@
 
    	dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + 
 						    init->ring_start, 
-						    init->ring_size);
+						    init->ring_size, dev);
 
    	if (dev_priv->ring.virtual_start == NULL) {
 		dev->dev_private = (void *) dev_priv;
diff -urN linux-2.4.24-pre1/drivers/char/drm/mga_dma.c linux-2.4.24-pre2/drivers/char/drm/mga_dma.c
--- linux-2.4.24-pre1/drivers/char/drm/mga_dma.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/mga_dma.c	2003-12-22 11:34:34.000000000 -0800
@@ -556,9 +556,9 @@
 		(drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle +
 				    init->sarea_priv_offset);
 
-	DRM_IOREMAP( dev_priv->warp );
-	DRM_IOREMAP( dev_priv->primary );
-	DRM_IOREMAP( dev_priv->buffers );
+	DRM_IOREMAP( dev_priv->warp, dev );
+	DRM_IOREMAP( dev_priv->primary, dev );
+	DRM_IOREMAP( dev_priv->buffers, dev );
 
 	if(!dev_priv->warp->handle ||
 	   !dev_priv->primary->handle ||
@@ -644,9 +644,9 @@
 	if ( dev->dev_private ) {
 		drm_mga_private_t *dev_priv = dev->dev_private;
 
-		DRM_IOREMAPFREE( dev_priv->warp );
-		DRM_IOREMAPFREE( dev_priv->primary );
-		DRM_IOREMAPFREE( dev_priv->buffers );
+		DRM_IOREMAPFREE( dev_priv->warp, dev );
+		DRM_IOREMAPFREE( dev_priv->primary, dev );
+		DRM_IOREMAPFREE( dev_priv->buffers, dev );
 
 		if ( dev_priv->head != NULL ) {
 			mga_freelist_cleanup( dev );
diff -urN linux-2.4.24-pre1/drivers/char/drm/r128_cce.c linux-2.4.24-pre2/drivers/char/drm/r128_cce.c
--- linux-2.4.24-pre1/drivers/char/drm/r128_cce.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/r128_cce.c	2003-12-22 11:34:34.000000000 -0800
@@ -542,9 +542,9 @@
 				     init->sarea_priv_offset);
 
 	if ( !dev_priv->is_pci ) {
-		DRM_IOREMAP( dev_priv->cce_ring );
-		DRM_IOREMAP( dev_priv->ring_rptr );
-		DRM_IOREMAP( dev_priv->buffers );
+		DRM_IOREMAP( dev_priv->cce_ring, dev );
+		DRM_IOREMAP( dev_priv->ring_rptr, dev );
+		DRM_IOREMAP( dev_priv->buffers, dev );
 		if(!dev_priv->cce_ring->handle ||
 		   !dev_priv->ring_rptr->handle ||
 		   !dev_priv->buffers->handle) {
@@ -618,9 +618,9 @@
 #if __REALLY_HAVE_SG
 		if ( !dev_priv->is_pci ) {
 #endif
-			DRM_IOREMAPFREE( dev_priv->cce_ring );
-			DRM_IOREMAPFREE( dev_priv->ring_rptr );
-			DRM_IOREMAPFREE( dev_priv->buffers );
+			DRM_IOREMAPFREE( dev_priv->cce_ring, dev );
+			DRM_IOREMAPFREE( dev_priv->ring_rptr, dev );
+			DRM_IOREMAPFREE( dev_priv->buffers, dev );
 #if __REALLY_HAVE_SG
 		} else {
 			if (!DRM(ati_pcigart_cleanup)( dev,
diff -urN linux-2.4.24-pre1/drivers/char/drm/radeon_cp.c linux-2.4.24-pre2/drivers/char/drm/radeon_cp.c
--- linux-2.4.24-pre1/drivers/char/drm/radeon_cp.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm/radeon_cp.c	2003-12-22 11:34:34.000000000 -0800
@@ -1145,9 +1145,9 @@
 				       init->sarea_priv_offset);
 
 	if ( !dev_priv->is_pci ) {
-		DRM_IOREMAP( dev_priv->cp_ring );
-		DRM_IOREMAP( dev_priv->ring_rptr );
-		DRM_IOREMAP( dev_priv->buffers );
+		DRM_IOREMAP( dev_priv->cp_ring, dev );
+		DRM_IOREMAP( dev_priv->ring_rptr, dev );
+		DRM_IOREMAP( dev_priv->buffers, dev );
 		if(!dev_priv->cp_ring->handle ||
 		   !dev_priv->ring_rptr->handle ||
 		   !dev_priv->buffers->handle) {
@@ -1266,9 +1266,9 @@
 		drm_radeon_private_t *dev_priv = dev->dev_private;
 
 		if ( !dev_priv->is_pci ) {
-			DRM_IOREMAPFREE( dev_priv->cp_ring );
-			DRM_IOREMAPFREE( dev_priv->ring_rptr );
-			DRM_IOREMAPFREE( dev_priv->buffers );
+			DRM_IOREMAPFREE( dev_priv->cp_ring, dev );
+			DRM_IOREMAPFREE( dev_priv->ring_rptr, dev );
+			DRM_IOREMAPFREE( dev_priv->buffers, dev );
 		} else {
 #if __REALLY_HAVE_SG
 			if (!DRM(ati_pcigart_cleanup)( dev,
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/bufs.c linux-2.4.24-pre2/drivers/char/drm-4.0/bufs.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/bufs.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/bufs.c	2003-12-22 11:34:34.000000000 -0800
@@ -87,7 +87,7 @@
 					     MTRR_TYPE_WRCOMB, 1);
 		}
 #endif
-		map->handle = drm_ioremap(map->offset, map->size);
+		map->handle = drm_ioremap(map->offset, map->size, dev);
 		break;
 			
 
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/drmP.h linux-2.4.24-pre2/drivers/char/drm-4.0/drmP.h
--- linux-2.4.24-pre1/drivers/char/drm-4.0/drmP.h	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/drmP.h	2003-12-22 11:34:34.000000000 -0800
@@ -679,8 +679,8 @@
 extern unsigned long drm_alloc_pages(int order, int area);
 extern void	     drm_free_pages(unsigned long address, int order,
 				    int area);
-extern void	     *drm_ioremap(unsigned long offset, unsigned long size);
-extern void	     drm_ioremapfree(void *pt, unsigned long size);
+extern void	     *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev);
+extern void	     drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev);
 
 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
 extern agp_memory    *drm_alloc_agp(int pages, u32 type);
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/ffb_drv.c linux-2.4.24-pre2/drivers/char/drm-4.0/ffb_drv.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/ffb_drv.c	2002-11-28 15:53:12.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/ffb_drv.c	2003-12-22 11:34:34.000000000 -0800
@@ -158,7 +158,7 @@
 			switch (map->type) {
 			case _DRM_REGISTERS:
 			case _DRM_FRAME_BUFFER:
-				drm_ioremapfree(map->handle, map->size);
+				drm_ioremapfree(map->handle, map->size, dev);
 				break;
 
 			case _DRM_SHM:
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/gamma_drv.c linux-2.4.24-pre2/drivers/char/drm-4.0/gamma_drv.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/gamma_drv.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/gamma_drv.c	2003-12-22 11:34:34.000000000 -0800
@@ -258,7 +258,7 @@
 					DRM_DEBUG("mtrr_del = %d\n", retcode);
 				}
 #endif
-				drm_ioremapfree(map->handle, map->size);
+				drm_ioremapfree(map->handle, map->size, dev);
 				break;
 			case _DRM_SHM:
 				drm_free_pages((unsigned long)map->handle,
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/i810_dma.c linux-2.4.24-pre2/drivers/char/drm-4.0/i810_dma.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/i810_dma.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/i810_dma.c	2003-12-22 11:34:34.000000000 -0800
@@ -305,7 +305,7 @@
 	   
 	   	if(dev_priv->ring.virtual_start) {
 		   	drm_ioremapfree((void *) dev_priv->ring.virtual_start,
-					dev_priv->ring.Size);
+					dev_priv->ring.Size, dev);
 		}
 	   	if(dev_priv->hw_status_page != 0UL) {
 		   	i810_free_page(dev, dev_priv->hw_status_page);
@@ -319,7 +319,7 @@
 		for (i = 0; i < dma->buf_count; i++) {
 			drm_buf_t *buf = dma->buflist[ i ];
 			drm_i810_buf_priv_t *buf_priv = buf->dev_private;
-			drm_ioremapfree(buf_priv->kernel_virtual, buf->total);
+			drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev);
 		}
 	}
    	return 0;
@@ -393,7 +393,7 @@
 	   	*buf_priv->in_use = I810_BUF_FREE;
 
 		buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, 
-						       buf->total);
+						       buf->total, dev);
 	}
 	return 0;
 }
@@ -430,7 +430,7 @@
 
    	dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + 
 						   init->ring_start, 
-						   init->ring_size);
+						   init->ring_size, dev);
 
    	dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
    
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/i810_drv.c linux-2.4.24-pre2/drivers/char/drm-4.0/i810_drv.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/i810_drv.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/i810_drv.c	2003-12-22 11:34:34.000000000 -0800
@@ -286,7 +286,7 @@
 					DRM_DEBUG("mtrr_del = %d\n", retcode);
 				}
 #endif
-				drm_ioremapfree(map->handle, map->size);
+				drm_ioremapfree(map->handle, map->size, dev);
 				break;
 			case _DRM_SHM:
 				drm_free_pages((unsigned long)map->handle,
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/memory.c linux-2.4.24-pre2/drivers/char/drm-4.0/memory.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/memory.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/memory.c	2003-12-22 11:34:34.000000000 -0800
@@ -296,7 +296,7 @@
 	}
 }
 
-void *drm_ioremap(unsigned long offset, unsigned long size)
+void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev)
 {
 	void *pt;
 	
@@ -319,7 +319,7 @@
 	return pt;
 }
 
-void drm_ioremapfree(void *pt, unsigned long size)
+void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev)
 {
 	int alloc_count;
 	int free_count;
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/mga_dma.c linux-2.4.24-pre2/drivers/char/drm-4.0/mga_dma.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/mga_dma.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/mga_dma.c	2003-12-22 11:34:34.000000000 -0800
@@ -308,7 +308,7 @@
 	temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
 
 	dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
-					temp);
+					temp, dev);
 	if(dev_priv->ioremap == NULL) {
 		DRM_ERROR("Ioremap failed\n");
 		return -ENOMEM;
@@ -635,7 +635,7 @@
 				    dev_priv->primary_size +
 				    PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
 
-			drm_ioremapfree((void *) dev_priv->ioremap, temp);
+			drm_ioremapfree((void *) dev_priv->ioremap, temp, dev);
 		}
 	   	if(dev_priv->status_page != NULL) {
 		   	iounmap(dev_priv->status_page);
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/mga_drv.c linux-2.4.24-pre2/drivers/char/drm-4.0/mga_drv.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/mga_drv.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/mga_drv.c	2003-12-22 11:34:34.000000000 -0800
@@ -286,7 +286,7 @@
 					DRM_DEBUG("mtrr_del = %d\n", retcode);
 				}
 #endif
-				drm_ioremapfree(map->handle, map->size);
+				drm_ioremapfree(map->handle, map->size, dev);
 				break;
 			case _DRM_SHM:
 				drm_free_pages((unsigned long)map->handle,
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/r128_cce.c linux-2.4.24-pre2/drivers/char/drm-4.0/r128_cce.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/r128_cce.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/r128_cce.c	2003-12-22 11:34:34.000000000 -0800
@@ -86,12 +86,12 @@
 };
 
 
-#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
+#define DO_REMAP(_m, _d) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size, (_d))
 
-#define DO_REMAPFREE(_m)                                                    \
+#define DO_REMAPFREE(_m, _d)                                                   \
 	do {                                                                \
 		if ((_m)->handle && (_m)->size)                             \
-			drm_ioremapfree((_m)->handle, (_m)->size);          \
+			drm_ioremapfree((_m)->handle, (_m)->size, (_d));    \
 	} while (0)
 
 #define DO_FIND_MAP(_m, _o)                                                 \
@@ -481,12 +481,12 @@
 		(drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle +
 				     init->sarea_priv_offset);
 
-	DO_REMAP( dev_priv->cce_ring );
-	DO_REMAP( dev_priv->ring_rptr );
-	DO_REMAP( dev_priv->buffers );
+	DO_REMAP( dev_priv->cce_ring, dev );
+	DO_REMAP( dev_priv->ring_rptr, dev );
+	DO_REMAP( dev_priv->buffers, dev );
 #if 0
 	if ( !dev_priv->is_pci ) {
-		DO_REMAP( dev_priv->agp_textures );
+		DO_REMAP( dev_priv->agp_textures, dev );
 	}
 #endif
 
@@ -521,12 +521,12 @@
 	if ( dev->dev_private ) {
 		drm_r128_private_t *dev_priv = dev->dev_private;
 
-		DO_REMAPFREE( dev_priv->cce_ring );
-		DO_REMAPFREE( dev_priv->ring_rptr );
-		DO_REMAPFREE( dev_priv->buffers );
+		DO_REMAPFREE( dev_priv->cce_ring, dev );
+		DO_REMAPFREE( dev_priv->ring_rptr, dev );
+		DO_REMAPFREE( dev_priv->buffers, dev );
 #if 0
 		if ( !dev_priv->is_pci ) {
-			DO_REMAPFREE( dev_priv->agp_textures );
+			DO_REMAPFREE( dev_priv->agp_textures, dev );
 		}
 #endif
 
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/r128_drv.c linux-2.4.24-pre2/drivers/char/drm-4.0/r128_drv.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/r128_drv.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/r128_drv.c	2003-12-22 11:34:34.000000000 -0800
@@ -296,7 +296,7 @@
 					DRM_DEBUG("mtrr_del = %d\n", retcode);
 				}
 #endif
-				drm_ioremapfree(map->handle, map->size);
+				drm_ioremapfree(map->handle, map->size, dev);
 				break;
 			case _DRM_SHM:
 				drm_free_pages((unsigned long)map->handle,
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/radeon_cp.c linux-2.4.24-pre2/drivers/char/drm-4.0/radeon_cp.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/radeon_cp.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/radeon_cp.c	2003-12-22 11:34:34.000000000 -0800
@@ -300,12 +300,12 @@
 };
 
 
-#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size)
+#define DO_IOREMAP(_m, _d) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size, (_d))
 
-#define DO_IOREMAPFREE(_m)						\
+#define DO_IOREMAPFREE(_m, _d)						\
 	do {								\
 		if ((_m)->handle && (_m)->size)				\
-			drm_ioremapfree((_m)->handle, (_m)->size);	\
+			drm_ioremapfree((_m)->handle, (_m)->size, (_d));\
 	} while (0)
 
 #define DO_FIND_MAP(_m, _o)						\
@@ -757,12 +757,12 @@
 		(drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle +
 				       init->sarea_priv_offset);
 
-	DO_IOREMAP( dev_priv->cp_ring );
-	DO_IOREMAP( dev_priv->ring_rptr );
-	DO_IOREMAP( dev_priv->buffers );
+	DO_IOREMAP( dev_priv->cp_ring, dev );
+	DO_IOREMAP( dev_priv->ring_rptr, dev );
+	DO_IOREMAP( dev_priv->buffers, dev );
 #if 0
 	if ( !dev_priv->is_pci ) {
-		DO_IOREMAP( dev_priv->agp_textures );
+		DO_IOREMAP( dev_priv->agp_textures, dev );
 	}
 #endif
 
@@ -828,12 +828,12 @@
 	if ( dev->dev_private ) {
 		drm_radeon_private_t *dev_priv = dev->dev_private;
 
-		DO_IOREMAPFREE( dev_priv->cp_ring );
-		DO_IOREMAPFREE( dev_priv->ring_rptr );
-		DO_IOREMAPFREE( dev_priv->buffers );
+		DO_IOREMAPFREE( dev_priv->cp_ring, dev );
+		DO_IOREMAPFREE( dev_priv->ring_rptr, dev );
+		DO_IOREMAPFREE( dev_priv->buffers, dev );
 #if 0
 		if ( !dev_priv->is_pci ) {
-			DO_IOREMAPFREE( dev_priv->agp_textures );
+			DO_IOREMAPFREE( dev_priv->agp_textures, dev );
 		}
 #endif
 
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/radeon_drv.c linux-2.4.24-pre2/drivers/char/drm-4.0/radeon_drv.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/radeon_drv.c	2002-02-25 11:37:57.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/radeon_drv.c	2003-12-22 11:34:34.000000000 -0800
@@ -294,7 +294,7 @@
 					DRM_DEBUG("mtrr_del = %d\n", retcode);
 				}
 #endif
-				drm_ioremapfree(map->handle, map->size);
+				drm_ioremapfree(map->handle, map->size, dev);
 				break;
 			case _DRM_SHM:
 				drm_free_pages((unsigned long)map->handle,
diff -urN linux-2.4.24-pre1/drivers/char/drm-4.0/tdfx_drv.c linux-2.4.24-pre2/drivers/char/drm-4.0/tdfx_drv.c
--- linux-2.4.24-pre1/drivers/char/drm-4.0/tdfx_drv.c	2002-11-28 15:53:12.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/drm-4.0/tdfx_drv.c	2003-12-22 11:34:34.000000000 -0800
@@ -264,7 +264,7 @@
 					DRM_DEBUG("mtrr_del = %d\n", retcode);
 				}
 #endif
-				drm_ioremapfree(map->handle, map->size);
+				drm_ioremapfree(map->handle, map->size, dev);
 				break;
 			case _DRM_SHM:
 				drm_free_pages((unsigned long)map->handle,
diff -urN linux-2.4.24-pre1/drivers/char/ds1286.c linux-2.4.24-pre2/drivers/char/ds1286.c
--- linux-2.4.24-pre1/drivers/char/ds1286.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/ds1286.c	2003-12-22 11:34:34.000000000 -0800
@@ -173,7 +173,7 @@
 		 * means "don't care" or "match all". Only the tm_hour,
 		 * tm_min, and tm_sec values are filled in.
 		 */
-
+		memset(&wtime, 0, sizeof(struct rtc_time));
 		ds1286_get_alm_time(&wtime);
 		break;
 	}
@@ -216,6 +216,7 @@
 	}
 	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
 	{
+		memset(&wtime, 0, sizeof(struct rtc_time));
 		ds1286_get_time(&wtime);
 		break;
 	}
diff -urN linux-2.4.24-pre1/drivers/char/efirtc.c linux-2.4.24-pre2/drivers/char/efirtc.c
--- linux-2.4.24-pre1/drivers/char/efirtc.c	2003-06-13 07:51:32.000000000 -0700
+++ linux-2.4.24-pre2/drivers/char/efirtc.c	2003-12-22 11:34:34.000000000 -0800
@@ -118,6 +118,7 @@
 static void
 convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)
 {
+	memset(wtime, 0, sizeof(struct rtc_time));
 	wtime->tm_sec  = eft->second;
 	wtime->tm_min  = eft->minute;
 	wtime->tm_hour = eft->hour;
diff -urN linux-2.4.24-pre1/drivers/char/ip27-rtc.c linux-2.4.24-pre2/drivers/char/ip27-rtc.c
--- linux-2.4.24-pre1/drivers/char/ip27-rtc.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/char/ip27-rtc.c	2003-12-22 11:34:34.000000000 -0800
@@ -83,6 +83,7 @@
 	switch (cmd) {
 	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
 	{
+		memset(&wtime, 0, sizeof(struct rtc_time));
 		get_rtc_time(&wtime);
 		break;
 	}
@@ -225,8 +226,8 @@
 		return -ENOENT;
 	}
 
-
 	rtc_freq = 1024;
+
 	return 0;
 }
 
diff -urN linux-2.4.24-pre1/drivers/char/mips_rtc.c linux-2.4.24-pre2/drivers/char/mips_rtc.c
--- linux-2.4.24-pre1/drivers/char/mips_rtc.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/char/mips_rtc.c	2003-12-22 11:34:34.000000000 -0800
@@ -82,6 +82,7 @@
 
 	switch (cmd) {
 	case RTC_RD_TIME:	/* Read the time/date from RTC  */
+		memset(&rtc_tm, 0, sizeof(struct rtc_time));
 		curr_time = rtc_get_time();
 		to_tm(curr_time, &rtc_tm);
 		rtc_tm.tm_year -= 1900;
diff -urN linux-2.4.24-pre1/drivers/char/misc.c linux-2.4.24-pre2/drivers/char/misc.c
--- linux-2.4.24-pre1/drivers/char/misc.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/char/misc.c	2003-12-22 11:34:34.000000000 -0800
@@ -66,7 +66,6 @@
 static unsigned char misc_minors[DYNAMIC_MINORS / 8];
 
 extern int psaux_init(void);
-extern void gfx_register(void);
 extern int rtc_DP8570A_init(void);
 extern int rtc_MK48T08_init(void);
 extern int ds1286_init(void);
@@ -264,12 +263,6 @@
 #ifdef CONFIG_PMAC_PBOOK
 	pmu_device_init();
 #endif
-#ifdef CONFIG_SGI_NEWPORT_GFX
-	gfx_register ();
-#endif
-#ifdef CONFIG_SGI_NEWPORT_GFX
-	gfx_register ();
-#endif
 #ifdef CONFIG_TOSHIBA
 	tosh_init();
 #endif
diff -urN linux-2.4.24-pre1/drivers/char/rtc.c linux-2.4.24-pre2/drivers/char/rtc.c
--- linux-2.4.24-pre1/drivers/char/rtc.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/rtc.c	2003-12-22 11:34:34.000000000 -0800
@@ -376,7 +376,7 @@
 		 * means "don't care" or "match all". Only the tm_hour,
 		 * tm_min, and tm_sec values are filled in.
 		 */
-
+		memset(&wtime, 0, sizeof(struct rtc_time));
 		get_rtc_alm_time(&wtime);
 		break; 
 	}
@@ -420,6 +420,7 @@
 	}
 	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
 	{
+		memset(&wtime, 0, sizeof(struct rtc_time));
 		get_rtc_time(&wtime);
 		break;
 	}
diff -urN linux-2.4.24-pre1/drivers/char/vr41xx_keyb.c linux-2.4.24-pre2/drivers/char/vr41xx_keyb.c
--- linux-2.4.24-pre1/drivers/char/vr41xx_keyb.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/drivers/char/vr41xx_keyb.c	2003-12-22 11:34:34.000000000 -0800
@@ -0,0 +1,410 @@
+/*
+ * FILE NAME
+ *	drivers/char/vr41xx_keyb.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Keyboard driver for NEC VR4100 series Keyboard Interface Unit.
+ *
+ * Copyright (C) 1999 Bradley D. LaRonde
+ * Copyright (C) 1999 Hiroshi Kawashima <kawashima@iname.com>
+ * Copyright (C) 2000 Michael Klar <wyldfier@iname.com>
+ * Copyright (C) 2002,2003 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+/*
+ * Changes:
+ *  version 1.0
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>  Mon, 25 Mar 2002
+ *  -  Rewrote extensively because of 2.4.18.
+ *
+ *  version 1.1
+ *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>  Wed,  9 Sep 200
+ *  -  Added NEC VRC4173 KIU support.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kbd_ll.h>
+#ifdef CONFIG_PCI
+#include <linux/pci.h>
+#endif
+#include <linux/pm.h>
+
+#include <asm/addrspace.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/param.h>
+#include <asm/vr41xx/vr41xx.h>
+#ifdef CONFIG_VRC4173
+#include <asm/vr41xx/vrc4173.h>
+#endif
+
+#define KIU_BASE			KSEG1ADDR(0x0b000180)
+#define MKIUINTREG			KSEG1ADDR(0x0b000092)
+
+#define VRC4173_KIU_OFFSET		0x100
+#define VRC4173_MKIUINTREG_OFFSET	0x072
+
+#define KIUDAT0				0x00
+#define KIUDAT1				0x02
+#define KIUDAT2				0x04
+#define KIUDAT3				0x06
+#define KIUDAT4				0x08
+#define KIUDAT5				0x0a
+#define KIUDAT6				0x0c
+#define KIUDAT7				0x0e
+#define KIUSCANREP			0x10
+ #define KIUSCANREP_KEYEN		0x8000
+ #define KIUSCANREP_STPREP(x)		((x) << 4)
+ #define KIUSCANREP_SCANSTP		0x0008
+ #define KIUSCANREP_SCANSTART		0x0004
+ #define KIUSCANREP_ATSTP		0x0002
+ #define KIUSCANREP_ATSCAN		0x0001
+#define KIUSCANS			0x12
+ #define KIUSCANS_SCANNING		0x0003
+ #define KIUSCANS_INTERVAL		0x0002
+ #define KIUSCANS_WAITKEYIN		0x0001
+ #define KIUSCANS_STOPPED		0x0000
+#define KIUWKS				0x14
+ #define KIUWKS_T3CNT			0x7c00
+ #define KIUWKS_T3CNT_SHIFT		10
+ #define KIUWKS_T2CNT			0x03e0
+ #define KIUWKS_T2CNT_SHIFT		5
+ #define KIUWKS_T1CNT			0x001f
+ #define KIUWKS_T1CNT_SHIFT		0
+ #define KIUWKS_CNT_USEC(x)		(((x) / 30) - 1)
+#define KIUWKI				0x16
+ #define KIUWKI_INTERVAL_USEC(x)	((x) / 30)
+#define KIUINT				0x18
+ #define KIUINT_KDATLOST		0x0004
+ #define KIUINT_KDATRDY			0x0002
+ #define KIUINT_SCANINT			0x0001
+#define KIURST				0x1a
+ #define KIURST_KIURST			0x0001
+#define KIUGPEN				0x1c
+ #define KIUGPEN_KGPEN(x)		((uint16_t)1 << (x))
+#define SCANLINE			0x1e
+ #define SCANLINE_DONTUSE		0x0003
+ #define SCANLINE_8LINES		0x0002
+ #define SCANLINE_10LINES		0x0001
+ #define SCANLINE_12LINES		0x0000
+
+static unsigned long kiu_base;
+static unsigned long mkiuintreg;
+
+#ifdef CONFIG_VRC4173
+#define kiu_readw(offset)		vrc4173_inw(kiu_base + (offset))
+#define kiu_writew(val, offset)		vrc4173_outw(val, kiu_base + (offset))
+#define mkiuintreg_writew(val)		vrc4173_outw((val), mkiuintreg)
+#else
+#define kiu_readw(offset)		readw(kiu_base + (offset))
+#define kiu_writew(val, offset)		writew(val, kiu_base + (offset))
+#define mkiuintreg_writew(val)		writew((val), mkiuintreg)
+#endif
+
+#define KIU_CLOCK			0x0008
+
+#ifdef CONFIG_VRC4173
+#define KIU_IRQ				VRC4173_KIU_IRQ
+#else
+#define KIU_IRQ				SYSINT1_IRQ(7)
+#endif
+
+#define KEY_UP				0
+#define KEY_DOWN			1
+
+#define DEFAULT_KIUDAT_REGS		6
+#define DEFAULT_DATA_NOT_REVERSED	0
+#define DEFAULT_T3CNT			KIUWKS_CNT_USEC(200)
+#define DEFAULT_T2CNT			KIUWKS_CNT_USEC(200)
+#define DEFAULT_T1CNT			KIUWKS_CNT_USEC(200)
+#define DEFAULT_SCAN_INTERVAL		KIUWKI_INTERVAL_USEC(30000)
+#define DEFAULT_REPEAT_DELAY		HZ/4
+#define DEFAULT_REPEAT_RATE		HZ/25
+
+static char *kiu_driver_name = "Keyboard driver";
+static char *kiu_driver_version = "1.1";
+static char *kiu_driver_revdate = "2003-09-09";
+static char *kiu_driver_device_name = "NEC VR4100 series KIU";
+
+static unsigned char kiudat_regs = DEFAULT_KIUDAT_REGS;
+static unsigned char data_reverse = DEFAULT_DATA_NOT_REVERSED;
+static uint16_t scanlines = SCANLINE_12LINES;
+static uint16_t t3cnt = DEFAULT_T3CNT;
+static uint16_t t2cnt = DEFAULT_T2CNT;
+static uint16_t t1cnt = DEFAULT_T1CNT;
+static uint16_t scan_interval = DEFAULT_SCAN_INTERVAL;
+
+static unsigned long repeat_delay = DEFAULT_REPEAT_DELAY;
+static unsigned long repeat_rate = DEFAULT_REPEAT_RATE;
+
+static int repeat_scancode = -1;
+static unsigned long next_handle_time;
+
+struct kiudat_t {
+	uint32_t reg;
+	uint16_t data;
+};
+
+static struct kiudat_t kiudat [8] = {
+	{KIUDAT0, 0}, {KIUDAT1, 0},
+	{KIUDAT2, 0}, {KIUDAT3, 0},
+	{KIUDAT4, 0}, {KIUDAT5, 0},
+	{KIUDAT6, 0}, {KIUDAT7, 0},
+};
+
+int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+	return (scancode == keycode) ? 0 : -EINVAL;
+}
+
+int kbd_getkeycode(unsigned int scancode)
+{
+	return scancode;
+}
+
+int kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode)
+{
+	*keycode = scancode;
+	return 1;
+}
+
+char kbd_unexpected_up(unsigned char keycode)
+{
+	printk(KERN_WARNING "vr41xx_keyb: unexpected up, keycode 0x%02x\n", keycode);
+	return 0x80;
+}
+
+void kbd_leds(unsigned char leds)
+{
+	return;
+}
+
+static inline void handle_kiudat(uint16_t data, uint16_t cmp_data, int scancode)
+{
+	uint16_t mask;
+	int down, candidate_scancode = 0;
+
+	for (mask = 0x0001; mask ; mask <<= 1) {
+		if (cmp_data & mask) {
+			down = data & mask ? KEY_DOWN : KEY_UP;
+			if (down == KEY_DOWN) {
+				repeat_scancode = scancode;
+				next_handle_time = jiffies + repeat_delay;
+			}
+			else {
+				if (repeat_scancode == scancode)
+					repeat_scancode = -1;
+			}
+			handle_scancode(scancode, down);
+		}
+		if (data & mask) {
+			candidate_scancode = scancode;
+		}
+		scancode++;
+	}
+
+	if ((repeat_scancode < 0) && (candidate_scancode > 0)) {
+			repeat_scancode = candidate_scancode;
+			next_handle_time = jiffies + repeat_delay;
+	}
+}
+
+static inline void handle_kiu_event(void)
+{
+	struct kiudat_t *kiu = kiudat;
+	uint16_t data, last_data, cmp_data;
+	int i;
+
+	for (i = 0; i < kiudat_regs; i++) {
+		last_data = kiu->data;
+		data = kiu_readw(kiu->reg);
+		if (data_reverse)
+			data = ~data;
+		kiu->data = data;
+		cmp_data = data ^ last_data;
+		handle_kiudat(data, cmp_data, i * 16);
+		kiu++;
+	}
+
+	if ((repeat_scancode >= 0) &&
+	    (time_after_eq(jiffies, next_handle_time))) {
+		handle_scancode(repeat_scancode, KEY_DOWN);
+		next_handle_time = jiffies + repeat_rate;
+	}
+}
+
+static void kiu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	uint16_t status;
+
+	mkiuintreg_writew(0);
+
+	status = kiu_readw(KIUINT);
+	kiu_writew(KIUINT_KDATLOST | KIUINT_KDATRDY | KIUINT_SCANINT, KIUINT);
+
+	if (status & KIUINT_KDATRDY)
+		handle_kiu_event();
+
+	mkiuintreg_writew(KIUINT_KDATLOST | KIUINT_KDATRDY);
+}
+
+#ifdef CONFIG_PM
+
+static int pm_kiu_request(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+	switch (rqst) {
+	case PM_SUSPEND:
+		mkiuintreg_writew(KIUINT_SCANINT);
+		break;
+	case PM_RESUME:
+		kiu_writew(KIUINT_KDATLOST | KIUINT_KDATRDY | KIUINT_SCANINT, KIUINT);
+		mkiuintreg_writew(KIUINT_KDATLOST | KIUINT_KDATRDY, MKIUINTREG);
+		break;
+	}
+
+	return 0;
+}
+
+#endif
+
+void __devinit kbd_init_hw(void)
+{
+	uint16_t kiugpen = 0;
+	int i;
+
+	if (current_cpu_data.cputype == CPU_VR4111 ||
+	    current_cpu_data.cputype == CPU_VR4121) {
+		kiu_base = KIU_BASE;
+		mkiuintreg = MKIUINTREG;
+#if defined(CONFIG_PCI) && defined(CONFIG_VRC4173)
+	} else if (current_cpu_data.cputype == CPU_VR4122 ||
+	           current_cpu_data.cputype == CPU_VR4131) {
+		struct pci_dev *dev;
+		int found = 0;
+		dev = pci_find_device(PCI_VENDOR_ID_NEC,
+		                      PCI_DEVICE_ID_NEC_VRC4173, NULL);
+		if (dev != NULL) {
+			switch (scanlines) {
+			case SCANLINE_8LINES:
+				vrc4173_select_function(KIU8_SELECT);
+				found = 1;
+				break;
+			case SCANLINE_10LINES:
+				vrc4173_select_function(KIU10_SELECT);
+				found = 1;
+				break;
+			case SCANLINE_12LINES:
+				vrc4173_select_function(KIU12_SELECT);
+				found = 1;
+				break;
+			default:
+				break;
+			}
+
+			if (found != 0) {
+				kiu_base = VRC4173_KIU_OFFSET;
+				mkiuintreg = VRC4173_MKIUINTREG_OFFSET;
+				vrc4173_clock_supply(VRC4173_KIU_CLOCK);
+			}
+		}
+#endif
+	}
+
+	if (kiu_base == 0 || mkiuintreg == 0)
+		return;
+
+	printk(KERN_INFO "%s version %s (%s) for %s\n",
+	       kiu_driver_name, kiu_driver_version,
+	       kiu_driver_revdate, kiu_driver_device_name);
+
+	mkiuintreg_writew(0);
+
+	if (current_cpu_data.cputype == CPU_VR4111 ||
+	    current_cpu_data.cputype == CPU_VR4121)
+		vr41xx_clock_supply(KIU_CLOCK);
+
+	kiu_writew(KIURST_KIURST, KIURST);
+
+	for (i = 0; i < scanlines; i++)
+		kiugpen &= ~(0x0001 << i);
+
+	kiu_writew(kiugpen, KIUGPEN);
+	kiu_writew(scanlines, SCANLINE);
+	kiu_writew((t3cnt << KIUWKS_T3CNT_SHIFT) |
+	           (t2cnt << KIUWKS_T2CNT_SHIFT) |
+	           (t1cnt << KIUWKS_T1CNT_SHIFT), KIUWKS);
+	kiu_writew(scan_interval, KIUWKI);
+	kiu_writew(KIUINT_KDATLOST | KIUINT_KDATRDY | KIUINT_SCANINT, KIUINT);
+
+
+	request_irq(KIU_IRQ, kiu_interrupt, 0, "keyboard", NULL);
+
+	mkiuintreg_writew(KIUINT_KDATLOST | KIUINT_KDATRDY);
+	kiu_writew(KIUSCANREP_KEYEN | KIUSCANREP_STPREP(1) |
+	       KIUSCANREP_ATSTP | KIUSCANREP_ATSCAN, KIUSCANREP);
+
+#ifdef CONFIG_PM
+	pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_kiu_request);
+#endif
+}
+
+static int __devinit vr41xx_kbd_setup(char *options)
+{
+	char *this_opt;
+	int num;
+
+	if (!options || !*options)
+		return 1;
+
+	for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) {
+		if (!strncmp(this_opt, "regs:", 5)) {
+			num = simple_strtoul(this_opt+5, NULL, 0);
+			if (num == 6 || num == 8)
+				kiudat_regs = num;
+		} else if (!strncmp(this_opt, "lines:", 6)) {
+			num = simple_strtoul(this_opt+6, NULL, 0);
+			if (num == 8)
+				scanlines = SCANLINE_8LINES;
+			else if (num == 10)
+				scanlines = SCANLINE_10LINES;
+			else if (num == 12)
+				scanlines = SCANLINE_12LINES;
+		} else if (!strncmp(this_opt, "reverse:", 8)) {
+			num = simple_strtoul(this_opt+8, NULL, 0);
+			if (num == 0 || num == 1)
+				data_reverse = num;
+		} else if (!strncmp(this_opt, "t3cnt:", 6)) {
+			num = simple_strtoul(this_opt+6, NULL, 0);
+			if (num >= 60 && num <= 960)
+				t3cnt = KIUWKS_CNT_USEC(num);
+		} else if (!strncmp(this_opt, "t2cnt:", 6)) {
+			num = simple_strtoul(this_opt+6, NULL, 0);
+			if (num >= 60 && num <= 960)
+				t2cnt = KIUWKS_CNT_USEC(num);
+		} else if (!strncmp(this_opt, "t1cnt:", 6)) {
+			num = simple_strtoul(this_opt+6, NULL, 0);
+			if (num >= 60 && num <= 960)
+				t1cnt = KIUWKS_CNT_USEC(num);
+		} else if (!strncmp(this_opt, "interval:", 9)) {
+			num = simple_strtoul(this_opt+9, NULL, 0);
+			if (num >= 30 && num <= 30690)
+				scan_interval = KIUWKI_INTERVAL_USEC(num);
+		} else if (!strncmp(this_opt, "delay:", 6)) {
+			num = simple_strtoul(this_opt+6, NULL, 0);
+			if (num > 0 && num <= HZ)
+				repeat_delay = num;
+		} else if (!strncmp(this_opt, "rate:", 5)) {
+			num = simple_strtoul(this_opt+5, NULL, 0);
+			if (num > 0 && num <= HZ)
+				repeat_rate = num;
+		}
+	}
+
+	return 1;
+}
+
+__setup("vr41xx_kbd=", vr41xx_kbd_setup);
diff -urN linux-2.4.24-pre1/drivers/hil/hp_sdc_rtc.c linux-2.4.24-pre2/drivers/hil/hp_sdc_rtc.c
--- linux-2.4.24-pre1/drivers/hil/hp_sdc_rtc.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.24-pre2/drivers/hil/hp_sdc_rtc.c	2003-12-22 11:34:34.000000000 -0800
@@ -561,6 +561,7 @@
         }
         case RTC_ALM_READ:      /* Read the present alarm time */
         {
+		memset(&ttime, 0, sizeof(struct timeval));
 		if (hp_sdc_rtc_read_mt(&ttime)) return -EFAULT;
                 break;
         }
@@ -609,6 +610,7 @@
         }
         case RTC_RD_TIME:       /* Read the time/date from RTC  */
         {
+		memset(&wtime, 0, sizeof(struct rtc_time));
 		if (hp_sdc_rtc_read_bbrtc(&wtime)) return -EFAULT;
                 break;
         }
diff -urN linux-2.4.24-pre1/drivers/i2c/i2c-algo-bit.c linux-2.4.24-pre2/drivers/i2c/i2c-algo-bit.c
--- linux-2.4.24-pre1/drivers/i2c/i2c-algo-bit.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/i2c/i2c-algo-bit.c	2003-12-22 11:34:34.000000000 -0800
@@ -123,7 +123,7 @@
 		if (current->need_resched)
 			schedule();
 	}
-	DEBSTAT(printk("needed %ld jiffies\n", jiffies-start));
+	DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start));
 #ifdef SLO_IO
 	SLO_IO
 #endif
@@ -179,12 +179,12 @@
 	struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
 
 	/* assert: scl is low */
-	DEB2(printk(" i2c_outb:%2.2X\n",c&0xff));
+	DEB2(printk(KERN_DEBUG " i2c_outb:%2.2X\n",c&0xff));
 	for ( i=7 ; i>=0 ; i-- ) {
 		sb = c & ( 1 << i );
 		setsda(adap,sb);
 		udelay(adap->udelay);
-		DEBPROTO(printk("%d",sb!=0));
+		DEBPROTO(printk(KERN_DEBUG "%d",sb!=0));
 		if (sclhi(adap)<0) { /* timed out */
 			sdahi(adap); /* we don't want to block the net */
 			return -ETIMEDOUT;
@@ -201,10 +201,10 @@
 	};
 	/* read ack: SDA should be pulled down by slave */
 	ack=getsda(adap);	/* ack: sda is pulled low ->success.	 */
-	DEB2(printk(" i2c_outb: getsda() =  0x%2.2x\n", ~ack ));
+	DEB2(printk(KERN_DEBUG " i2c_outb: getsda() =  0x%2.2x\n", ~ack ));
 
-	DEBPROTO( printk("[%2.2x]",c&0xff) );
-	DEBPROTO(if (0==ack){ printk(" A ");} else printk(" NA ") );
+	DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) );
+	DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") );
 	scllo(adap);
 	return 0==ack;		/* return 1 if device acked	 */
 	/* assert: scl is low (sda undef) */
@@ -220,7 +220,7 @@
 	struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
 
 	/* assert: scl is low */
-	DEB2(printk("i2c_inb.\n"));
+	DEB2(printk(KERN_DEBUG "i2c_inb.\n"));
 
 	sdahi(adap);
 	for (i=0;i<8;i++) {
@@ -233,7 +233,7 @@
 		scllo(adap);
 	}
 	/* assert: scl is low */
-	DEBPROTO(printk(" %2.2x", indata & 0xff));
+	DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff));
 	return (int) (indata & 0xff);
 }
 
@@ -341,7 +341,7 @@
 		i2c_start(adap);
 		udelay(adap->udelay);
 	}
-	DEB2(if (i) printk("i2c-algo-bit.o: needed %d retries for %d\n",
+	DEB2(if (i) printk(KERN_DEBUG "i2c-algo-bit.o: needed %d retries for %d\n",
 	                   i,addr));
 	return ret;
 }
@@ -356,7 +356,7 @@
 
 	while (count > 0) {
 		c = *temp;
-		DEB2(printk("i2c-algo-bit.o: %s i2c_write: writing %2.2X\n",
+		DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: %s sendbytes: writing %2.2X\n",
 			    i2c_adap->name, c&0xff));
 		retval = i2c_outb(i2c_adap,c);
 		if (retval>0) {
@@ -364,7 +364,7 @@
 			temp++;
 			wrcount++;
 		} else { /* arbitration or no acknowledge */
-			printk("i2c-algo-bit.o: %s i2c_write: error - bailout.\n",
+			printk(KERN_ERR "i2c-algo-bit.o: %s sendbytes: error - bailout.\n",
 			       i2c_adap->name);
 			i2c_stop(adap);
 			return (retval<0)? retval : -EFAULT;
@@ -392,7 +392,7 @@
 			*temp = inval;
 			rdcount++;
 		} else {   /* read timed out */
-			printk("i2c-algo-bit.o: i2c_read: i2c_inb timed out.\n");
+			printk(KERN_ERR "i2c-algo-bit.o: readbytes: i2c_inb timed out.\n");
 			break;
 		}
 
@@ -405,7 +405,7 @@
 		}
 		if (sclhi(adap)<0) {	/* timeout */
 			sdahi(adap);
-			printk("i2c-algo-bit.o: i2c_read: Timeout at ack\n");
+			printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n");
 			return -ETIMEDOUT;
 		};
 		scllo(adap);
@@ -435,18 +435,18 @@
 	if ( (flags & I2C_M_TEN)  ) { 
 		/* a ten bit address */
 		addr = 0xf0 | (( msg->addr >> 7) & 0x03);
-		DEB2(printk("addr0: %d\n",addr));
+		DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
 		/* try extended address code...*/
 		ret = try_address(i2c_adap, addr, retries);
 		if (ret!=1) {
-			printk("died at extended address code.\n");
+			printk(KERN_ERR "died at extended address code.\n");
 			return -EREMOTEIO;
 		}
 		/* the remaining 8 bit address */
 		ret = i2c_outb(i2c_adap,msg->addr & 0x7f);
 		if (ret != 1) {
 			/* the chip did not ack / xmission error occurred */
-			printk("died at 2nd address code.\n");
+			printk(KERN_ERR "died at 2nd address code.\n");
 			return -EREMOTEIO;
 		}
 		if ( flags & I2C_M_RD ) {
@@ -455,7 +455,7 @@
 			addr |= 0x01;
 			ret = try_address(i2c_adap, addr, retries);
 			if (ret!=1) {
-				printk("died at extended address code.\n");
+				printk(KERN_ERR "died at extended address code.\n");
 				return -EREMOTEIO;
 			}
 		}
@@ -490,22 +490,22 @@
 			}
 			ret = bit_doAddress(i2c_adap,pmsg,i2c_adap->retries);
 			if (ret != 0) {
-				DEB2(printk("i2c-algo-bit.o: NAK from device adr %#2x msg #%d\n"
-				       ,msgs[i].addr,i));
+				DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n",
+					msgs[i].addr,i));
 				return (ret<0) ? ret : -EREMOTEIO;
 			}
 		}
 		if (pmsg->flags & I2C_M_RD ) {
 			/* read bytes into buffer*/
 			ret = readbytes(i2c_adap,pmsg->buf,pmsg->len);
-			DEB2(printk("i2c-algo-bit.o: read %d bytes.\n",ret));
+			DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret));
 			if (ret < pmsg->len ) {
 				return (ret<0)? ret : -EREMOTEIO;
 			}
 		} else {
 			/* write bytes from buffer */
 			ret = sendbytes(i2c_adap,pmsg->buf,pmsg->len);
-			DEB2(printk("i2c-algo-bit.o: wrote %d bytes.\n",ret));
+			DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret));
 			if (ret < pmsg->len ) {
 				return (ret<0) ? ret : -EREMOTEIO;
 			}
@@ -555,7 +555,7 @@
 			return -ENODEV;
 	}
 
-	DEB2(printk("i2c-algo-bit.o: hw routines for %s registered.\n",
+	DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: hw routines for %s registered.\n",
 	            adap->name));
 
 	/* register new adapter to i2c module... */
diff -urN linux-2.4.24-pre1/drivers/i2c/i2c-algo-pcf.c linux-2.4.24-pre2/drivers/i2c/i2c-algo-pcf.c
--- linux-2.4.24-pre1/drivers/i2c/i2c-algo-pcf.c	2001-10-11 08:05:47.000000000 -0700
+++ linux-2.4.24-pre2/drivers/i2c/i2c-algo-pcf.c	2003-12-22 11:34:34.000000000 -0800
@@ -99,7 +99,7 @@
 	}
 #endif
 	if (timeout <= 0) {
-		printk("Timeout waiting for Bus Busy\n");
+		printk(KERN_ERR "Timeout waiting for Bus Busy\n");
 	}
 	
 	return (timeout<=0);
@@ -144,7 +144,7 @@
 {
 	unsigned char temp;
 
-	DEB3(printk("i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
+	DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
 
 	/* S1=0x80: S0 selected, serial interface off */
 	set_pcf(adap, 1, I2C_PCF_PIN);
@@ -152,7 +152,7 @@
 	   PCF8584 does that when ESO is zero */
 	/* PCF also resets PIN bit */
 	if ((temp = get_pcf(adap, 1)) != (0)) {
-		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
+		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
 		return -ENXIO; /* definetly not PCF8584 */
 	}
 
@@ -160,7 +160,7 @@
 	i2c_outb(adap, get_own(adap));
 	/* check it's realy writen */
 	if ((temp = i2c_inb(adap)) != get_own(adap)) {
-		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
+		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
 		return -ENXIO;
 	}
 
@@ -168,7 +168,7 @@
 	set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
 	/* check to see S2 now selected */
 	if ((temp = get_pcf(adap, 1)) != I2C_PCF_ES1) {
-		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
+		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
 		return -ENXIO;
 	}
 
@@ -176,7 +176,7 @@
 	i2c_outb(adap, get_clock(adap));
 	/* check it's realy writen, the only 5 lowest bits does matter */
 	if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
-		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
+		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
 		return -ENXIO;
 	}
 
@@ -185,11 +185,11 @@
 
 	/* check to see PCF is realy idled and we can access status register */
 	if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
-		DEB2(printk("i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
+		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
 		return -ENXIO;
 	}
 	
-	printk("i2c-algo-pcf.o: deteted and initialized PCF8584.\n");
+	printk(KERN_DEBUG "i2c-algo-pcf.o: deteted and initialized PCF8584.\n");
 
 	return 0;
 }
@@ -215,7 +215,7 @@
 		i2c_stop(adap);
 		udelay(adap->udelay);
 	}
-	DEB2(if (i) printk("i2c-algo-pcf.o: needed %d retries for %d\n",i,
+	DEB2(if (i) printk(KERN_DEBUG "i2c-algo-pcf.o: needed %d retries for %d\n",i,
 	                   addr));
 	return ret;
 }
@@ -228,20 +228,20 @@
 	int wrcount, status, timeout;
     
 	for (wrcount=0; wrcount<count; ++wrcount) {
-		DEB2(printk("i2c-algo-pcf.o: %s i2c_write: writing %2.2X\n",
+		DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: %s i2c_write: writing %2.2X\n",
 		      i2c_adap->name, buf[wrcount]&0xff));
 		i2c_outb(adap, buf[wrcount]);
 		timeout = wait_for_pin(adap, &status);
 		if (timeout) {
 			i2c_stop(adap);
-			printk("i2c-algo-pcf.o: %s i2c_write: "
+			printk(KERN_ERR "i2c-algo-pcf.o: %s i2c_write: "
 			       "error - timeout.\n", i2c_adap->name);
 			return -EREMOTEIO; /* got a better one ?? */
 		}
 #ifndef STUB_I2C
 		if (status & I2C_PCF_LRB) {
 			i2c_stop(adap);
-			printk("i2c-algo-pcf.o: %s i2c_write: "
+			printk(KERN_ERR "i2c-algo-pcf.o: %s i2c_write: "
 			       "error - no ack.\n", i2c_adap->name);
 			return -EREMOTEIO; /* got a better one ?? */
 		}
@@ -269,14 +269,14 @@
 
 		if (wait_for_pin(adap, &status)) {
 			i2c_stop(adap);
-			printk("i2c-algo-pcf.o: pcf_readbytes timed out.\n");
+			printk(KERN_ERR "i2c-algo-pcf.o: pcf_readbytes timed out.\n");
 			return (-1);
 		}
 
 #ifndef STUB_I2C
 		if ((status & I2C_PCF_LRB) && (i != count)) {
 			i2c_stop(adap);
-			printk("i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n");
+			printk(KERN_ERR "i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n");
 			return (-1);
 		}
 #endif
@@ -312,18 +312,18 @@
 	if ( (flags & I2C_M_TEN)  ) { 
 		/* a ten bit address */
 		addr = 0xf0 | (( msg->addr >> 7) & 0x03);
-		DEB2(printk("addr0: %d\n",addr));
+		DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
 		/* try extended address code...*/
 		ret = try_address(adap, addr, retries);
 		if (ret!=1) {
-			printk("died at extended address code.\n");
+			printk(KERN_ERR "died at extended address code.\n");
 			return -EREMOTEIO;
 		}
 		/* the remaining 8 bit address */
 		i2c_outb(adap,msg->addr & 0x7f);
 /* Status check comes here */
 		if (ret != 1) {
-			printk("died at 2nd address code.\n");
+			printk(KERN_ERR "died at 2nd address code.\n");
 			return -EREMOTEIO;
 		}
 		if ( flags & I2C_M_RD ) {
@@ -332,7 +332,7 @@
 			addr |= 0x01;
 			ret = try_address(adap, addr, retries);
 			if (ret!=1) {
-				printk("died at extended address code.\n");
+				printk(KERN_ERR "died at extended address code.\n");
 				return -EREMOTEIO;
 			}
 		}
@@ -360,7 +360,7 @@
 	/* Check for bus busy */
 	timeout = wait_for_bb(adap);
 	if (timeout) {
-		DEB2(printk("i2c-algo-pcf.o: "
+		DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
 		            "Timeout waiting for BB in pcf_xfer\n");)
 		return -EIO;
 	}
@@ -368,7 +368,7 @@
 	for (i = 0;ret >= 0 && i < num; i++) {
 		pmsg = &msgs[i];
 
-		DEB2(printk("i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
+		DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
 		     pmsg->flags & I2C_M_RD ? "read" : "write",
                      pmsg->len, pmsg->addr, i + 1, num);)
     
@@ -383,7 +383,7 @@
 		timeout = wait_for_pin(adap, &status);
 		if (timeout) {
 			i2c_stop(adap);
-			DEB2(printk("i2c-algo-pcf.o: Timeout waiting "
+			DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting "
 				    "for PIN(1) in pcf_xfer\n");)
 			return (-EREMOTEIO);
 		}
@@ -392,12 +392,12 @@
 		/* Check LRB (last rcvd bit - slave ack) */
 		if (status & I2C_PCF_LRB) {
 			i2c_stop(adap);
-			DEB2(printk("i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
+			DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
 			return (-EREMOTEIO);
 		}
 #endif
     
-		DEB3(printk("i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
+		DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
 			    i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
     
 		/* Read */
@@ -407,20 +407,20 @@
                                             (i + 1 == num));
         
 			if (ret != pmsg->len) {
-				DEB2(printk("i2c-algo-pcf.o: fail: "
+				DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
 					    "only read %d bytes.\n",ret));
 			} else {
-				DEB2(printk("i2c-algo-pcf.o: read %d bytes.\n",ret));
+				DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));
 			}
 		} else { /* Write */
 			ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
                                             (i + 1 == num));
         
 			if (ret != pmsg->len) {
-				DEB2(printk("i2c-algo-pcf.o: fail: "
+				DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
 					    "only wrote %d bytes.\n",ret));
 			} else {
-				DEB2(printk("i2c-algo-pcf.o: wrote %d bytes.\n",ret));
+				DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret));
 			}
 		}
 	}
@@ -461,7 +461,7 @@
 	int i, status;
 	struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
 
-	DEB2(printk("i2c-algo-pcf.o: hw routines for %s registered.\n",
+	DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: hw routines for %s registered.\n",
 	            adap->name));
 
 	/* register new adapter to i2c module... */
diff -urN linux-2.4.24-pre1/drivers/i2c/i2c-core.c linux-2.4.24-pre2/drivers/i2c/i2c-core.c
--- linux-2.4.24-pre1/drivers/i2c/i2c-core.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/i2c/i2c-core.c	2003-12-22 11:34:34.000000000 -0800
@@ -188,7 +188,7 @@
 			drivers[j]->attach_adapter(adap);
 	DRV_UNLOCK();
 	
-	DEB(printk("i2c-core.o: adapter %s registered as adapter %d.\n",
+	DEB(printk(KERN_DEBUG "i2c-core.o: adapter %s registered as adapter %d.\n",
 	           adap->name,i));
 
 	return 0;	
@@ -214,7 +214,7 @@
 		if (adap == adapters[i])
 			break;
 	if (I2C_ADAP_MAX == i) {
-		printk( "i2c-core.o: unregister_adapter adap [%s] not found.\n",
+		printk(KERN_WARNING "i2c-core.o: unregister_adapter adap [%s] not found.\n",
 			adap->name);
 		res = -ENODEV;
 		goto ERROR0;
@@ -229,7 +229,7 @@
 	for (j = 0; j < I2C_DRIVER_MAX; j++) 
 		if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY))
 			if ((res = drivers[j]->attach_adapter(adap))) {
-				printk("i2c-core.o: can't detach adapter %s "
+				printk(KERN_WARNING "i2c-core.o: can't detach adapter %s "
 				       "while detaching driver %s: driver not "
 				       "detached!",adap->name,drivers[j]->name);
 				goto ERROR1;	
@@ -247,7 +247,7 @@
 		     * must be deleted, as this would cause invalid states.
 		     */
 			if ((res=client->driver->detach_client(client))) {
-				printk("i2c-core.o: adapter %s not "
+				printk(KERN_ERR "i2c-core.o: adapter %s not "
 					"unregistered, because client at "
 					"address %02x can't be detached. ",
 					adap->name, client->addr);
@@ -266,7 +266,7 @@
 	adap_count--;
 	
 	ADAP_UNLOCK();	
-	DEB(printk("i2c-core.o: adapter unregistered: %s\n",adap->name));
+	DEB(printk(KERN_DEBUG "i2c-core.o: adapter unregistered: %s\n",adap->name));
 	return 0;
 
 ERROR0:
@@ -305,7 +305,7 @@
 	
 	DRV_UNLOCK();	/* driver was successfully added */
 	
-	DEB(printk("i2c-core.o: driver %s registered.\n",driver->name));
+	DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name));
 	
 	ADAP_LOCK();
 
@@ -340,7 +340,7 @@
 	 * attached. If so, detach them to be able to kill the driver 
 	 * afterwards.
 	 */
-	DEB2(printk("i2c-core.o: unregister_driver - looking for clients.\n"));
+	DEB2(printk(KERN_DEBUG "i2c-core.o: unregister_driver - looking for clients.\n"));
 	/* removing clients does not depend on the notify flag, else 
 	 * invalid operation might (will!) result, when using stale client
 	 * pointers.
@@ -350,7 +350,7 @@
 		struct i2c_adapter *adap = adapters[k];
 		if (adap == NULL) /* skip empty entries. */
 			continue;
-		DEB2(printk("i2c-core.o: examining adapter %s:\n",
+		DEB2(printk(KERN_DEBUG "i2c-core.o: examining adapter %s:\n",
 			    adap->name));
 		if (driver->flags & I2C_DF_DUMMY) {
 		/* DUMMY drivers do not register their clients, so we have to
@@ -359,7 +359,7 @@
 		 * this or hell will break loose...  
 		 */
 			if ((res = driver->attach_adapter(adap))) {
-				printk("i2c-core.o: while unregistering "
+				printk(KERN_WARNING "i2c-core.o: while unregistering "
 				       "dummy driver %s, adapter %s could "
 				       "not be detached properly; driver "
 				       "not unloaded!",driver->name,
@@ -372,13 +372,13 @@
 				struct i2c_client *client = adap->clients[j];
 				if (client != NULL && 
 				    client->driver == driver) {
-					DEB2(printk("i2c-core.o: "
+					DEB2(printk(KERN_DEBUG "i2c-core.o: "
 						    "detaching client %s:\n",
 					            client->name));
 					if ((res = driver->
 							detach_client(client)))
 					{
-						printk("i2c-core.o: while "
+						printk(KERN_ERR "i2c-core.o: while "
 						       "unregistering driver "
 						       "`%s', the client at "
 						       "address %02x of "
@@ -400,7 +400,7 @@
 	driver_count--;
 	DRV_UNLOCK();
 	
-	DEB(printk("i2c-core.o: driver unregistered: %s\n",driver->name));
+	DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name));
 	return 0;
 }
 
@@ -436,10 +436,10 @@
 	
 	if (adapter->client_register) 
 		if (adapter->client_register(client)) 
-			printk("i2c-core.o: warning: client_register seems "
+			printk(KERN_DEBUG "i2c-core.o: warning: client_register seems "
 			       "to have failed for client %02x at adapter %s\n",
 			       client->addr,adapter->name);
-	DEB(printk("i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n",
+	DEB(printk(KERN_DEBUG "i2c-core.o: client [%s] registered to adapter [%s](pos. %d).\n",
 		client->name, adapter->name,i));
 
 	if(client->flags & I2C_CLIENT_ALLOW_USE)
@@ -470,7 +470,7 @@
 	
 	if (adapter->client_unregister != NULL) 
 		if ((res = adapter->client_unregister(client))) {
-			printk("i2c-core.o: client_unregister [%s] failed, "
+			printk(KERN_ERR "i2c-core.o: client_unregister [%s] failed, "
 			       "client not detached",client->name);
 			return res;
 		}
@@ -478,7 +478,7 @@
 	adapter->clients[i] = NULL;
 	adapter->client_count--;
 
-	DEB(printk("i2c-core.o: client [%s] unregistered.\n",client->name));
+	DEB(printk(KERN_DEBUG "i2c-core.o: client [%s] unregistered.\n",client->name));
 	return 0;
 }
 
@@ -727,7 +727,7 @@
  	} 
 	proc_bus_i2c = create_proc_entry("i2c",0,proc_bus);
 	if (!proc_bus_i2c) {
-		printk("i2c-core.o: Could not create /proc/bus/i2c");
+		printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c");
 		i2cproc_cleanup();
 		return -ENOENT;
  	}
@@ -764,7 +764,7 @@
 	int ret;
 
 	if (adap->algo->master_xfer) {
- 	 	DEB2(printk("i2c-core.o: master_xfer: %s with %d msgs.\n",
+ 	 	DEB2(printk(KERN_DEBUG "i2c-core.o: master_xfer: %s with %d msgs.\n",
 		            adap->name,num));
 
 		I2C_LOCK(adap);
@@ -773,7 +773,7 @@
 
 		return ret;
 	} else {
-		printk("i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
+		printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
 		       adap->id);
 		return -ENOSYS;
 	}
@@ -791,7 +791,7 @@
 		msg.len = count;
 		(const char *)msg.buf = buf;
 	
-		DEB2(printk("i2c-core.o: master_send: writing %d bytes on %s.\n",
+		DEB2(printk(KERN_DEBUG "i2c-core.o: master_send: writing %d bytes on %s.\n",
 			count,client->adapter->name));
 	
 		I2C_LOCK(adap);
@@ -803,7 +803,7 @@
 		 */
 		return (ret == 1 )? count : ret;
 	} else {
-		printk("i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
+		printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
 		       client->adapter->id);
 		return -ENOSYS;
 	}
@@ -821,14 +821,14 @@
 		msg.len = count;
 		msg.buf = buf;
 
-		DEB2(printk("i2c-core.o: master_recv: reading %d bytes on %s.\n",
+		DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: reading %d bytes on %s.\n",
 			count,client->adapter->name));
 	
 		I2C_LOCK(adap);
 		ret = adap->algo->master_xfer(adap,&msg,1);
 		I2C_UNLOCK(adap);
 	
-		DEB2(printk("i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n",
+		DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n",
 			ret, count, client->addr));
 	
 		/* if everything went ok (i.e. 1 msg transmitted), return #bytes
@@ -836,7 +836,7 @@
 	 	*/
 		return (ret == 1 )? count : ret;
 	} else {
-		printk("i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
+		printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
 		       client->adapter->id);
 		return -ENOSYS;
 	}
@@ -849,7 +849,7 @@
 	int ret = 0;
 	struct i2c_adapter *adap = client->adapter;
 
-	DEB2(printk("i2c-core.o: i2c ioctl, cmd: 0x%x, arg: %#lx\n", cmd, arg));
+	DEB2(printk(KERN_DEBUG "i2c-core.o: i2c ioctl, cmd: 0x%x, arg: %#lx\n", cmd, arg));
 	switch ( cmd ) {
 		case I2C_RETRIES:
 			adap->retries = arg;
@@ -894,7 +894,7 @@
 			if (((adap_id == address_data->force[i]) || 
 			     (address_data->force[i] == ANY_I2C_BUS)) &&
 			     (addr == address_data->force[i+1])) {
-				DEB2(printk("i2c-core.o: found force parameter for adapter %d, addr %04x\n",
+				DEB2(printk(KERN_DEBUG "i2c-core.o: found force parameter for adapter %d, addr %04x\n",
 				            adap_id,addr));
 				if ((err = found_proc(adapter,addr,0,0)))
 					return err;
@@ -912,7 +912,7 @@
 			if (((adap_id == address_data->ignore[i]) || 
 			    ((address_data->ignore[i] == ANY_I2C_BUS))) &&
 			    (addr == address_data->ignore[i+1])) {
-				DEB2(printk("i2c-core.o: found ignore parameter for adapter %d, "
+				DEB2(printk(KERN_DEBUG "i2c-core.o: found ignore parameter for adapter %d, "
 				     "addr %04x\n", adap_id ,addr));
 				found = 1;
 			}
@@ -924,7 +924,7 @@
 			    ((address_data->ignore_range[i]==ANY_I2C_BUS))) &&
 			    (addr >= address_data->ignore_range[i+1]) &&
 			    (addr <= address_data->ignore_range[i+2])) {
-				DEB2(printk("i2c-core.o: found ignore_range parameter for adapter %d, "
+				DEB2(printk(KERN_DEBUG "i2c-core.o: found ignore_range parameter for adapter %d, "
 				            "addr %04x\n", adap_id,addr));
 				found = 1;
 			}
@@ -939,7 +939,7 @@
 		     i += 1) {
 			if (addr == address_data->normal_i2c[i]) {
 				found = 1;
-				DEB2(printk("i2c-core.o: found normal i2c entry for adapter %d, "
+				DEB2(printk(KERN_DEBUG "i2c-core.o: found normal i2c entry for adapter %d, "
 				            "addr %02x", adap_id,addr));
 			}
 		}
@@ -950,7 +950,7 @@
 			if ((addr >= address_data->normal_i2c_range[i]) &&
 			    (addr <= address_data->normal_i2c_range[i+1])) {
 				found = 1;
-				DEB2(printk("i2c-core.o: found normal i2c_range entry for adapter %d, "
+				DEB2(printk(KERN_DEBUG "i2c-core.o: found normal i2c_range entry for adapter %d, "
 				            "addr %04x\n", adap_id,addr));
 			}
 		}
@@ -962,7 +962,7 @@
 			    ((address_data->probe[i] == ANY_I2C_BUS))) &&
 			    (addr == address_data->probe[i+1])) {
 				found = 1;
-				DEB2(printk("i2c-core.o: found probe parameter for adapter %d, "
+				DEB2(printk(KERN_DEBUG "i2c-core.o: found probe parameter for adapter %d, "
 				            "addr %04x\n", adap_id,addr));
 			}
 		}
@@ -974,7 +974,7 @@
 			   (addr >= address_data->probe_range[i+1]) &&
 			   (addr <= address_data->probe_range[i+2])) {
 				found = 1;
-				DEB2(printk("i2c-core.o: found probe_range parameter for adapter %d, "
+				DEB2(printk(KERN_DEBUG "i2c-core.o: found probe_range parameter for adapter %d, "
 				            "addr %04x\n", adap_id,addr));
 			}
 		}
@@ -1186,13 +1186,13 @@
 		break;
 	case I2C_SMBUS_BLOCK_DATA:
 		if (read_write == I2C_SMBUS_READ) {
-			printk("i2c-core.o: Block read not supported under "
-			       "I2C emulation!\n");
-		return -1;
+			printk(KERN_ERR "i2c-core.o: Block read not supported "
+			       "under I2C emulation!\n");
+			return -1;
 		} else {
 			msg[0].len = data->block[0] + 2;
 			if (msg[0].len > 34) {
-				printk("i2c-core.o: smbus_access called with "
+				printk(KERN_ERR "i2c-core.o: smbus_access called with "
 				       "invalid block write size (%d)\n",
 				       msg[0].len);
 				return -1;
@@ -1202,7 +1202,7 @@
 		}
 		break;
 	default:
-		printk("i2c-core.o: smbus_access called with invalid size (%d)\n",
+		printk(KERN_ERR "i2c-core.o: smbus_access called with invalid size (%d)\n",
 		       size);
 		return -1;
 	}
@@ -1264,7 +1264,7 @@
 
 static int __init i2c_init(void)
 {
-	printk(KERN_INFO "i2c-core.o: i2c core module\n");
+	printk(KERN_INFO "i2c-core.o: i2c core module version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	memset(adapters,0,sizeof(adapters));
 	memset(drivers,0,sizeof(drivers));
 	adap_count=0;
@@ -1427,9 +1427,10 @@
 #ifdef MODULE
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus main module");
+MODULE_LICENSE("GPL");
+
 MODULE_PARM(i2c_debug, "i");
 MODULE_PARM_DESC(i2c_debug,"debug level");
-MODULE_LICENSE("GPL");
 
 int init_module(void) 
 {
diff -urN linux-2.4.24-pre1/drivers/i2c/i2c-dev.c linux-2.4.24-pre2/drivers/i2c/i2c-dev.c
--- linux-2.4.24-pre1/drivers/i2c/i2c-dev.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.24-pre2/drivers/i2c/i2c-dev.c	2003-12-22 11:34:34.000000000 -0800
@@ -159,16 +159,16 @@
 
 	struct i2c_client *client = (struct i2c_client *)file->private_data;
 
-	if(count > 8192)
+	if (count > 8192)
 		count = 8192;
-		
+
 	/* copy user space data to kernel space. */
 	tmp = kmalloc(count,GFP_KERNEL);
 	if (tmp==NULL)
 		return -ENOMEM;
 
 #ifdef DEBUG
-	printk("i2c-dev.o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev),
+	printk(KERN_DEBUG "i2c-dev.o: i2c-%d reading %d bytes.\n",MINOR(inode->i_rdev),
 	       count);
 #endif
 
@@ -190,9 +190,9 @@
 	struct inode *inode = file->f_dentry->d_inode;
 #endif /* DEBUG */
 
-	if(count > 8192)
+	if (count > 8192)
 		count = 8192;
-		
+
 	/* copy user space data to kernel space. */
 	tmp = kmalloc(count,GFP_KERNEL);
 	if (tmp==NULL)
@@ -203,7 +203,7 @@
 	}
 
 #ifdef DEBUG
-	printk("i2c-dev.o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev),
+	printk(KERN_DEBUG "i2c-dev.o: i2c-%d writing %d bytes.\n",MINOR(inode->i_rdev),
 	       count);
 #endif
 	ret = i2c_master_send(client,tmp,count);
@@ -224,7 +224,7 @@
 	unsigned long funcs;
 
 #ifdef DEBUG
-	printk("i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", 
+	printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n", 
 	       MINOR(inode->i_rdev),cmd, arg);
 #endif /* DEBUG */
 
@@ -346,7 +346,7 @@
 		    (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
 		    (data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA)) {
 #ifdef DEBUG
-			printk("i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n",
+			printk(KERN_DEBUG "i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n",
 			       data_arg.size);
 #endif
 			return -EINVAL;
@@ -356,7 +356,7 @@
 		if ((data_arg.read_write != I2C_SMBUS_READ) && 
 		    (data_arg.read_write != I2C_SMBUS_WRITE)) {
 #ifdef DEBUG
-			printk("i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n",
+			printk(KERN_DEBUG "i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n",
 			       data_arg.read_write);
 #endif
 			return -EINVAL;
@@ -376,7 +376,7 @@
 
 		if (data_arg.data == NULL) {
 #ifdef DEBUG
-			printk("i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n");
+			printk(KERN_DEBUG "i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n");
 #endif
 			return -EINVAL;
 		}
@@ -418,7 +418,7 @@
 
 	if ((minor >= I2CDEV_ADAPS_MAX) || ! (i2cdev_adaps[minor])) {
 #ifdef DEBUG
-		printk("i2c-dev.o: Trying to open unattached adapter i2c-%d\n",
+		printk(KERN_DEBUG "i2c-dev.o: Trying to open unattached adapter i2c-%d\n",
 		       minor);
 #endif
 		return -ENODEV;
@@ -439,7 +439,7 @@
 #endif /* LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0) */
 
 #ifdef DEBUG
-	printk("i2c-dev.o: opened i2c-%d\n",minor);
+	printk(KERN_DEBUG "i2c-dev.o: opened i2c-%d\n",minor);
 #endif
 	return 0;
 }
@@ -450,7 +450,7 @@
 	kfree(file->private_data);
 	file->private_data=NULL;
 #ifdef DEBUG
-	printk("i2c-dev.o: Closed: i2c-%d\n", minor);
+	printk(KERN_DEBUG "i2c-dev.o: Closed: i2c-%d\n", minor);
 #endif
 #if LINUX_KERNEL_VERSION < KERNEL_VERSION(2,4,0)
 	MOD_DEC_USE_COUNT;
@@ -471,11 +471,11 @@
 	char name[8];
 
 	if ((i = i2c_adapter_id(adap)) < 0) {
-		printk("i2c-dev.o: Unknown adapter ?!?\n");
+		printk(KERN_DEBUG "i2c-dev.o: Unknown adapter ?!?\n");
 		return -ENODEV;
 	}
 	if (i >= I2CDEV_ADAPS_MAX) {
-		printk("i2c-dev.o: Adapter number too large?!? (%d)\n",i);
+		printk(KERN_DEBUG "i2c-dev.o: Adapter number too large?!? (%d)\n",i);
 		return -ENODEV;
 	}
 
@@ -488,7 +488,7 @@
 			S_IFCHR | S_IRUSR | S_IWUSR,
 			&i2cdev_fops, NULL);
 #endif
-		printk("i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i);
+		printk(KERN_DEBUG "i2c-dev.o: Registered '%s' as minor %d\n",adap->name,i);
 	} else {
 		/* This is actually a detach_adapter call! */
 #ifdef CONFIG_DEVFS_FS
@@ -496,7 +496,7 @@
 #endif
 		i2cdev_adaps[i] = NULL;
 #ifdef DEBUG
-		printk("i2c-dev.o: Adapter unregistered: %s\n",adap->name);
+		printk(KERN_DEBUG "i2c-dev.o: Adapter unregistered: %s\n",adap->name);
 #endif
 	}
 
@@ -518,7 +518,7 @@
 {
 	int res;
 
-	printk("i2c-dev.o: i2c /dev entries driver module\n");
+	printk(KERN_INFO "i2c-dev.o: i2c /dev entries driver module version %s (%s)\n", I2C_VERSION, I2C_DATE);
 
 	i2cdev_initialized = 0;
 #ifdef CONFIG_DEVFS_FS
@@ -526,7 +526,7 @@
 #else
 	if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) {
 #endif
-		printk("i2c-dev.o: unable to get major %d for i2c bus\n",
+		printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n",
 		       I2C_MAJOR);
 		return -EIO;
 	}
@@ -536,7 +536,7 @@
 	i2cdev_initialized ++;
 
 	if ((res = i2c_add_driver(&i2cdev_driver))) {
-		printk("i2c-dev.o: Driver registration failed, module not inserted.\n");
+		printk(KERN_ERR "i2c-dev.o: Driver registration failed, module not inserted.\n");
 		i2cdev_cleanup();
 		return res;
 	}
diff -urN linux-2.4.24-pre1/drivers/i2c/i2c-elektor.c linux-2.4.24-pre2/drivers/i2c/i2c-elektor.c
--- linux-2.4.24-pre1/drivers/i2c/i2c-elektor.c	2001-10-11 08:05:47.000000000 -0700
+++ linux-2.4.24-pre2/drivers/i2c/i2c-elektor.c	2003-12-22 11:34:34.000000000 -0800
@@ -78,7 +78,7 @@
 		val |= I2C_PCF_ENI;
 	}
 
-	DEB3(printk("i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
+	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
 
 	switch (mmapped) {
 	case 0: /* regular I/O */
@@ -99,7 +99,7 @@
 	int address = ctl ? (base + 1) : base;
 	int val = mmapped ? readb(address) : inb(address);
 
-	DEB3(printk("i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
+	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
 
 	return (val);
 }
@@ -142,7 +142,9 @@
 {
 	if (!mmapped) {
 		if (check_region(base, 2) < 0 ) {
-			printk("i2c-elektor.o: requested I/O region (0x%X:2) is in use.\n", base);
+			printk(KERN_ERR
+			       "i2c-elektor.o: requested I/O region (0x%X:2) "
+			       "is in use.\n", base);
 			return -ENODEV;
 		} else {
 			request_region(base, 2, "i2c (isa bus adapter)");
@@ -150,7 +152,7 @@
 	}
 	if (irq > 0) {
 		if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
-			printk("i2c-elektor.o: Request irq%d failed\n", irq);
+			printk(KERN_ERR "i2c-elektor.o: Request irq%d failed\n", irq);
 			irq = 0;
 		} else
 			enable_irq(irq);
@@ -238,7 +240,7 @@
 			/* yeap, we've found cypress, let's check config */
 			if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
 				
-				DEB3(printk("i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
+				DEB3(printk(KERN_DEBUG "i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
 
 				/* UP2000 board has this register set to 0xe1,
                                    but the most significant bit as seems can be 
@@ -260,7 +262,7 @@
 					   8.25 MHz (PCI/4) clock
 					   (this can be read from cypress) */
 					clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
-					printk("i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
+					printk(KERN_INFO "i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
 				}
 			}
 		}
@@ -269,11 +271,11 @@
 
 	/* sanity checks for mmapped I/O */
 	if (mmapped && base < 0xc8000) {
-		printk("i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
+		printk(KERN_ERR "i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
 		return -ENODEV;
 	}
 
-	printk("i2c-elektor.o: i2c pcf8584-isa adapter module\n");
+	printk(KERN_INFO "i2c-elektor.o: i2c pcf8584-isa adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
 
 	if (base == 0) {
 		base = DEFAULT_BASE;
@@ -289,7 +291,7 @@
 		return -ENODEV;
 	}
 	
-	printk("i2c-elektor.o: found device at %#x.\n", base);
+	printk(KERN_DEBUG "i2c-elektor.o: found device at %#x.\n", base);
 
 	return 0;
 }
diff -urN linux-2.4.24-pre1/drivers/i2c/i2c-elv.c linux-2.4.24-pre2/drivers/i2c/i2c-elv.c
--- linux-2.4.24-pre1/drivers/i2c/i2c-elv.c	2001-10-11 08:05:47.000000000 -0700
+++ linux-2.4.24-pre2/drivers/i2c/i2c-elv.c	2003-12-22 11:34:34.000000000 -0800
@@ -95,14 +95,14 @@
 	} else {
 						/* test for ELV adap. 	*/
 		if (inb(base+1) & 0x80) {	/* BUSY should be high	*/
-			DEBINIT(printk("i2c-elv.o: Busy was low.\n"));
+			DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n"));
 			return -ENODEV;
 		} else {
 			outb(0x0c,base+2);	/* SLCT auf low		*/
 			udelay(400);
 			if ( !(inb(base+1) && 0x10) ) {
 				outb(0x04,base+2);
-				DEBINIT(printk("i2c-elv.o: Select was high.\n"));
+				DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n"));
 				return -ENODEV;
 			}
 		}
@@ -170,7 +170,7 @@
 
 int __init i2c_bitelv_init(void)
 {
-	printk("i2c-elv.o: i2c ELV parallel port adapter module\n");
+	printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	if (base==0) {
 		/* probe some values */
 		base=DEFAULT_BASE;
@@ -190,7 +190,7 @@
 			return -ENODEV;
 		}
 	}
-	printk("i2c-elv.o: found device at %#x.\n",base);
+	printk(KERN_DEBUG "i2c-elv.o: found device at %#x.\n",base);
 	return 0;
 }
 
@@ -202,7 +202,6 @@
 MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter");
 MODULE_LICENSE("GPL");
 
-
 MODULE_PARM(base, "i");
 
 int init_module(void)
diff -urN linux-2.4.24-pre1/drivers/i2c/i2c-philips-par.c linux-2.4.24-pre2/drivers/i2c/i2c-philips-par.c
--- linux-2.4.24-pre1/drivers/i2c/i2c-philips-par.c	2001-09-30 12:26:05.000000000 -0700
+++ linux-2.4.24-pre2/drivers/i2c/i2c-philips-par.c	2003-12-22 11:34:34.000000000 -0800
@@ -190,18 +190,18 @@
 	struct i2c_par *adapter = kmalloc(sizeof(struct i2c_par),
 					  GFP_KERNEL);
 	if (!adapter) {
-		printk("i2c-philips-par: Unable to malloc.\n");
+		printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n");
 		return;
 	}
 
-	printk("i2c-philips-par.o: attaching to %s\n", port->name);
+	printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name);
 
 	adapter->pdev = parport_register_device(port, "i2c-philips-par",
 						NULL, NULL, NULL, 
 						PARPORT_FLAG_EXCL,
 						NULL);
 	if (!adapter->pdev) {
-		printk("i2c-philips-par: Unable to register with parport.\n");
+		printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n");
 		return;
 	}
 
@@ -218,7 +218,7 @@
 
 	if (i2c_bit_add_bus(&adapter->adapter) < 0)
 	{
-		printk("i2c-philips-par: Unable to register with I2C.\n");
+		printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n");
 		parport_unregister_device(adapter->pdev);
 		kfree(adapter);
 		return;		/* No good */
@@ -264,7 +264,7 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,4)
 	struct parport *port;
 #endif
-	printk("i2c-philips-par.o: i2c Philips parallel port adapter module\n");
+	printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,4)
 	parport_register_driver(&i2c_driver);
diff -urN linux-2.4.24-pre1/drivers/i2c/i2c-proc.c linux-2.4.24-pre2/drivers/i2c/i2c-proc.c
--- linux-2.4.24-pre1/drivers/i2c/i2c-proc.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.24-pre2/drivers/i2c/i2c-proc.c	2003-12-22 11:34:34.000000000 -0800
@@ -38,10 +38,6 @@
 
 #include <linux/init.h>
 
-/* FIXME need i2c versioning */
-#define LM_DATE "20010825"
-#define LM_VERSION "2.6.1"
-
 #ifndef THIS_MODULE
 #define THIS_MODULE NULL
 #endif
@@ -684,7 +680,7 @@
 				    && (addr == this_force->force[j + 1])) {
 #ifdef DEBUG
 					printk
-					    ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n",
+					    (KERN_DEBUG "i2c-proc.o: found force parameter for adapter %d, addr %04x\n",
 					     adapter_id, addr);
 #endif
 					if (
@@ -714,7 +710,7 @@
 			    && (addr == address_data->ignore[i + 1])) {
 #ifdef DEBUG
 				printk
-				    ("i2c-proc.o: found ignore parameter for adapter %d, "
+				    (KERN_DEBUG "i2c-proc.o: found ignore parameter for adapter %d, "
 				     "addr %04x\n", adapter_id, addr);
 #endif
 				found = 1;
@@ -734,7 +730,7 @@
 			    && (addr <= address_data->ignore_range[i + 2])) {
 #ifdef DEBUG
 				printk
-				    ("i2c-proc.o: found ignore_range parameter for adapter %d, "
+				    (KERN_DEBUG "i2c-proc.o: found ignore_range parameter for adapter %d, "
 				     "addr %04x\n", adapter_id, addr);
 #endif
 				found = 1;
@@ -753,7 +749,7 @@
 				if (addr == address_data->normal_isa[i]) {
 #ifdef DEBUG
 					printk
-					    ("i2c-proc.o: found normal isa entry for adapter %d, "
+					    (KERN_DEBUG "i2c-proc.o: found normal isa entry for adapter %d, "
 					     "addr %04x\n", adapter_id,
 					     addr);
 #endif
@@ -775,7 +771,7 @@
 				     0)) {
 #ifdef DEBUG
 					printk
-					    ("i2c-proc.o: found normal isa_range entry for adapter %d, "
+					    (KERN_DEBUG "i2c-proc.o: found normal isa_range entry for adapter %d, "
 					     "addr %04x", adapter_id, addr);
 #endif
 					found = 1;
@@ -789,7 +785,7 @@
 					found = 1;
 #ifdef DEBUG
 					printk
-					    ("i2c-proc.o: found normal i2c entry for adapter %d, "
+					    (KERN_DEBUG "i2c-proc.o: found normal i2c entry for adapter %d, "
 					     "addr %02x", adapter_id, addr);
 #endif
 				}
@@ -805,7 +801,7 @@
 				{
 #ifdef DEBUG
 					printk
-					    ("i2c-proc.o: found normal i2c_range entry for adapter %d, "
+					    (KERN_DEBUG "i2c-proc.o: found normal i2c_range entry for adapter %d, "
 					     "addr %04x\n", adapter_id, addr);
 #endif
 					found = 1;
@@ -822,7 +818,7 @@
 			    && (addr == address_data->probe[i + 1])) {
 #ifdef DEBUG
 				printk
-				    ("i2c-proc.o: found probe parameter for adapter %d, "
+				    (KERN_DEBUG "i2c-proc.o: found probe parameter for adapter %d, "
 				     "addr %04x\n", adapter_id, addr);
 #endif
 				found = 1;
@@ -841,7 +837,7 @@
 				found = 1;
 #ifdef DEBUG
 				printk
-				    ("i2c-proc.o: found probe_range parameter for adapter %d, "
+				    (KERN_DEBUG "i2c-proc.o: found probe_range parameter for adapter %d, "
 				     "addr %04x\n", adapter_id, addr);
 #endif
 			}
@@ -862,7 +858,7 @@
 
 int __init sensors_init(void)
 {
-	printk("i2c-proc.o version %s (%s)\n", LM_VERSION, LM_DATE);
+	printk(KERN_INFO "i2c-proc.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	i2c_initialized = 0;
 	if (!
 	    (i2c_proc_header =
diff -urN linux-2.4.24-pre1/drivers/i2c/i2c-velleman.c linux-2.4.24-pre2/drivers/i2c/i2c-velleman.c
--- linux-2.4.24-pre1/drivers/i2c/i2c-velleman.c	2001-10-11 08:05:47.000000000 -0700
+++ linux-2.4.24-pre2/drivers/i2c/i2c-velleman.c	2003-12-22 11:34:34.000000000 -0800
@@ -160,7 +160,7 @@
 
 int __init  i2c_bitvelle_init(void)
 {
-	printk("i2c-velleman.o: i2c Velleman K8000 adapter module\n");
+	printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	if (base==0) {
 		/* probe some values */
 		base=DEFAULT_BASE;
@@ -180,7 +180,7 @@
 			return -ENODEV;
 		}
 	}
-	printk("i2c-velleman.o: found device at %#x.\n",base);
+	printk(KERN_DEBUG "i2c-velleman.o: found device at %#x.\n",base);
 	return 0;
 }
 
diff -urN linux-2.4.24-pre1/drivers/input/Config.in linux-2.4.24-pre2/drivers/input/Config.in
--- linux-2.4.24-pre1/drivers/input/Config.in	2001-09-12 15:34:06.000000000 -0700
+++ linux-2.4.24-pre2/drivers/input/Config.in	2003-12-22 11:34:34.000000000 -0800
@@ -14,5 +14,6 @@
 fi
 dep_tristate '  Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_INPUT
 dep_tristate '  Event interface support' CONFIG_INPUT_EVDEV $CONFIG_INPUT
+dep_tristate '  User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT
 
 endmenu
diff -urN linux-2.4.24-pre1/drivers/input/Makefile linux-2.4.24-pre2/drivers/input/Makefile
--- linux-2.4.24-pre1/drivers/input/Makefile	2000-12-29 14:07:22.000000000 -0800
+++ linux-2.4.24-pre2/drivers/input/Makefile	2003-12-22 11:34:34.000000000 -0800
@@ -24,6 +24,7 @@
 obj-$(CONFIG_INPUT_MOUSEDEV)	+= mousedev.o
 obj-$(CONFIG_INPUT_JOYDEV)	+= joydev.o
 obj-$(CONFIG_INPUT_EVDEV)	+= evdev.o
+obj-$(CONFIG_INPUT_UINPUT)	+= uinput.o
 
 # The global Rules.make.
 
diff -urN linux-2.4.24-pre1/drivers/input/keybdev.c linux-2.4.24-pre2/drivers/input/keybdev.c
--- linux-2.4.24-pre1/drivers/input/keybdev.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.24-pre2/drivers/input/keybdev.c	2003-12-22 11:34:34.000000000 -0800
@@ -154,16 +154,18 @@
 
 static struct input_handler keybdev_handler;
 
+static unsigned int ledstate = 0xff;
+
 void keybdev_ledfunc(unsigned int led)
 {
 	struct input_handle *handle;	
 
-	for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
+	ledstate = led;
 
+	for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
 		input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01));
 		input_event(handle->dev, EV_LED, LED_NUML,    !!(led & 0x02));
 		input_event(handle->dev, EV_LED, LED_CAPSL,   !!(led & 0x04));
-
 	}
 }
 
@@ -202,7 +204,12 @@
 	input_open_device(handle);
 
 //	printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number);
-	kbd_refresh_leds();
+
+	if (ledstate != 0xff) {
+		input_event(dev, EV_LED, LED_SCROLLL, !!(ledstate & 0x01));
+		input_event(dev, EV_LED, LED_NUML,    !!(ledstate & 0x02));
+		input_event(dev, EV_LED, LED_CAPSL,   !!(ledstate & 0x04));
+	}
 
 	return handle;
 }
diff -urN linux-2.4.24-pre1/drivers/input/uinput.c linux-2.4.24-pre2/drivers/input/uinput.c
--- linux-2.4.24-pre1/drivers/input/uinput.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/drivers/input/uinput.c	2003-12-22 11:34:34.000000000 -0800
@@ -0,0 +1,428 @@
+/*
+ *  User level driver support for input subsystem
+ *
+ * Heavily based on evdev.c by Vojtech Pavlik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
+ * 
+ * Changes/Revisions:
+ *	0.1	20/06/2002
+ *		- first public version
+ */
+
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/smp_lock.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uinput.h>
+
+static int uinput_dev_open(struct input_dev *dev)
+{
+	return 0;
+}
+
+static void uinput_dev_close(struct input_dev *dev)
+{
+}
+
+static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+	struct uinput_device	*udev;
+
+	udev = (struct uinput_device *)dev->private;
+
+	udev->buff[udev->head].type = type;
+	udev->buff[udev->head].code = code;
+	udev->buff[udev->head].value = value;
+	do_gettimeofday(&udev->buff[udev->head].time);
+	udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
+
+	wake_up_interruptible(&udev->waitq);
+
+	return 0;
+}
+
+static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
+{
+	return 0;
+}
+
+static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
+{
+	return 0;
+}					
+
+static int uinput_create_device(struct uinput_device *udev)
+{
+	if (!udev->dev->name) {
+		printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
+		return -EINVAL;
+	}
+
+	udev->dev->open = uinput_dev_open;
+	udev->dev->close = uinput_dev_close;
+	udev->dev->event = uinput_dev_event;
+	udev->dev->upload_effect = uinput_dev_upload_effect;
+	udev->dev->erase_effect = uinput_dev_erase_effect;
+	udev->dev->private = udev;
+
+	init_waitqueue_head(&(udev->waitq));
+
+	input_register_device(udev->dev);
+
+	set_bit(UIST_CREATED, &(udev->state));
+
+	return 0;
+}
+
+static int uinput_destroy_device(struct uinput_device *udev)
+{
+	if (!test_bit(UIST_CREATED, &(udev->state))) {
+		printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
+		return -EINVAL;
+	}
+
+	input_unregister_device(udev->dev);
+
+	clear_bit(UIST_CREATED, &(udev->state));
+
+	return 0;
+}
+
+static int uinput_open(struct inode *inode, struct file *file)
+{
+	struct uinput_device	*newdev;
+	struct input_dev	*newinput;
+
+	newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
+	if (!newdev)
+		goto error;
+	memset(newdev, 0, sizeof(struct uinput_device));
+
+	newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
+	if (!newinput)
+		goto cleanup;
+	memset(newinput, 0, sizeof(struct input_dev));
+
+	newdev->dev = newinput;
+	
+	file->private_data = newdev;
+
+	return 0;
+cleanup:
+	kfree(newdev);
+error:
+	return -ENOMEM;
+}
+
+static int uinput_validate_absbits(struct input_dev *dev)
+{
+	unsigned int cnt;
+	int retval = 0;
+	
+	for (cnt = 0; cnt < ABS_MAX; cnt++) {
+		if (!test_bit(cnt, dev->absbit)) 
+			continue;
+		
+		if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
+		    (dev->absmax[cnt] <= dev->absmin[cnt])) {
+			printk(KERN_DEBUG 
+				"%s: invalid abs[%02x] min:%d max:%d\n",
+				UINPUT_NAME, cnt, 
+				dev->absmin[cnt], dev->absmax[cnt]);
+			retval = -EINVAL;
+			break;
+		}
+
+		if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
+		    (dev->absflat[cnt] > dev->absmax[cnt])) {
+			printk(KERN_DEBUG 
+				"%s: absflat[%02x] out of range: %d "
+				"(min:%d/max:%d)\n",
+				UINPUT_NAME, cnt, dev->absflat[cnt],
+				dev->absmin[cnt], dev->absmax[cnt]);
+			retval = -EINVAL;
+			break;
+		}
+	}
+	return retval;
+}
+
+static int uinput_alloc_device(struct file *file, const char *buffer, size_t count)
+{
+	struct uinput_user_dev	*user_dev;
+	struct input_dev	*dev;
+	struct uinput_device	*udev;
+	int			size,
+				retval;
+
+	retval = count;
+
+	udev = (struct uinput_device *)file->private_data;
+	dev = udev->dev;
+
+	user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL);
+	if (!user_dev) {
+		retval = -ENOMEM;
+		goto exit;
+	}
+
+	if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
+		retval = -EFAULT;
+		goto exit;
+	}
+
+	if (NULL != dev->name) 
+		kfree(dev->name);
+
+	size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
+	dev->name = kmalloc(size, GFP_KERNEL);
+	if (!dev->name) {
+		retval = -ENOMEM;
+		goto exit;
+	}
+
+	strncpy(dev->name, user_dev->name, size);
+	dev->idbus	= user_dev->idbus;
+	dev->idvendor	= user_dev->idvendor;
+	dev->idproduct	= user_dev->idproduct;
+	dev->idversion	= user_dev->idversion;
+	dev->ff_effects_max = user_dev->ff_effects_max;
+
+	size = sizeof(int) * (ABS_MAX + 1);
+	memcpy(dev->absmax, user_dev->absmax, size);
+	memcpy(dev->absmin, user_dev->absmin, size);
+	memcpy(dev->absfuzz, user_dev->absfuzz, size);
+	memcpy(dev->absflat, user_dev->absflat, size);
+
+	/* check if absmin/absmax/absfuzz/absflat are filled as
+	 * told in Documentation/input/input-programming.txt */
+	if (test_bit(EV_ABS, dev->evbit)) {
+		retval = uinput_validate_absbits(dev);
+		if (retval < 0)
+			kfree(dev->name);
+	}
+
+exit:
+	kfree(user_dev);
+	return retval;
+}
+
+static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+	struct uinput_device	*udev = file->private_data;
+	
+	if (test_bit(UIST_CREATED, &(udev->state))) {
+		struct input_event	ev;
+
+		if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
+			return -EFAULT;
+		input_event(udev->dev, ev.type, ev.code, ev.value);
+	}
+	else
+		count = uinput_alloc_device(file, buffer, count);
+
+	return count;
+}
+
+static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct uinput_device *udev = file->private_data;
+	int retval = 0;
+	
+	if (!test_bit(UIST_CREATED, &(udev->state)))
+		return -ENODEV;
+
+	if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK))
+		return -EAGAIN;
+
+	retval = wait_event_interruptible(udev->waitq,
+			(udev->head != udev->tail) || 
+			!test_bit(UIST_CREATED, &(udev->state)));
+	
+	if (retval)
+		return retval;
+
+	if (!test_bit(UIST_CREATED, &(udev->state)))
+		return -ENODEV;
+
+	while ((udev->head != udev->tail) && 
+	    (retval + sizeof(struct input_event) <= count)) {
+		if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
+		    sizeof(struct input_event))) return -EFAULT;
+		udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
+		retval += sizeof(struct input_event);
+	}
+
+	return retval;
+}
+
+static unsigned int uinput_poll(struct file *file, poll_table *wait)
+{
+	struct uinput_device *udev = file->private_data;
+
+	poll_wait(file, &udev->waitq, wait);
+
+	if (udev->head != udev->tail)
+		return POLLIN | POLLRDNORM;
+
+	return 0;			
+}
+
+static int uinput_burn_device(struct uinput_device *udev)
+{
+	if (test_bit(UIST_CREATED, &(udev->state)))
+		uinput_destroy_device(udev);
+
+	kfree(udev->dev);
+	kfree(udev);
+
+	return 0;
+}
+
+static int uinput_close(struct inode *inode, struct file *file)
+{
+	return uinput_burn_device((struct uinput_device *)file->private_data);
+}
+
+static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int			retval = 0;
+	struct uinput_device	*udev;
+
+	udev = (struct uinput_device *)file->private_data;
+
+	/* device attributes can not be changed after the device is created */
+	if (cmd >= UI_SET_EVBIT && test_bit(UIST_CREATED, &(udev->state)))
+		return -EINVAL;
+
+	switch (cmd) {
+		case UI_DEV_CREATE:
+			retval = uinput_create_device(udev);
+			break;
+			
+		case UI_DEV_DESTROY:
+			retval = uinput_destroy_device(udev);
+			break;
+
+		case UI_SET_EVBIT:
+			if (arg > EV_MAX) {
+				retval = -EINVAL;
+				break;
+			}
+			set_bit(arg, udev->dev->evbit);
+			break;
+			
+		case UI_SET_KEYBIT:
+			if (arg > KEY_MAX) {
+				retval = -EINVAL;
+				break;
+			}
+			set_bit(arg, udev->dev->keybit);
+			break;
+			
+		case UI_SET_RELBIT:
+			if (arg > REL_MAX) {
+				retval = -EINVAL;
+				break;
+			}
+			set_bit(arg, udev->dev->relbit);
+			break;
+			
+		case UI_SET_ABSBIT:
+			if (arg > ABS_MAX) {
+				retval = -EINVAL;
+				break;
+			}
+			set_bit(arg, udev->dev->absbit);
+			break;
+			
+		case UI_SET_MSCBIT:
+			if (arg > MSC_MAX) {
+				retval = -EINVAL;
+				break;
+			}
+			set_bit(arg, udev->dev->mscbit);
+			break;
+			
+		case UI_SET_LEDBIT:
+			if (arg > LED_MAX) {
+				retval = -EINVAL;
+				break;
+			}
+			set_bit(arg, udev->dev->ledbit);
+			break;
+			
+		case UI_SET_SNDBIT:
+			if (arg > SND_MAX) {
+				retval = -EINVAL;
+				break;
+			}
+			set_bit(arg, udev->dev->sndbit);
+			break;
+			
+		case UI_SET_FFBIT:
+			if (arg > FF_MAX) {
+				retval = -EINVAL;
+				break;
+			}
+			set_bit(arg, udev->dev->ffbit);
+			break;
+			
+		default:
+			retval = -EFAULT;
+	}
+	return retval;
+}
+
+struct file_operations uinput_fops = {
+	owner:		THIS_MODULE,
+	open:		uinput_open,
+	release:	uinput_close,
+	read:		uinput_read,
+	write:		uinput_write,
+	poll:		uinput_poll,
+	ioctl:		uinput_ioctl,
+};
+
+static struct miscdevice uinput_misc = {
+	fops:		&uinput_fops,
+	minor:		UINPUT_MINOR,
+	name:		UINPUT_NAME,
+};
+
+static int __init uinput_init(void)
+{
+	return misc_register(&uinput_misc);
+}
+
+static void __exit uinput_exit(void)
+{
+	misc_deregister(&uinput_misc);
+}
+
+MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
+MODULE_DESCRIPTION("User level driver support for input subsystem");
+MODULE_LICENSE("GPL");
+
+module_init(uinput_init);
+module_exit(uinput_exit);
+
diff -urN linux-2.4.24-pre1/drivers/macintosh/rtc.c linux-2.4.24-pre2/drivers/macintosh/rtc.c
--- linux-2.4.24-pre1/drivers/macintosh/rtc.c	2002-02-25 11:37:58.000000000 -0800
+++ linux-2.4.24-pre2/drivers/macintosh/rtc.c	2003-12-22 11:34:34.000000000 -0800
@@ -64,6 +64,7 @@
 	case RTC_RD_TIME:
 		if (ppc_md.get_rtc_time)
 		{
+			memset(&rtc_tm, 0, sizeof(struct rtc_time));
 			get_rtc_time(&rtc_tm);
 
 			if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
diff -urN linux-2.4.24-pre1/drivers/md/raid1.c linux-2.4.24-pre2/drivers/md/raid1.c
--- linux-2.4.24-pre1/drivers/md/raid1.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.24-pre2/drivers/md/raid1.c	2003-12-22 11:34:35.000000000 -0800
@@ -1436,7 +1436,7 @@
 	block_nr = sector_nr;
 	bsize = 512;
 	while (!(block_nr & 1) && bsize < PAGE_SIZE
-			&& (block_nr+2)*(bsize>>9) < (mddev->sb->size *2)) {
+			&& (block_nr+2)*(bsize>>9) <= (mddev->sb->size *2)) {
 		block_nr >>= 1;
 		bsize <<= 1;
 	}
diff -urN linux-2.4.24-pre1/drivers/media/video/saa7110.c linux-2.4.24-pre2/drivers/media/video/saa7110.c
--- linux-2.4.24-pre1/drivers/media/video/saa7110.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/media/video/saa7110.c	2003-12-22 11:34:35.000000000 -0800
@@ -404,7 +404,7 @@
 {
 	"saa7110",			/* name */
 
-	I2C_DRIVERID_VIDEODECODER,	/* in i2c.h */
+	I2C_DRIVERID_VIDEODECODER,	/* in i2c-old.h */
 	I2C_SAA7110, I2C_SAA7110+1,	/* Addr range */
 
 	saa7110_attach,
diff -urN linux-2.4.24-pre1/drivers/net/8139too.c linux-2.4.24-pre2/drivers/net/8139too.c
--- linux-2.4.24-pre1/drivers/net/8139too.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/8139too.c	2003-12-22 11:34:35.000000000 -0800
@@ -116,6 +116,11 @@
 #define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION
 #define PFX DRV_NAME ": "
 
+/* Default Message level */
+#define RTL8139_DEF_MSG_ENABLE   (NETIF_MSG_DRV   | \
+                                 NETIF_MSG_PROBE  | \
+                                 NETIF_MSG_LINK)
+
 
 /* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */
 #ifdef CONFIG_8139TOO_PIO
@@ -559,6 +564,7 @@
 	int drv_flags;
 	struct pci_dev *pci_dev;
 	u32 pci_state[16];
+	u32 msg_enable;
 	struct net_device_stats stats;
 	unsigned char *rx_ring;
 	unsigned int cur_rx;	/* Index into the Rx buffer of next Rx pkt. */
@@ -984,6 +990,8 @@
 	/* note: tp->chipset set in rtl8139_init_board */
 	tp->drv_flags = board_info[ent->driver_data].hw_flags;
 	tp->mmio_addr = ioaddr;
+	tp->msg_enable =
+		(debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
 	spin_lock_init (&tp->lock);
 	init_waitqueue_head (&tp->thr_wait);
 	init_completion (&tp->thr_exited);
@@ -1286,9 +1294,7 @@
 {
 	struct rtl8139_private *tp = dev->priv;
 	int retval;
-#ifdef RTL8139_DEBUG
 	void *ioaddr = tp->mmio_addr;
-#endif
 
 	retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
 	if (retval)
@@ -1318,7 +1324,8 @@
 	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
 
-	DPRINTK ("%s: rtl8139_open() ioaddr %#lx IRQ %d"
+	if (netif_msg_ifup(tp))
+		printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d"
 			" GP Pins %2.2x %s-duplex.\n",
 			dev->name, pci_resource_start (tp->pci_dev, 1),
 			dev->irq, RTL_R8 (MediaStatus),
@@ -1335,7 +1342,7 @@
 	struct rtl8139_private *tp = dev->priv;
 
 	if (tp->phys[0] >= 0) {
-		mii_check_media(&tp->mii, 1, init_media);
+		mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
 	}
 }
 
@@ -1724,8 +1731,9 @@
 		netif_stop_queue (dev);
 	spin_unlock_irq(&tp->lock);
 
-	DPRINTK ("%s: Queued Tx packet size %u to slot %d.\n",
-		 dev->name, len, entry);
+	if (netif_msg_tx_queued(tp))
+		printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
+			dev->name, len, entry);
 
 	return 0;
 }
@@ -1755,8 +1763,9 @@
 		/* Note: TxCarrierLost is always asserted at 100mbps. */
 		if (txstatus & (TxOutOfWindow | TxAborted)) {
 			/* There was an major error, log it. */
-			DPRINTK ("%s: Transmit error, Tx status %8.8x.\n",
-				 dev->name, txstatus);
+			if (netif_msg_tx_err(tp))
+				printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
+					dev->name, txstatus);
 			tp->stats.tx_errors++;
 			if (txstatus & TxAborted) {
 				tp->stats.tx_aborted_errors++;
@@ -1811,8 +1820,9 @@
 	int tmp_work;
 #endif
 
-	DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
-	         dev->name, rx_status);
+	if (netif_msg_rx_err (tp)) 
+		printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
+			dev->name, rx_status);
 	tp->stats.rx_errors++;
 	if (!(rx_status & RxStatusOK)) {
 		if (rx_status & RxTooLong) {
@@ -1916,8 +1926,9 @@
 		rx_size = rx_status >> 16;
 		pkt_size = rx_size - 4;
 
-		DPRINTK ("%s:  rtl8139_rx() status %4.4x, size %4.4x,"
-			 " cur %4.4x.\n", dev->name, rx_status,
+		if (netif_msg_rx_status(tp))
+			printk(KERN_DEBUG "%s:  rtl8139_rx() status %4.4x, size %4.4x,"
+				" cur %4.4x.\n", dev->name, rx_status,
 			 rx_size, cur_rx);
 #if RTL8139_DEBUG > 2
 		{
@@ -2078,8 +2089,9 @@
 		ackstat = status & ~(RxAckBits | TxErr);
 		RTL_W16 (IntrStatus, ackstat);
 
-		DPRINTK ("%s: interrupt  status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n",
-			 dev->name, status, ackstat, RTL_R16 (IntrStatus));
+		if (netif_msg_intr(tp))
+			printk (KERN_DEBUG "%s: interrupt  status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n",
+				dev->name, status, ackstat, RTL_R16 (IntrStatus));
 
 		if (netif_running (dev) && (status & RxAckBits))
 			rtl8139_rx_interrupt (dev, tp, ioaddr);
@@ -2134,8 +2146,9 @@
 		}
 		wait_for_completion (&tp->thr_exited);
 	}
-
-	DPRINTK ("%s: Shutting down ethercard, status was 0x%4.4x.\n",
+	
+	if (netif_msg_ifdown(tp))
+		printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
 			dev->name, RTL_R16 (IntrStatus));
 
 	spin_lock_irqsave (&tp->lock, flags);
@@ -2293,12 +2306,14 @@
 
 static u32 rtl8139_get_msglevel(struct net_device *dev)
 {
-	return debug;
+	struct rtl8139_private *np = dev->priv;
+	return np->msg_enable;
 }
 
 static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
 {
-	debug = datum;
+	struct rtl8139_private *np = dev->priv;
+	np->msg_enable = datum;
 }
 
 /* TODO: we are too slack to do reg dumping for pio, for now */
diff -urN linux-2.4.24-pre1/drivers/net/Makefile.lib linux-2.4.24-pre2/drivers/net/Makefile.lib
--- linux-2.4.24-pre1/drivers/net/Makefile.lib	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.24-pre2/drivers/net/Makefile.lib	2003-12-22 11:34:35.000000000 -0800
@@ -34,6 +34,7 @@
 obj-$(CONFIG_VIA_RHINE)		+= crc32.o
 obj-$(CONFIG_WINBOND_840)	+= crc32.o
 obj-$(CONFIG_YELLOWFIN)		+= crc32.o
+obj-$(CONFIG_NATSEMI)		+= crc32.o
 
 # These rely on drivers/net/7990.o which requires crc32.o
 obj-$(CONFIG_HPLANCE)		+= crc32.o	
diff -urN linux-2.4.24-pre1/drivers/net/de4x5.c linux-2.4.24-pre2/drivers/net/de4x5.c
--- linux-2.4.24-pre1/drivers/net/de4x5.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.24-pre2/drivers/net/de4x5.c	2003-12-22 11:34:35.000000000 -0800
@@ -999,7 +999,7 @@
 static void    srom_repair(struct net_device *dev, int card);
 static int     test_bad_enet(struct net_device *dev, int status);
 static int     an_exception(struct de4x5_bus_type *lp);
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
+#ifdef CONFIG_EISA
 static void    eisa_probe(struct net_device *dev, u_long iobase);
 #endif
 static void    pci_probe(struct net_device *dev, u_long iobase);
@@ -1053,7 +1053,7 @@
 #endif /* MODULE */
 
 static char name[DE4X5_NAME_LENGTH + 1];
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
+#ifdef CONFIG_EISA
 static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
 static int lastEISA;
 #  ifdef DE4X5_FORCE_EISA                 /* Force an EISA bus probe or not */
@@ -1131,7 +1131,7 @@
     u_long iobase = dev->base_addr;
 
     pci_probe(dev, iobase);
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
+#ifdef CONFIG_EISA
     if ((lastPCI == NO_MORE_PCI) && ((num_de4x5s == 0) || forceEISA)) {
         eisa_probe(dev, iobase);
     }
@@ -2093,7 +2093,7 @@
     return;
 }
 
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
+#ifdef CONFIG_EISA
 /*
 ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
 ** the motherboard. Upto 15 EISA devices are supported.
@@ -5363,7 +5363,7 @@
 	t = *q;
 	*q = '\0';
 
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
+#ifdef CONFIG_EISA
 	if (strstr(p, "force_eisa") || strstr(p, "FORCE_EISA")) forceEISA = 1;
 #endif
 	if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = 1;
@@ -5865,7 +5865,7 @@
     u_int class = DE4X5_CLASS_CODE;
     u_int device;
 
-#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
+#ifdef CONFIG_EISA
     char name[DE4X5_STRLEN];
     u_long iobase = 0x1000;
 
diff -urN linux-2.4.24-pre1/drivers/net/ioc3-eth.c linux-2.4.24-pre2/drivers/net/ioc3-eth.c
--- linux-2.4.24-pre1/drivers/net/ioc3-eth.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/ioc3-eth.c	2003-12-22 11:34:35.000000000 -0800
@@ -1461,11 +1461,11 @@
 #endif
 
 	spin_lock_init(&ip->ioc3_lock);
+	init_timer(&ip->ioc3_timer);
 
 	ioc3_stop(ip);
 	ioc3_init(ip);
 
-	init_timer(&ip->ioc3_timer);
 	ioc3_mii_init(ip);
 
 	if (ip->phy == -1) {
diff -urN linux-2.4.24-pre1/drivers/net/natsemi.c linux-2.4.24-pre2/drivers/net/natsemi.c
--- linux-2.4.24-pre1/drivers/net/natsemi.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/natsemi.c	2003-12-22 11:34:35.000000000 -0800
@@ -164,6 +164,7 @@
 #include <linux/delay.h>
 #include <linux/rtnetlink.h>
 #include <linux/mii.h>
+#include <linux/crc32.h>
 #include <asm/processor.h>	/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -365,7 +366,7 @@
 	{ "NatSemi DP8381[56]", PCI_IOTYPE },
 };
 
-static struct pci_device_id natsemi_pci_tbl[] __devinitdata = {
+static struct pci_device_id natsemi_pci_tbl[] = {
 	{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0, },
 };
@@ -695,7 +696,7 @@
 static void reinit_ring(struct net_device *dev);
 static void init_registers(struct net_device *dev);
 static int start_tx(struct sk_buff *skb, struct net_device *dev);
-static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
 static void netdev_error(struct net_device *dev, int intr_status);
 static void netdev_rx(struct net_device *dev);
 static void netdev_tx_done(struct net_device *dev);
@@ -763,19 +764,13 @@
 	SET_MODULE_OWNER(dev);
 
 	i = pci_request_regions(pdev, dev->name);
-	if (i) {
-		kfree(dev);
-		return i;
-	}
+	if (i)
+		goto err_pci_request_regions;
 
-	{
-		void *mmio = ioremap (ioaddr, iosize);
-		if (!mmio) {
-			pci_release_regions(pdev);
-			kfree(dev);
-			return -ENOMEM;
-		}
-		ioaddr = (unsigned long) mmio;
+	ioaddr = (unsigned long) ioremap (ioaddr, iosize);
+	if (!ioaddr) {
+		i = -ENOMEM;
+		goto err_ioremap;
 	}
 
 	/* Work around the dropped serial bit. */
@@ -833,13 +828,9 @@
 		dev->mtu = mtu;
 
 	i = register_netdev(dev);
-	if (i) {
-		pci_release_regions(pdev);
-		unregister_netdev(dev);
-		kfree(dev);
-		pci_set_drvdata(pdev, NULL);
-		return i;
-	}
+	if (i)
+		goto err_register_netdev;
+
 	netif_carrier_off(dev);
 
 	if (netif_msg_drv(np)) {
@@ -876,6 +867,17 @@
 
 
 	return 0;
+
+ err_register_netdev:
+	iounmap ((void *) dev->base_addr);
+
+ err_ioremap:
+	pci_release_regions(pdev);
+	pci_set_drvdata(pdev, NULL);
+
+ err_pci_request_regions:
+	free_netdev(dev);
+	return i;
 }
 
 
@@ -1679,15 +1681,16 @@
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
 {
 	struct net_device *dev = dev_instance;
 	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 	int boguscnt = max_interrupt_work;
+	unsigned int handled = 0;
 
 	if (np->hands_off)
-		return;
+		return IRQ_NONE;
 	do {
 		/* Reading automatically acknowledges all int sources. */
 		u32 intr_status = readl(ioaddr + IntrStatus);
@@ -1700,6 +1703,7 @@
 
 		if (intr_status == 0)
 			break;
+		handled = 1;
 
 		if (intr_status &
 		   (IntrRxDone | IntrRxIntr | RxStatusFIFOOver |
@@ -1730,6 +1734,8 @@
 
 	if (netif_msg_intr(np))
 		printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name);
+
+	return IRQ_RETVAL(handled);
 }
 
 /* This routine is logically part of the interrupt handler, but separated
@@ -1898,44 +1904,6 @@
 	return &np->stats;
 }
 
-/**
- * dp83815_crc - computer CRC for hash table entries
- *
- * Note - this is, for some reason, *not* the same function
- * as ether_crc_le() or ether_crc(), though it uses the
- * same big-endian polynomial.
- */
-#define DP_POLYNOMIAL			0x04C11DB7
-static unsigned dp83815_crc(int length, unsigned char *data)
-{
-	u32 crc;
-	u8 cur_byte;
-	u8 msb;
-	u8 byte, bit;
-
-	crc = ~0;
-	for (byte=0; byte<length; byte++) {
-		cur_byte = *data++;
-		for (bit=0; bit<8; bit++) {
-			msb = crc >> 31;
-			crc <<= 1;
-			if (msb ^ (cur_byte & 1)) {
-				crc ^= DP_POLYNOMIAL;
-				crc |= 1;
-			}
-			cur_byte >>= 1;
-		}
-	}
-	crc >>= 23;
-
-	return (crc);
-}
-
-
-void set_bit_le(int offset, unsigned char * data)
-{
-	data[offset >> 3] |= (1 << (offset & 0x07));
-}
 #define HASH_TABLE	0x200
 static void __set_rx_mode(struct net_device *dev)
 {
@@ -1960,9 +1928,8 @@
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			set_bit_le(
-				dp83815_crc(ETH_ALEN, mclist->dmi_addr) & 0x1ff,
-				mc_filter);
+			int i = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 23) & 0x1ff;
+			mc_filter[i/8] |= (1 << (i & 0x07));
 		}
 		rx_mode = RxFilterEnable | AcceptBroadcast
 			| AcceptMulticast | AcceptMyPhys;
@@ -2000,7 +1967,7 @@
 		strncpy(info.driver, DRV_NAME, ETHTOOL_BUSINFO_LEN);
 		strncpy(info.version, DRV_VERSION, ETHTOOL_BUSINFO_LEN);
 		info.fw_version[0] = '\0';
-		strncpy(info.bus_info, np->pci_dev->slot_name,
+		strncpy(info.bus_info, pci_name(np->pci_dev),
 			ETHTOOL_BUSINFO_LEN);
 		info.eedump_len = NATSEMI_EEPROM_SIZE;
 		info.regdump_len = NATSEMI_REGS_SIZE;
@@ -2585,7 +2552,7 @@
 	unregister_netdev (dev);
 	pci_release_regions (pdev);
 	iounmap ((char *) dev->base_addr);
-	kfree (dev);
+	free_netdev (dev);
 	pci_set_drvdata(pdev, NULL);
 }
 
@@ -2646,7 +2613,7 @@
 			if (wol) {
 				/* restart the NIC in WOL mode.
 				 * The nic must be stopped for this.
-				 * FIXME: use the WOL interupt
+				 * FIXME: use the WOL interrupt
 				 */
 				enable_wol_mode(dev, 0);
 			} else {
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/Makefile linux-2.4.24-pre2/drivers/net/sk98lin/Makefile
--- linux-2.4.24-pre1/drivers/net/sk98lin/Makefile	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/Makefile	2003-12-22 11:34:35.000000000 -0800
@@ -78,7 +78,7 @@
 # SK_DBGCAT_DRV_INT_SRC         0x04000000      interrupts sources
 # SK_DBGCAT_DRV_EVENT           0x08000000      driver events
 
-EXTRA_CFLAGS += -I. -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
+EXTRA_CFLAGS += -I. -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skcsum.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skcsum.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skcsum.h	2001-07-04 11:50:39.000000000 -0700
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skcsum.h	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skcsum.h
  * Project:	GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
- * Version:	$Revision: 1.9 $
- * Date:	$Date: 2001/02/06 11:21:39 $
+ * Version:	$Revision: 1.10 $
+ * Date:	$Date: 2003/08/20 13:59:57 $
  * Purpose:	Store/verify Internet checksum in send/receive packets.
  *
  ******************************************************************************/
@@ -26,6 +26,10 @@
  * History:
  *
  *	$Log: skcsum.h,v $
+ *	Revision 1.10  2003/08/20 13:59:57  mschmid
+ *	Changed notation of #ifndef SkCsCalculateChecksum to
+ *	#ifndef SK_CS_CALCULATE_CHECKSUM
+ *	
  *	Revision 1.9  2001/02/06 11:21:39  rassmann
  *	Editorial changes.
  *	
@@ -226,11 +230,11 @@
 
 /* function prototypes ********************************************************/
 
-#ifndef SkCsCalculateChecksum
+#ifndef SK_CS_CALCULATE_CHECKSUM
 extern unsigned SkCsCalculateChecksum(
 	void		*pData,
 	unsigned	Length);
-#endif
+#endif /* SK_CS_CALCULATE_CHECKSUM */
 
 extern int SkCsEvent(
 	SK_AC		*pAc,
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skdrv1st.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skdrv1st.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skdrv1st.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skdrv1st.h	2003-12-22 11:34:35.000000000 -0800
@@ -2,15 +2,16 @@
  *
  * Name:	skdrv1st.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.1 $
- * Date:	$Date: 2003/07/21 07:22:43 $
+ * Version:	$Revision: 1.4 $
+ * Date:	$Date: 2003/11/12 14:28:14 $
  * Purpose:	First header file for driver and all other modules
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -26,6 +27,15 @@
  * History:
  *
  *	$Log: skdrv1st.h,v $
+ *	Revision 1.4  2003/11/12 14:28:14  rroesler
+ *	Fix: use dedicated ip_fast_csum() on X86_64 systems
+ *	
+ *	Revision 1.3  2003/10/07 08:16:52  mlindner
+ *	Fix: Copyright changes
+ *	
+ *	Revision 1.2  2003/09/29 12:05:59  mlindner
+ *	Fix: Added define SK_CS_CALCULSTE_CHECKSUM
+ *	
  *	Revision 1.1  2003/07/21 07:22:43  rroesler
  *	Fix: Re-Enter after CVS crash
  *	
@@ -127,11 +137,8 @@
 #define SK_PNMI_READ_U32(p,v)		memcpy((char*)&(v),(char*)(p),4)
 #define SK_PNMI_READ_U64(p,v)		memcpy((char*)&(v),(char*)(p),8)
 
-#define SkCsCalculateChecksum(p,l)	((~ip_compute_csum(p, l)) & 0xffff)
-
 #define SK_ADDR_EQUAL(a1,a2)		(!memcmp(a1,a2,6))
 
-
 #if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
 #warning  You must compile this file with the correct options!
 #warning  See the last lines of the source file.
@@ -158,6 +165,13 @@
 #include <asm/uaccess.h>
 #include <net/checksum.h>
 
+#define SK_CS_CALCULATE_CHECKSUM
+#ifndef CONFIG_X86_64
+#define SkCsCalculateChecksum(p,l)	((~ip_compute_csum(p, l)) & 0xffff)
+#else
+#define SkCsCalculateChecksum(p,l)	((~ip_fast_csum(p, l)) & 0xffff)
+#endif
+
 #include	"h/sktypes.h"
 #include	"h/skerror.h"
 #include	"h/skdebug.h"
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skdrv2nd.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skdrv2nd.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skdrv2nd.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skdrv2nd.h	2003-12-22 11:34:35.000000000 -0800
@@ -2,15 +2,16 @@
  *
  * Name:	skdrv2nd.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.3 $
- * Date:	$Date: 2003/08/12 16:51:18 $
+ * Version:	$Revision: 1.10 $
+ * Date:	$Date: 2003/12/11 16:04:45 $
  * Purpose:	Second header file for driver and all other modules
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -26,6 +27,27 @@
  * History:
  *
  *	$Log: skdrv2nd.h,v $
+ *	Revision 1.10  2003/12/11 16:04:45  mlindner
+ *	Add: New pnmi data backup structure
+ *	
+ *	Revision 1.9  2003/11/10 09:31:37  rroesler
+ *	Add: pnmiBackup structure for DIAG backup restore
+ *	
+ *	Revision 1.8  2003/10/22 14:18:32  rroesler
+ *	Fix: DIAG handling for DualNet cards
+ *	
+ *	Revision 1.7  2003/10/07 09:34:59  mlindner
+ *	Add: New defines for lower and upper range values (interrupt moderation)
+ *	
+ *	Revision 1.6  2003/10/07 08:16:51  mlindner
+ *	Fix: Copyright changes
+ *	
+ *	Revision 1.5  2003/09/01 13:10:39  rroesler
+ *	Add: Prototypes for DIAG Attach/Detach functions
+ *	
+ *	Revision 1.4  2003/09/01 12:33:38  rroesler
+ *	Add: Defines for optimized DIAG interaction
+ *	
  *	Revision 1.3  2003/08/12 16:51:18  mlindner
  *	Fix: UDP and TCP Proto checks
  *	Fix: UDP header offset
@@ -206,6 +228,11 @@
 extern int		SkPciWriteCfgByte(SK_AC*, int, SK_U8);
 extern int		SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
 
+#ifdef SK_DIAG_SUPPORT
+extern int		SkDrvEnterDiagMode(SK_AC *pAc);
+extern int		SkDrvLeaveDiagMode(SK_AC *pAc);
+#endif
+
 struct s_DrvRlmtMbuf {
 	SK_MBUF		*pNext;		/* Pointer to next RLMT Mbuf. */
 	SK_U8		*pData;		/* Data buffer (virtually contig.). */
@@ -247,6 +274,7 @@
 #define		SK_IOCTL_SETMIB		(SK_IOCTL_BASE + 1)
 #define		SK_IOCTL_PRESETMIB	(SK_IOCTL_BASE + 2)
 #define		SK_IOCTL_GEN		(SK_IOCTL_BASE + 3)
+#define		SK_IOCTL_DIAG		(SK_IOCTL_BASE + 4)
 
 typedef struct s_IOCTL	SK_GE_IOCTL;
 
@@ -462,6 +490,9 @@
 #define C_INTS_PER_SEC_DEFAULT      2000 
 #define C_INT_MOD_ENABLE_PERCENTAGE   50 /* if higher 50% enable */
 #define C_INT_MOD_DISABLE_PERCENTAGE  50 /* if lower 50% disable */
+#define C_INT_MOD_IPS_LOWER_RANGE     30
+#define C_INT_MOD_IPS_UPPER_RANGE     40000
+
 
 typedef struct s_DynIrqModInfo  DIM_INFO;
 struct s_DynIrqModInfo {
@@ -493,6 +524,11 @@
 
 #define SK_ALLOC_IRQ	0x00000001
 
+#ifdef SK_DIAG_SUPPORT
+#define	DIAG_ACTIVE		1
+#define	DIAG_NOTACTIVE		0
+#endif
+
 /****************************************************************************
  * Per board structure / Adapter Context structure:
  *	Allocated within attach(9e) and freed within detach(9e).
@@ -563,9 +599,18 @@
 	int		PortUp;
 	int		PortDown;
 	int		ChipsetType;	/*  Chipset family type 
-							 *  0 == Genesis family support
-							 *  1 == Yukon family support
-							 */
+					 *  0 == Genesis family support
+					 *  1 == Yukon family support
+					 */
+#ifdef SK_DIAG_SUPPORT
+	SK_U32		DiagModeActive;		/* is diag active?	*/
+	SK_BOOL		DiagFlowCtrl;		/* for control purposes	*/
+	SK_PNMI_STRUCT_DATA PnmiBackup;		/* backup structure for all Pnmi-Data */
+	SK_BOOL         WasIfUp[SK_MAX_MACS];   /* for OpenClose while 
+						 * DIAG is busy with NIC 
+						 */
+#endif
+
 };
 
 
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skgehw.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skgehw.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skgehw.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skgehw.h	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skgehw.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
- * Version:	$Revision: 1.53 $
- * Date:	$Date: 2003/07/04 12:39:01 $
+ * Version:	$Revision: 1.56 $
+ * Date:	$Date: 2003/09/23 09:01:00 $
  * Purpose:	Defines and Macros for the Gigabit Ethernet Adapter Product Family
  *
  ******************************************************************************/
@@ -26,6 +26,17 @@
  *
  * History:
  * $Log: skgehw.h,v $
+ * Revision 1.56  2003/09/23 09:01:00  malthoff
+ * Minor change: Define I2C device size constants as long.
+ *
+ * Revision 1.55  2003/09/16 14:03:34  rschmidt
+ * Added define for YUKON-Lite Rev. A1,A2 Chip Revision
+ * Moved defines for PHY power down modes to skgeinit.h
+ * Editorial changes
+ *
+ * Revision 1.54  2003/09/16 07:37:58  mschmid
+ * Added defines for Marvell PHY low power modes
+ *
  * Revision 1.53  2003/07/04 12:39:01  rschmidt
  * Added SK_FAR to pointers in XM_IN32() and GM_IN32() macros (for PXE)
  * Editorial changes
@@ -84,7 +95,7 @@
  * Editorial changes
  *
  * Revision 1.39  2002/06/10 09:37:07  rschmidt
- * Added macros for the ADDR-Modul
+ * Added macros for the ADDR-Module
  *
  * Revision 1.38  2002/06/05 08:15:19  rschmidt
  * Added defines for WOL Registers
@@ -628,12 +639,12 @@
 #define B2_FAR			0x0120	/* 32 bit	Flash-Prom Addr Reg/Cnt */
 #define B2_FDP			0x0124	/*  8 bit	Flash-Prom Data Port */
 	/* 0x0125 - 0x0127:	reserved */
-#define B2_LD_CRTL		0x0128	/*  8 bit	EPROM loader control register */
+#define B2_LD_CTRL		0x0128	/*  8 bit	EPROM loader control register */
 #define B2_LD_TEST		0x0129	/*  8 bit	EPROM loader test register */
 	/* 0x012a - 0x012f:	reserved */
 #define B2_TI_INI		0x0130	/* 32 bit	Timer Init Value */
 #define B2_TI_VAL		0x0134	/* 32 bit	Timer Value */
-#define B2_TI_CRTL		0x0138	/*  8 bit	Timer Control */
+#define B2_TI_CTRL		0x0138	/*  8 bit	Timer Control */
 #define B2_TI_TEST		0x0139	/*  8 Bit	Timer Test */
 	/* 0x013a - 0x013f:	reserved */
 #define B2_IRQM_INI		0x0140	/* 32 bit	IRQ Moderation Timer Init Reg.*/
@@ -1021,7 +1032,7 @@
 								/* Bit 7:	reserved */
 #define RAP_RAP			0x3f	/* Bit 6..0:	0 = block 0,..,6f = block 6f */
 
-/*	B0_CTST		16 bit	Control/Status register */
+/*	B0_CTST			16 bit	Control/Status register */
 								/* Bit 15..14:	reserved */
 #define CS_CLK_RUN_HOT	BIT_13S		/* CLK_RUN hot m. (YUKON-Lite only) */
 #define CS_CLK_RUN_RST	BIT_12S		/* CLK_RUN reset  (YUKON-Lite only) */
@@ -1038,7 +1049,7 @@
 #define CS_RST_CLR		BIT_1S		/* Clear Software reset	*/
 #define CS_RST_SET		BIT_0S		/* Set   Software reset	*/
 
-/*	B0_LED		 8 Bit	LED register */
+/*	B0_LED			 8 Bit	LED register */
 								/* Bit  7.. 2:	reserved */
 #define LED_STAT_ON		BIT_1S		/* Status LED on	*/
 #define LED_STAT_OFF	BIT_0S		/* Status LED off	*/
@@ -1053,9 +1064,9 @@
 #define PC_VCC_ON		BIT_1       /* Switch VCC On  */
 #define PC_VCC_OFF		BIT_0       /* Switch VCC Off */
 
-/*	B0_ISRC		32 bit	Interrupt Source Register */
-/*	B0_IMSK		32 bit	Interrupt Mask Register */
-/*	B0_SP_ISRC	32 bit	Special Interrupt Source Reg */
+/*	B0_ISRC			32 bit	Interrupt Source Register */
+/*	B0_IMSK			32 bit	Interrupt Mask Register */
+/*	B0_SP_ISRC		32 bit	Special Interrupt Source Reg */
 /*	B2_IRQM_MSK 	32 bit	IRQ Moderation Mask */
 #define IS_ALL_MSK		0xbfffffffUL	/* All Interrupt bits */
 #define IS_HW_ERR		BIT_31		/* Interrupt HW Error */
@@ -1099,9 +1110,9 @@
 #define IS_XA2_C		BIT_0		/* Q_XA2 Encoding Error */
 
 
-/*	B0_HWE_ISRC	32 bit	HW Error Interrupt Src Reg */
-/*	B0_HWE_IMSK	32 bit	HW Error Interrupt Mask Reg */
-/*	B2_IRQM_HWE_MSK 32 bit	IRQ Moderation HW Error Mask */
+/*	B0_HWE_ISRC		32 bit	HW Error Interrupt Src Reg */
+/*	B0_HWE_IMSK		32 bit	HW Error Interrupt Mask Reg */
+/*	B2_IRQM_HWE_MSK	32 bit	IRQ Moderation HW Error Mask */
 #define IS_ERR_MSK		0x00000fffL	/* 		All Error bits */
 								/* Bit 31..14:	reserved */
 #define IS_IRQ_TIST_OV	BIT_13	/* Time Stamp Timer Overflow (YUKON only) */
@@ -1119,29 +1130,32 @@
 #define IS_R1_PAR_ERR	BIT_1	/* Queue R1 Parity Error */
 #define IS_R2_PAR_ERR	BIT_0	/* Queue R2 Parity Error */
 
-/*	B2_CONN_TYP	 8 bit	Connector type */
-/*	B2_PMD_TYP	 8 bit	PMD type */
+/*	B2_CONN_TYP		 8 bit	Connector type */
+/*	B2_PMD_TYP		 8 bit	PMD type */
 /*	Values of connector and PMD type comply to SysKonnect internal std */
 
-/*	B2_MAC_CFG	 8 bit	MAC Configuration / Chip Revision */
+/*	B2_MAC_CFG		 8 bit	MAC Configuration / Chip Revision */
 #define CFG_CHIP_R_MSK	(0xf<<4)	/* Bit 7.. 4: Chip Revision */
 									/* Bit 3.. 2:	reserved */
 #define CFG_DIS_M2_CLK	BIT_1S		/* Disable Clock for 2nd MAC */
 #define CFG_SNG_MAC		BIT_0S		/* MAC Config: 0=2 MACs / 1=1 MAC*/
 
-/*	B2_CHIP_ID	 8 bit 	Chip Identification Number */
+/*	B2_CHIP_ID		 8 bit 	Chip Identification Number */
 #define CHIP_ID_GENESIS		0x0a	/* Chip ID for GENESIS */
 #define CHIP_ID_YUKON		0xb0	/* Chip ID for YUKON */
-#define CHIP_ID_YUKON_LITE	0xb1	/* Chip ID for YUKON-Lite (Rev. A1) */
+#define CHIP_ID_YUKON_LITE	0xb1	/* Chip ID for YUKON-Lite (Rev. A1-A3) */
 #define CHIP_ID_YUKON_LP	0xb2	/* Chip ID for YUKON-LP */
 
-/*	B2_FAR		32 bit	Flash-Prom Addr Reg/Cnt */
+#define CHIP_REV_YU_LITE_A1	3		/* Chip Rev. for YUKON-Lite A1,A2 */
+#define CHIP_REV_YU_LITE_A3	7		/* Chip Rev. for YUKON-Lite A3 */
+
+/*	B2_FAR			32 bit	Flash-Prom Addr Reg/Cnt */
 #define FAR_ADDR		0x1ffffL	/* Bit 16.. 0:	FPROM Address mask */
 
-/*	B2_LD_CRTL	 8 bit	EPROM loader control register */
+/*	B2_LD_CTRL		 8 bit	EPROM loader control register */
 /*	Bits are currently reserved */
 
-/*	B2_LD_TEST	 8 bit	EPROM loader test register */
+/*	B2_LD_TEST		 8 bit	EPROM loader test register */
 								/* Bit 7.. 4:	reserved */
 #define LD_T_ON			BIT_3S	/* Loader Test mode on */
 #define LD_T_OFF		BIT_2S	/* Loader Test mode off */
@@ -1151,16 +1165,16 @@
 /*
  *	Timer Section
  */
-/*	B2_TI_CRTL	 8 bit	Timer control */
+/*	B2_TI_CTRL		 8 bit	Timer control */
 /*	B2_IRQM_CTRL	 8 bit	IRQ Moderation Timer Control */
 								/* Bit 7.. 3:	reserved */
 #define TIM_START		BIT_2S	/* Start Timer */
 #define TIM_STOP		BIT_1S	/* Stop  Timer */
 #define TIM_CLR_IRQ		BIT_0S	/* Clear Timer IRQ (!IRQM) */
 
-/*	B2_TI_TEST	 8 Bit	Timer Test */
+/*	B2_TI_TEST		 8 Bit	Timer Test */
 /*	B2_IRQM_TEST	 8 bit	IRQ Moderation Timer Test */
-/*	B28_DPT_TST	 8 bit	Descriptor Poll Timer Test Reg */
+/*	B28_DPT_TST		 8 bit	Descriptor Poll Timer Test Reg */
 								/* Bit 7.. 3:	reserved */
 #define TIM_T_ON		BIT_2S	/* Test mode on */
 #define TIM_T_OFF		BIT_1S	/* Test mode off */
@@ -1197,7 +1211,7 @@
 #define TST_FRC_APERR_1M64	BIT_1S	/* AddrPERR on 1. phase */
 #define TST_FRC_APERR_2M64	BIT_0S	/* AddrPERR on 2. phase */
 
-/*	B2_GP_IO	32 bit	General Purpose I/O Register */
+/*	B2_GP_IO		32 bit	General Purpose I/O Register */
 							/* Bit 31..26:	reserved */
 #define GP_DIR_9	BIT_25	/* IO_9 direct, 0=In/1=Out */
 #define GP_DIR_8	BIT_24	/* IO_8 direct, 0=In/1=Out */
@@ -1221,28 +1235,28 @@
 #define GP_IO_1		BIT_1	/* IO_1 pin */
 #define GP_IO_0		BIT_0	/* IO_0 pin */
 
-/*	B2_I2C_CTRL	32 bit	I2C HW Control Register */
+/*	B2_I2C_CTRL		32 bit	I2C HW Control Register */
 #define I2C_FLAG		BIT_31		/* Start read/write if WR */
 #define I2C_ADDR		(0x7fffL<<16)	/* Bit 30..16:	Addr to be RD/WR */
 #define I2C_DEV_SEL		(0x7fL<<9)		/* Bit 15.. 9:	I2C Device Select */
 								/* Bit	8.. 5:	reserved	*/
 #define I2C_BURST_LEN	BIT_4		/* Burst Len, 1/4 bytes */
-#define I2C_DEV_SIZE	(7L<<1)		/* Bit	3.. 1:	I2C Device Size	*/
-#define I2C_025K_DEV	(0L<<1)		/*		0: 256 Bytes or smal. */
-#define I2C_05K_DEV		(1L<<1)		/* 		1: 512	Bytes	*/
-#define I2C_1K_DEV		(2L<<1)		/*		2: 1024 Bytes	*/
-#define I2C_2K_DEV		(3L<<1)		/*		3: 2048	Bytes	*/
-#define I2C_4K_DEV		(4L<<1)		/*		4: 4096 Bytes	*/
-#define I2C_8K_DEV		(5L<<1)		/*		5: 8192 Bytes	*/
-#define I2C_16K_DEV		(6L<<1)		/*		6: 16384 Bytes	*/
-#define I2C_32K_DEV		(7L<<1)		/*		7: 32768 Bytes	*/
+#define I2C_DEV_SIZE	(7<<1)		/* Bit	3.. 1:	I2C Device Size	*/
+#define I2C_025K_DEV	(0<<1)		/*		0: 256 Bytes or smal. */
+#define I2C_05K_DEV		(1<<1)		/* 		1: 512	Bytes	*/
+#define I2C_1K_DEV		(2<<1)		/*		2: 1024 Bytes	*/
+#define I2C_2K_DEV		(3<<1)		/*		3: 2048	Bytes	*/
+#define I2C_4K_DEV		(4<<1)		/*		4: 4096 Bytes	*/
+#define I2C_8K_DEV		(5<<1)		/*		5: 8192 Bytes	*/
+#define I2C_16K_DEV		(6<<1)		/*		6: 16384 Bytes	*/
+#define I2C_32K_DEV		(7<<1)		/*		7: 32768 Bytes	*/
 #define I2C_STOP		BIT_0		/* Interrupt I2C transfer */
 
-/*	B2_I2C_IRQ	32 bit	I2C HW IRQ Register */
+/*	B2_I2C_IRQ		32 bit	I2C HW IRQ Register */
 								/* Bit 31.. 1	reserved */
 #define I2C_CLR_IRQ		BIT_0	/* Clear I2C IRQ */
 
-/*	B2_I2C_SW	32 bit (8 bit access)	I2C HW SW Port Register */
+/*	B2_I2C_SW		32 bit (8 bit access)	I2C HW SW Port Register */
 								/* Bit  7.. 3:	reserved */
 #define I2C_DATA_DIR	BIT_2S		/* direction of I2C_DATA */
 #define I2C_DATA		BIT_1S		/* I2C Data Port	*/
@@ -1254,27 +1268,27 @@
 #define I2C_SENS_ADDR	LM80_ADDR	/* I2C Sensor Address, (Volt and Temp)*/
 
 
-/*	B2_BSC_CTRL	 8 bit	Blink Source Counter Control */
+/*	B2_BSC_CTRL		 8 bit	Blink Source Counter Control */
 							/* Bit  7.. 2:	reserved */
 #define BSC_START	BIT_1S		/* Start Blink Source Counter */
 #define BSC_STOP	BIT_0S		/* Stop  Blink Source Counter */
 
-/*	B2_BSC_STAT	 8 bit	Blink Source Counter Status */
+/*	B2_BSC_STAT		 8 bit	Blink Source Counter Status */
 							/* Bit  7.. 1:	reserved */
 #define BSC_SRC		BIT_0S		/* Blink Source, 0=Off / 1=On */
 
-/*	B2_BSC_TST	16 bit	Blink Source Counter Test Reg */
+/*	B2_BSC_TST		16 bit	Blink Source Counter Test Reg */
 #define BSC_T_ON	BIT_2S		/* Test mode on */
 #define BSC_T_OFF	BIT_1S		/* Test mode off */
 #define BSC_T_STEP	BIT_0S		/* Test step */
 
 
-/*	B3_RAM_ADDR	32 bit	RAM Address, to read or write */
+/*	B3_RAM_ADDR		32 bit	RAM Address, to read or write */
 					/* Bit 31..19:	reserved */
 #define RAM_ADR_RAN	0x0007ffffL	/* Bit 18.. 0:	RAM Address Range */
 
 /* RAM Interface Registers */
-/*	B3_RI_CTRL	16 bit	RAM Iface Control Register */
+/*	B3_RI_CTRL		16 bit	RAM Iface Control Register */
 								/* Bit 15..10:	reserved */
 #define RI_CLR_RD_PERR	BIT_9S	/* Clear IRQ RAM Read Parity Err */
 #define RI_CLR_WR_PERR	BIT_8S	/* Clear IRQ RAM Write Parity Err*/
@@ -1282,7 +1296,7 @@
 #define RI_RST_CLR		BIT_1S	/* Clear RAM Interface Reset */
 #define RI_RST_SET		BIT_0S	/* Set   RAM Interface Reset */
 
-/*	B3_RI_TEST	 8 bit	RAM Iface Test Register */
+/*	B3_RI_TEST		 8 bit	RAM Iface Test Register */
 								/* Bit 15.. 4:	reserved */
 #define RI_T_EV			BIT_3S	/* Timeout Event occured */
 #define RI_T_ON			BIT_2S	/* Timeout Timer Test On */
@@ -1309,7 +1323,7 @@
 #define MA_DIS_REC_RX1	BIT_0S	/* Disable Recovery Timer RX1 */
 
 /* Packet Arbiter Registers */
-/*	B3_PA_CTRL	16 bit	Packet Arbiter Ctrl Register */
+/*	B3_PA_CTRL		16 bit	Packet Arbiter Ctrl Register */
 								/* Bit 15..14:	reserved */
 #define PA_CLR_TO_TX2	BIT_13S	/* Clear IRQ Packet Timeout TX2 */
 #define PA_CLR_TO_TX1	BIT_12S	/* Clear IRQ Packet Timeout TX1 */
@@ -1332,7 +1346,7 @@
 /* Rx/Tx Path related Arbiter Test Registers */
 /*	B3_MA_TO_TEST	16 bit	MAC Arbiter Timeout Test Reg */
 /*	B3_MA_RC_TEST	16 bit	MAC Arbiter Recovery Test Reg */
-/*	B3_PA_TEST	16 bit	Packet Arbiter Test Register */
+/*	B3_PA_TEST		16 bit	Packet Arbiter Test Register */
 /*			Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
 #define TX2_T_EV	BIT_15S		/* TX2 Timeout/Recv Event occured */
 #define TX2_T_ON	BIT_14S		/* TX2 Timeout/Recv Timer Test On */
@@ -1353,14 +1367,14 @@
 
 
 /* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
-/*	TXA_ITI_INI	32 bit	Tx Arb Interval Timer Init Val */
-/*	TXA_ITI_VAL	32 bit	Tx Arb Interval Timer Value */
-/*	TXA_LIM_INI	32 bit	Tx Arb Limit Counter Init Val */
-/*	TXA_LIM_VAL	32 bit	Tx Arb Limit Counter Value */
+/*	TXA_ITI_INI		32 bit	Tx Arb Interval Timer Init Val */
+/*	TXA_ITI_VAL		32 bit	Tx Arb Interval Timer Value */
+/*	TXA_LIM_INI		32 bit	Tx Arb Limit Counter Init Val */
+/*	TXA_LIM_VAL		32 bit	Tx Arb Limit Counter Value */
 								/* Bit 31..24:	reserved */
 #define TXA_MAX_VAL	0x00ffffffUL/* Bit 23.. 0:	Max TXA Timer/Cnt Val */
 
-/*	TXA_CTRL	 8 bit	Tx Arbiter Control Register */
+/*	TXA_CTRL		 8 bit	Tx Arbiter Control Register */
 #define TXA_ENA_FSYNC	BIT_7S	/* Enable  force of sync Tx queue */
 #define TXA_DIS_FSYNC	BIT_6S	/* Disable force of sync Tx queue */
 #define TXA_ENA_ALLOC	BIT_5S	/* Enable  alloc of free bandwidth */
@@ -1370,7 +1384,7 @@
 #define TXA_ENA_ARB		BIT_1S	/* Enable  Tx Arbiter */
 #define TXA_DIS_ARB		BIT_0S	/* Disable Tx Arbiter */
 
-/*	TXA_TEST	 8 bit	Tx Arbiter Test Register */
+/*	TXA_TEST		 8 bit	Tx Arbiter Test Register */
 								/* Bit 7.. 6:	reserved */
 #define TXA_INT_T_ON	BIT_5S	/* Tx Arb Interval Timer Test On */
 #define TXA_INT_T_OFF	BIT_4S	/* Tx Arb Interval Timer Test Off */
@@ -1379,22 +1393,22 @@
 #define TXA_LIM_T_OFF	BIT_1S	/* Tx Arb Limit Timer Test Off */
 #define TXA_LIM_T_STEP	BIT_0S	/* Tx Arb Limit Timer Step */
 
-/*	TXA_STAT	 8 bit	Tx Arbiter Status Register */
+/*	TXA_STAT		 8 bit	Tx Arbiter Status Register */
 								/* Bit 7.. 1:	reserved */
 #define TXA_PRIO_XS		BIT_0S	/* sync queue has prio to send */
 
-/*	Q_BC	32 bit	Current Byte Counter */
+/*	Q_BC			32 bit	Current Byte Counter */
 								/* Bit 31..16:	reserved */
 #define BC_MAX			0xffff	/* Bit 15.. 0:	Byte counter */
 
 /* BMU Control Status Registers */
-/*	B0_R1_CSR	32 bit	BMU Ctrl/Stat Rx Queue 1 */
-/*	B0_R2_CSR	32 bit	BMU Ctrl/Stat Rx Queue 2 */
-/*	B0_XA1_CSR	32 bit	BMU Ctrl/Stat Sync Tx Queue 1 */
-/*	B0_XS1_CSR	32 bit	BMU Ctrl/Stat Async Tx Queue 1 */
-/*	B0_XA2_CSR	32 bit	BMU Ctrl/Stat Sync Tx Queue 2 */
-/*	B0_XS2_CSR	32 bit	BMU Ctrl/Stat Async Tx Queue 2 */
-/*	Q_CSR		32 bit	BMU Control/Status Register */
+/*	B0_R1_CSR		32 bit	BMU Ctrl/Stat Rx Queue 1 */
+/*	B0_R2_CSR		32 bit	BMU Ctrl/Stat Rx Queue 2 */
+/*	B0_XA1_CSR		32 bit	BMU Ctrl/Stat Sync Tx Queue 1 */
+/*	B0_XS1_CSR		32 bit	BMU Ctrl/Stat Async Tx Queue 1 */
+/*	B0_XA2_CSR		32 bit	BMU Ctrl/Stat Sync Tx Queue 2 */
+/*	B0_XS2_CSR		32 bit	BMU Ctrl/Stat Async Tx Queue 2 */
+/*	Q_CSR			32 bit	BMU Control/Status Register */
 								/* Bit 31..25:	reserved */
 #define CSR_SV_IDLE		BIT_24		/* BMU SM Idle */
 								/* Bit 23..22:	reserved */
@@ -1428,7 +1442,7 @@
 						CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
 						CSR_TRANS_RUN)
 
-/*	Q_F	32 bit	Flag Register */
+/*	Q_F				32 bit	Flag Register */
 									/* Bit 31..28:	reserved */
 #define F_ALM_FULL		BIT_27		/* Rx FIFO: almost full */
 #define F_EMPTY			BIT_27		/* Tx FIFO: empty flag */
@@ -1439,17 +1453,17 @@
 									/* Bit 15..11: 	reserved */
 #define F_WATER_MARK	0x0007ffL	/* Bit 10.. 0:	Watermark */
 
-/*	Q_T1	32 bit	Test Register 1 */
+/*	Q_T1			32 bit	Test Register 1 */
 /*		Holds four State Machine control Bytes */
-#define SM_CRTL_SV_MSK	(0xffL<<24)	/* Bit 31..24:	Control Supervisor SM */
-#define SM_CRTL_RD_MSK	(0xffL<<16)	/* Bit 23..16:	Control Read Desc SM */
-#define SM_CRTL_WR_MSK	(0xffL<<8)	/* Bit 15.. 8:	Control Write Desc SM */
-#define SM_CRTL_TR_MSK	0xffL		/* Bit	7.. 0:	Control Transfer SM */
-
-/*	Q_T1_TR	 8 bit	Test Register 1 Transfer SM */
-/*	Q_T1_WR	 8 bit	Test Register 1 Write Descriptor SM */
-/*	Q_T1_RD	 8 bit	Test Register 1 Read Descriptor SM */
-/*	Q_T1_SV	 8 bit	Test Register 1 Supervisor SM */
+#define SM_CTRL_SV_MSK	(0xffL<<24)	/* Bit 31..24:	Control Supervisor SM */
+#define SM_CTRL_RD_MSK	(0xffL<<16)	/* Bit 23..16:	Control Read Desc SM */
+#define SM_CTRL_WR_MSK	(0xffL<<8)	/* Bit 15.. 8:	Control Write Desc SM */
+#define SM_CTRL_TR_MSK	0xffL		/* Bit	7.. 0:	Control Transfer SM */
+
+/*	Q_T1_TR			 8 bit	Test Register 1 Transfer SM */
+/*	Q_T1_WR			 8 bit	Test Register 1 Write Descriptor SM */
+/*	Q_T1_RD			 8 bit	Test Register 1 Read Descriptor SM */
+/*	Q_T1_SV			 8 bit	Test Register 1 Supervisor SM */
 
 /* The control status byte of each machine looks like ... */
 #define SM_STATE		0xf0	/* Bit 7.. 4:	State which shall be loaded */
@@ -1459,7 +1473,7 @@
 #define SM_STEP			BIT_0S	/* Step the State Machine */
 /* The encoding of the states is not supported by the Diagnostics Tool */
 
-/*	Q_T2	32 bit	Test Register 2	*/
+/*	Q_T2			32 bit	Test Register 2	*/
 								/* Bit 31.. 8:	reserved */
 #define T2_AC_T_ON		BIT_7	/* Address Counter Test Mode on */
 #define T2_AC_T_OFF		BIT_6	/* Address Counter Test Mode off */
@@ -1470,23 +1484,23 @@
 #define T2_STEP02		BIT_1	/* Inc AC/Dec BC by 2 */
 #define T2_STEP01		BIT_0	/* Inc AC/Dec BC by 1 */
 
-/*	Q_T3	32 bit	Test Register 3	*/
+/*	Q_T3			32 bit	Test Register 3	*/
 								/* Bit 31.. 7:	reserved */
 #define T3_MUX_MSK		(7<<4)	/* Bit  6.. 4:	Mux Position */
 								/* Bit  3:	reserved */
 #define T3_VRAM_MSK		7		/* Bit  2.. 0:	Virtual RAM Buffer Address */
 
 /* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
-/*	RB_START	32 bit	RAM Buffer Start Address */
-/*	RB_END		32 bit	RAM Buffer End Address */
-/*	RB_WP		32 bit	RAM Buffer Write Pointer */
-/*	RB_RP		32 bit	RAM Buffer Read Pointer */
-/*	RB_RX_UTPP	32 bit	Rx Upper Threshold, Pause Pack */
-/*	RB_RX_LTPP	32 bit	Rx Lower Threshold, Pause Pack */
-/*	RB_RX_UTHP	32 bit	Rx Upper Threshold, High Prio */
-/*	RB_RX_LTHP	32 bit	Rx Lower Threshold, High Prio */
-/*	RB_PC		32 bit	RAM Buffer Packet Counter */
-/*	RB_LEV		32 bit	RAM Buffer Level Register */
+/*	RB_START		32 bit	RAM Buffer Start Address */
+/*	RB_END			32 bit	RAM Buffer End Address */
+/*	RB_WP			32 bit	RAM Buffer Write Pointer */
+/*	RB_RP			32 bit	RAM Buffer Read Pointer */
+/*	RB_RX_UTPP		32 bit	Rx Upper Threshold, Pause Pack */
+/*	RB_RX_LTPP		32 bit	Rx Lower Threshold, Pause Pack */
+/*	RB_RX_UTHP		32 bit	Rx Upper Threshold, High Prio */
+/*	RB_RX_LTHP		32 bit	Rx Lower Threshold, High Prio */
+/*	RB_PC			32 bit	RAM Buffer Packet Counter */
+/*	RB_LEV			32 bit	RAM Buffer Level Register */
 				/* Bit 31..19:	reserved */
 #define RB_MSK	0x0007ffff	/* Bit 18.. 0:	RAM Buffer Pointer Bits */
 
@@ -1519,17 +1533,17 @@
 
 /* Receive and Transmit MAC FIFO Registers (GENESIS only) */
 
-/*	RX_MFF_EA	32 bit	Receive MAC FIFO End Address */
-/*	RX_MFF_WP	32 bit 	Receive MAC FIFO Write Pointer */
-/*	RX_MFF_RP	32 bit	Receive MAC FIFO Read Pointer */
-/*	RX_MFF_PC	32 bit	Receive MAC FIFO Packet Counter */
-/*	RX_MFF_LEV	32 bit	Receive MAC FIFO Level */
-/*	TX_MFF_EA	32 bit	Transmit MAC FIFO End Address */
-/*	TX_MFF_WP	32 bit 	Transmit MAC FIFO Write Pointer */
-/*	TX_MFF_WSP	32 bit	Transmit MAC FIFO WR Shadow Pointer */
-/*	TX_MFF_RP	32 bit	Transmit MAC FIFO Read Pointer */
-/*	TX_MFF_PC	32 bit	Transmit MAC FIFO Packet Cnt */
-/*	TX_MFF_LEV	32 bit	Transmit MAC FIFO Level */
+/*	RX_MFF_EA		32 bit	Receive MAC FIFO End Address */
+/*	RX_MFF_WP		32 bit 	Receive MAC FIFO Write Pointer */
+/*	RX_MFF_RP		32 bit	Receive MAC FIFO Read Pointer */
+/*	RX_MFF_PC		32 bit	Receive MAC FIFO Packet Counter */
+/*	RX_MFF_LEV		32 bit	Receive MAC FIFO Level */
+/*	TX_MFF_EA		32 bit	Transmit MAC FIFO End Address */
+/*	TX_MFF_WP		32 bit 	Transmit MAC FIFO Write Pointer */
+/*	TX_MFF_WSP		32 bit	Transmit MAC FIFO WR Shadow Pointer */
+/*	TX_MFF_RP		32 bit	Transmit MAC FIFO Read Pointer */
+/*	TX_MFF_PC		32 bit	Transmit MAC FIFO Packet Cnt */
+/*	TX_MFF_LEV		32 bit	Transmit MAC FIFO Level */
 								/* Bit 31.. 6:	reserved */
 #define MFF_MSK			0x007fL	/* Bit	5.. 0:	MAC FIFO Address/Ptr Bits */
 
@@ -1682,7 +1696,7 @@
 
 #define RX_GMF_FL_THR_DEF	0x0a	/* Rx GMAC FIFO Flush Threshold default */
 
-/*	GMAC_TI_ST_CTRL		  8 bit	Time Stamp Timer Ctrl Reg (YUKON only) */
+/*	GMAC_TI_ST_CTRL	 8 bit	Time Stamp Timer Ctrl Reg (YUKON only) */
 								/* Bit 7.. 3:	reserved */
 #define GMT_ST_START	BIT_2S		/* Start Time Stamp Timer */
 #define GMT_ST_STOP		BIT_1S		/* Stop  Time Stamp Timer */
@@ -1766,13 +1780,13 @@
 #define GMAC_DEF_MSK	(GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
 						GM_IS_TX_FF_UR)
 
-/*	GMAC_LINK_CTRL		16 bit	GMAC Link Control Reg (YUKON only) */
+/*	GMAC_LINK_CTRL	16 bit	GMAC Link Control Reg (YUKON only) */
 						/* Bits 15.. 2:	reserved */
 #define GMLC_RST_CLR	BIT_1S		/* Clear GMAC Link Reset */
 #define GMLC_RST_SET	BIT_0S		/* Set   GMAC Link Reset */
 
 
-/*	WOL_CTRL_STAT		16 bit	WOL Control/Status Reg */
+/*	WOL_CTRL_STAT	16 bit	WOL Control/Status Reg */
 #define WOL_CTL_LINK_CHG_OCC			BIT_15S
 #define WOL_CTL_MAGIC_PKT_OCC			BIT_14S
 #define WOL_CTL_PATTERN_OCC				BIT_13S
@@ -1801,7 +1815,7 @@
 	WOL_CTL_DIS_PATTERN_UNIT |		\
 	WOL_CTL_DIS_MAGIC_PKT_UNIT)
 
-/*	WOL_MATCH_CTL		 8 bit	WOL Match Control Reg */
+/*	WOL_MATCH_CTL	 8 bit	WOL Match Control Reg */
 #define WOL_CTL_PATT_ENA(x)				(BIT_0 << (x))
 
 #define SK_NUM_WOL_PATTERN		7
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skgehwt.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skgehwt.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skgehwt.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skgehwt.h	2003-12-22 11:34:35.000000000 -0800
@@ -1,9 +1,9 @@
 /******************************************************************************
  *
  * Name:	skhwt.h
- * Project:	Gigabit Ethernet Adapters, Schedule-Modul
- * Version:	$Revision: 1.6 $
- * Date:	$Date: 2003/05/13 17:57:48 $
+ * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 1.7 $
+ * Date:	$Date: 2003/09/16 12:55:08 $
  * Purpose:	Defines for the hardware timer functions
  *
  ******************************************************************************/
@@ -27,6 +27,9 @@
  * History:
  *
  *	$Log: skgehwt.h,v $
+ *	Revision 1.7  2003/09/16 12:55:08  rschmidt
+ *	Editorial changes
+ *	
  *	Revision 1.6  2003/05/13 17:57:48  mkarl
  *	Editorial changes.
  *	
@@ -34,7 +37,7 @@
  *	Changed license header to GPL.
  *	
  *	Revision 1.4  1998/08/19 09:50:58  gklug
- *	fix: remove struct keyword from c-code (see CCC) add typedefs
+ *	fix: remove struct keyword from C-code (see CCC) add typedefs
  *	
  *	Revision 1.3  1998/08/14 07:09:29  gklug
  *	fix: chg pAc -> pAC
@@ -44,10 +47,6 @@
  *	
  *	Revision 1.1  1998/08/07 09:32:58  gklug
  *	first version
- *	
- *	
- *	
- *	
  *
  ******************************************************************************/
 
@@ -64,14 +63,14 @@
  * - use in Adapters context name pAC->Hwt
  */
 typedef	struct s_Hwt {
-	SK_U32		TStart ;	/* HWT start */
-	SK_U32		TStop ;		/* HWT stop */
-	int		TActive ;	/* HWT: flag : active/inactive */
+	SK_U32		TStart;	/* HWT start */
+	SK_U32		TStop;	/* HWT stop */
+	int		TActive;	/* HWT: flag : active/inactive */
 } SK_HWT;
 
 extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
 extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
 extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
-extern SK_U32 SkHwtRead(SK_AC *pAC,SK_IOC Ioc);
+extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc);
 extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
 #endif	/* _SKGEHWT_H_ */
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skgei2c.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skgei2c.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skgei2c.h	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skgei2c.h	2003-12-22 11:34:35.000000000 -0800
@@ -1,16 +1,17 @@
 /******************************************************************************
  *
  * Name:	skgei2c.h
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.23 $
- * Date:	$Date: 2002/12/19 14:34:27 $
- * Purpose:	Special GEnesis defines for TWSI
+ * Project:	Gigabit Ethernet Adapters, TWSI-Module
+ * Version:	$Revision: 1.25 $
+ * Date:	$Date: 2003/10/20 09:06:05 $
+ * Purpose:	Special defines for TWSI
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -26,6 +27,12 @@
  * History:
  *
  *	$Log: skgei2c.h,v $
+ *	Revision 1.25  2003/10/20 09:06:05  rschmidt
+ *	Editorial changes.
+ *	
+ *	Revision 1.24  2003/09/23 09:31:15  malthoff
+ *	Parameter dev_size added to macro definition of SK_I2C_CTL.
+ *	
  *	Revision 1.23  2002/12/19 14:34:27  rschmidt
  *	Added cast in macros SK_I2C_SET_BIT() and SK_I2C_CLR_BIT()
  *	Editorial changes (TWSI)
@@ -107,8 +114,6 @@
  *	Revision 1.1  1998/07/17 11:27:56  gklug
  *	Created.
  *
- *
- *
  ******************************************************************************/
 
 /*
@@ -121,12 +126,13 @@
 /*
  * Macros to access the B2_I2C_CTRL
  */
-#define SK_I2C_CTL(IoC, flag, dev, reg, burst) \
+#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
 	SK_OUT32(IoC, B2_I2C_CTRL,\
 		(flag ? 0x80000000UL : 0x0L) | \
-		(((SK_U32) reg << 16) & I2C_ADDR) | \
-		(((SK_U32) dev << 9) & I2C_DEV_SEL) | \
-		(( burst << 4) & I2C_BURST_LEN))
+		(((SK_U32)reg << 16) & I2C_ADDR) | \
+		(((SK_U32)dev << 9) & I2C_DEV_SEL) | \
+		(dev_size & I2C_DEV_SIZE) | \
+		((burst << 4) & I2C_BURST_LEN))
 
 #define SK_I2C_STOP(IoC) {				\
 	SK_U32	I2cCtrl;				\
@@ -166,42 +172,42 @@
  */
 #define	SK_LM80_VT_LSB		22	/* 22mV LSB resolution */
 #define	SK_LM80_TEMP_LSB	10	/* 1 degree LSB resolution */
-#define	SK_LM80_TEMPEXT_LSB	5	/* 0.5 degree LSB resolution for the
-					 * extension value
-					 */
-#define SK_LM80_FAN_FAKTOR	((22500L*60)/(1*2))
-/* formula: counter = (22500*60)/(rpm * divisor * pulses/2)
+#define	SK_LM80_TEMPEXT_LSB	 5	/* 0.5 degree LSB resolution for ext. val. */
+
+/*
+ * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
  * assuming: 6500rpm, 4 pulses, divisor 1
  */
+#define SK_LM80_FAN_FAKTOR	((22500L*60)/(1*2))
 
 /*
  * Define sensor management data
- * Maximum is reached on copperfield with dual Broadcom.
+ * Maximum is reached on Genesis copper dual port and Yukon-64
  * Board specific maximum is in pAC->I2c.MaxSens
  */
 #define	SK_MAX_SENSORS	8	/* maximal no. of installed sensors */
 #define	SK_MIN_SENSORS	5	/* minimal no. of installed sensors */
 
 /*
- * To watch the statemachine (JS) use the timer in two ways instead of one as hitherto
+ * To watch the state machine (SM) use the timer in two ways
+ * instead of one as hitherto
  */
-#define	SK_TIMER_WATCH_STATEMACHINE	0	/* Watch the statemachine to finish in a specific time */
-#define	SK_TIMER_NEW_GAUGING    	1	/* Start a new gauging when timer expires */
-
+#define	SK_TIMER_WATCH_SM		0	/* Watch the SM to finish in a spec. time */
+#define	SK_TIMER_NEW_GAUGING	1	/* Start a new gauging when timer expires */
 
 /*
- * Defines for the individual Thresholds
+ * Defines for the individual thresholds
  */
 
 /* Temperature sensor */
-#define	SK_SEN_TEMP_HIGH_ERR    800	/* Temperature High Err  Threshold */
+#define	SK_SEN_TEMP_HIGH_ERR	800	/* Temperature High Err  Threshold */
 #define	SK_SEN_TEMP_HIGH_WARN	700	/* Temperature High Warn Threshold */
 #define	SK_SEN_TEMP_LOW_WARN	100	/* Temperature Low  Warn Threshold */
-#define	SK_SEN_TEMP_LOW_ERR       0	/* Temperature Low  Err  Threshold */
+#define	SK_SEN_TEMP_LOW_ERR		  0	/* Temperature Low  Err  Threshold */
 
 /* VCC which should be 5 V */
-#define	SK_SEN_PCI_5V_HIGH_ERR  	5588	/* Voltage PCI High Err  Threshold */
-#define	SK_SEN_PCI_5V_HIGH_WARN     5346	/* Voltage PCI High Warn Threshold */
+#define	SK_SEN_PCI_5V_HIGH_ERR		5588	/* Voltage PCI High Err  Threshold */
+#define	SK_SEN_PCI_5V_HIGH_WARN		5346	/* Voltage PCI High Warn Threshold */
 #define	SK_SEN_PCI_5V_LOW_WARN		4664	/* Voltage PCI Low  Warn Threshold */
 #define	SK_SEN_PCI_5V_LOW_ERR		4422	/* Voltage PCI Low  Err  Threshold */
 
@@ -229,17 +235,16 @@
 #define	SK_SEN_PCI_IO_3V3_HIGH_ERR	3850	/* + 15% V PCI-IO High Err Threshold */
 #define	SK_SEN_PCI_IO_3V3_HIGH_WARN	3674	/* + 10% V PCI-IO High Warn Threshold */
 					/*		3300	mVolt */
-#define	SK_SEN_PCI_IO_3V3_LOW_WARN  2926	/* - 10% V PCI-IO Low Warn Threshold */
-#define	SK_SEN_PCI_IO_3V3_LOW_ERR   2772	/* - 15% V PCI-IO Low Err  Threshold */
-
+#define	SK_SEN_PCI_IO_3V3_LOW_WARN	2926	/* - 10% V PCI-IO Low Warn Threshold */
+#define	SK_SEN_PCI_IO_3V3_LOW_ERR	2772	/* - 15% V PCI-IO Low Err  Threshold */
 
 /*
  * VDD voltage
  */
-#define	SK_SEN_VDD_HIGH_ERR	    3630	/* Voltage ASIC High Err  Threshold */
-#define	SK_SEN_VDD_HIGH_WARN    3476	/* Voltage ASIC High Warn Threshold */
-#define	SK_SEN_VDD_LOW_WARN     3146	/* Voltage ASIC Low  Warn Threshold */
-#define	SK_SEN_VDD_LOW_ERR      2970	/* Voltage ASIC Low  Err  Threshold */
+#define	SK_SEN_VDD_HIGH_ERR		3630	/* Voltage ASIC High Err  Threshold */
+#define	SK_SEN_VDD_HIGH_WARN	3476	/* Voltage ASIC High Warn Threshold */
+#define	SK_SEN_VDD_LOW_WARN		3146	/* Voltage ASIC Low  Warn Threshold */
+#define	SK_SEN_VDD_LOW_ERR		2970	/* Voltage ASIC Low  Err  Threshold */
 
 /*
  * PHY PLL 3V3 voltage
@@ -255,8 +260,8 @@
 #define	SK_SEN_VAUX_3V3_HIGH_ERR	3630	/* Voltage VAUX High Err Threshold */
 #define	SK_SEN_VAUX_3V3_HIGH_WARN	3476	/* Voltage VAUX High Warn Threshold */
 #define	SK_SEN_VAUX_3V3_LOW_WARN	3146	/* Voltage VAUX Low Warn Threshold */
-#define	SK_SEN_VAUX_3V3_LOW_ERR	    2970	/* Voltage VAUX Low Err Threshold */
-#define	SK_SEN_VAUX_0V_WARN_ERR	       0	/* if VAUX not present */
+#define	SK_SEN_VAUX_3V3_LOW_ERR		2970	/* Voltage VAUX Low Err Threshold */
+#define	SK_SEN_VAUX_0V_WARN_ERR		   0	/* if VAUX not present */
 #define	SK_SEN_VAUX_RANGE_LIMITER	1000	/* 1000 mV range delimiter */
 
 /*
@@ -270,7 +275,7 @@
 /*
  * ASIC Core 1V5 voltage (YUKON only)
  */
-#define	SK_SEN_CORE_1V5_HIGH_ERR    1650	/* Voltage ASIC Core High Err Threshold */
+#define	SK_SEN_CORE_1V5_HIGH_ERR	1650	/* Voltage ASIC Core High Err Threshold */
 #define	SK_SEN_CORE_1V5_HIGH_WARN	1575	/* Voltage ASIC Core High Warn Threshold */
 #define	SK_SEN_CORE_1V5_LOW_WARN	1425	/* Voltage ASIC Core Low Warn Threshold */
 #define	SK_SEN_CORE_1V5_LOW_ERR 	1350	/* Voltage ASIC Core Low Err Threshold */
@@ -285,8 +290,8 @@
  */
 #define	SK_SEN_FAN_HIGH_ERR		20000	/* FAN Speed High Err Threshold */
 #define	SK_SEN_FAN_HIGH_WARN	20000	/* FAN Speed High Warn Threshold */
-#define	SK_SEN_FAN_LOW_WARN 	5200	/* FAN Speed Low Warn Threshold */
-#define	SK_SEN_FAN_LOW_ERR		4550	/* FAN Speed Low Err Threshold */
+#define	SK_SEN_FAN_LOW_WARN		 5200	/* FAN Speed Low Warn Threshold */
+#define	SK_SEN_FAN_LOW_ERR		 4550	/* FAN Speed Low Err Threshold */
 
 /*
  * Some Voltages need dynamic thresholds
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skgeinit.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skgeinit.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skgeinit.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skgeinit.h	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skgeinit.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
- * Version:	$Revision: 1.81 $
- * Date:	$Date: 2003/07/04 12:30:38 $
+ * Version:	$Revision: 1.83 $
+ * Date:	$Date: 2003/09/16 14:07:37 $
  * Purpose:	Structures and prototypes for the GE Init Module
  *
  ******************************************************************************/
@@ -27,6 +27,23 @@
  * History:
  *
  *	$Log: skgeinit.h,v $
+ *	Revision 1.83  2003/09/16 14:07:37  rschmidt
+ *	Moved defines for PHY power down modes from skgehw.h
+ *	Added prototypes for SkMacClearRst()
+ *	Editorial changes
+ *	
+ *	Revision 1.82  2003/09/16 07:18:36  mschmid
+ *	Added members to port structure for MAC control
+ *	- PMacColThres
+ *	- PMacJamLen
+ *	- PMacJamIpgVal
+ *	- PMacJamIpgData
+ *	- PMacIpgData
+ *	- PMacLimit4
+ *	Added PHY power state to port structure
+ *	- PPhyPowerState
+ *	Added function prototypes to enter and leave low power modes
+ *	
  *	Revision 1.81  2003/07/04 12:30:38  rschmidt
  *	Added SK_FAR to pointers in MAC statistic functions (for PXE)
  *	Editorial changes
@@ -594,6 +611,13 @@
 #define SK_PRT_INIT		2	/* the port is initialized */
 #define SK_PRT_RUN		3	/* the port has an active link */
 
+/* PHY power down modes */
+#define PHY_PM_OPERATIONAL_MODE		0	/* PHY operational mode */
+#define PHY_PM_DEEP_SLEEP			1	/* coma mode --> minimal power */
+#define PHY_PM_IEEE_POWER_DOWN		2	/* IEEE 22.2.4.1.5 compl. power down */
+#define PHY_PM_ENERGY_DETECT		3	/* energy detect */
+#define PHY_PM_ENERGY_DETECT_PLUS	4	/* energy detect plus */
+
 /* Default receive frame limit for Workaround of XMAC Errata */
 #define SK_DEF_RX_WA_LIM	SK_CONSTU64(100)
 
@@ -685,6 +709,13 @@
 	SK_U8	PCableLen;		/* Cable Length */
 	SK_U8	PMdiPairLen[4];	/* MDI[0..3] Pair Length */
 	SK_U8	PMdiPairSts[4];	/* MDI[0..3] Pair Diagnostic Status */
+	SK_U8	PPhyPowerState;	/* PHY current power state */
+	int		PMacColThres;	/* MAC Collision Threshold */
+	int		PMacJamLen;		/* MAC Jam length */
+	int		PMacJamIpgVal;	/* MAC Jam IPG */
+	int		PMacJamIpgData;	/* MAC IPG Jam to Data */
+	int		PMacIpgData;	/* MAC Data IPG */
+	SK_BOOL PMacLimit4;		/* reset collision counter and backoff algorithm */
 } SK_GEPORT;
 
 /*
@@ -865,6 +896,11 @@
 	SK_IOC	IoC,
 	int		Port);
 
+extern void	SkMacClearRst(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	int		Port);
+
 extern void	SkXmInitMac(
 	SK_AC	*pAC,
 	SK_IOC	IoC,
@@ -1040,6 +1076,17 @@
 	int		Port,
 	SK_BOOL	StartTest);
 
+extern int SkGmEnterLowPowerMode(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	int		Port,
+	SK_U8	Mode);
+
+extern int SkGmLeaveLowPowerMode(
+	SK_AC	*pAC,
+	SK_IOC	IoC,
+	int		Port);
+
 #ifdef SK_DIAG
 extern void	SkGePhyRead(
 	SK_AC	*pAC,
@@ -1101,6 +1148,7 @@
 extern void SkMacRxTxDisable();
 extern void	SkMacSoftRst();
 extern void	SkMacHardRst();
+extern void	SkMacClearRst();
 extern void SkMacInitPhy();
 extern int  SkMacRxTxEnable();
 extern void SkMacPromiscMode();
@@ -1131,6 +1179,8 @@
 extern int	SkXmOverflowStatus();
 extern int	SkGmOverflowStatus();
 extern int	SkGmCableDiagStatus();
+extern int	SkGmEnterLowPowerMode();
+extern int	SkGmLeaveLowPowerMode();
 
 #ifdef SK_DIAG
 extern void	SkGePhyRead();
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skgepnmi.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skgepnmi.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skgepnmi.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skgepnmi.h	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skgepnmi.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.61 $
- * Date:	$Date: 2003/05/23 12:53:52 $
+ * Version:	$Revision: 1.62 $
+ * Date:	$Date: 2003/08/15 12:31:52 $
  * Purpose:	Defines for Private Network Management Interface
  *
  ****************************************************************************/
@@ -27,6 +27,18 @@
  * History:
  *
  *	$Log: skgepnmi.h,v $
+ *	Revision 1.62  2003/08/15 12:31:52  tschilli
+ *	Added new OIDs:
+ *	OID_SKGE_DRIVER_RELDATE
+ *	OID_SKGE_DRIVER_FILENAME
+ *	OID_SKGE_CHIPID
+ *	OID_SKGE_RAMSIZE
+ *	OID_SKGE_VAUXAVAIL
+ *	OID_SKGE_PHY_TYPE
+ *	OID_SKGE_PHY_LP_MODE
+ *	
+ *	Added new define SK_DIAG_ATTACHED for OID_SKGE_DIAG_MODE handling.
+ *	
  *	Revision 1.61  2003/05/23 12:53:52  tschilli
  *	Generic PNMI IOCTL subcommands added.
  *	Function prototype SkPnmiGenIoctl() added.
@@ -568,15 +580,23 @@
 #define OID_SKGE_ALL_DATA				0xFF020190
 
 /* Defines for VCT. */
-#define OID_SKGE_VCT_GET			0xFF020200
-#define OID_SKGE_VCT_SET			0xFF020201
-#define OID_SKGE_VCT_STATUS			0xFF020202
+#define OID_SKGE_VCT_GET				0xFF020200
+#define OID_SKGE_VCT_SET				0xFF020201
+#define OID_SKGE_VCT_STATUS				0xFF020202
 
 #ifdef SK_DIAG_SUPPORT
 /* Defines for driver DIAG mode. */
-#define OID_SKGE_DIAG_MODE			0xFF020204
+#define OID_SKGE_DIAG_MODE				0xFF020204
 #endif /* SK_DIAG_SUPPORT */
 
+/* New OIDs */
+#define OID_SKGE_DRIVER_RELDATE			0xFF020210
+#define OID_SKGE_DRIVER_FILENAME		0xFF020211
+#define OID_SKGE_CHIPID					0xFF020212
+#define OID_SKGE_RAMSIZE				0xFF020213
+#define OID_SKGE_VAUXAVAIL				0xFF020214
+#define OID_SKGE_PHY_TYPE				0xFF020215
+#define OID_SKGE_PHY_LP_MODE			0xFF020216
 
 /* VCT struct to store a backup copy of VCT data after a port reset. */
 typedef struct s_PnmiVct {
@@ -613,6 +633,12 @@
 #define OID_SKGE_TRAP_RLMT_PORT_UP		523
 #define OID_SKGE_TRAP_RLMT_SEGMENTATION	524
 
+#ifdef SK_DIAG_SUPPORT
+/* Defines for driver DIAG mode. */
+#define SK_DIAG_ATTACHED	2
+#define SK_DIAG_RUNNING		1
+#define SK_DIAG_IDLE		0
+#endif /* SK_DIAG_SUPPORT */
 
 /*
  * Generic PNMI IOCTL subcommand definitions.
@@ -730,6 +756,14 @@
 #define SK_PNMI_ERR051MSG	"SkPnmiEvent: Port switch suspicious"
 #define SK_PNMI_ERR052		(SK_ERRBASE_PNMI + 52)
 #define SK_PNMI_ERR052MSG	""
+#define SK_PNMI_ERR053		(SK_ERRBASE_PNMI + 53)
+#define SK_PNMI_ERR053MSG	"General: Driver release date not initialized"
+#define SK_PNMI_ERR054		(SK_ERRBASE_PNMI + 54)
+#define SK_PNMI_ERR054MSG	"General: Driver release date string too long"
+#define SK_PNMI_ERR055		(SK_ERRBASE_PNMI + 55)
+#define SK_PNMI_ERR055MSG	"General: Driver file name not initialized"
+#define SK_PNMI_ERR056		(SK_ERRBASE_PNMI + 56)
+#define SK_PNMI_ERR056MSG	"General: Driver file name string too long"
 
 /*
  * Management counter macros called by the driver
@@ -740,6 +774,11 @@
 #define SK_PNMI_SET_DRIVER_VER(pAC,v)	((pAC)->Pnmi.pDriverVersion = \
 	(char *)(v))
 
+#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v)	((pAC)->Pnmi.pDriverReleaseDate = \
+	(char *)(v))
+
+#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v)	((pAC)->Pnmi.pDriverFileName = \
+	(char *)(v))
 
 #define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
 	{ \
@@ -916,6 +955,8 @@
 	char			ConfMacFactoryAddr[6];
 	SK_U8			ConfPMD;
 	SK_U8			ConfConnector;
+	SK_U32			ConfPhyType;
+	SK_U32			ConfPhyMode;
 	SK_U8			ConfLinkCapability;
 	SK_U8			ConfLinkMode;
 	SK_U8			ConfLinkModeStatus;
@@ -964,9 +1005,14 @@
 	SK_U32			DeviceType;
 	char			DriverDescr[SK_PNMI_STRINGLEN1];
 	char			DriverVersion[SK_PNMI_STRINGLEN2];
+	char			DriverReleaseDate[SK_PNMI_STRINGLEN1];
+	char			DriverFileName[SK_PNMI_STRINGLEN1];
 	char			HwDescr[SK_PNMI_STRINGLEN1];
 	char			HwVersion[SK_PNMI_STRINGLEN2];
 	SK_U16			Chipset;
+	SK_U32			ChipId;
+	SK_U8			VauxAvail;
+	SK_U32			RamSize;
 	SK_U32			MtuSize;
 	SK_U32			Action;
 	SK_U32			TestResult;
@@ -1090,6 +1136,8 @@
 
 	char			*pDriverDescription;
 	char			*pDriverVersion;
+	char			*pDriverReleaseDate;
+	char			*pDriverFileName;
 
 	int				MacUpdatedFlag;
 	int				RlmtUpdatedFlag;
@@ -1119,6 +1167,9 @@
 	SK_U8		VctStatus[SK_MAX_MACS];
 	SK_PNMI_VCT	VctBackup[SK_MAX_MACS];
 	SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
+#ifdef SK_DIAG_SUPPORT
+	SK_U32			DiagAttached;
+#endif /* SK_DIAG_SUPPORT */
 } SK_PNMI;
 
 
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/ski2c.h linux-2.4.24-pre2/drivers/net/sk98lin/h/ski2c.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/ski2c.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/ski2c.h	2003-12-22 11:34:35.000000000 -0800
@@ -1,16 +1,17 @@
 /******************************************************************************
  *
  * Name:	ski2c.h
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.34 $
- * Date:	$Date: 2003/01/28 09:11:21 $
+ * Project:	Gigabit Ethernet Adapters, TWSI-Module
+ * Version:	$Revision: 1.35 $
+ * Date:	$Date: 2003/10/20 09:06:30 $
  * Purpose:	Defines to access Voltage and Temperature Sensor
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -26,6 +27,10 @@
  * History:
  *
  *	$Log: ski2c.h,v $
+ *	Revision 1.35  2003/10/20 09:06:30  rschmidt
+ *	Added prototypes for SkI2cRead() and SkI2cWrite().
+ *	Editorial changes.
+ *	
  *	Revision 1.34  2003/01/28 09:11:21  rschmidt
  *	Editorial changes
  *	
@@ -137,7 +142,6 @@
  *	Revision 1.1  1998/06/19 14:30:10  malthoff
  *	Created. Sources taken from ML Project.
  *
- *
  ******************************************************************************/
 
 /*
@@ -252,7 +256,7 @@
 	SK_I32	SenThreWarnLow;		/* Lower warning Threshold of the sensor */
 	int		SenErrFlag;			/* Sensor indicated an error */
 	SK_BOOL	SenInit;			/* Is sensor initialized ? */
-	SK_U64	SenErrCts;			/* Error  trap counter */
+	SK_U64	SenErrCts;			/* Error trap counter */
 	SK_U64	SenWarnCts;			/* Warning trap counter */
 	SK_U64	SenBegErrTS;		/* Begin error timestamp */
 	SK_U64	SenBegWarnTS;		/* Begin warning timestamp */
@@ -279,13 +283,17 @@
 #endif /* !SK_DIAG */
 } SK_I2C;
 
+extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
+extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size,
+					   int Reg, int Burst);
 extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
-#ifndef SK_DIAG
+#ifdef SK_DIAG
+extern	SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
+						 int Burst);
+#else /* !SK_DIAG */
 extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
-extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
 extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
 extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
-
-#endif
+#endif /* !SK_DIAG */
 #endif /* n_SKI2C_H */
 
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skqueue.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skqueue.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skqueue.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skqueue.h	2003-12-22 11:34:35.000000000 -0800
@@ -1,9 +1,9 @@
 /******************************************************************************
  *
  * Name:	skqueue.h
- * Project:	Gigabit Ethernet Adapters, Schedule-Modul
- * Version:	$Revision: 1.15 $
- * Date:	$Date: 2003/05/13 17:54:57 $
+ * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 1.16 $
+ * Date:	$Date: 2003/09/16 12:50:32 $
  * Purpose:	Defines for the Event queue
  *
  ******************************************************************************/
@@ -27,6 +27,9 @@
  * History:
  *
  *	$Log: skqueue.h,v $
+ *	Revision 1.16  2003/09/16 12:50:32  rschmidt
+ *	Editorial changes
+ *	
  *	Revision 1.15  2003/05/13 17:54:57  mkarl
  *	Editorial changes.
  *	
@@ -47,7 +50,7 @@
  *	add: typedef SK_QUEUE
  *	
  *	Revision 1.9  1998/08/19 09:50:59  gklug
- *	fix: remove struct keyword from c-code (see CCC) add typedefs
+ *	fix: remove struct keyword from C-code (see CCC) add typedefs
  *	
  *	Revision 1.8  1998/08/18 07:00:01  gklug
  *	fix: SK_PTR not defined use void * instead.
@@ -74,8 +77,6 @@
  *	Revision 1.1  1998/07/30 14:52:12  gklug
  *	Initial version.
  *	Defines Event Classes, Event structs and queue management variables.
- *	
- *	
  *
  ******************************************************************************/
 
@@ -92,7 +93,7 @@
  */
 #define	SKGE_DRV	1	/* Driver Event Class */
 #define	SKGE_RLMT	2	/* RLMT Event Class */
-#define	SKGE_I2C	3	/* i2C Event Class */
+#define	SKGE_I2C	3	/* I2C Event Class */
 #define	SKGE_PNMI	4	/* PNMI Event Class */
 #define	SKGE_CSUM	5	/* Checksum Event Class */
 #define	SKGE_HWAC	6	/* Hardware Access Event Class */
@@ -121,25 +122,25 @@
  * Event Queue
  *	skqueue.c
  * events are class/value pairs
- *	class	is addressee, e.g. RMT, PCM etc.
+ *	class	is addressee, e.g. RLMT, PNMI etc.
  *	value	is command, e.g. line state change, ring op change etc.
  */
 typedef	struct s_EventElem {
-	SK_U32		Class ;			/* Event class */
-	SK_U32		Event ;			/* Event value */
-	SK_EVPARA	Para ;			/* Event parameter */
+	SK_U32		Class;			/* Event class */
+	SK_U32		Event;			/* Event value */
+	SK_EVPARA	Para;			/* Event parameter */
 } SK_EVENTELEM;
 
 typedef	struct s_Queue {
 	SK_EVENTELEM	EvQueue[SK_MAX_EVENT];
-	SK_EVENTELEM	*EvPut ;
-	SK_EVENTELEM	*EvGet ;
+	SK_EVENTELEM	*EvPut;
+	SK_EVENTELEM	*EvGet;
 } SK_QUEUE;
 
 extern	void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
 extern	void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
 	SK_EVPARA Para);
-extern	int SkEventDispatcher(SK_AC *pAC,SK_IOC Ioc);
+extern	int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc);
 
 
 /* Define Error Numbers and messages */
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/sktimer.h linux-2.4.24-pre2/drivers/net/sk98lin/h/sktimer.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/sktimer.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/sktimer.h	2003-12-22 11:34:35.000000000 -0800
@@ -1,9 +1,9 @@
 /******************************************************************************
  *
  * Name:	sktimer.h
- * Project:	Gigabit Ethernet Adapters, Schedule-Modul
- * Version:	$Revision: 1.10 $
- * Date:	$Date: 2003/05/13 17:56:44 $
+ * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 1.11 $
+ * Date:	$Date: 2003/09/16 12:58:18 $
  * Purpose:	Defines for the timer functions
  *
  ******************************************************************************/
@@ -27,6 +27,9 @@
  * History:
  *
  *	$Log: sktimer.h,v $
+ *	Revision 1.11  2003/09/16 12:58:18  rschmidt
+ *	Editorial changes
+ *	
  *	Revision 1.10  2003/05/13 17:56:44  mkarl
  *	Editorial changes.
  *	
@@ -40,7 +43,7 @@
  *	fix: SK_TIMCTRL needs to be defined
  *	
  *	Revision 1.6  1998/08/19 09:51:00  gklug
- *	fix: remove struct keyword from c-code (see CCC) add typedefs
+ *	fix: remove struct keyword from C-code (see CCC) add typedefs
  *	
  *	Revision 1.5  1998/08/17 13:43:21  gklug
  *	chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
@@ -78,25 +81,25 @@
 typedef	struct s_Timer SK_TIMER;
 
 struct s_Timer {
-	SK_TIMER	*TmNext ;	/* linked list */
-	SK_U32		TmClass ;	/* Timer Event class */
-	SK_U32		TmEvent ;	/* Timer Event value */
-	SK_EVPARA	TmPara ;	/* Timer Event parameter */
-	SK_U32		TmDelta ;	/* delta time */
-	int		TmActive ;	/* flag : active/inactive */
-} ;
+	SK_TIMER	*TmNext;	/* linked list */
+	SK_U32		TmClass;	/* Timer Event class */
+	SK_U32		TmEvent;	/* Timer Event value */
+	SK_EVPARA	TmPara;		/* Timer Event parameter */
+	SK_U32		TmDelta;	/* delta time */
+	int			TmActive;	/* flag: active/inactive */
+};
 
 /*
  * Timer control struct.
  * - use in Adapters context name pAC->Tim
  */
 typedef	struct s_TimCtrl {
-	SK_TIMER	*StQueue ;	/* Head of Timer queue */
-} SK_TIMCTRL ;
+	SK_TIMER	*StQueue;	/* Head of Timer queue */
+} SK_TIMCTRL;
 
-extern void SkTimerInit(SK_AC *pAC,SK_IOC Ioc, int Level);
-extern void SkTimerStop(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer);
-extern void SkTimerStart(SK_AC *pAC,SK_IOC Ioc,SK_TIMER *pTimer,
-	SK_U32 Time,SK_U32 Class,SK_U32 Event,SK_EVPARA Para);
-extern void SkTimerDone(SK_AC *pAC,SK_IOC Ioc);
+extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level);
+extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer);
+extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer,
+	SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para);
+extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc);
 #endif	/* _SKTIMER_H_ */
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/sktypes.h linux-2.4.24-pre2/drivers/net/sk98lin/h/sktypes.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/sktypes.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/sktypes.h	2003-12-22 11:34:35.000000000 -0800
@@ -2,15 +2,16 @@
  *
  * Name:	sktypes.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.1 $
- * Date:	$Date: 2003/07/21 07:26:01 $
+ * Version:	$Revision: 1.2 $
+ * Date:	$Date: 2003/10/07 08:16:51 $
  * Purpose:	Define data types for Linux
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -26,6 +27,9 @@
  * History:
  *
  *	$Log: sktypes.h,v $
+ *	Revision 1.2  2003/10/07 08:16:51  mlindner
+ *	Fix: Copyright changes
+ *	
  *	Revision 1.1  2003/07/21 07:26:01  rroesler
  *	Fix: Re-Enter after CVS crash
  *	
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/skversion.h linux-2.4.24-pre2/drivers/net/sk98lin/h/skversion.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/skversion.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/skversion.h	2003-12-22 11:34:35.000000000 -0800
@@ -2,15 +2,16 @@
  *
  * Name:	version.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.3 $
- * Date:	$Date: 2003/08/25 13:34:48 $
+ * Version:	$Revision: 1.5 $
+ * Date:	$Date: 2003/10/07 08:16:51 $
  * Purpose:	SK specific Error log support
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -25,6 +26,12 @@
  *
  * History:
  *	$Log: skversion.h,v $
+ *	Revision 1.5  2003/10/07 08:16:51  mlindner
+ *	Fix: Copyright changes
+ *	
+ *	Revision 1.4  2003/09/22 08:40:10  mlindner
+ *	Add: Added DRIVER_FILE_NAME and DRIVER_REL_DATE
+ *	
  *	Revision 1.3  2003/08/25 13:34:48  mlindner
  *	Fix: Lint changes
  *	
@@ -54,12 +61,14 @@
 #ifdef	lint
 static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
 static const char SysKonnectBuildNumber[] =
-	"@(#)SK-BUILD: 6.18 PL: 01"; 
+	"@(#)SK-BUILD: 6.21 PL: 01"; 
 #endif	/* !defined(lint) */
 
-#define BOOT_STRING	"sk98lin: Network Device Driver v6.18\n" \
+#define BOOT_STRING	"sk98lin: Network Device Driver v6.21\n" \
 			"(C)Copyright 1999-2003 Marvell(R)."
 
-#define VER_STRING	"6.18"
+#define VER_STRING	"6.21"
+#define DRIVER_FILE_NAME	"sk98lin"
+#define DRIVER_REL_DATE		"Dec-15-2003"
 
 
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/h/xmac_ii.h linux-2.4.24-pre2/drivers/net/sk98lin/h/xmac_ii.h
--- linux-2.4.24-pre1/drivers/net/sk98lin/h/xmac_ii.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/h/xmac_ii.h	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	xmac_ii.h
  * Project:	Gigabit Ethernet Adapters, Common Modules
- * Version:	$Revision: 1.48 $
- * Date:	$Date: 2003/05/13 17:17:55 $
+ * Version:	$Revision: 1.52 $
+ * Date:	$Date: 2003/10/02 16:35:50 $
  * Purpose:	Defines and Macros for Gigabit Ethernet Controller
  *
  ******************************************************************************/
@@ -27,6 +27,22 @@
  * History:
  *
  *	$Log: xmac_ii.h,v $
+ *	Revision 1.52  2003/10/02 16:35:50  rschmidt
+ *	Added defines for default values of GMAC parameters
+ *	Changed defines for setting GMAC parameters
+ *	Editorial changes
+ *	
+ *	Revision 1.51  2003/09/23 09:04:27  malthoff
+ *	Add bit definitions for PHY_MARV_EXT_P_STAT.
+ *	
+ *	Revision 1.50  2003/09/16 14:15:07  rschmidt
+ *	Added defines for Extended PHY Specific Control
+ *	Editorial changes
+ *	
+ *	Revision 1.49  2003/09/16 07:22:46  mschmid
+ *	Added defines for Marvell PHY energy detect modes
+ *	Added macros for MAC parameter setting in port structure
+ *	
  *	Revision 1.48  2003/05/13 17:17:55  mkarl
  *	Editorial changes.
  *	
@@ -676,7 +692,7 @@
 #define PHY_XMAC_AUNE_LP	0x05	/* 16 bit r/o	Link Partner Abi Reg */
 #define PHY_XMAC_AUNE_EXP	0x06	/* 16 bit r/o	Auto-Neg. Expansion Reg */
 #define PHY_XMAC_NEPG		0x07	/* 16 bit r/w	Next Page Register */
-#define PHY_XMAC_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link P Reg */
+#define PHY_XMAC_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link Partner */
 	/* 0x09 - 0x0e:		reserved */
 #define PHY_XMAC_EXT_STAT	0x0f	/* 16 bit r/o	Ext Status Register */
 #define PHY_XMAC_RES_ABI	0x10	/* 16 bit r/o	PHY Resolved Ability */
@@ -693,7 +709,7 @@
 #define PHY_BCOM_AUNE_LP	0x05	/* 16 bit r/o	Link Part Ability Reg */
 #define PHY_BCOM_AUNE_EXP	0x06	/* 16 bit r/o	Auto-Neg. Expansion Reg */
 #define PHY_BCOM_NEPG		0x07	/* 16 bit r/w	Next Page Register */
-#define PHY_BCOM_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link P Reg */
+#define PHY_BCOM_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link Partner */
 	/* Broadcom-specific registers */
 #define PHY_BCOM_1000T_CTRL	0x09	/* 16 bit r/w	1000Base-T Ctrl Reg */
 #define PHY_BCOM_1000T_STAT	0x0a	/* 16 bit r/o	1000Base-T Status Reg */
@@ -702,7 +718,7 @@
 #define PHY_BCOM_P_EXT_CTRL	0x10	/* 16 bit r/w	PHY Extended Ctrl Reg */
 #define PHY_BCOM_P_EXT_STAT	0x11	/* 16 bit r/o	PHY Extended Stat Reg */
 #define PHY_BCOM_RE_CTR		0x12	/* 16 bit r/w	Receive Error Counter */
-#define PHY_BCOM_FC_CTR		0x13	/* 16 bit r/w	False Carr Sense Cnt */
+#define PHY_BCOM_FC_CTR		0x13	/* 16 bit r/w	False Carrier Sense Cnt */
 #define PHY_BCOM_RNO_CTR	0x14	/* 16 bit r/w	Receiver NOT_OK Cnt */
 	/* 0x15 - 0x17:		reserved */
 #define PHY_BCOM_AUX_CTRL	0x18	/* 16 bit r/w	Auxiliary Control Reg */
@@ -724,7 +740,7 @@
 #define PHY_MARV_AUNE_LP	0x05	/* 16 bit r/o	Link Part Ability Reg */
 #define PHY_MARV_AUNE_EXP	0x06	/* 16 bit r/o	Auto-Neg. Expansion Reg */
 #define PHY_MARV_NEPG		0x07	/* 16 bit r/w	Next Page Register */
-#define PHY_MARV_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link P Reg */
+#define PHY_MARV_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link Partner */
 	/* Marvel-specific registers */
 #define PHY_MARV_1000T_CTRL	0x09	/* 16 bit r/w	1000Base-T Ctrl Reg */
 #define PHY_MARV_1000T_STAT	0x0a	/* 16 bit r/o	1000Base-T Status Reg */
@@ -757,7 +773,7 @@
 #define PHY_LONE_AUNE_LP	0x05	/* 16 bit r/o	Link Part Ability Reg */
 #define PHY_LONE_AUNE_EXP	0x06	/* 16 bit r/o	Auto-Neg. Expansion Reg */
 #define PHY_LONE_NEPG		0x07	/* 16 bit r/w	Next Page Register */
-#define PHY_LONE_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link Partner*/
+#define PHY_LONE_NEPG_LP	0x08	/* 16 bit r/o	Next Page Link Partner */
 	/* Level One-specific registers */
 #define PHY_LONE_1000T_CTRL	0x09	/* 16 bit r/w	1000Base-T Control Reg*/
 #define PHY_LONE_1000T_STAT	0x0a	/* 16 bit r/o	1000Base-T Status Reg */
@@ -804,12 +820,13 @@
 /*
  * PHY bit definitions
  * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
- * Xmac/Broadcom/LevelOne/National-specific.
+ * XMAC/Broadcom/LevelOne/National/Marvell-specific.
  * All other are general.
  */
 
 /*****  PHY_XMAC_CTRL	16 bit r/w	PHY Control Register *****/
 /*****  PHY_BCOM_CTRL	16 bit r/w	PHY Control Register *****/
+/*****  PHY_MARV_CTRL	16 bit r/w	PHY Status Register *****/
 /*****  PHY_LONE_CTRL	16 bit r/w	PHY Control Register *****/
 #define PHY_CT_RESET	(1<<15)	/* Bit 15: (sc)	clear all PHY related regs */
 #define PHY_CT_LOOP		(1<<14)	/* Bit 14:	enable Loopback over PHY */
@@ -909,27 +926,20 @@
 
 /*****  PHY_XMAC_AUNE_EXP	16 bit r/o	Auto-Negotiation Expansion Reg *****/
 								/* Bit 15..4:	reserved */
-#define PHY_AN_LP_NP	(1<<3)	/* Bit  3:	Link Partner can Next Page */
-#define PHY_AN_LOC_NP	(1<<2)	/* Bit  2:	Local PHY can Next Page */
-#define PHY_AN_RX_PG	(1<<1)	/* Bit  1:	Page Received */
+#define PHY_ANE_LP_NP	(1<<3)	/* Bit  3:	Link Partner can Next Page */
+#define PHY_ANE_LOC_NP	(1<<2)	/* Bit  2:	Local PHY can Next Page */
+#define PHY_ANE_RX_PG	(1<<1)	/* Bit  1:	Page Received */
 								/* Bit  0:	reserved */
 
 /*****  PHY_BCOM_AUNE_EXP	16 bit r/o	Auto-Negotiation Expansion Reg *****/
-								/* Bit 15..5:	reserved */
-#define PHY_B_AN_PDF	(1<<4)	/* Bit  4:	Parallel Detection Fault */
-/*	PHY_AN_LP_NP		(see XMAC) Bit  3:	Link Partner can Next Page */
-/*	PHY_AN_LOC_NP		(see XMAC) Bit  2:	Local PHY can Next Page */
-/*	PHY_AN_RX_PG		(see XMAC) Bit  1:	Page Received */
-#define PHY_B_AN_LP_CAP	(1<<0)	/* Bit  0:	Link Partner Auto-Neg. Cap. */ 	
-
 /*****  PHY_LONE_AUNE_EXP	16 bit r/o	Auto-Negotiation Expansion Reg *****/
-#define PHY_L_AN_BP		(1<<5)	/* Bit  5:	Base Page Indication */
-#define PHY_L_AN_PDF	(1<<4)	/* Bit  4:	Parallel Detection Fault */
-/*	PHY_AN_LP_NP		(see XMAC) Bit  3:	Link Partner can Next Page */
-/*	PHY_AN_LOC_NP		(see XMAC) Bit  2:	Local PHY can Next Page */
-/*	PHY_AN_RX_PG		(see XMAC) Bit  1:	Page Received */
-#define PHY_B_AN_LP_CAP	(1<<0)	/* Bit  0:	Link Partner Auto-Neg. Cap. */ 	
-
+/*****  PHY_MARV_AUNE_EXP	16 bit r/o	Auto-Negotiation Expansion Reg *****/
+								/* Bit 15..5:	reserved */
+#define PHY_ANE_PAR_DF	(1<<4)	/* Bit  4:	Parallel Detection Fault */
+/*	PHY_ANE_LP_NP		(see XMAC) Bit  3:	Link Partner can Next Page */
+/*	PHY_ANE_LOC_NP		(see XMAC) Bit  2:	Local PHY can Next Page */
+/*	PHY_ANE_RX_PG		(see XMAC) Bit  1:	Page Received */
+#define PHY_ANE_LP_CAP	(1<<0)	/* Bit  0:	Link Partner Auto-Neg. Cap. */ 	
 
 /*****  PHY_XMAC_NEPG		16 bit r/w	Next Page Register *****/
 /*****  PHY_BCOM_NEPG		16 bit r/w	Next Page Register *****/
@@ -958,7 +968,7 @@
 #define PHY_X_RS_HD		(1<<6)	/* Bit  6:	Half Duplex Mode selected */
 #define PHY_X_RS_FD		(1<<5)	/* Bit  5:	Full Duplex Mode selected */
 #define PHY_X_RS_ABLMIS (1<<4)	/* Bit  4:	duplex or pause cap mismatch */
-#define PHY_X_RS_PAUMIS (1<<3)	/* Bit  3:	pause capability missmatch */
+#define PHY_X_RS_PAUMIS (1<<3)	/* Bit  3:	pause capability mismatch */
 								/* Bit  2..0:	reserved */
 /*
  * Remote Fault Bits (PHY_X_AN_RFB) encoding
@@ -990,6 +1000,7 @@
 									/* Bit  7..0:	reserved */
 
 /*****  PHY_BCOM_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
+/*****  PHY_MARV_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
 #define PHY_B_1000S_MSF		(1<<15)	/* Bit 15:	Master/Slave Fault */
 #define PHY_B_1000S_MSR		(1<<14)	/* Bit 14:	Master/Slave Result */
 #define PHY_B_1000S_LRS		(1<<13)	/* Bit 13:	Local Receiver Status */
@@ -1309,7 +1320,6 @@
 									/* Bit  7..0:	reserved */
 
 /*****  PHY_MARV_PHY_CTRL	16 bit r/w	PHY Specific Ctrl Reg *****/
-
 #define PHY_M_PC_TX_FFD_MSK	(3<<14)	/* Bit 15..14:	Tx FIFO Depth Mask */
 #define PHY_M_PC_RX_FFD_MSK	(3<<12)	/* Bit 13..12:	Rx FIFO Depth Mask */
 #define PHY_M_PC_ASS_CRS_TX	(1<<11)	/* Bit 11:	Assert CRS on Transmit */
@@ -1323,6 +1333,9 @@
 #define PHY_M_PC_POL_R_DIS	(1<<1)	/* Bit  1:	Polarity Reversal Disabled */
 #define PHY_M_PC_DIS_JABBER	(1<<0)	/* Bit  0:	Disable Jabber */
 
+#define PHY_M_PC_EN_DET			SHIFT8(2)	/* Energy Detect (Mode 1) */
+#define PHY_M_PC_EN_DET_PLUS	SHIFT8(3)	/* Energy Detect Plus (Mode 2) */
+
 #define PHY_M_PC_MDI_XMODE(x)	SHIFT5(x)	
 #define PHY_M_PC_MAN_MDI	0    	/* 00 = Manual MDI configuration */
 #define PHY_M_PC_MAN_MDIX	1		/* 01 = Manual MDIX configuration */
@@ -1373,6 +1386,7 @@
 #define PHY_M_EC_M_DSC_MSK	(3<<10)	/* Bit 11..10:	Master downshift counter */
 #define PHY_M_EC_S_DSC_MSK	(3<<8)	/* Bit  9.. 8:	Slave  downshift counter */
 #define PHY_M_EC_MAC_S_MSK	(7<<4)	/* Bit  6.. 4:	Def. MAC interface speed */
+#define PHY_M_EC_FIB_AN_ENA	(1<<3)	/* Bit  3:	Fiber Auto-Neg. Enable */
 
 #define PHY_M_EC_M_DSC(x)		SHIFT10(x)	/* 00=1x; 01=2x; 10=3x; 11=4x */
 #define PHY_M_EC_S_DSC(x)		SHIFT8(x)	/* 00=dis; 01=1x; 10=2x; 11=3x */
@@ -1434,6 +1448,18 @@
 #define PHY_M_EC2_FO_BOOST	(1<<3)	/* Bit  3:	Fiber Output Boost */
 #define PHY_M_EC2_FO_AM_MSK	7		/* Bit  2.. 0:	Fiber Output Amplitude */
 
+/*****	PHY_MARV_EXT_P_STAT 16 bit r/w	Ext. PHY Specific Status *****/
+#define PHY_M_FC_AUTO_SEL	(1<<15)	/* Bit 15:	Fiber/Copper Auto Sel. dis. */
+#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14:	Fiber/Copper Autoneg. reg acc */
+#define PHY_M_FC_RESULUTION (1<<13)	/* Bit 13:	Fiber/Copper Resulution */
+#define PHY_M_SER_IF_AN_BP  (1<<12) /* Bit 12:	Ser IF autoneg. bypass enable */
+#define PHY_M_SER_IF_BP_ST	(1<<11) /* Bit 11:	Ser IF autoneg. bypass status */
+#define PHY_M_IRQ_POLARITY	(1<<10) /* Bit 10:	IRQ polarity */
+									/* Bit 9..4: reserved */
+#define PHY_M_UNDOC1		(1<< 7) /* undocumented bit !! */
+#define PHY_M_MODE_MASK		(0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
+
+
 /*****  PHY_MARV_CABLE_DIAG	16 bit r/o	Cable Diagnostic Reg *****/
 #define PHY_M_CABD_ENA_TEST	(1<<15)	/* Bit 15:	Enable Test */
 #define PHY_M_CABD_STAT_MSK	(3<<13)	/* Bit 14..13:	Status */
@@ -1531,7 +1557,7 @@
 #define GM_RXF_SHT \
 			(GM_MIB_CNT_BASE + 80)	/* Frames <64 Byte Received OK */
 #define GM_RXE_FRAG \
-			(GM_MIB_CNT_BASE + 88)	/* Frames <64 Byte Receeived with FCS Err */
+			(GM_MIB_CNT_BASE + 88)	/* Frames <64 Byte Received with FCS Err */
 #define GM_RXF_64B \
 			(GM_MIB_CNT_BASE + 96)	/* 64 Byte Rx Frame */
 #define GM_RXF_127B \
@@ -1606,7 +1632,6 @@
  */
 
 /*	GM_GP_STAT	16 bit r/o	General Purpose Status Register */
-
 #define GM_GPSR_SPEED		(1<<15) /* Bit 15:	Port Speed (1 = 100 Mbps) */
 #define GM_GPSR_DUPLEX		(1<<14) /* Bit 14:	Duplex Mode (1 = Full) */
 #define GM_GPSR_FC_TX_DIS	(1<<13) /* Bit 13:	Tx Flow-Control Mode Disabled */
@@ -1646,11 +1671,14 @@
 							 GM_GPCR_AU_SPD_DIS)
 	
 /*	GM_TX_CTRL				16 bit r/w	Transmit Control Register */
-
 #define GM_TXCR_FORCE_JAM	(1<<15)	/* Bit 15:	Force Jam / Flow-Control */
 #define GM_TXCR_CRC_DIS		(1<<14)	/* Bit 14:	Disable insertion of CRC */
 #define GM_TXCR_PAD_DIS		(1<<13)	/* Bit 13:	Disable padding of packets */
-#define GM_TXCR_COL_THR		(4<<10)	/* Bit 12..10:	Collision Threshold */
+#define GM_TXCR_COL_THR_MSK	(1<<10)	/* Bit 12..10:	Collision Threshold */
+
+#define TX_COL_THR(x)		(SHIFT10(x) & GM_TXCR_COL_THR_MSK)
+
+#define TX_COL_DEF			0x04
 	
 /*	GM_RX_CTRL				16 bit r/w	Receive Control Register */
 #define GM_RXCR_UCF_ENA		(1<<15)	/* Bit 15:	Enable Unicast filtering */
@@ -1663,35 +1691,41 @@
 #define GM_TXPA_JAMIPG_MSK	(0x1f<<9)	/* Bit 13..9:	Jam IPG */
 #define GM_TXPA_JAMDAT_MSK	(0x1f<<4)	/* Bit  8..4:	IPG Jam to Data */
 								/* Bit  3..0:	reserved */
-#define JAM_LEN_VAL(x)		SHIFT14(x)
-#define JAM_IPG_VAL(x)		SHIFT9(x)
-#define IPG_JAM_DATA(x)		SHIFT4(x)
+
+#define TX_JAM_LEN_VAL(x)	(SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
+#define TX_JAM_IPG_VAL(x)	(SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
+#define TX_IPG_JAM_DATA(x)	(SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
+
+#define TX_JAM_LEN_DEF		0x03
+#define TX_JAM_IPG_DEF		0x0b
+#define TX_IPG_JAM_DEF		0x1c
 
 /*	GM_SERIAL_MODE			16 bit r/w	Serial Mode Register */
-#define GM_SMOD_DATABL_MSK	(0x1f<<11)	/* Bit 15..11:	Data Blinder */
+#define GM_SMOD_DATABL_MSK	(0x1f<<11)	/* Bit 15..11:	Data Blinder (r/o) */
 #define GM_SMOD_LIMIT_4		(1<<10)	/* Bit 10:	4 consecutive Tx trials */
 #define GM_SMOD_VLAN_ENA	(1<<9)	/* Bit  9:	Enable VLAN  (Max. Frame Len) */
 #define GM_SMOD_JUMBO_ENA	(1<<8)	/* Bit  8:	Enable Jumbo (Max. Frame Len) */
 								/* Bit  7..5:	reserved */
 #define GM_SMOD_IPG_MSK		0x1f	/* Bit 4..0:	Inter-Packet Gap (IPG) */
 	
-#define DATA_BLIND_VAL(x)	SHIFT11(x)
-#define DATA_BLIND_FAST_ETH	0x1c
-#define DATA_BLIND_GIGABIT	4
+#define DATA_BLIND_VAL(x)	(SHIFT11(x) & GM_SMOD_DATABL_MSK)
+#define DATA_BLIND_DEF		0x04
 
-#define IPG_VAL_FAST_ETH	0x1e
-#define IPG_VAL_GIGABIT		6
+#define IPG_DATA_VAL(x)		(x & GM_SMOD_IPG_MSK)
+#define IPG_DATA_DEF		0x1e
 
 /*	GM_SMI_CTRL				16 bit r/w	SMI Control Register */
-
-#define GM_SMI_CT_PHY_AD(x)	SHIFT11(x)
-#define GM_SMI_CT_REG_AD(x)	SHIFT6(x)
+#define GM_SMI_CT_PHY_A_MSK	(0x1f<<11)	/* Bit 15..11:	PHY Device Address */
+#define GM_SMI_CT_REG_A_MSK	(0x1f<<6)	/* Bit 10.. 6:	PHY Register Address */
 #define GM_SMI_CT_OP_RD		(1<<5)	/* Bit  5:	OpCode Read (0=Write)*/
 #define GM_SMI_CT_RD_VAL	(1<<4)	/* Bit  4:	Read Valid (Read completed) */
 #define GM_SMI_CT_BUSY		(1<<3)	/* Bit  3:	Busy (Operation in progress) */
 								/* Bit   2..0:	reserved */
 	
-/*	GM_PHY_ADDR				16 bit r/w	GPHY Address Register */
+#define GM_SMI_CT_PHY_AD(x)	(SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
+#define GM_SMI_CT_REG_AD(x)	(SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
+
+	/*	GM_PHY_ADDR				16 bit r/w	GPHY Address Register */
 								/* Bit  15..6:	reserved */
 #define GM_PAR_MIB_CLR		(1<<5)	/* Bit  5:	Set MIB Clear Counter Mode */
 #define GM_PAR_MIB_TST		(1<<4)	/* Bit  4:	MIB Load Counter (Test Mode) */
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skcsum.c linux-2.4.24-pre2/drivers/net/sk98lin/skcsum.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skcsum.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skcsum.c	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skcsum.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.11 $
- * Date:	$Date: 2003/03/11 14:05:55 $
+ * Version:	$Revision: 1.12 $
+ * Date:	$Date: 2003/08/20 13:55:53 $
  * Purpose:	Store/verify Internet checksum in send/receive packets.
  *
  ******************************************************************************/
@@ -26,6 +26,10 @@
  * History:
  *
  *	$Log: skcsum.c,v $
+ *	Revision 1.12  2003/08/20 13:55:53  mschmid
+ *	Changed notation of #ifndef SkCsCalculateChecksum to
+ *	#ifndef SK_CS_CALCULATE_CHECKSUM
+ *	
  *	Revision 1.11  2003/03/11 14:05:55  rschmidt
  *	Replaced memset() by macro SK_MEMSET()
  *	Editorial changes
@@ -78,7 +82,7 @@
 
 #ifndef lint
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skcsum.c,v 1.11 2003/03/11 14:05:55 rschmidt Exp $ (C) SysKonnect.";
+	"@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect.";
 #endif	/* !lint */
 
 /******************************************************************************
@@ -791,7 +795,7 @@
 	*pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;
 }	/* SkCsSetReceiveFlags */
 
-#ifndef SkCsCalculateChecksum
+#ifndef SK_CS_CALCULATE_CHECKSUM
 
 /******************************************************************************
  *
@@ -856,7 +860,7 @@
 	return ((unsigned) Checksum);
 }	/* SkCsCalculateChecksum */
 
-#endif /* SkCsCalculateChecksum */
+#endif /* SK_CS_CALCULATE_CHECKSUM */
 
 /******************************************************************************
  *
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skdim.c linux-2.4.24-pre2/drivers/net/sk98lin/skdim.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skdim.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skdim.c	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skdim.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.2 $
- * Date:	$Date: 2003/08/21 12:35:05 $
+ * Version:	$Revision: 1.5 $
+ * Date:	$Date: 2003/11/28 12:55:40 $
  * Purpose:	All functions to maintain interrupt moderation
  *
  ******************************************************************************/
@@ -11,6 +11,7 @@
 /******************************************************************************
  *
  *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -26,6 +27,15 @@
  * History:
  *	
  *	$Log: skdim.c,v $
+ *	Revision 1.5  2003/11/28 12:55:40  rroesler
+ *	Fix: support for new process timing interface added
+ *	
+ *	Revision 1.4  2003/10/10 10:58:56  mlindner
+ *	Fix: CPU detection under the kernel 2.6
+ *	
+ *	Revision 1.3  2003/10/07 08:17:08  mlindner
+ *	Fix: Copyright changes
+ *	
  *	Revision 1.2  2003/08/21 12:35:05  mlindner
  *	Fix: Corrected CPU detection and compile errors on single CPU machines
  *	
@@ -62,7 +72,7 @@
 
 #ifndef	lint
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skdim.c,v 1.2 2003/08/21 12:35:05 mlindner Exp $ (C) SysKonnect.";
+	"@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
 #endif
 
 #define __SKADDR_C
@@ -318,6 +328,7 @@
 	unsigned int  TotalTime   = 0;
 	unsigned int  UsedTime    = 0;
 	unsigned int  SystemLoad  = 0;
+
 #ifdef CONFIG_SMP
 	unsigned int  SKNumCpus   = smp_num_cpus;
 #else
@@ -327,9 +338,23 @@
 	unsigned int  NbrCpu      = 0;
 
     for (NbrCpu = 0; NbrCpu < SKNumCpus; NbrCpu++) {
+#ifdef _LINUX_PROCESS_TIMING_H
+	/*
+	** all seconds and usec values being obtained from the
+	** process_timing entries need to be adapted to jiffies
+	** (in case we have a system supporting process times)
+	*/
+        UserTime   = UserTime   + (kstat_percpu[NbrCpu].user.tv_sec * 10)
+	                        + (kstat_percpu[NbrCpu].user.tv_usec/100000);
+        NiceTime   = NiceTime   + (kstat_percpu[NbrCpu].nice.tv_sec * 10)
+	                        + (kstat_percpu[NbrCpu].nice.tv_usec/100000);
+        SystemTime = SystemTime + (kstat_percpu[NbrCpu].system.tv_sec * 10)
+	                        + (kstat_percpu[NbrCpu].system.tv_usec/100000);
+#else
         UserTime   = UserTime   + kstat.per_cpu_user[NbrCpu];
         NiceTime   = NiceTime   + kstat.per_cpu_nice[NbrCpu];
         SystemTime = SystemTime + kstat.per_cpu_system[NbrCpu];
+#endif
     }
 
 	UsedTime  = UserTime + NiceTime + SystemTime;
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skge.c linux-2.4.24-pre2/drivers/net/sk98lin/skge.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skge.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skge.c	2003-12-22 11:34:35.000000000 -0800
@@ -1,35 +1,20 @@
 /******************************************************************************
  *
- * Name:    skge.c
+ * Name:	skge.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.11 $
- * Date:       	$Date: 2003/08/26 16:05:19 $
+ * Version:	$Revision: 1.42 $
+ * Date:       	$Date: 2003/12/12 10:05:43 $
  * Purpose:	The main driver source module
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2003 Marvell.
  *
- *	Driver for SysKonnect Gigabit Ethernet Server Adapters:
- *
- *	SK-9871 (single link 1000Base-ZX)
- *	SK-9872 (dual link   1000Base-ZX)
- *	SK-9861 (single link 1000Base-SX, VF45 Volition Plug)
- *	SK-9862 (dual link   1000Base-SX, VF45 Volition Plug)
- *	SK-9841 (single link 1000Base-LX)
- *	SK-9842 (dual link   1000Base-LX)
- *	SK-9843 (single link 1000Base-SX)
- *	SK-9844 (dual link   1000Base-SX)
- *	SK-9821 (single link 1000Base-T)
- *	SK-9822 (dual link   1000Base-T)
- *	SK-9881 (single link 1000Base-SX V2 LC)
- *	SK-9871 (single link 1000Base-ZX V2)
- *	SK-9861 (single link 1000Base-SX V2, VF45 Volition Plug)
- *	SK-9841 (single link 1000Base-LX V2)
- *	SK-9843 (single link 1000Base-SX V2)
- *	SK-9821 (single link 1000Base-T V2)
+ *	Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet 
+ *      Server Adapters.
  *
  *	Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
  *	SysKonnects GEnesis Solaris driver
@@ -56,6 +41,87 @@
  * History:
  *
  *	$Log: skge.c,v $
+ *	Revision 1.42  2003/12/12 10:05:43  mlindner
+ *	Fix: Format of error message corrected
+ *	
+ *	Revision 1.41  2003/12/11 16:03:57  mlindner
+ *	Fix: Create backup from pnmi data structure
+ *	
+ *	Revision 1.40  2003/12/11 12:14:48  mlindner
+ *	Fix: Initalize Board before network configuration
+ *	Fix: Change device names to driver name
+ *	
+ *	Revision 1.39  2003/12/10 08:57:38  rroesler
+ *	Fix: Modifications regarding try_module_get() and capable()
+ *	
+ *	Revision 1.38  2003/12/01 17:16:50  mlindner
+ *	Fix: Remove useless register_netdev
+ *	
+ *	Revision 1.37  2003/12/01 17:11:30  mlindner
+ *	Fix: Register net device before SkGeBoardInit
+ *	
+ *	Revision 1.36  2003/11/28 13:04:27  rroesler
+ *	Fix: do not print interface status in case DIAG is used
+ *	
+ *	Revision 1.35  2003/11/17 14:41:06  mlindner
+ *	Fix: Endif command
+ *	
+ *	Revision 1.34  2003/11/17 13:29:05  mlindner
+ *	Fix: Editorial changes
+ *	
+ *	Revision 1.33  2003/11/14 14:56:54  rroesler
+ *	Fix: corrected compilation warnings kernel 2.2
+ *	
+ *	Revision 1.32  2003/11/13 14:18:47  rroesler
+ *	Fix: added latest changes regarding the use of the proc system
+ *	
+ *	Revision 1.31  2003/11/13 09:28:35  rroesler
+ *	Fix: removed kernel warning 'driver changed get_stats after register'
+ *	
+ *	Revision 1.30  2003/11/11 13:15:27  rroesler
+ *	Fix: use suitables kernel usage count macros when using the diag
+ *	
+ *	Revision 1.29  2003/11/10 09:38:26  rroesler
+ *	Fix: restore PNMI structure backup for DIAG actions
+ *	
+ *	Revision 1.28  2003/11/07 17:28:45  rroesler
+ *	Fix: Additions for the LeaveDiagMode
+ *	
+ *	Revision 1.27  2003/11/03 13:21:14  mlindner
+ *	Add: SkGeBuffPad function for padding to ensure the trailing bytes exist
+ *	
+ *	Revision 1.26  2003/10/30 09:20:40  mlindner
+ *	Fix: Control bit check
+ *	
+ *	Revision 1.25  2003/10/29 07:43:37  rroesler
+ *	Fix: Implemented full None values handling for parameter Moderation
+ *	
+ *	Revision 1.24  2003/10/22 14:18:12  rroesler
+ *	Fix: DIAG handling for DualNet cards
+ *	
+ *	Revision 1.23  2003/10/17 10:05:13  mlindner
+ *	Add: New blinkmode for Morvell cards
+ *	
+ *	Revision 1.22  2003/10/15 12:31:25  rroesler
+ *	Fix: Corrected bugreport #10954 (Linux System crash when using vlans)
+ *	
+ *	Revision 1.21  2003/10/07 12:32:28  mlindner
+ *	Fix: Editorial changes
+ *	
+ *	Revision 1.20  2003/10/07 12:22:40  mlindner
+ *	Fix: Compiler warnings
+ *	
+ *	Revision 1.19  2003/10/07 09:33:40  mlindner
+ *	Fix: No warnings for illegal values of Mod and IntsPerSec
+ *	Fix: Speed 100 in Half Duplex not allowed for Yukon
+ *	Fix: PrefPort=B not allowed on single NICs
+ *	
+ *	Revision 1.18  2003/10/07 08:17:08  mlindner
+ *	Fix: Copyright changes
+ *	
+ *	Revision 1.17  2003/09/29 12:06:59  mlindner
+ *	*** empty log message ***
+ *	
  *	Revision 1.16  2003/09/23 11:07:35  mlindner
  *	Fix: IO-control return race condition
  *	Fix: Interrupt moderation value check
@@ -68,6 +134,12 @@
  *	Add: Yukon Plus changes (ChipID, PCI...)
  *	Fix: TCP and UDP Checksum calculation
  *	
+ *	Revision 1.13  2003/09/01 13:30:08  rroesler
+ *	Fix: Corrected missing defines
+ *	
+ *	Revision 1.12  2003/09/01 13:12:02  rroesler
+ *	Add: Code for improved DIAG Attach/Detach interface
+ *	
  *	Revision 1.11  2003/08/26 16:05:19  mlindner
  *	Fix: Compiler warnings (void *)
  *	
@@ -406,7 +478,6 @@
  *	<linux/module.h>
  *
  *	"h/skdrv1st.h"
- *		<linux/version.h>
  *		<linux/types.h>
  *		<linux/kernel.h>
  *		<linux/string.h>
@@ -568,6 +639,12 @@
 static void	StopDrvCleanupTimer(SK_AC *pAC);
 static int	XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
 
+#ifdef SK_DIAG_SUPPORT
+static SK_U32   ParseDeviceNbrFromSlotName(const char *SlotName);
+static int      SkDrvInitAdapter(SK_AC *pAC, int devNbr);
+static int      SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
+#endif
+
 /*******************************************************************************
  *
  * Extern Function Prototypes
@@ -576,14 +653,13 @@
 
 #ifdef CONFIG_PROC_FS
 static const char 	SK_Root_Dir_entry[] = "sk98lin";
-static struct		proc_dir_entry *pSkRootDir;
-
-extern int 		sk_proc_read(	char   *buffer,
-					char	**buffer_location,
-					off_t	offset,
-					int	buffer_length,
-					int	*eof,
-					void	*data);
+static struct		proc_dir_entry *pSkRootDir = NULL;
+extern int 	sk_proc_read(	char   *buffer,
+				char	**buffer_location,
+				off_t	offset,
+				int	buffer_length,
+				int	*eof,
+				void	*data);
 #endif
 
 extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);	
@@ -601,6 +677,7 @@
 static const char *BootString = BOOT_STRING;
 struct SK_NET_DEVICE *SkGeRootDev = NULL;
 static int probed __initdata = 0;
+static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
 
 /* local variables **********************************************************/
 static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
@@ -672,17 +749,11 @@
 			break;
 		}
 
-		if (dev->priv == NULL) {
-			printk(KERN_ERR "Unable to allocate adapter "
-			       "structure!\n");
-			break;
-		}
-
 		pNet = dev->priv;
 		pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
 		if (pNet->pAC == NULL){
-			dev->get_stats = NULL;
 			unregister_netdev(dev);
+			dev->get_stats = NULL;
 			kfree(dev->priv);
 			printk(KERN_ERR "Unable to allocate adapter "
 			       "structure!\n");
@@ -712,8 +783,8 @@
 		retval = SkGeInitPCI(pAC);
 		if (retval) {
 			printk("SKGE: PCI setup failed: %i\n", retval);
-			dev->get_stats = NULL;
 			unregister_netdev(dev);
+			dev->get_stats = NULL;
 			kfree(dev);
 			continue;
 		}
@@ -740,12 +811,30 @@
 #endif
 
 		pAC->Index = boards_found;
+
 		if (SkGeBoardInit(dev, pAC)) {
-			FreeResources(dev);
+			unregister_netdev(dev);
 			kfree(dev);
 			continue;
 		}
 
+
+		/* Print adapter specific string from vpd */
+		ProductStr(pAC);
+		printk("%s: %s\n", dev->name, pAC->DeviceStr);
+
+		/* Print configuration settings */
+		printk("      PrefPort:%c  RlmtMode:%s\n",
+			'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
+			(pAC->RlmtMode==0)  ? "Check Link State" :
+			((pAC->RlmtMode==1) ? "Check Link State" :
+			((pAC->RlmtMode==3) ? "Check Local Port" :
+			((pAC->RlmtMode==7) ? "Check Segmentation" :
+			((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
+
+		SkGeYellowLED(pAC, pAC->IoBase, 1);
+
+
 		memcpy((caddr_t) &dev->dev_addr,
 			(caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6);
 
@@ -770,27 +859,16 @@
 			S_IFREG | S_IXUSR | S_IWGRP | S_IROTH,
 			pSkRootDir);
 
-		
-		pProcFile->read_proc = sk_proc_read;
-		pProcFile->write_proc = NULL;
-		pProcFile->nlink = 1;
-		pProcFile->size = sizeof(dev->name + 1);
-		pProcFile->data = (void *)pProcFile;
-		pProcFile->owner = THIS_MODULE;
+		pProcFile->read_proc   = sk_proc_read;
+		pProcFile->write_proc  = NULL;
+		pProcFile->nlink       = 1;
+		pProcFile->size        = sizeof(dev->name + 1);
+		pProcFile->data        = (void *)pProcFile;
+		pProcFile->owner       = THIS_MODULE;
 #endif
 
 		pNet->PortNr = 0;
-		pNet->NetNr = 0;
-
-
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
-			if (pAC->ChipsetType) {
-				/* SG and ZEROCOPY - fly baby... */
-				dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-			}
-#endif
-#endif
+		pNet->NetNr  = 0;
 
 		boards_found++;
 
@@ -802,23 +880,23 @@
 				break;
 			}
 
-			pAC->dev[1] = dev;
-			pNet = dev->priv;
-			pNet->PortNr = 1;
-			pNet->NetNr = 1;
-			pNet->pAC = pAC;
-			pNet->Mtu = 1500;
-			pNet->Up = 0;
-
-			dev->open =		&SkGeOpen;
-			dev->stop =		&SkGeClose;
-			dev->hard_start_xmit =	&SkGeXmit;
-			dev->get_stats =	&SkGeStats;
+			pAC->dev[1]   = dev;
+			pNet          = dev->priv;
+			pNet->PortNr  = 1;
+			pNet->NetNr   = 1;
+			pNet->pAC     = pAC;
+			pNet->Mtu     = 1500;
+			pNet->Up      = 0;
+
+			dev->open               = &SkGeOpen;
+			dev->stop               = &SkGeClose;
+			dev->hard_start_xmit    = &SkGeXmit;
+			dev->get_stats          = &SkGeStats;
 			dev->set_multicast_list = &SkGeSetRxMode;
-			dev->set_mac_address =	&SkGeSetMacAddr;
-			dev->do_ioctl =		&SkGeIoctl;
-			dev->change_mtu =	&SkGeChangeMtu;
-			dev->flags &= 		~IFF_RUNNING;
+			dev->set_mac_address    = &SkGeSetMacAddr;
+			dev->do_ioctl           = &SkGeIoctl;
+			dev->change_mtu         = &SkGeChangeMtu;
+			dev->flags             &= ~IFF_RUNNING;
 
 #ifdef SK_ZEROCOPY
 #ifdef USE_SK_TX_CHECKSUM
@@ -833,14 +911,12 @@
 			pProcFile = create_proc_entry(dev->name,
 				S_IFREG | S_IXUSR | S_IWGRP | S_IROTH,
 				pSkRootDir);
-
-		
-			pProcFile->read_proc = sk_proc_read;
+			pProcFile->read_proc  = sk_proc_read;
 			pProcFile->write_proc = NULL;
-			pProcFile->nlink = 1;
-			pProcFile->size = sizeof(dev->name + 1);
-			pProcFile->data = (void *)pProcFile;
-			pProcFile->owner = THIS_MODULE;
+			pProcFile->nlink      = 1;
+			pProcFile->size       = sizeof(dev->name + 1);
+			pProcFile->data       = (void *)pProcFile;
+			pProcFile->owner      = THIS_MODULE;
 #endif
 
 			memcpy((caddr_t) &dev->dev_addr,
@@ -848,14 +924,20 @@
 	
 			printk("%s: %s\n", dev->name, pAC->DeviceStr);
 			printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
-
 		}
 
-
 		/* Save the hardware revision */
 		pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
 			(pAC->GIni.GIPciHwRev & 0x0F);
 
+		/* Set driver globals */
+		pAC->Pnmi.pDriverFileName    = DRIVER_FILE_NAME;
+		pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE;
+
+		SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
+		SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), 
+				sizeof(SK_PNMI_STRUCT_DATA));
+
 		/*
 		 * This is bollocks, but we need to tell the net-init
 		 * code that it shall go for the next device.
@@ -875,7 +957,6 @@
 } /* skge_probe */
 
 
-
 /*****************************************************************************
  *
  * 	SkGeInitPCI - Init the PCI resources
@@ -1249,7 +1330,7 @@
 	SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA);
 	SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA);
 	SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
-	
+
 	pAC->BoardLevel = SK_INIT_DATA;
 	pAC->RxBufSize  = ETH_BUF_SIZE;
 
@@ -1261,7 +1342,7 @@
 	/* level 1 init common modules here (HW init) */
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
 	if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
-		printk("HWInit (1) failed.\n");
+		printk("sk98lin: HWInit (1) failed.\n");
 		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 		return(-EAGAIN);
 	}
@@ -1293,14 +1374,14 @@
 		Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
 			pAC->Name, dev);
 	} else {
-		printk(KERN_WARNING "%s: Illegal number of ports: %d\n",
-		       dev->name, pAC->GIni.GIMacsFound);
+		printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
+		       pAC->GIni.GIMacsFound);
 		return -EAGAIN;
 	}
 
 	if (Ret) {
-		printk(KERN_WARNING "%s: Requested IRQ %d is busy.\n",
-		       dev->name, dev->irq);
+		printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
+		       dev->irq);
 		return -EAGAIN;
 	}
 	pAC->AllocFlag |= SK_ALLOC_IRQ;
@@ -1328,25 +1409,10 @@
 		pAC->ActivePort,
 		DualNet)) {
 		BoardFreeMem(pAC);
-		printk("SkGeInitAssignRamToQueues failed.\n");
+		printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
 		return(-EAGAIN);
 	}
 
-	/* Print adapter specific string from vpd */
-	ProductStr(pAC);
-	printk("%s: %s\n", dev->name, pAC->DeviceStr);
-
-	/* Print configuration settings */
-	printk("      PrefPort:%c  RlmtMode:%s\n",
-		'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber,
-		(pAC->RlmtMode==0)  ? "Check Link State" :
-		((pAC->RlmtMode==1) ? "Check Link State" :
-		((pAC->RlmtMode==3) ? "Check Local Port" :
-		((pAC->RlmtMode==7) ? "Check Segmentation" :
-		((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error")))));
-
-	SkGeYellowLED(pAC, pAC->IoBase, 1);
-
 	/*
 	 * Register the device here
 	 */
@@ -1904,9 +1970,17 @@
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
 
+#ifdef SK_DIAG_SUPPORT
+	if (pAC->DiagModeActive == DIAG_ACTIVE) {
+		if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
+			return (-1);   /* still in use by diag; deny actions */
+		} 
+	}
+#endif
+
 
 	/* Set blink mode */
-	if (pAC->PciDev->vendor == 0x1186)
+	if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
 		pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
 
 	if (pAC->BoardLevel == SK_INIT_DATA) {
@@ -2001,26 +2075,50 @@
 static int SkGeClose(
 struct SK_NET_DEVICE	*dev)
 {
-	DEV_NET			*pNet;
-	SK_AC			*pAC;
+	DEV_NET		*pNet;
+	DEV_NET		*newPtrNet;
+	SK_AC		*pAC;
 
 	unsigned long	Flags;		/* for spin lock */
-	int				i;
-	int				PortIdx;
-	SK_EVPARA		EvPara;
+	int		i;
+	int		PortIdx;
+	SK_EVPARA	EvPara;
+
+	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+		("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
 
-	netif_stop_queue(dev);
 	pNet = (DEV_NET*) dev->priv;
 	pAC = pNet->pAC;
 
+#ifdef SK_DIAG_SUPPORT
+	if (pAC->DiagModeActive == DIAG_ACTIVE) {
+		if (pAC->DiagFlowCtrl == SK_FALSE) {
+			MOD_DEC_USE_COUNT;
+			/* 
+			** notify that the interface which has been closed
+			** by operator interaction must not be started up 
+			** again when the DIAG has finished. 
+			*/
+			newPtrNet = (DEV_NET *) pAC->dev[0]->priv;
+			if (newPtrNet == pNet) {
+				pAC->WasIfUp[0] = SK_FALSE;
+			} else {
+				pAC->WasIfUp[1] = SK_FALSE;
+			}
+			return 0; /* return to system everything is fine... */
+		} else {
+			pAC->DiagFlowCtrl = SK_FALSE;
+		}
+	}
+#endif
+
+	netif_stop_queue(dev);
+
 	if (pAC->RlmtNets == 1)
 		PortIdx = pAC->ActivePort;
 	else
 		PortIdx = pNet->NetNr;
 
-	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
-		("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
-
         StopDrvCleanupTimer(pAC);
 
 	/*
@@ -2078,6 +2176,10 @@
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeClose: done "));
 
+	SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
+	SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), 
+			sizeof(SK_PNMI_STRUCT_DATA));
+
 	pAC->MaxPorts--;
 	pNet->Up = 0;
 
@@ -2224,9 +2326,10 @@
 	** This is to resolve faulty padding by the HW with 0xaa bytes.
 	*/
 	if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
-	    skb_put(pMessage, (C_LEN_ETHERNET_MINSIZE-BytesSend));
-	    SK_MEMSET( ((char *)(pMessage->data))+BytesSend,
-	            0, C_LEN_ETHERNET_MINSIZE-BytesSend);
+		if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) {
+			return 0;
+		}
+		pMessage->len = C_LEN_ETHERNET_MINSIZE;
 	}
 
 	/* 
@@ -3343,6 +3446,16 @@
 		return -EINVAL;
 	}
 
+#ifdef SK_DIAG_SUPPORT
+	if (pAC->DiagModeActive == DIAG_ACTIVE) {
+		if (pAC->DiagFlowCtrl == SK_FALSE) {
+			return -1; /* still in use, deny any actions of MTU */
+		} else {
+			pAC->DiagFlowCtrl = SK_FALSE;
+		}
+	}
+#endif
+
 	pNet->Mtu = NewMtu;
 	pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv;
 	if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
@@ -3562,11 +3675,20 @@
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
 		("SkGeStats starts now...\n"));
 	pPnmiStruct = &pAC->PnmiStruct;
-        memset(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
+
+#ifdef SK_DIAG_SUPPORT
+        if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
+                (pAC->BoardLevel == SK_INIT_RUN)) {
+#endif
+        SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
         Size = SK_PNMI_STRUCT_SIZE;
 		SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+#ifdef SK_DIAG_SUPPORT
+	}
+#endif
+
         pPnmiStat = &pPnmiStruct->Stat[0];
         pPnmiConf = &pPnmiStruct->Conf[0];
 
@@ -3629,7 +3751,7 @@
 DEV_NET		*pNet;
 SK_AC		*pAC;
 void		*pMemBuf;
-
+struct pci_dev  *pdev = NULL;
 SK_GE_IOCTL	Ioctl;
 unsigned int	Err = 0;
 int		Size = 0;
@@ -3696,6 +3818,45 @@
 fault_gen:
 		kfree(pMemBuf); /* cleanup everything */
 		break;
+#ifdef SK_DIAG_SUPPORT
+       case SK_IOCTL_DIAG:
+		if (!capable(CAP_NET_ADMIN)) return -EPERM;
+		if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
+			Length = Ioctl.Len;
+		} else {
+			Length = sizeof(pAC->PnmiStruct) + HeaderLength;
+		}
+		if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
+			return -ENOMEM;
+		}
+		if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
+			Err = -EFAULT;
+			goto fault_diag;
+		}
+		pdev = pAC->PciDev;
+		Length = 3 * sizeof(SK_U32);  /* Error, Bus and Device */
+		/* 
+		** While coding this new IOCTL interface, only a few lines of code
+		** are to to be added. Therefore no dedicated function has been 
+		** added. If more functionality is added, a separate function 
+		** should be used...
+		*/
+		* ((SK_U32 *)pMemBuf) = 0;
+		* ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
+		* ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pdev->slot_name);
+		if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
+			Err = -EFAULT;
+			goto fault_diag;
+		}
+		Ioctl.Len = Length;
+		if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
+			Err = -EFAULT;
+			goto fault_diag;
+		}
+fault_diag:
+		kfree(pMemBuf); /* cleanup everything */
+		break;
+#endif
 	default:
 		Err = -EOPNOTSUPP;
 	}
@@ -3851,10 +4012,9 @@
 				(strcmp(ConType[pAC->Index],"Auto")!=0) &&
 				(strcmp(ConType[pAC->Index],"")!=0)) {
 				/* Set the speed parameter back */
-					printk("%s: Illegal value \"%s\" " 
+					printk("sk98lin: Illegal value \"%s\" " 
 							"for ConType."
 							" Using Auto.\n", 
-							pAC->dev[0]->name, 
 							ConType[pAC->Index]);
 
 					sprintf(ConType[pAC->Index], "Auto");	
@@ -3898,8 +4058,8 @@
 			M_CurrPort.PLinkSpeed    = SK_LSPEED_10MBPS;
 		    }
                 } else { 
-		    printk("%s: Illegal value \"%s\" for ConType\n", 
-			pAC->dev[0]->name, ConType[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for ConType\n", 
+			ConType[pAC->Index]);
 		    IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
 		}
         } else {
@@ -3923,8 +4083,8 @@
 		} else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
 		    LinkSpeed = SK_LSPEED_1000MBPS;
 		} else {
-		    printk("%s: Illegal value \"%s\" for Speed_A\n",
-			pAC->dev[0]->name, Speed_A[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
+			Speed_A[pAC->Index]);
 		    IsLinkSpeedDefined = SK_FALSE;
 		}
 	} else {
@@ -3938,9 +4098,9 @@
 	if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
 		((LinkSpeed != SK_LSPEED_AUTO) &&
 		(LinkSpeed != SK_LSPEED_1000MBPS))) {
-		printk("%s: Illegal value for Speed_A. "
+		printk("sk98lin: Illegal value for Speed_A. "
 			"Not a copper card or GE V2 card\n    Using "
-			"speed 1000\n", pAC->dev[0]->name);
+			"speed 1000\n");
 		LinkSpeed = SK_LSPEED_1000MBPS;
 	}
 	
@@ -3970,8 +4130,8 @@
 		} else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
 		    AutoNeg = AN_SENS;
 		} else {
-		    printk("%s: Illegal value \"%s\" for AutoNeg_A\n",
-			pAC->dev[0]->name, AutoNeg_A[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n",
+			AutoNeg_A[pAC->Index]);
 		}
 	}
 
@@ -3989,33 +4149,32 @@
 		} else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
 		    DuplexCap = DC_HALF;
 		} else {
-		    printk("%s: Illegal value \"%s\" for DupCap_A\n",
-			pAC->dev[0]->name, DupCap_A[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for DupCap_A\n",
+			DupCap_A[pAC->Index]);
 		}
 	}
-	
+
 	/* 
 	** Check for illegal combinations 
 	*/
-	if ((LinkSpeed = SK_LSPEED_1000MBPS) &&
+	if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
 		((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
 		(DuplexCap == SK_LMODE_STAT_HALF)) &&
 		(pAC->ChipsetType)) {
-		    printk("%s: Half Duplex not possible with Gigabit speed!\n"
-					"    Using Full Duplex.\n",
-				pAC->dev[0]->name);
+		    printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
+					"    Using Full Duplex.\n");
 				DuplexCap = DC_FULL;
 	}
 
 	if ( AutoSet && AutoNeg==AN_SENS && DupSet) {
-		printk("%s, Port A: DuplexCapabilities"
-			" ignored using Sense mode\n", pAC->dev[0]->name);
+		printk("sk98lin, Port A: DuplexCapabilities"
+			" ignored using Sense mode\n");
 	}
 
 	if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
-		printk("%s, Port A: Illegal combination"
+		printk("sk98lin: Port A: Illegal combination"
 			" of values AutoNeg. and DuplexCap.\n    Using "
-			"Full Duplex\n", pAC->dev[0]->name);
+			"Full Duplex\n");
 		DuplexCap = DC_FULL;
 	}
 
@@ -4024,10 +4183,9 @@
 	}
 	
 	if (!AutoSet && DupSet) {
-		printk("%s, Port A: Duplex setting not"
+		printk("sk98lin: Port A: Duplex setting not"
 			" possible in\n    default AutoNegotiation mode"
-			" (Sense).\n    Using AutoNegotiation On\n",
-			pAC->dev[0]->name);
+			" (Sense).\n    Using AutoNegotiation On\n");
 		AutoNeg = AN_ON;
 	}
 	
@@ -4054,8 +4212,8 @@
 		} else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
 		    FlowCtrl = SK_FLOW_MODE_NONE;
 		} else {
-		    printk("%s: Illegal value \"%s\" for FlowCtrl_A\n",
-                        pAC->dev[0]->name, FlowCtrl_A[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
+                        FlowCtrl_A[pAC->Index]);
 		    IsFlowCtrlDefined = SK_FALSE;
 		}
 	} else {
@@ -4064,9 +4222,9 @@
 
 	if (IsFlowCtrlDefined) {
 	    if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
-		printk("%s, Port A: FlowControl"
+		printk("sk98lin: Port A: FlowControl"
 			" impossible without AutoNegotiation,"
-			" disabled\n", pAC->dev[0]->name);
+			" disabled\n");
 		FlowCtrl = SK_FLOW_MODE_NONE;
 	    }
 	    pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl;
@@ -4086,8 +4244,8 @@
 		} else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
 		    MSMode = SK_MS_MODE_SLAVE;
 		} else {
-		    printk("%s: Illegal value \"%s\" for Role_A\n",
-			pAC->dev[0]->name, Role_A[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for Role_A\n",
+			Role_A[pAC->Index]);
 		    IsRoleDefined = SK_FALSE;
 		}
 	} else {
@@ -4122,8 +4280,8 @@
 		} else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
 		    LinkSpeed = SK_LSPEED_1000MBPS;
 		} else {
-		    printk("%s: Illegal value \"%s\" for Speed_B\n",
-			pAC->dev[1]->name, Speed_B[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for Speed_B\n",
+			Speed_B[pAC->Index]);
 		    IsLinkSpeedDefined = SK_FALSE;
 		}
 	} else {
@@ -4137,9 +4295,9 @@
 	if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
 		((LinkSpeed != SK_LSPEED_AUTO) &&
 		(LinkSpeed != SK_LSPEED_1000MBPS))) {
-		printk("%s: Illegal value for Speed_B. "
+		printk("sk98lin: Illegal value for Speed_B. "
 			"Not a copper card or GE V2 card\n    Using "
-			"speed 1000\n", pAC->dev[1]->name);
+			"speed 1000\n");
 		LinkSpeed = SK_LSPEED_1000MBPS;
 	}
 
@@ -4169,8 +4327,8 @@
 		} else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
 		    AutoNeg = AN_SENS;
 		} else {
-		    printk("%s: Illegal value \"%s\" for AutoNeg_B\n",
-			pAC->dev[0]->name, AutoNeg_B[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n",
+			AutoNeg_B[pAC->Index]);
 		}
 	}
 
@@ -4188,8 +4346,8 @@
 		} else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
 		    DuplexCap = DC_HALF;
 		} else {
-		    printk("%s: Illegal value \"%s\" for DupCap_B\n",
-			pAC->dev[0]->name, DupCap_B[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for DupCap_B\n",
+			DupCap_B[pAC->Index]);
 		}
 	}
 
@@ -4197,25 +4355,24 @@
 	/* 
 	** Check for illegal combinations 
 	*/
-	if ((LinkSpeed = SK_LSPEED_1000MBPS) &&
+	if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
 		((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
 		(DuplexCap == SK_LMODE_STAT_HALF)) &&
 		(pAC->ChipsetType)) {
-		    printk("%s: Half Duplex not possible with Gigabit speed!\n"
-					"    Using Full Duplex.\n",
-				pAC->dev[1]->name);
+		    printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
+					"    Using Full Duplex.\n");
 				DuplexCap = DC_FULL;
 	}
 
 	if (AutoSet && AutoNeg==AN_SENS && DupSet) {
-		printk("%s, Port B: DuplexCapabilities"
-			" ignored using Sense mode\n", pAC->dev[1]->name);
+		printk("sk98lin, Port B: DuplexCapabilities"
+			" ignored using Sense mode\n");
 	}
 
 	if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
-		printk("%s, Port B: Illegal combination"
+		printk("sk98lin: Port B: Illegal combination"
 			" of values AutoNeg. and DuplexCap.\n    Using "
-			"Full Duplex\n", pAC->dev[1]->name);
+			"Full Duplex\n");
 		DuplexCap = DC_FULL;
 	}
 
@@ -4224,10 +4381,9 @@
 	}
 	
 	if (!AutoSet && DupSet) {
-		printk("%s, Port B: Duplex setting not"
+		printk("sk98lin: Port B: Duplex setting not"
 			" possible in\n    default AutoNegotiation mode"
-			" (Sense).\n    Using AutoNegotiation On\n",
-			pAC->dev[1]->name);
+			" (Sense).\n    Using AutoNegotiation On\n");
 		AutoNeg = AN_ON;
 	}
 
@@ -4254,8 +4410,8 @@
 		} else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
 		    FlowCtrl = SK_FLOW_MODE_NONE;
 		} else {
-		    printk("%s: Illegal value \"%s\" for FlowCtrl_B\n",
-			pAC->dev[0]->name, FlowCtrl_B[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n",
+			FlowCtrl_B[pAC->Index]);
 		    IsFlowCtrlDefined = SK_FALSE;
 		}
 	} else {
@@ -4264,9 +4420,9 @@
 
 	if (IsFlowCtrlDefined) {
 	    if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
-		printk("%s, Port B: FlowControl"
+		printk("sk98lin: Port B: FlowControl"
 			" impossible without AutoNegotiation,"
-			" disabled\n", pAC->dev[1]->name);
+			" disabled\n");
 		FlowCtrl = SK_FLOW_MODE_NONE;
 	    }
 	    pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl;
@@ -4286,8 +4442,8 @@
 		} else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
 		    MSMode = SK_MS_MODE_SLAVE;
 		} else {
-		    printk("%s: Illegal value \"%s\" for Role_B\n",
-			pAC->dev[1]->name, Role_B[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for Role_B\n",
+			Role_B[pAC->Index]);
 		    IsRoleDefined = SK_FALSE;
 		}
 	} else {
@@ -4305,28 +4461,37 @@
 	if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
 		PrefPort[pAC->Index] != NULL) {
 		if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
-		    pAC->ActivePort             =  0;
-		    pAC->Rlmt.Net[0].Preference = -1; /* auto */
-		    pAC->Rlmt.Net[0].PrefPort   =  0;
+			pAC->ActivePort             =  0;
+			pAC->Rlmt.Net[0].Preference = -1; /* auto */
+			pAC->Rlmt.Net[0].PrefPort   =  0;
 		} else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
-		    /*
-		    ** do not set ActivePort here, thus a port
-		    ** switch is issued after net up.
-		    */
-		    Port                        = 0;
-		    pAC->Rlmt.Net[0].Preference = Port;
-		    pAC->Rlmt.Net[0].PrefPort   = Port;
+			/*
+			** do not set ActivePort here, thus a port
+			** switch is issued after net up.
+			*/
+			Port                        = 0;
+			pAC->Rlmt.Net[0].Preference = Port;
+			pAC->Rlmt.Net[0].PrefPort   = Port;
 		} else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
-		    /*
-		    ** do not set ActivePort here, thus a port
-		    ** switch is issued after net up.
-		    */
-		    Port                        = 1;
-		    pAC->Rlmt.Net[0].Preference = Port;
-		    pAC->Rlmt.Net[0].PrefPort   = Port;
+			/*
+			** do not set ActivePort here, thus a port
+			** switch is issued after net up.
+			*/
+			if (pAC->GIni.GIMacsFound == 1) {
+				printk("sk98lin: Illegal value \"B\" for PrefPort.\n"
+					"      Port B not available on single port adapters.\n");
+
+				pAC->ActivePort             =  0;
+				pAC->Rlmt.Net[0].Preference = -1; /* auto */
+				pAC->Rlmt.Net[0].PrefPort   =  0;
+			} else {
+				Port                        = 1;
+				pAC->Rlmt.Net[0].Preference = Port;
+				pAC->Rlmt.Net[0].PrefPort   = Port;
+			}
 		} else {
-		    printk("%s: Illegal value \"%s\" for PrefPort\n",
-			pAC->dev[0]->name, PrefPort[pAC->Index]);
+		    printk("sk98lin: Illegal value \"%s\" for PrefPort\n",
+			PrefPort[pAC->Index]);
 		}
 	}
 
@@ -4350,9 +4515,9 @@
 			pAC->RlmtMode = SK_RLMT_CHECK_LINK;
 			pAC->RlmtNets = 2;
 		} else {
-		    printk("%s: Illegal value \"%s\" for"
+		    printk("sk98lin: Illegal value \"%s\" for"
 			" RlmtMode, using default\n", 
-			pAC->dev[0]->name, RlmtMode[pAC->Index]);
+			RlmtMode[pAC->Index]);
 			pAC->RlmtMode = 0;
 		}
 	} else {
@@ -4363,97 +4528,111 @@
 	** Check the interrupt moderation parameters
 	*/
 	if (Moderation[pAC->Index] != NULL) {
-	    if (strcmp(Moderation[pAC->Index], "Static") == 0) {
-                pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
-	    } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
-	        pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
-	    } else {
-	        pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
-	    }
+		if (strcmp(Moderation[pAC->Index], "") == 0) {
+			pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+		} else if (strcmp(Moderation[pAC->Index], "Static") == 0) {
+			pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
+		} else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
+			pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
+		} else if (strcmp(Moderation[pAC->Index], "None") == 0) {
+			pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+		} else {
+	   		printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
+				"      Disable interrupt moderation.\n",
+				Moderation[pAC->Index]);
+			pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+		}
 	} else {
-	    pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+		pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
 	}
 
 	if (Stats[pAC->Index] != NULL) {
-	    if (strcmp(Stats[pAC->Index], "Yes") == 0) {
-	        pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
-	    } else {
-		pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
-	    }
+		if (strcmp(Stats[pAC->Index], "Yes") == 0) {
+			pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
+		} else {
+			pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
+		}
 	} else {
-	    pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
+		pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
 	}
 
-        if (ModerationMask[pAC->Index] != NULL) {
-           if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
-           } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
-           } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
-           } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
-           } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
-           } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
-           } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
-           } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
-           } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
-           } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-           } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-           } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-           } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-           } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-           } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
-           } else { /* some rubbish */
-               pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
-           }
-        } else {  /* operator has stated nothing */
-           pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
-        }
-
-        if (AutoSizing[pAC->Index] != NULL) {
-           if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
-               pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
-           } else {
-               pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
-           }
-        } else {  /* operator has stated nothing */
-           pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
-        }
+	if (ModerationMask[pAC->Index] != NULL) {
+		if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
+		} else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
+		} else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
+		} else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
+		} else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
+		} else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+		} else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+		} else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
+		} else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
+		} else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+		} else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+		} else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+		} else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+		} else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+		} else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+		} else { /* some rubbish */
+			pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
+		}
+	} else {  /* operator has stated nothing */
+		pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+	}
+
+	if (AutoSizing[pAC->Index] != NULL) {
+		if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
+			pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+		} else {
+			pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+		}
+	} else {  /* operator has stated nothing */
+		pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+	}
 
-        if (IntsPerSec[pAC->Index] != 0) {
-           if ((IntsPerSec[pAC->Index]< 30) || (IntsPerSec[pAC->Index]> 40000)) {
-              pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
-           } else {
-              pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
-           }
-        } else {
-           pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
-        }
+	if (IntsPerSec[pAC->Index] != 0) {
+		if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || 
+			(IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
+	   		printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n"
+				"      Using default value of %i.\n", 
+				IntsPerSec[pAC->Index],
+				C_INT_MOD_IPS_LOWER_RANGE,
+				C_INT_MOD_IPS_UPPER_RANGE,
+				C_INTS_PER_SEC_DEFAULT);
+			pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
+		} else {
+			pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
+		}
+	} else {
+		pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
+	}
 
-        /*
+	/*
 	** Evaluate upper and lower moderation threshold
 	*/
-        pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
-            pAC->DynIrqModInfo.MaxModIntsPerSec +
-            (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
-
-        pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
-            pAC->DynIrqModInfo.MaxModIntsPerSec -
-            (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
+	pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
+		pAC->DynIrqModInfo.MaxModIntsPerSec +
+		(pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
+
+	pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
+		pAC->DynIrqModInfo.MaxModIntsPerSec -
+		(pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
 
-        pAC->DynIrqModInfo.PrevTimeVal = jiffies;  /* initial value */
+	pAC->DynIrqModInfo.PrevTimeVal = jiffies;  /* initial value */
 
 
 } /* GetConfiguration */
@@ -4851,6 +5030,10 @@
 		FromPort = Param.Para32[0];
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("NET UP EVENT, Port: %d ", Param.Para32[0]));
+		/* Mac update */
+		SkAddrMcUpdate(pAC,IoC, FromPort);
+
+		if (DoPrintInterfaceChange) {
 		printk("%s: network connection up using"
 			" port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
 
@@ -4866,8 +5049,6 @@
 			printk("    speed:           unknown\n");
 		}
 
-		/* Mac update */
-		SkAddrMcUpdate(pAC,IoC, FromPort);
 
 		Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
 		if (Stat == SK_LMODE_STAT_AUTOHALF ||
@@ -4945,6 +5126,9 @@
 			printk("    rx-checksum:     disabled\n");
 #endif
 
+		} else {
+                        DoPrintInterfaceChange = SK_TRUE;
+                }
 	
 		if ((Param.Para32[0] != pAC->ActivePort) &&
 			(pAC->RlmtNets == 1)) {
@@ -4962,7 +5146,12 @@
 		/* action list 7 */
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
 			("NET DOWN EVENT "));
-		printk("%s: network connection down\n", pAC->dev[Param.Para32[1]]->name);
+		if (DoPrintInterfaceChange) {
+			printk("%s: network connection down\n", 
+				pAC->dev[Param.Para32[1]]->name);
+		} else {
+			DoPrintInterfaceChange = SK_TRUE;
+		}
 		pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
 		break;
 	case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
@@ -5147,6 +5336,229 @@
 
 } /* SkErrorLog */
 
+#ifdef SK_DIAG_SUPPORT
+
+/*****************************************************************************
+ *
+ *	SkDrvEnterDiagMode - handles DIAG attach request
+ *
+ * Description:
+ *	Notify the kernel to NOT access the card any longer due to DIAG
+ *	Deinitialize the Card
+ *
+ * Returns:
+ *	int
+ */
+int SkDrvEnterDiagMode(
+SK_AC   *pAc)   /* pointer to adapter context */
+{
+	SK_AC   *pAC  = NULL;
+	DEV_NET *pNet = NULL;
+
+	pNet = (DEV_NET *) pAc->dev[0]->priv;
+	pAC = pNet->pAC;
+
+	SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), 
+			sizeof(SK_PNMI_STRUCT_DATA));
+
+	pAC->DiagModeActive = DIAG_ACTIVE;
+	if (pAC->BoardLevel > SK_INIT_DATA) {
+		if (pNet->Up) {
+			pAC->WasIfUp[0] = SK_TRUE;
+			pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose      */
+			DoPrintInterfaceChange = SK_FALSE;
+			SkDrvDeInitAdapter(pAC, 0);  /* performs SkGeClose */
+		} else {
+			pAC->WasIfUp[0] = SK_FALSE;
+		}
+		if (pNet != (DEV_NET *) pAc->dev[1]->priv) {
+			pNet = (DEV_NET *) pAc->dev[1]->priv;
+			if (pNet->Up) {
+				pAC->WasIfUp[1] = SK_TRUE;
+				pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
+				DoPrintInterfaceChange = SK_FALSE;
+				SkDrvDeInitAdapter(pAC, 1);  /* do SkGeClose  */
+			} else {
+				pAC->WasIfUp[1] = SK_FALSE;
+			}
+		}
+		pAC->BoardLevel = SK_INIT_DATA;
+	}
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *	SkDrvLeaveDiagMode - handles DIAG detach request
+ *
+ * Description:
+ *	Notify the kernel to may access the card again after use by DIAG
+ *	Initialize the Card
+ *
+ * Returns:
+ * 	int
+ */
+int SkDrvLeaveDiagMode(
+SK_AC   *pAc)   /* pointer to adapter control context */
+{ 
+	SK_MEMCPY(&(pAc->PnmiStruct), &(pAc->PnmiBackup), 
+			sizeof(SK_PNMI_STRUCT_DATA));
+	pAc->DiagModeActive    = DIAG_NOTACTIVE;
+	pAc->Pnmi.DiagAttached = SK_DIAG_IDLE;
+        if (pAc->WasIfUp[0] == SK_TRUE) {
+                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
+		DoPrintInterfaceChange = SK_FALSE;
+                SkDrvInitAdapter(pAc, 0);    /* first device  */
+        }
+        if (pAc->WasIfUp[1] == SK_TRUE) {
+                pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
+		DoPrintInterfaceChange = SK_FALSE;
+                SkDrvInitAdapter(pAc, 1);    /* second device */
+        }
+	return(0);
+}
+
+/*****************************************************************************
+ *
+ *	ParseDeviceNbrFromSlotName - Evaluate PCI device number
+ *
+ * Description:
+ * 	This function parses the PCI slot name information string and will
+ *	retrieve the devcie number out of it. The slot_name maintianed by
+ *	linux is in the form of '02:0a.0', whereas the first two characters 
+ *	represent the bus number in hex (in the sample above this is 
+ *	pci bus 0x02) and the next two characters the device number (0x0a).
+ *
+ * Returns:
+ *	SK_U32: The device number from the PCI slot name
+ */ 
+
+static SK_U32 ParseDeviceNbrFromSlotName(
+const char *SlotName)   /* pointer to pci slot name eg. '02:0a.0' */
+{
+	char	*CurrCharPos	= (char *) SlotName;
+	int	FirstNibble	= -1;
+	int	SecondNibble	= -1;
+	SK_U32	Result		=  0;
+
+	while (*CurrCharPos != '\0') {
+		if (*CurrCharPos == ':') { 
+			while (*CurrCharPos != '.') {
+				CurrCharPos++;  
+				if (	(*CurrCharPos >= '0') && 
+					(*CurrCharPos <= '9')) {
+					if (FirstNibble == -1) {
+						/* dec. value for '0' */
+						FirstNibble = *CurrCharPos - 48;
+					} else {
+						SecondNibble = *CurrCharPos - 48;
+					}  
+				} else if (	(*CurrCharPos >= 'a') && 
+						(*CurrCharPos <= 'f')  ) {
+					if (FirstNibble == -1) {
+						FirstNibble = *CurrCharPos - 87; 
+					} else {
+						SecondNibble = *CurrCharPos - 87; 
+					}
+				} else {
+					Result = 0;
+				}
+			}
+
+			Result = FirstNibble;
+			Result = Result << 4; /* first nibble is higher one */
+			Result = Result | SecondNibble;
+		}
+		CurrCharPos++;   /* next character */
+	}
+	return (Result);
+}
+
+/****************************************************************************
+ *
+ *	SkDrvDeInitAdapter - deinitialize adapter (this function is only 
+ *				called if Diag attaches to that card)
+ *
+ * Description:
+ *	Close initialized adapter.
+ *
+ * Returns:
+ *	0 - on success
+ *	error code - on error
+ */
+static int SkDrvDeInitAdapter(
+SK_AC   *pAC,		/* pointer to adapter context   */
+int      devNbr)	/* what device is to be handled */
+{
+	struct SK_NET_DEVICE *dev;
+
+	dev = pAC->dev[devNbr];
+
+	/*
+	** Function SkGeClose() uses MOD_DEC_USE_COUNT (2.2/2.4)
+	** or module_put() (2.6) to decrease the number of users for
+	** a device, but if a device is to be put under control of 
+	** the DIAG, that count is OK already and does not need to 
+	** be adapted! Hence the opposite MOD_INC_USE_COUNT or 
+	** try_module_get() needs to be used again to correct that.
+	*/
+	MOD_INC_USE_COUNT;
+
+	if (SkGeClose(dev) != 0) {
+		MOD_DEC_USE_COUNT;
+		return (-1);
+	}
+	return (0);
+
+} /* SkDrvDeInitAdapter() */
+
+/****************************************************************************
+ *
+ *	SkDrvInitAdapter - Initialize adapter (this function is only 
+ *				called if Diag deattaches from that card)
+ *
+ * Description:
+ *	Close initialized adapter.
+ *
+ * Returns:
+ *	0 - on success
+ *	error code - on error
+ */
+static int SkDrvInitAdapter(
+SK_AC   *pAC,		/* pointer to adapter context   */
+int      devNbr)	/* what device is to be handled */
+{
+	struct SK_NET_DEVICE *dev;
+
+	dev = pAC->dev[devNbr];
+
+	if (SkGeOpen(dev) != 0) {
+		return (-1);
+	} else {
+		/*
+		** Function SkGeOpen() uses MOD_INC_USE_COUNT (2.2/2.4) 
+		** or try_module_get() (2.6) to increase the number of 
+		** users for a device, but if a device was just under 
+		** control of the DIAG, that count is OK already and 
+		** does not need to be adapted! Hence the opposite 
+		** MOD_DEC_USE_COUNT or module_put() needs to be used 
+		** again to correct that.
+		*/
+		MOD_DEC_USE_COUNT;
+	}
+
+	/*
+	** Use correct MTU size and indicate to kernel TX queue can be started
+	*/ 
+	if (SkGeChangeMtu(dev, dev->mtu) != 0) {
+		return (-1);
+	} 
+	return (0);
+
+} /* SkDrvInitAdapter */
+
+#endif
+
 #ifdef DEBUG
 /****************************************************************************/
 /* "debug only" section *****************************************************/
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skgehwt.c linux-2.4.24-pre2/drivers/net/sk98lin/skgehwt.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skgehwt.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skgehwt.c	2003-12-22 11:34:35.000000000 -0800
@@ -1,10 +1,10 @@
 /******************************************************************************
  *
  * Name:	skgehwt.c
- * Project:	Gigabit Ethernet Adapters, Common Modules
- * Version:	$Revision: 1.14 $
- * Date:	$Date: 2003/05/13 18:01:58 $
- * Purpose:	Hardware Timer.
+ * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 1.15 $
+ * Date:	$Date: 2003/09/16 13:41:23 $
+ * Purpose:	Hardware Timer
  *
  ******************************************************************************/
 
@@ -27,6 +27,10 @@
  * History:
  *
  *	$Log: skgehwt.c,v $
+ *	Revision 1.15  2003/09/16 13:41:23  rschmidt
+ *	Added (C) Marvell to SysKonnectFileId
+ *	Editorial changes
+ *	
  *	Revision 1.14  2003/05/13 18:01:58  mkarl
  *	Editorial changes.
  *	
@@ -69,19 +73,15 @@
  *	
  *	Revision 1.1  1998/08/05 11:28:36  gklug
  *	first version: adapted from SMT/FDDI
- *	
- *	
- *	
  *
  ******************************************************************************/
 
-
 /*
-	Event queue and dispatcher
-*/
+ *	Event queue and dispatcher
+ */
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.14 2003/05/13 18:01:58 mkarl Exp $" ;
+	"@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell.";
 #endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
@@ -89,10 +89,7 @@
 
 #ifdef __C2MAN__
 /*
-	Hardware Timer function queue management.
-
-	General Description:
-
+ *   Hardware Timer function queue management.
  */
 intro()
 {}
@@ -117,9 +114,9 @@
 {
 	pAC->Hwt.TStart = 0 ;
 	pAC->Hwt.TStop	= 0 ;
-	pAC->Hwt.TActive = SK_FALSE ;
+	pAC->Hwt.TActive = SK_FALSE;
 
-	SkHwtStop(pAC,Ioc) ;
+	SkHwtStop(pAC, Ioc);
 }
 
 /*
@@ -132,28 +129,29 @@
 SK_IOC	Ioc,	/* IoContext */
 SK_U32	Time)	/* Time in units of 16us to load the timer with. */
 {
-	SK_U32	Cnt ;
+	SK_U32	Cnt;
 
 	if (Time > SK_HWT_MAX)
-		Time = SK_HWT_MAX ;
+		Time = SK_HWT_MAX;
 
-	pAC->Hwt.TStart = Time ;
-	pAC->Hwt.TStop = 0L ;
+	pAC->Hwt.TStart = Time;
+	pAC->Hwt.TStop = 0L;
 
-	Cnt = Time ;
+	Cnt = Time;
 
 	/*
 	 * if time < 16 us
 	 *	time = 16 us
 	 */
 	if (!Cnt) {
-		Cnt++ ;
+		Cnt++;
 	}
 
-	SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC) ;
-	SK_OUT16(Ioc, B2_TI_CRTL, TIM_START) ;	/* Start timer. */
+	SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC);
+	
+	SK_OUT16(Ioc, B2_TI_CTRL, TIM_START);	/* Start timer. */
 
-	pAC->Hwt.TActive = SK_TRUE ;
+	pAC->Hwt.TActive = SK_TRUE;
 }
 
 /*
@@ -164,10 +162,11 @@
 SK_AC	*pAC,	/* Adapters context */
 SK_IOC	Ioc)	/* IoContext */
 {
-	SK_OUT16(Ioc, B2_TI_CRTL, TIM_STOP) ;
-	SK_OUT16(Ioc, B2_TI_CRTL, TIM_CLR_IRQ) ;
+	SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP);
+	
+	SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ);
 
-	pAC->Hwt.TActive = SK_FALSE ;
+	pAC->Hwt.TActive = SK_FALSE;
 }
 
 
@@ -182,26 +181,31 @@
 SK_AC	*pAC,	/* Adapters context */
 SK_IOC	Ioc)	/* IoContext */
 {
-	SK_U32	TRead ;
-	SK_U32	IStatus ;
+	SK_U32	TRead;
+	SK_U32	IStatus;
 
 	if (pAC->Hwt.TActive) {
-		SkHwtStop(pAC,Ioc) ;
+		
+		SkHwtStop(pAC, Ioc);
 
 		SK_IN32(Ioc, B2_TI_VAL, &TRead);
 		TRead /= SK_HWT_FAC;
 
 		SK_IN32(Ioc, B0_ISRC, &IStatus);
 
-		/* Check if timer expired (or wraparound). */
+		/* Check if timer expired (or wraped around) */
 		if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) {
-			SkHwtStop(pAC,Ioc) ;
-			pAC->Hwt.TStop = pAC->Hwt.TStart ;
-		} else {
-			pAC->Hwt.TStop = pAC->Hwt.TStart - TRead ;
+			
+			SkHwtStop(pAC, Ioc);
+			
+			pAC->Hwt.TStop = pAC->Hwt.TStart;
+		}
+		else {
+			
+			pAC->Hwt.TStop = pAC->Hwt.TStart - TRead;
 		}
 	}
-	return (pAC->Hwt.TStop) ;
+	return(pAC->Hwt.TStop);
 }
 
 /*
@@ -211,9 +215,11 @@
 SK_AC	*pAC,	/* Adapters context */
 SK_IOC	Ioc)	/* IoContext */
 {
-	SkHwtStop(pAC,Ioc);
+	SkHwtStop(pAC, Ioc);
+	
 	pAC->Hwt.TStop = pAC->Hwt.TStart;
-	SkTimerDone(pAC,Ioc) ;
+	
+	SkTimerDone(pAC, Ioc);
 }
 
 /* End of file */
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skgeinit.c linux-2.4.24-pre2/drivers/net/sk98lin/skgeinit.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skgeinit.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skgeinit.c	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skgeinit.c
  * Project:	Gigabit Ethernet Adapters, Common Modules
- * Version:	$Revision: 1.93 $
- * Date:	$Date: 2003/05/28 15:44:43 $
+ * Version:	$Revision: 1.97 $
+ * Date:	$Date: 2003/10/02 16:45:31 $
  * Purpose:	Contains functions to initialize the adapter
  *
  ******************************************************************************/
@@ -27,6 +27,32 @@
  * History:
  *
  *	$Log: skgeinit.c,v $
+ *	Revision 1.97  2003/10/02 16:45:31  rschmidt
+ *	Replaced default values of GMAC parameters with defines.
+ *	Removed hard reset of MACs in SkGeDeInit().
+ *	Added define SK_PHY_LP_MODE around power saving mode in SkGeDeInit().
+ *	Added check for VAUX available before switch power to VAUX.
+ *	
+ *	Revision 1.96  2003/09/18 14:02:41  rroesler
+ *	Add: Perform a hardreset of MACs in GeDeInit()
+ *	
+ *	Revision 1.95  2003/09/16 14:26:59  rschmidt
+ *	Added switch power to VCC (WA for VAUX problem) in SkGeInit1().
+ *	Fixed setting PHY to coma mode and D3 power state in SkGeDeInit().
+ *	Editorial changes.
+ *	
+ *	Revision 1.94  2003/09/16 07:17:10  mschmid
+ *	Added init for new members in port structure for MAC control
+ *	- PMacColThres
+ *	- PMacJamLen
+ *	- PMacJamIpgVal
+ *	- PMacJamIpgData
+ *	- PMacIpgData
+ *	- PMacLimit4
+ *	Added init for PHY power state in port structure
+ *	- PPhyPowerState
+ *	Added shutdown handling for Yukon Plus in SkGeDeInit()
+ *	
  *	Revision 1.93  2003/05/28 15:44:43  rschmidt
  *	Added check for chip Id on WOL WA for chip Rev. A.
  *	Added setting of GILevel in SkGeDeInit().
@@ -446,7 +472,7 @@
 
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skgeinit.c,v 1.93 2003/05/28 15:44:43 rschmidt Exp $ (C) Marvell.";
+	"@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell.";
 #endif
 
 struct s_QOffTab {
@@ -1013,8 +1039,6 @@
 	 *	- enable the FIFO
 	 */
 	
-	Word = (SK_U16)GMF_RX_CTRL_DEF;
-	
 #ifdef GENESIS
 	if (pAC->GIni.GIGenesis) {
 		/* Configure Rx MAC FIFO */
@@ -1039,6 +1063,8 @@
 		/* set Rx GMAC FIFO Flush Mask */
 		SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK);
 		
+		Word = (SK_U16)GMF_RX_CTRL_DEF;
+
 		/* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */
 		if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) {
 
@@ -1809,6 +1835,13 @@
 		pPrt->PAutoNegFail = SK_FALSE;
 		pPrt->PHWLinkUp = SK_FALSE;
 		pPrt->PLinkBroken = SK_TRUE; /* See WA code */
+		pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
+		pPrt->PMacColThres = TX_COL_DEF;
+		pPrt->PMacJamLen = TX_JAM_LEN_DEF;
+		pPrt->PMacJamIpgVal	= TX_JAM_IPG_DEF;
+		pPrt->PMacJamIpgData = TX_IPG_JAM_DEF;
+		pPrt->PMacIpgData = IPG_DATA_DEF;
+		pPrt->PMacLimit4 = SK_FALSE;
 	}
 
 	pAC->GIni.GIPortUsage = SK_RED_LINK;
@@ -1963,7 +1996,7 @@
 	/* restore CLK_RUN bits */
 	SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat &
 		(CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA)));
-	
+
 	/* read Chip Identification Number */
 	SK_IN8(IoC, B2_CHIP_ID, &Byte);
 	pAC->GIni.GIChipId = Byte;
@@ -2053,6 +2086,10 @@
 			}
 		}
 
+		/* switch power to VCC (WA for VAUX problem) */
+		SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA |
+			PC_VAUX_OFF | PC_VCC_ON));
+
 		/* read the Interrupt source */
 		SK_IN32(IoC, B0_ISRC, &DWord);
 		
@@ -2395,6 +2432,11 @@
 	int	i;
 	SK_U16	Word;
 
+#ifdef SK_PHY_LP_MODE
+	SK_U8	Byte;
+	SK_U16	PmCtlSts;
+#endif /* SK_PHY_LP_MODE */
+
 #if (!defined(SK_SLIM) && !defined(VCPU))
 	/* ensure I2C is ready */
 	SkI2cWaitIrq(pAC, IoC);
@@ -2409,6 +2451,38 @@
 		}
 	}
 
+#ifdef SK_PHY_LP_MODE
+    /*
+	 * for power saving purposes within mobile environments
+	 * we set the PHY to coma mode and switch to D3 power state.
+	 */
+	if (pAC->GIni.GIYukonLite &&
+		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+
+		/* for all ports switch PHY to coma mode */
+		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
+			
+			SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP);
+		}
+
+		if (pAC->GIni.GIVauxAvail) {
+			/* switch power to VAUX */
+			Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF;
+
+			SK_OUT8(IoC, B0_POWER_CTRL, Byte);
+		}
+		
+		/* switch to D3 state */
+		SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts);
+
+		PmCtlSts |= PCI_PM_STATE_D3;
+
+		SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
+		SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts);
+	}
+#endif /* SK_PHY_LP_MODE */
+
 	/* Reset all bits in the PCI STATUS register */
 	/*
 	 * Note: PCI Cfg cycles cannot be used, because they are not
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skgemib.c linux-2.4.24-pre2/drivers/net/sk98lin/skgemib.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skgemib.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skgemib.c	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skgemib.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.9 $
- * Date:	$Date: 2003/05/23 12:55:20 $
+ * Version:	$Revision: 1.11 $
+ * Date:	$Date: 2003/09/15 13:38:12 $
  * Purpose:	Private Network Management Interface Management Database
  *
  ****************************************************************************/
@@ -27,6 +27,19 @@
  * History:
  *
  *	$Log: skgemib.c,v $
+ *	Revision 1.11  2003/09/15 13:38:12  tschilli
+ *	OID_SKGE_PHY_LP_MODE included only after using #define SK_PHY_LP_MODE.
+ *	
+ *	Revision 1.10  2003/08/15 12:28:59  tschilli
+ *	Added new OIDs:
+ *	OID_SKGE_DRIVER_RELDATE
+ *	OID_SKGE_DRIVER_FILENAME
+ *	OID_SKGE_CHIPID
+ *	OID_SKGE_RAMSIZE
+ *	OID_SKGE_VAUXAVAIL
+ *	OID_SKGE_PHY_TYPE
+ *	OID_SKGE_PHY_LP_MODE
+ *	
  *	Revision 1.9  2003/05/23 12:55:20  tschilli
  *	OID_SKGE_BOARDLEVEL added.
  *	
@@ -356,6 +369,16 @@
 		0,
 		SK_PNMI_MAI_OFF(DriverVersion),
 		SK_PNMI_RO, General, 0},
+	{OID_SKGE_DRIVER_RELDATE,
+		1,
+		0,
+		SK_PNMI_MAI_OFF(DriverReleaseDate),
+		SK_PNMI_RO, General, 0},
+	{OID_SKGE_DRIVER_FILENAME,
+		1,
+		0,
+		SK_PNMI_MAI_OFF(DriverFileName),
+		SK_PNMI_RO, General, 0},
 	{OID_SKGE_HW_DESCR,
 		1,
 		0,
@@ -371,6 +394,21 @@
 		0,
 		SK_PNMI_MAI_OFF(Chipset),
 		SK_PNMI_RO, General, 0},
+	{OID_SKGE_CHIPID,
+		1,
+		0,
+		SK_PNMI_MAI_OFF(ChipId),
+		SK_PNMI_RO, General, 0},
+	{OID_SKGE_RAMSIZE,
+		1,
+		0,
+		SK_PNMI_MAI_OFF(RamSize),
+		SK_PNMI_RO, General, 0},
+	{OID_SKGE_VAUXAVAIL,
+		1,
+		0,
+		SK_PNMI_MAI_OFF(VauxAvail),
+		SK_PNMI_RO, General, 0},
 	{OID_SKGE_ACTION,
 		1,
 		0,
@@ -876,6 +914,18 @@
 		sizeof(SK_PNMI_CONF),
 		SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector),
 		SK_PNMI_RO, MacPrivateConf, 0},
+	{OID_SKGE_PHY_TYPE,
+		SK_PNMI_MAC_ENTRIES,
+		sizeof(SK_PNMI_CONF),
+		SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType),
+		SK_PNMI_RO, MacPrivateConf, 0},
+#ifdef SK_PHY_LP_MODE
+		{OID_SKGE_PHY_LP_MODE,
+		SK_PNMI_MAC_ENTRIES,
+		sizeof(SK_PNMI_CONF),
+		SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode),
+		SK_PNMI_RW, MacPrivateConf, 0},
+#endif	
 	{OID_SKGE_LINK_CAP,
 		SK_PNMI_MAC_ENTRIES,
 		sizeof(SK_PNMI_CONF),
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skgepnmi.c linux-2.4.24-pre2/drivers/net/sk98lin/skgepnmi.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skgepnmi.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skgepnmi.c	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skgepnmi.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.109 $
- * Date:	$Date: 2003/07/17 14:15:24 $
+ * Version:	$Revision: 1.111 $
+ * Date:	$Date: 2003/09/15 13:35:35 $
  * Purpose:	Private Network Management Interface
  *
  ****************************************************************************/
@@ -27,6 +27,22 @@
  * History:
  *
  *	$Log: skgepnmi.c,v $
+ *	Revision 1.111  2003/09/15 13:35:35  tschilli
+ *	Code for OID_SKGE_PHY_LP_MODE completed (using #define SK_PHY_LP_MODE).
+ *	SK_DIAG_ATTACHED handling for OID_SKGE_DIAG_MODE in DiagActions() changed.
+ *	
+ *	Revision 1.110  2003/08/15 12:28:04  tschilli
+ *	Added new OIDs:
+ *	OID_SKGE_DRIVER_RELDATE
+ *	OID_SKGE_DRIVER_FILENAME
+ *	OID_SKGE_CHIPID
+ *	OID_SKGE_RAMSIZE
+ *	OID_SKGE_VAUXAVAIL
+ *	OID_SKGE_PHY_TYPE
+ *	OID_SKGE_PHY_LP_MODE
+ *	
+ *	Added SK_DIAG_ATTACHED handling for OID_SKGE_DIAG_MODE in DiagActions().
+ *	
  *	Revision 1.109  2003/07/17 14:15:24  tschilli
  *	Bug in SkPnmiGenIoctl() fixed.
  *	
@@ -471,7 +487,7 @@
 
 #ifndef _lint
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skgepnmi.c,v 1.109 2003/07/17 14:15:24 tschilli Exp $ (C) Marvell.";
+	"@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
 #endif /* !_lint */
 
 #include "h/skdrv1st.h"
@@ -4008,14 +4024,6 @@
 #endif /* SK_NDIS_64BIT_CTR */
 		break;
 
-	case OID_SKGE_BOARDLEVEL:
-		if (*pLen < sizeof(SK_U32)) {
-
-			*pLen = sizeof(SK_U32);
-			return (SK_PNMI_ERR_TOO_SHORT);
-		}
-		break;
-
 	case OID_SKGE_PORT_NUMBER:
 	case OID_SKGE_DEVICE_TYPE:
 	case OID_SKGE_RESULT:
@@ -4023,6 +4031,9 @@
 	case OID_GEN_TRANSMIT_QUEUE_LENGTH:
 	case OID_SKGE_TRAP_NUMBER:
 	case OID_SKGE_MDB_VERSION:
+	case OID_SKGE_BOARDLEVEL:
+	case OID_SKGE_CHIPID:
+	case OID_SKGE_RAMSIZE:
 		if (*pLen < sizeof(SK_U32)) {
 
 			*pLen = sizeof(SK_U32);
@@ -4043,6 +4054,7 @@
 	case OID_SKGE_BUS_WIDTH:
 	case OID_SKGE_SENSOR_NUMBER:
 	case OID_SKGE_CHKSM_NUMBER:
+	case OID_SKGE_VAUXAVAIL:
 		if (*pLen < sizeof(SK_U8)) {
 
 			*pLen = sizeof(SK_U8);
@@ -4234,6 +4246,66 @@
 		*pLen = Len;
 		break;
 
+	case OID_SKGE_DRIVER_RELDATE:
+		if (pAC->Pnmi.pDriverReleaseDate == NULL) {
+
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
+				SK_PNMI_ERR053MSG);
+
+			*pLen = 0;
+			return (SK_PNMI_ERR_GENERAL);
+		}
+
+		Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
+		if (Len > SK_PNMI_STRINGLEN1) {
+
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
+				SK_PNMI_ERR054MSG);
+
+			*pLen = 0;
+			return (SK_PNMI_ERR_GENERAL);
+		}
+
+		if (*pLen < Len) {
+
+			*pLen = Len;
+			return (SK_PNMI_ERR_TOO_SHORT);
+		}
+		*pBuf = (char)(Len - 1);
+		SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
+		*pLen = Len;
+		break;
+
+	case OID_SKGE_DRIVER_FILENAME:
+		if (pAC->Pnmi.pDriverFileName == NULL) {
+
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
+				SK_PNMI_ERR055MSG);
+
+			*pLen = 0;
+			return (SK_PNMI_ERR_GENERAL);
+		}
+
+		Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
+		if (Len > SK_PNMI_STRINGLEN1) {
+
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
+				SK_PNMI_ERR056MSG);
+
+			*pLen = 0;
+			return (SK_PNMI_ERR_GENERAL);
+		}
+
+		if (*pLen < Len) {
+
+			*pLen = Len;
+			return (SK_PNMI_ERR_TOO_SHORT);
+		}
+		*pBuf = (char)(Len - 1);
+		SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
+		*pLen = Len;
+		break;
+
 	case OID_SKGE_HW_DESCR:
 		/*
 		 * The hardware description is located in the VPD. This
@@ -4291,8 +4363,25 @@
 		*pLen = sizeof(SK_U16);
 		break;
 
+	case OID_SKGE_CHIPID:
+		Val32 = pAC->GIni.GIChipId;
+		SK_PNMI_STORE_U32(pBuf, Val32);
+		*pLen = sizeof(SK_U32);
+		break;
+
+	case OID_SKGE_RAMSIZE:
+		Val32 = pAC->GIni.GIRamSize;
+		SK_PNMI_STORE_U32(pBuf, Val32);
+		*pLen = sizeof(SK_U32);
+		break;
+
+	case OID_SKGE_VAUXAVAIL:
+		*pBuf = (char) pAC->GIni.GIVauxAvail;
+		*pLen = sizeof(char);
+		break;
+
 	case OID_SKGE_BUS_TYPE:
-		*pBuf = (char)SK_PNMI_BUS_PCI;
+		*pBuf = (char) SK_PNMI_BUS_PCI;
 		*pLen = sizeof(char);
 		break;
 
@@ -5435,6 +5524,9 @@
 		case OID_SKGE_SPEED_CAP:
 		case OID_SKGE_SPEED_MODE:
 		case OID_SKGE_SPEED_STATUS:
+#ifdef SK_PHY_LP_MODE
+		case OID_SKGE_PHY_LP_MODE:
+#endif
 			if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
 
 				*pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
@@ -5443,6 +5535,7 @@
 			break;
 
         case OID_SKGE_MTU:
+        case OID_SKGE_PHY_TYPE:
 			if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
 
 				*pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
@@ -5488,6 +5581,49 @@
 				Offset += sizeof(char);
 				break;
 
+			case OID_SKGE_PHY_TYPE:
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+					if (LogPortIndex == 0) {
+						continue;
+					}
+					else {
+						/* Get value for physical ports */
+						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
+							pAC, LogPortIndex);
+						Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
+						SK_PNMI_STORE_U32(pBufPtr, Val32);
+					}
+				}
+				else { /* DualNetMode */
+					
+					Val32 = pAC->GIni.GP[NetIndex].PhyType;
+					SK_PNMI_STORE_U32(pBufPtr, Val32);
+				}
+				Offset += sizeof(SK_U32);
+				break;
+
+#ifdef SK_PHY_LP_MODE
+			case OID_SKGE_PHY_LP_MODE:
+				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+					if (LogPortIndex == 0) {
+						continue;
+					}
+					else {
+						/* Get value for physical ports */
+						PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+						Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
+						*pBufPtr = Val8;
+					}
+				}
+				else { /* DualNetMode */
+					
+					Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
+					*pBufPtr = Val8;
+				}
+				Offset += sizeof(SK_U8);
+				break;
+#endif
+
 			case OID_SKGE_LINK_CAP:
 				if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
 					if (LogPortIndex == 0) {
@@ -5804,6 +5940,16 @@
 		}
 		break;
 
+#ifdef SK_PHY_LP_MODE
+	case OID_SKGE_PHY_LP_MODE:
+		if (*pLen < Limit - LogPortIndex) {
+
+			*pLen = Limit - LogPortIndex;
+			return (SK_PNMI_ERR_TOO_SHORT);
+		}
+		break;
+#endif
+
 	case OID_SKGE_MTU:
 		if (*pLen < sizeof(SK_U32)) {
 
@@ -6160,6 +6306,116 @@
 
 			Offset += sizeof(SK_U32);
 			break;
+		
+#ifdef SK_PHY_LP_MODE
+		case OID_SKGE_PHY_LP_MODE:
+			/* The preset ends here */
+			if (Action == SK_PNMI_PRESET) {
+
+				return (SK_PNMI_ERR_OK);
+			}
+
+			if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
+				if (LogPortIndex == 0) {
+					Offset = 0;
+					continue;
+				}
+				else {
+					/* Set value for physical ports */
+					PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
+
+					switch (*(pBuf + Offset)) {
+						case 0:
+							/* If LowPowerMode is active, we can leave it. */
+							if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
+
+								Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
+								
+								if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3)	{
+									
+									SkDrvInitAdapter(pAC);
+								}
+								break;
+							}
+							else {
+								*pLen = 0;
+								return (SK_PNMI_ERR_GENERAL);
+							}
+						case 1:
+						case 2:
+						case 3:
+						case 4:
+							/* If no LowPowerMode is active, we can enter it. */
+							if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
+
+								if ((*(pBuf + Offset)) < 3)	{
+								
+									SkDrvDeInitAdapter(pAC);
+								}
+
+								Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
+								break;
+							}
+							else {
+								*pLen = 0;
+								return (SK_PNMI_ERR_GENERAL);
+							}
+						default:
+							*pLen = 0;
+							return (SK_PNMI_ERR_BAD_VALUE);
+					}
+				}
+			}
+			else { /* DualNetMode */
+				
+				switch (*(pBuf + Offset)) {
+					case 0:
+						/* If we are in a LowPowerMode, we can leave it. */
+						if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
+
+							Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
+							
+							if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3)	{
+
+								SkDrvInitAdapter(pAC);
+							}
+							break;
+						}
+						else {
+							*pLen = 0;
+							return (SK_PNMI_ERR_GENERAL);
+						}
+					
+					case 1:
+					case 2:
+					case 3:
+					case 4:
+						/* If we are not already in LowPowerMode, we can enter it. */
+						if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
+
+							if ((*(pBuf + Offset)) < 3)	{
+
+								SkDrvDeInitAdapter(pAC);
+							}
+							else {
+
+								Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
+							}
+							break;
+						}
+						else {
+							*pLen = 0;
+							return (SK_PNMI_ERR_GENERAL);
+						}
+					
+					default:
+						*pLen = 0;
+						return (SK_PNMI_ERR_BAD_VALUE);
+				}
+			}
+			Offset += sizeof(SK_U8);
+			break;
+#endif
 
 		default:
             SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
@@ -6318,6 +6574,7 @@
 	unsigned int	PhysPortMax;
 	unsigned int	PhysPortIndex;
 	SK_U8		Val8;
+	SK_U32		Val32;
 	SK_BOOL		PortActiveFlag;
 	SK_GEPORT	*pPrt;
 
@@ -6340,6 +6597,14 @@
 
 		switch (Id) {
 
+		case OID_SKGE_PHY_TYPE:
+			/* Check if it is the first active port */
+			if (*pBuf == 0) {
+				Val32 = pPrt->PhyType;
+				SK_PNMI_STORE_U32(pBuf, Val32);
+				continue;
+			}
+
 		case OID_SKGE_LINK_CAP:
 
 			/*
@@ -7974,6 +8239,7 @@
 SK_U32 NetIndex)	/* NetIndex (0..n), in single net mode always zero */
 {
 
+	SK_U32	DiagStatus;
 	SK_U32	RetCode = SK_PNMI_ERR_GENERAL;
 
 	/*
@@ -8012,7 +8278,8 @@
 		switch (Id) {
 
 		case OID_SKGE_DIAG_MODE:
-			SK_PNMI_STORE_U32(pBuf, pAC->DiagModeActive);
+			DiagStatus = pAC->Pnmi.DiagAttached;
+			SK_PNMI_STORE_U32(pBuf, DiagStatus);
 			*pLen = sizeof(SK_U32);	
 			RetCode = SK_PNMI_ERR_OK;
 			break;
@@ -8022,7 +8289,6 @@
 			RetCode = SK_PNMI_ERR_GENERAL;
 			break;
 		}
-
 		return (RetCode); 
 	}
 
@@ -8039,23 +8305,84 @@
 
 			/* Handle the SET. */
 			switch (*pBuf) {
-		
+
+				/* Attach the DIAG to this adapter. */
+				case SK_DIAG_ATTACHED:
+					/* Check if we come from running */
+					if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
+
+						RetCode = SkDrvLeaveDiagMode(pAC);
+
+					}
+					else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
+
+						RetCode = SK_PNMI_ERR_OK;
+					}	
+					
+					else {
+
+						RetCode = SK_PNMI_ERR_GENERAL;
+
+					}
+					
+					if (RetCode == SK_PNMI_ERR_OK) {
+
+						pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
+					}
+					break;
+
 				/* Enter the DIAG mode in the driver. */
-				case 1:
-					/* If DiagMode is not active, we can enter it. */
-					if (!pAC->DiagModeActive) {
+				case SK_DIAG_RUNNING:
+					RetCode = SK_PNMI_ERR_OK;
+					
+					/*
+					 * If DiagAttached is set, we can tell the driver
+					 * to enter the DIAG mode.
+					 */
+					if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
+						/* If DiagMode is not active, we can enter it. */
+						if (!pAC->DiagModeActive) {
 
-						RetCode = SkDrvEnterDiagMode(pAC);	
+							RetCode = SkDrvEnterDiagMode(pAC); 
+						}
+						else {
+
+							RetCode = SK_PNMI_ERR_GENERAL;
+						}
 					}
 					else {
 
 						RetCode = SK_PNMI_ERR_GENERAL;
 					}
+					
+					if (RetCode == SK_PNMI_ERR_OK) {
+
+						pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
+					}
 					break;
 
-				/* Leave the DIAG mode in the driver. */
-				case 0:
-					RetCode = SkDrvLeaveDiagMode(pAC);	
+				case SK_DIAG_IDLE:
+					/* Check if we come from running */
+					if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
+
+						RetCode = SkDrvLeaveDiagMode(pAC);
+
+					}
+					else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
+
+						RetCode = SK_PNMI_ERR_OK;
+					}	
+					
+					else {
+
+						RetCode = SK_PNMI_ERR_GENERAL;
+
+					}
+
+					if (RetCode == SK_PNMI_ERR_OK) {
+
+						pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
+					}
 					break;
 
 				default:
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skgesirq.c linux-2.4.24-pre2/drivers/net/sk98lin/skgesirq.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skgesirq.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skgesirq.c	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skgesirq.c
  * Project:	Gigabit Ethernet Adapters, Common Modules
- * Version:	$Revision: 1.91 $
- * Date:	$Date: 2003/07/04 12:46:22 $
+ * Version:	$Revision: 1.92 $
+ * Date:	$Date: 2003/09/16 14:37:07 $
  * Purpose:	Special IRQ module
  *
  ******************************************************************************/
@@ -27,6 +27,12 @@
  * History:
  *
  *	$Log: skgesirq.c,v $
+ *	Revision 1.92  2003/09/16 14:37:07  rschmidt
+ *	Added debug messages in some SkGePortCheckUp...() routines.
+ *	Fixed compiler warnings for different types.
+ *	Avoided port check up in reset state (eg. coma mode).
+ *	Editorial changes.
+ *	
  *	Revision 1.91  2003/07/04 12:46:22  rschmidt
  *	Added debug messages in SkGePortCheckUpGmac().
  *	Added error log message and new driver event SK_DRV_DOWNSHIFT_DET
@@ -410,7 +416,7 @@
 
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skgesirq.c,v 1.91 2003/07/04 12:46:22 rschmidt Exp $ (C) Marvell.";
+	"@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell.";
 #endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
@@ -490,7 +496,7 @@
 		("AutoSensing: First mode %d on Port %d\n",
 		(int)SK_LMODE_AUTOFULL, Port));
 
-	pPrt->PLinkMode = SK_LMODE_AUTOFULL;
+	pPrt->PLinkMode = (SK_U8)SK_LMODE_AUTOFULL;
 
 	return;
 }	/* SkHWInitDefSense */
@@ -606,7 +612,7 @@
 	/* Reset Port stati */
     pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
     pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE;
-	pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_INDETERMINATED;
+	pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED;
 
 	/* Re-init Phy especially when the AutoSense default is set now */
 	SkMacInitPhy(pAC, IoC, Port, SK_FALSE);
@@ -655,19 +661,19 @@
 		case SK_LSPEED_AUTO:
 			/* default is 1000 Mbps */
 		case SK_LSPEED_1000MBPS:
-			pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+			pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
 			break;
 		case SK_LSPEED_100MBPS:
-			pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
+			pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
 			break;
 		case SK_LSPEED_10MBPS:
-			pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
+			pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
 			break;
 		}
 
 		/* Set Link Mode Status */
 		if (pPrt->PLinkMode == SK_LMODE_FULL) {
-			pPrt->PLinkModeStatus = SK_LMODE_STAT_FULL;
+			pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL;
 		}
 		else {
             pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF;
@@ -1598,8 +1604,7 @@
 			 * (clear Page Received bit if set)
 			 */
 			SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat);
-			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-				("AutoNeg done Port %d\n", Port));
+			
 			return(SK_HW_PS_LINK);
 		}
 		
@@ -1870,7 +1875,7 @@
 	SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
 	
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("AutoNeg: %d, PhyStat: 0x%04X\n", AutoNeg, PhyStat));
+		("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
 
 	SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb);
 
@@ -1897,8 +1902,11 @@
 
 	if (AutoNeg) {
 		if ((PhyStat & PHY_ST_AN_OVER) != 0) {
+			
 			SkHWLinkUp(pAC, IoC, Port);
+			
 			Done = SkMacAutoNegDone(pAC, IoC, Port);
+			
 			if (Done != SK_AND_OK) {
 #ifdef DEBUG
 				/* Get PHY parameters, for debugging only */
@@ -1924,9 +1932,6 @@
 						(void *)NULL);
 				}
 #endif /* DEBUG */
-				
-				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-					("AutoNeg done Port %d\n", Port));
 				return(SK_HW_PS_LINK);
 			}
 		}
@@ -1989,9 +1994,22 @@
 	SK_U16		PhySpecStat;/* PHY Specific Status */
 	SK_U16		ResAb;		/* Master/Slave resolution */
 	SK_EVPARA	Para;
+#ifdef DEBUG
+	SK_U16		Word;		/* I/O helper */
+#endif /* DEBUG */
 
 	pPrt = &pAC->GIni.GP[Port];
 
+	if (pPrt->PHWLinkUp) {
+		return(SK_HW_PS_NONE);
+	}
+
+	/* Read PHY Status */
+	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
+
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat));
+
 	/* Read PHY Interrupt Status */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc);
 
@@ -2005,16 +2023,6 @@
 			("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc));
 	}
 
-	if (pPrt->PHWLinkUp) {
-		return(SK_HW_PS_NONE);
-	}
-
-	/* Read PHY Status */
-	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat);
-
-	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("AutoNeg: %d, PhyStat: 0x%04X\n", AutoNeg, PhyStat));
-
 	SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat);
 	
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb);
@@ -2034,7 +2042,20 @@
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat);
 	
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("AutoNeg: %d, PhySpecStat: 0x%04X\n", AutoNeg, PhySpecStat));
+		("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat));
+
+#ifdef DEBUG
+	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word);
+
+	if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 ||
+		(PhySpecStat & PHY_M_PS_PAGE_REC) != 0)  {
+		/* Read PHY Next Page Link Partner */
+		SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word);
+
+		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+			("Page Received, NextPage: 0x%04X\n", Word));
+	}
+#endif /* DEBUG */
 
 	if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) {
 		return(SK_HW_PS_NONE);
@@ -2069,8 +2090,6 @@
 				return(SK_HW_PS_RESTART);
 			}
 			
-			SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-				("AutoNeg done Port %d\n", Port));
 			return(SK_HW_PS_LINK);
 		}
 	}
@@ -2179,8 +2198,6 @@
 				 * extra link down/ups
 				 */
 				SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat);
-				SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-					("AutoNeg done Port %d\n", Port));
 				return(SK_HW_PS_LINK);
 			}
 		}
@@ -2278,8 +2295,14 @@
 
 	switch (Event) {
 	case SK_HWEV_WATIM:
-		/* Check whether port came up */
-		PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
+		if (pPrt->PState == SK_PRT_RESET) {
+		
+			PortStat = SK_HW_PS_NONE;
+		}
+		else {
+			/* Check whether port came up */
+			PortStat = SkGePortCheckUp(pAC, IoC, (int)Port);
+		}
 
 		switch (PortStat) {
 		case SK_HW_PS_RESTART:
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/ski2c.c linux-2.4.24-pre2/drivers/net/sk98lin/ski2c.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/ski2c.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/ski2c.c	2003-12-22 11:34:35.000000000 -0800
@@ -1,16 +1,17 @@
 /******************************************************************************
  *
  * Name:	ski2c.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.57 $
- * Date:	$Date: 2003/01/28 09:17:38 $
+ * Project:	Gigabit Ethernet Adapters, TWSI-Module
+ * Version:	$Revision: 1.59 $
+ * Date:	$Date: 2003/10/20 09:07:25 $
  * Purpose:	Functions to access Voltage and Temperature Sensor
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -26,6 +27,14 @@
  * History:
  *
  *	$Log: ski2c.c,v $
+ *	Revision 1.59  2003/10/20 09:07:25  rschmidt
+ *	Added cast SK_U32 in SkI2cWrite() to avoid compiler warning.
+ *	Editorial changes.
+ *	
+ *	Revision 1.58  2003/09/23 09:22:53  malthoff
+ *	Parameter I2cDevSize added in SkI2cRead and SkI2cWrite to
+ *	support larger devices on the TWSI bus.
+ *	
  *	Revision 1.57  2003/01/28 09:17:38  rschmidt
  *	Fixed handling for sensors on YUKON Fiber.
  *	Editorial changes.
@@ -224,15 +233,15 @@
  *	Created. Sources taken from ML Projekt.
  *	Sources have to be reworked for GE.
  *
- *
  ******************************************************************************/
 
-
 /*
  *	I2C Protocol
  */
+#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"$Id: ski2c.c,v 1.57 2003/01/28 09:17:38 rschmidt Exp $";
+	"@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
+#endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
 #include "h/lm80.h"
@@ -312,7 +321,7 @@
 {}
 #endif
 
-#ifdef	SK_DIAG
+#ifdef SK_DIAG
 /*
  * I2C Fast Mode timing values used by the LM80.
  * If new devices are added to the I2C bus the timing values have to be checked.
@@ -516,7 +525,6 @@
 {
 	/*
 	 * Received bit must be zero.
-	 *
 	 */
 	SkI2cSndBit(IoC, 0);
 }	/* SkI2cSndAck */
@@ -590,7 +598,7 @@
 	return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
 }	/* SkI2cSndDev */
 
-#endif	/* SK_DIAG */
+#endif /* SK_DIAG */
 
 /*----------------- I2C CTRL Register Functions ----------*/
 
@@ -620,7 +628,7 @@
 			SK_I2C_STOP(IoC);
 #ifndef SK_DIAG
 			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
-#endif	/* !SK_DIAG */
+#endif /* !SK_DIAG */
 			return(1);
 		}
 		
@@ -661,15 +669,19 @@
 	}
 
 	StartTime = SkOsGetTime(pAC);
+	
 	do {
 		if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
+			
 			SK_I2C_STOP(IoC);
 #ifndef SK_DIAG
 			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG);
-#endif	/* !SK_DIAG */
+#endif /* !SK_DIAG */
 			return;
 		}
+		
 		SK_IN32(IoC, B0_ISRC, &IrqSrc);
+
 	} while ((IrqSrc & IS_I2C_READY) == 0);
 
 	pSen->SenState = SK_SEN_IDLE;
@@ -687,18 +699,19 @@
 SK_IOC	IoC,		/* I/O Context */
 SK_U32	I2cData,	/* I2C Data to write */
 int		I2cDev,		/* I2C Device Address */
+int		I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
 int		I2cReg,		/* I2C Device Register Address */
 int		I2cBurst)	/* I2C Burst Flag */
 {
 	SK_OUT32(IoC, B2_I2C_DATA, I2cData);
-	SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
+	
+	SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
 	
 	return(SkI2cWait(pAC, IoC, I2C_WRITE));
 }	/* SkI2cWrite*/
 
 
 #ifdef	SK_DIAG
-
 /*
  * reads a single byte or 4 bytes from the I2C device
  *
@@ -708,23 +721,24 @@
 SK_AC	*pAC,		/* Adapter Context */
 SK_IOC	IoC,		/* I/O Context */
 int		I2cDev,		/* I2C Device Address */
+int		I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
 int		I2cReg,		/* I2C Device Register Address */
 int		I2cBurst)	/* I2C Burst Flag */
 {
 	SK_U32	Data;
 
 	SK_OUT32(IoC, B2_I2C_DATA, 0);
-	SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
+	SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
 	
 	if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
 		w_print("%s\n", SKERR_I2C_E002MSG);
 	}
 	
 	SK_IN32(IoC, B2_I2C_DATA, &Data);
+	
 	return(Data);
 }	/* SkI2cRead */
-
-#endif	/* SK_DIAG */
+#endif /* SK_DIAG */
 
 
 /*
@@ -745,9 +759,10 @@
     if (pSen->SenRead != NULL) {
         return((*pSen->SenRead)(pAC, IoC, pSen));
     }
-    else
+	else {
         return(0); /* no success */
-}	/* SkI2cReadSensor*/
+	}
+}	/* SkI2cReadSensor */
 
 /*
  * Do the Init state 0 initialization
@@ -761,12 +776,12 @@
 	pAC->I2c.CurrSens = 0;
 	
 	/* Begin with timeout control for state machine */
-	pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
+	pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
 	
 	/* Set sensor number to zero */
 	pAC->I2c.MaxSens = 0;
 
-#ifndef	SK_DIAG
+#ifndef SK_DIAG
 	/* Initialize Number of Dummy Reads */
 	pAC->I2c.DummyReads = SK_MAX_SENSORS;
 #endif
@@ -840,19 +855,20 @@
     }
 
 	/* Check for 64 Bit Yukon without sensors */
-	if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_CFG, 0) != 0) {
+	if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) {
         return(0);
     }
 
-	(void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_1, 0);
+	(void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
 	
-	(void)SkI2cWrite(pAC, IoC, 0xff, LM80_ADDR, LM80_IMSK_2, 0);
+	(void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
 	
-	(void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_FAN_CTRL, 0);
+	(void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
 	
-	(void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, LM80_TEMP_CTRL, 0);
+	(void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
 	
-	(void)SkI2cWrite(pAC, IoC, LM80_CFG_START, LM80_ADDR, LM80_CFG, 0);
+	(void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
+		LM80_CFG, 0);
 	
 	/*
 	 * MaxSens has to be updated here, because PhyType is not
@@ -957,7 +973,7 @@
 				pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR;
 			}
 			else {
-				pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC-Co 1V5";
+				pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5";
 				pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR;
 				pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN;
 				pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN;
@@ -1015,9 +1031,9 @@
 		pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
 	}
 
-#ifndef	SK_DIAG
+#ifndef SK_DIAG
 	pAC->I2c.DummyReads = pAC->I2c.MaxSens;
-#endif	/* !SK_DIAG */
+#endif /* !SK_DIAG */
 	
 	/* Clear I2C IRQ */
 	SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
@@ -1208,15 +1224,13 @@
 			pSen->SenLastErrLogTS = CurrTime;
 
 			if (pSen->SenType == SK_SEN_TEMP) {
-				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011,
-					SKERR_I2C_E011MSG);
-			} else if (pSen->SenType == SK_SEN_VOLT) {
-				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012,
-					SKERR_I2C_E012MSG);
-			} else
-			{
-				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015,
-					SKERR_I2C_E015MSG);
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
+			}
+			else if (pSen->SenType == SK_SEN_VOLT) {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
+			}
+			else {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
 			}
 		}
 	}
@@ -1235,8 +1249,7 @@
 			/* This state is the former one */
 
 			/* So check first whether we have to send a trap */
-			if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD >
-			    CurrTime) {
+			if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
 				/*
 				 * Do NOT send the Trap. The hold back time
 				 * has to run out first.
@@ -1245,8 +1258,7 @@
 			}
 
 			/* Check now whether we have to log an Error */
-			if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD >
-			    CurrTime) {
+			if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
 				/*
 				 * Do NOT log the error. The hold back time
 				 * has to run out first.
@@ -1277,15 +1289,13 @@
 			pSen->SenLastWarnLogTS = CurrTime;
 
 			if (pSen->SenType == SK_SEN_TEMP) {
-				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
-					SKERR_I2C_E009MSG);
-			} else if (pSen->SenType == SK_SEN_VOLT) {
-				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
-					SKERR_I2C_E010MSG);
-			} else
-			{
-				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
-					SKERR_I2C_E014MSG);
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
+			}
+			else if (pSen->SenType == SK_SEN_VOLT) {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
+			}
+			else {
+				SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
 			}
 		}
 	}
@@ -1317,7 +1327,7 @@
 		}
 	}
 	
-#if 0
+#ifdef TEST_ONLY
     /* Dynamic thresholds also for VAUX of LM80 sensor */
 	if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
 
@@ -1359,7 +1369,7 @@
 	if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
 		SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
 	}
-}	/* SkI2cCheckSensor*/
+}	/* SkI2cCheckSensor */
 
 
 /*
@@ -1390,7 +1400,7 @@
 
 		if (ReadComplete) {
 			/* Check sensor against defined thresholds */
-			SkI2cCheckSensor (pAC, pSen);
+			SkI2cCheckSensor(pAC, pSen);
 
 			/* Increment Current sensor and set appropriate Timeout */
 			pAC->I2c.CurrSens++;
@@ -1414,7 +1424,7 @@
 			/* Start Timer */
 			ParaLocal.Para64 = (SK_U64)0;
 
-			pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE;
+			pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
 
             SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
 				SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
@@ -1431,7 +1441,7 @@
 
 			if (ReadComplete) {
 				/* Check sensor against defined thresholds */
-				SkI2cCheckSensor (pAC, pSen);
+				SkI2cCheckSensor(pAC, pSen);
 
 				/* Increment Current sensor and set appropriate Timeout */
 				pAC->I2c.CurrSens++;
@@ -1496,4 +1506,4 @@
 	return(0);
 }	/* SkI2cEvent*/
 
-#endif	/* !SK_DIAG */
+#endif /* !SK_DIAG */
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/sklm80.c linux-2.4.24-pre2/drivers/net/sk98lin/sklm80.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/sklm80.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.24-pre2/drivers/net/sk98lin/sklm80.c	2003-12-22 11:34:35.000000000 -0800
@@ -1,16 +1,17 @@
 /******************************************************************************
  *
  * Name:	sklm80.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.20 $
- * Date:	$Date: 2002/08/13 09:16:27 $
- * Purpose:	Funktions to access Voltage and Temperature Sensor (LM80)
+ * Project:	Gigabit Ethernet Adapters, TWSI-Module
+ * Version:	$Revision: 1.22 $
+ * Date:	$Date: 2003/10/20 09:08:21 $
+ * Purpose:	Functions to access Voltage and Temperature Sensor (LM80)
  *
  ******************************************************************************/
 
 /******************************************************************************
  *
- *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -26,15 +27,21 @@
  * History:
  *
  *	$Log: sklm80.c,v $
+ *	Revision 1.22  2003/10/20 09:08:21  rschmidt
+ *	Editorial changes.
+ *	
+ *	Revision 1.21  2003/09/23 09:29:04  malthoff
+ *	Parameter Dev_Size added to macro SK_I2C_CTL.
+ *	
  *	Revision 1.20  2002/08/13 09:16:27  rschmidt
  *	Changed return value for SkLm80ReadSensor() back to 'int'
- *	Editorial changes
+ *	Editorial changes.
  *	
  *	Revision 1.19  2002/08/06 09:43:31  jschmalz
- *	Extensions and changes for Yukon
+ *	Extensions and changes for Yukon.
  *	
  *	Revision 1.18  2002/08/02 12:26:57  rschmidt
- *	Editorial changes
+ *	Editorial changes.
  *	
  *	Revision 1.17  1999/11/22 13:35:51  cgoos
  *	Changed license header to GPL.
@@ -93,16 +100,15 @@
  *	Revision 1.1  1998/07/17 09:57:12  gklug
  *	initial version
  *
- *
- *
  ******************************************************************************/
 
-
 /*
 	LM80 functions
 */
+#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"$Id: sklm80.c,v 1.20 2002/08/13 09:16:27 rschmidt Exp $" ;
+	"@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. ";
+#endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
 #include "h/lm80.h"
@@ -202,7 +208,7 @@
 	switch (pSen->SenState) {
 	case SK_SEN_IDLE:
 		/* Send address to ADDR register */
-		SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, pSen->SenReg, 0);
+		SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, pSen->SenReg, 0);
 
 		pSen->SenState = SK_SEN_VALUE ;
 		BREAK_OR_WAIT(pAC, IoC, I2C_READ);
@@ -250,7 +256,7 @@
 			(pSen->SenValue % SK_LM80_TEMP_LSB);
 
 		/* Send address to ADDR register */
-		SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, LM80_TEMP_CTRL, 0);
+		SK_I2C_CTL(IoC, I2C_READ, pSen->SenDev, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
 
 		pSen->SenState = SK_SEN_VALEXT ;
 		BREAK_OR_WAIT(pAC, IoC, I2C_READ);
@@ -284,3 +290,4 @@
 	/* Not completed */
 	return(0);
 }
+
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skproc.c linux-2.4.24-pre2/drivers/net/sk98lin/skproc.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skproc.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skproc.c	2003-12-22 11:34:35.000000000 -0800
@@ -1,16 +1,17 @@
 /******************************************************************************
  *
- * Name:    skproc.c
+ * Name:	skproc.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.2 $
- * Date:    $Date: 2003/08/12 16:45:29 $
+ * Version:	$Revision: 1.11 $
+ * Date:	$Date: 2003/12/11 16:03:57 $
  * Purpose:	Funktions to display statictic data
  *
  ******************************************************************************/
  
 /******************************************************************************
  *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
+ *	(C)Copyright 1998-2002 SysKonnect GmbH.
+ *	(C)Copyright 2002-2003 Marvell.
  *
  *	This program is free software; you can redistribute it and/or modify
  *	it under the terms of the GNU General Public License as published by
@@ -28,6 +29,33 @@
  * History:
  *
  *	$Log: skproc.c,v $
+ *	Revision 1.11  2003/12/11 16:03:57  mlindner
+ *	Fix: Create backup from pnmi data structure
+ *	
+ *	Revision 1.10  2003/11/19 16:25:36  mlindner
+ *	Fix: Print output as 64-bit digit
+ *	
+ *	Revision 1.9  2003/11/17 13:29:05  mlindner
+ *	Fix: Editorial changes
+ *	
+ *	Revision 1.8  2003/11/13 14:18:48  rroesler
+ *	Fix: added latest changes regarding the use of the proc system
+ *	
+ *	Revision 1.7  2003/11/10 09:35:07  rroesler
+ *	Fix: diag backup restore of PNMI structure
+ *	
+ *	Revision 1.6  2003/11/07 17:31:39  rroesler
+ *	Add: security counter for the proc file system
+ *	
+ *	Revision 1.5  2003/10/07 08:17:08  mlindner
+ *	Fix: Copyright changes
+ *	
+ *	Revision 1.4  2003/09/01 15:29:24  mlindner
+ *	Fix: Editorial changes
+ *	
+ *	Revision 1.3  2003/08/29 12:30:58  mlindner
+ *	Add: Version entry in the proc file system
+ *	
  *	Revision 1.2  2003/08/12 16:45:29  mlindner
  *	Add: Removed SkNumber and SkDoDiv
  *	Add: Counter output as (unsigned long long)
@@ -93,54 +121,83 @@
 
 #include "h/skdrv1st.h"
 #include "h/skdrv2nd.h"
+#include "h/skversion.h"
 
-	extern struct net_device	*SkGeRootDev;
+extern struct SK_NET_DEVICE *SkGeRootDev;
+static int sk_proc_print(void *writePtr, char *format, ...);
+static void sk_gen_browse(void *buffer);
+int len;
 
+struct proc_dir_entry *file = NULL;
 
-int sk_proc_read(char *buffer,
-				char **buffer_location,
-				off_t offset,
-				int buffer_length,
-				int *eof,
-				void *data);
+/*****************************************************************************
+ *
+ *      sk_proc_read - show proc information of a particular adapter
+ *
+ * Description:
+ *  This function fills the proc entry with statistic data about 
+ *  the ethernet device. It invokes the generic sk_gen_browse() to
+ *  print out all items one per one.
+ *  
+ * Returns: number of bytes written
+ *      
+ */
+int sk_proc_read(char   *buffer,
+		char  **buffer_location,
+		off_t   offset,
+		int     buffer_length,
+		int    *eof,
+		void   *data)
+{
+	void *castedBuffer = (void *) buffer;
+	file               = (struct proc_dir_entry*) data;
+	len                = 0; /* initial value */
+	sk_gen_browse(castedBuffer);
 
+	if (offset >= len) {
+		*eof = 1;
+		return 0;
+	}
 
+	*buffer_location = buffer + offset;
+	if (buffer_length >= len - offset) {
+		*eof = 1;
+	}
+	return (min_t(int, buffer_length, len - offset));
+}
 
 /*****************************************************************************
  *
- * 	sk_proc_read - print "summaries" entry 
+ * 	sk_gen_browse -generic  print "summaries" entry 
  *
  * Description:
  *  This function fills the proc entry with statistic data about 
  *  the ethernet device.
  *  
- *
- * Returns: buffer with statistic data
+ * Returns: -
  *	
  */
-int sk_proc_read(char *buffer,
-char **buffer_location,
-off_t offset,
-int buffer_length,
-int *eof,
-void *data)
+static void sk_gen_browse(void *buffer)
 {
-	int len = 0;
-	int t;
-	int i;
-	DEV_NET					*pNet;
-	SK_AC					*pAC;
-	char					sens_msg[50];
-	unsigned long			Flags;	
-	unsigned int			Size;
-	struct SK_NET_DEVICE 		*next;
-	struct SK_NET_DEVICE 		*SkgeProcDev = SkGeRootDev;
-
+	struct SK_NET_DEVICE	*SkgeProcDev = SkGeRootDev;
+	struct SK_NET_DEVICE	*next;
 	SK_PNMI_STRUCT_DATA 	*pPnmiStruct;
 	SK_PNMI_STAT		*pPnmiStat;
-	struct proc_dir_entry *file = (struct proc_dir_entry*) data;
+	unsigned long		Flags;	
+	unsigned int		Size;
+	DEV_NET			*pNet;
+	SK_AC			*pAC;
+	char			sens_msg[50];
+	int			MaxSecurityCount = 0;
+	int 			t;
+	int 			i;
 
 	while (SkgeProcDev) {
+		MaxSecurityCount++;
+		if (MaxSecurityCount > 100) {
+			printk("Max limit for sk_proc_read security counter!\n");
+			return;
+		}
 		pNet = (DEV_NET*) SkgeProcDev->priv;
 		pAC = pNet->pAC;
 		next = pAC->Next;
@@ -153,38 +210,52 @@
 
 			spin_lock_irqsave(&pAC->SlowPathLock, Flags);
 			Size = SK_PNMI_STRUCT_SIZE;
+#ifdef SK_DIAG_SUPPORT
+			if (pAC->BoardLevel == SK_INIT_DATA) {
+				SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
+				if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
+					pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
+				}
+			} else {
+				SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
+			}
+#else
 			SkPnmiGetStruct(pAC, pAC->IoBase, 
 				pPnmiStruct, &Size, t-1);
+#endif
 			spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 	
 			if (strcmp(pAC->dev[t-1]->name, file->name) == 0) {
 				pPnmiStat = &pPnmiStruct->Stat[0];
-				len = sprintf(buffer, 
+				len = sk_proc_print(buffer, 
 					"\nDetailed statistic for device %s\n",
 					pAC->dev[t-1]->name);
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
 					"=======================================\n");
 	
 				/* Board statistics */
-				len += sprintf(buffer + len, 
+				len += sk_proc_print(buffer, 
 					"\nBoard statistics\n\n");
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
 					"Active Port                    %c\n",
 					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
 					Net[t-1].PrefPort]->PortNumber);
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
 					"Preferred Port                 %c\n",
 					'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
 					Net[t-1].PrefPort]->PortNumber);
 
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
 					"Bus speed (MHz)                %d\n",
 					pPnmiStruct->BusSpeed);
 
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
 					"Bus width (Bit)                %d\n",
 					pPnmiStruct->BusWidth);
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
+					"Driver version                 %s\n",
+					VER_STRING);
+				len += sk_proc_print(buffer,
 					"Hardware revision              v%d.%d\n",
 					(pAC->GIni.GIPciHwRev >> 4) & 0x0F,
 					pAC->GIni.GIPciHwRev & 0x0F);
@@ -196,7 +267,7 @@
 					case 1:
 						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
 						strcat(sens_msg, " (C)");
-						len += sprintf(buffer + len,
+						len += sk_proc_print(buffer,
 							"%-25s      %d.%02d\n",
 							sens_msg,
 							pAC->I2c.SenTable[i].SenValue / 10,
@@ -204,7 +275,7 @@
 
 						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
 						strcat(sens_msg, " (F)");
-						len += sprintf(buffer + len,
+						len += sk_proc_print(buffer,
 							"%-25s      %d.%02d\n",
 							sens_msg,
 							((((pAC->I2c.SenTable[i].SenValue)
@@ -215,7 +286,7 @@
 					case 2:
 						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
 						strcat(sens_msg, " (V)");
-						len += sprintf(buffer + len,
+						len += sk_proc_print(buffer,
 							"%-25s      %d.%03d\n",
 							sens_msg,
 							pAC->I2c.SenTable[i].SenValue / 1000,
@@ -224,7 +295,7 @@
 					case 3:
 						strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
 						strcat(sens_msg, " (rpm)");
-						len += sprintf(buffer + len,
+						len += sk_proc_print(buffer,
 							"%-25s      %d\n",
 							sens_msg,
 							pAC->I2c.SenTable[i].SenValue);
@@ -235,14 +306,14 @@
 				}
 				
 				/*Receive statistics */
-				len += sprintf(buffer + len, 
+				len += sk_proc_print(buffer, 
 				"\nReceive statistics\n\n");
 
-				len += sprintf(buffer + len,
-					"Received bytes                 %Ld\n",
+				len += sk_proc_print(buffer,
+					"Received bytes                 %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxOctetsOkCts);
-				len += sprintf(buffer + len,
-					"Received packets               %Ld\n",
+				len += sk_proc_print(buffer,
+					"Received packets               %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxOkCts);
 #if 0
 				if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
@@ -256,110 +327,138 @@
 					pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
 						pPnmiStat->StatRxTooLongCts;
 
-				len += sprintf(buffer + len,
-					"Receive errors                 %Ld\n",
+				len += sk_proc_print(buffer,
+					"Receive errors                 %Lu\n",
 					(unsigned long long) pPnmiStruct->InErrorsCts);
-				len += sprintf(buffer + len,
-					"Receive dropped                %Ld\n",
+				len += sk_proc_print(buffer,
+					"Receive dropped                %Lu\n",
 					(unsigned long long) pPnmiStruct->RxNoBufCts);
-				len += sprintf(buffer + len,
-					"Received multicast             %Ld\n",
+				len += sk_proc_print(buffer,
+					"Received multicast             %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxMulticastOkCts);
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
 					"Receive error types\n");
-				len += sprintf(buffer + len,
-					"   length                      %Ld\n",
+				len += sk_proc_print(buffer,
+					"   length                      %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxRuntCts);
-				len += sprintf(buffer + len,
-					"   buffer overflow             %Ld\n",
+				len += sk_proc_print(buffer,
+					"   buffer overflow             %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
-				len += sprintf(buffer + len,
-					"   bad crc                     %Ld\n",
+				len += sk_proc_print(buffer,
+					"   bad crc                     %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxFcsCts);
-				len += sprintf(buffer + len,
-					"   framing                     %Ld\n",
+				len += sk_proc_print(buffer,
+					"   framing                     %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxFramingCts);
-				len += sprintf(buffer + len,
-					"   missed frames               %Ld\n",
+				len += sk_proc_print(buffer,
+					"   missed frames               %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxMissedCts);
 
 				if (pNet->Mtu > 1500)
 					pPnmiStat->StatRxTooLongCts = 0;
 
-				len += sprintf(buffer + len,
-					"   too long                    %Ld\n",
+				len += sk_proc_print(buffer,
+					"   too long                    %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxTooLongCts);					
-				len += sprintf(buffer + len,
-					"   carrier extension           %Ld\n",
+				len += sk_proc_print(buffer,
+					"   carrier extension           %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxCextCts);				
-				len += sprintf(buffer + len,
-					"   too short                   %Ld\n",
+				len += sk_proc_print(buffer,
+					"   too short                   %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxShortsCts);				
-				len += sprintf(buffer + len,
-					"   symbol                      %Ld\n",
+				len += sk_proc_print(buffer,
+					"   symbol                      %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxSymbolCts);				
-				len += sprintf(buffer + len,
-					"   LLC MAC size                %Ld\n",
+				len += sk_proc_print(buffer,
+					"   LLC MAC size                %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxIRLengthCts);				
-				len += sprintf(buffer + len,
-					"   carrier event               %Ld\n",
+				len += sk_proc_print(buffer,
+					"   carrier event               %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxCarrierCts);				
-				len += sprintf(buffer + len,
-					"   jabber                      %Ld\n",
+				len += sk_proc_print(buffer,
+					"   jabber                      %Lu\n",
 					(unsigned long long) pPnmiStat->StatRxJabberCts);				
 
 
 				/*Transmit statistics */
-				len += sprintf(buffer + len, 
+				len += sk_proc_print(buffer, 
 				"\nTransmit statistics\n\n");
 				
-				len += sprintf(buffer + len,
-					"Transmited bytes               %Ld\n",
+				len += sk_proc_print(buffer,
+					"Transmited bytes               %Lu\n",
 					(unsigned long long) pPnmiStat->StatTxOctetsOkCts);
-				len += sprintf(buffer + len,
-					"Transmited packets             %Ld\n",
+				len += sk_proc_print(buffer,
+					"Transmited packets             %Lu\n",
 					(unsigned long long) pPnmiStat->StatTxOkCts);
-				len += sprintf(buffer + len,
-					"Transmit errors                %Ld\n",
+				len += sk_proc_print(buffer,
+					"Transmit errors                %Lu\n",
 					(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-				len += sprintf(buffer + len,
-					"Transmit dropped               %Ld\n",
+				len += sk_proc_print(buffer,
+					"Transmit dropped               %Lu\n",
 					(unsigned long long) pPnmiStruct->TxNoBufCts);
-				len += sprintf(buffer + len,
-					"Transmit collisions            %Ld\n",
+				len += sk_proc_print(buffer,
+					"Transmit collisions            %Lu\n",
 					(unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
 					"Transmit error types\n");
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
 					"   excessive collision         %ld\n",
 					pAC->stats.tx_aborted_errors);
-				len += sprintf(buffer + len,
-					"   carrier                     %Ld\n",
+				len += sk_proc_print(buffer,
+					"   carrier                     %Lu\n",
 					(unsigned long long) pPnmiStat->StatTxCarrierCts);
-				len += sprintf(buffer + len,
-					"   fifo underrun               %Ld\n",
+				len += sk_proc_print(buffer,
+					"   fifo underrun               %Lu\n",
 					(unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
-				len += sprintf(buffer + len,
-					"   heartbeat                   %Ld\n",
+				len += sk_proc_print(buffer,
+					"   heartbeat                   %Lu\n",
 					(unsigned long long) pPnmiStat->StatTxCarrierCts);
-				len += sprintf(buffer + len,
+				len += sk_proc_print(buffer,
 					"   window                      %ld\n",
 					pAC->stats.tx_window_errors);
 				
-			}
+			} /* if (strcmp(pACname, currDeviceName) == 0) */
 		}
 		SkgeProcDev = next;
 	}
-	if (offset >= len) {
-		*eof = 1;
-		return 0;
-	}
+}
 
-	*buffer_location = buffer + offset;
-	if (buffer_length >= len - offset) {
-		*eof = 1;
-	}
-	return (min_t(int, buffer_length, len - offset));
+/*****************************************************************************
+ *
+ *      sk_proc_print -generic line print  
+ *
+ * Description:
+ *  This function fills the proc entry with statistic data about 
+ *  the ethernet device.
+ *  
+ * Returns: number of bytes written
+ *      
+ */ 
+static int sk_proc_print(void *writePtr, char *format, ...)
+{   
+#define MAX_LEN_SINGLE_LINE 256
+	char     str[MAX_LEN_SINGLE_LINE];
+	va_list  a_start;
+	int      lenght = 0;
+
+	char    *buffer = (char *) writePtr;
+	buffer = buffer + len; /* plus global variable len for current location */
+
+	SK_MEMSET(str, 0, MAX_LEN_SINGLE_LINE);
+
+	va_start(a_start, format);
+	vsprintf(str, format, a_start);
+	va_end(a_start);
+
+	lenght = strlen(str);
+
+	sprintf(buffer, str);
+	return lenght;
 }
 
 
+/*******************************************************************************
+ *
+ * End of file
+ *
+ ******************************************************************************/
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skqueue.c linux-2.4.24-pre2/drivers/net/sk98lin/skqueue.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skqueue.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skqueue.c	2003-12-22 11:34:35.000000000 -0800
@@ -1,9 +1,9 @@
 /******************************************************************************
  *
  * Name:	skqueue.c
- * Project:	Gigabit Ethernet Adapters, Schedule-Modul
- * Version:	$Revision: 1.19 $
- * Date:	$Date: 2003/05/13 18:00:07 $
+ * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 1.20 $
+ * Date:	$Date: 2003/09/16 13:44:00 $
  * Purpose:	Management of an event queue.
  *
  ******************************************************************************/
@@ -27,6 +27,10 @@
  * History:
  *
  *	$Log: skqueue.c,v $
+ *	Revision 1.20  2003/09/16 13:44:00  rschmidt
+ *	Added (C) Marvell to SysKonnectFileId
+ *	Editorial changes
+ *	
  *	Revision 1.19  2003/05/13 18:00:07  mkarl
  *	Removed calls to RLMT, TWSI, and PNMI for SLIM driver (SK_SLIM).
  *	Editorial changes.
@@ -85,18 +89,16 @@
  *	
  *	Revision 1.1  1998/07/30 15:14:01  gklug
  *	Initial version. Adapted from SMT
- *	
- *	
  *
  ******************************************************************************/
 
 
 /*
-	Event queue and dispatcher
-*/
+ *	Event queue and dispatcher
+ */
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.19 2003/05/13 18:00:07 mkarl Exp $" ;
+	"@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell.";
 #endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
@@ -124,11 +126,11 @@
 void	SkEventInit(
 SK_AC	*pAC,	/* Adapter context */
 SK_IOC	Ioc,	/* IO context */
-int	Level)	/* Init level */
+int		Level)	/* Init level */
 {
 	switch (Level) {
 	case SK_INIT_DATA:
-		pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue ;
+		pAC->Event.EvPut = pAC->Event.EvGet = pAC->Event.EvQueue;
 		break;
 	default:
 		break;
@@ -144,14 +146,15 @@
 SK_U32		Event,	/* Event to be queued */
 SK_EVPARA	Para)	/* Event parameter */
 {
-	pAC->Event.EvPut->Class = Class ;
-	pAC->Event.EvPut->Event = Event ;
-	pAC->Event.EvPut->Para = Para ;
+	pAC->Event.EvPut->Class = Class;
+	pAC->Event.EvPut->Event = Event;
+	pAC->Event.EvPut->Para = Para;
+	
 	if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT])
-		pAC->Event.EvPut = pAC->Event.EvQueue ;
+		pAC->Event.EvPut = pAC->Event.EvQueue;
 
 	if (pAC->Event.EvPut == pAC->Event.EvGet) {
-		SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG) ;
+		SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG);
 	}
 }
 
@@ -168,77 +171,79 @@
 SK_AC	*pAC,	/* Adapters Context */
 SK_IOC	Ioc)	/* Io context */
 {
-	SK_EVENTELEM	*pEv ;	/* pointer into queue */
-	SK_U32			Class ;
-	int			Rtv ;
-
-	pEv = pAC->Event.EvGet ;
-	PRINTF("dispatch get %x put %x\n",pEv,pAC->Event.ev_put) ;
+	SK_EVENTELEM	*pEv;	/* pointer into queue */
+	SK_U32			Class;
+	int			Rtv;
+
+	pEv = pAC->Event.EvGet;
+	
+	PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put);
+	
 	while (pEv != pAC->Event.EvPut) {
-		PRINTF("dispatch Class %d Event %d\n",pEv->Class,pEv->Event) ;
-		switch(Class = pEv->Class) {
+		PRINTF("dispatch Class %d Event %d\n", pEv->Class, pEv->Event);
+
+		switch (Class = pEv->Class) {
 #ifndef SK_USE_LAC_EV
 #ifndef SK_SLIM
-		case SKGE_RLMT :	/* RLMT Event */
-			Rtv = SkRlmtEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
-		case SKGE_I2C :		/* I2C Event */
-			Rtv = SkI2cEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
-		case SKGE_PNMI :
-			Rtv = SkPnmiEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
+		case SKGE_RLMT:		/* RLMT Event */
+			Rtv = SkRlmtEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
+		case SKGE_I2C:		/* I2C Event */
+			Rtv = SkI2cEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
+		case SKGE_PNMI:		/* PNMI Event */
+			Rtv = SkPnmiEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
 #endif	/* not SK_SLIM */
 #endif	/* not SK_USE_LAC_EV */
-		case SKGE_DRV :		/* Driver Event */
-			Rtv = SkDrvEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
-#ifndef SK_USE_SW_TIMER        
-		case SKGE_HWAC :
-			Rtv = SkGeSirqEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
+		case SKGE_DRV:		/* Driver Event */
+			Rtv = SkDrvEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
+#ifndef SK_USE_SW_TIMER
+		case SKGE_HWAC:
+			Rtv = SkGeSirqEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
 #else /* !SK_USE_SW_TIMER */
-        case SKGE_SWT : 
-			Rtv = SkSwtEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
+        case SKGE_SWT :
+			Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
 #endif /* !SK_USE_SW_TIMER */
-#ifdef SK_USE_LAC_EV        
+#ifdef SK_USE_LAC_EV
 		case SKGE_LACP :
-			Rtv = SkLacpEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
+			Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
 		case SKGE_RSF :
-			Rtv = SkRsfEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
+			Rtv = SkRsfEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
 		case SKGE_MARKER :
-			Rtv = SkMarkerEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
+			Rtv = SkMarkerEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
 		case SKGE_FD :
-			Rtv = SkFdEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
+			Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
 #endif /* SK_USE_LAC_EV */
 #ifdef	SK_USE_CSUM
 		case SKGE_CSUM :
-			Rtv = SkCsEvent(pAC,Ioc,pEv->Event,pEv->Para);
-			break ;
+			Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para);
+			break;
 #endif	/* SK_USE_CSUM */
 		default :
-			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002,
-				SKERR_Q_E002MSG) ;
+			SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E002, SKERR_Q_E002MSG);
 			Rtv = 0;
 		}
 
 		if (Rtv != 0) {
-			return(Rtv) ;
+			return(Rtv);
 		}
 
 		if (++pEv == &pAC->Event.EvQueue[SK_MAX_EVENT])
-			pEv = pAC->Event.EvQueue ;
+			pEv = pAC->Event.EvQueue;
 
 		/* Renew get: it is used in queue_events to detect overruns */
 		pAC->Event.EvGet = pEv;
 	}
 
-	return(0) ;
+	return(0);
 }
 
 /* End of file */
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/sktimer.c linux-2.4.24-pre2/drivers/net/sk98lin/sktimer.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/sktimer.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/sktimer.c	2003-12-22 11:34:35.000000000 -0800
@@ -1,9 +1,9 @@
 /******************************************************************************
  *
  * Name:	sktimer.c
- * Project:	Gigabit Ethernet Adapters, Schedule-Modul
- * Version:	$Revision: 1.13 $
- * Date:	$Date: 2003/05/13 18:01:01 $
+ * Project:	Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version:	$Revision: 1.14 $
+ * Date:	$Date: 2003/09/16 13:46:51 $
  * Purpose:	High level timer functions.
  *
  ******************************************************************************/
@@ -27,6 +27,10 @@
  * History:
  *
  *	$Log: sktimer.c,v $
+ *	Revision 1.14  2003/09/16 13:46:51  rschmidt
+ *	Added (C) Marvell to SysKonnectFileId
+ *	Editorial changes
+ *	
  *	Revision 1.13  2003/05/13 18:01:01  mkarl
  *	Editorial changes.
  *	
@@ -68,19 +72,16 @@
  *	
  *	Revision 1.1  1998/08/05 11:27:55  gklug
  *	first version: adapted from SMT
- *	
- *	
- *	
  *
  ******************************************************************************/
 
 
 /*
-	Event queue and dispatcher
-*/
+ *	Event queue and dispatcher
+ */
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.13 2003/05/13 18:01:01 mkarl Exp $" ;
+	"@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell.";
 #endif
 
 #include "h/skdrv1st.h"		/* Driver Specific Definitions */
@@ -110,14 +111,14 @@
 void	SkTimerInit(
 SK_AC	*pAC,		/* Adapters context */
 SK_IOC	Ioc,		/* IoContext */
-int	Level)		/* Init Level */
+int		Level)		/* Init Level */
 {
 	switch (Level) {
 	case SK_INIT_DATA:
-		pAC->Tim.StQueue = 0 ;
+		pAC->Tim.StQueue = 0;
 		break;
 	case SK_INIT_IO:
-		SkHwtInit(pAC,Ioc) ;
+		SkHwtInit(pAC, Ioc);
 		SkTimerDone(pAC, Ioc);
 		break;
 	default:
@@ -134,31 +135,34 @@
 SK_IOC		Ioc,		/* IoContext */
 SK_TIMER	*pTimer)	/* Timer Pointer to be started */
 {
-	SK_TIMER	**ppTimPrev ;
-	SK_TIMER	*pTm ;
+	SK_TIMER	**ppTimPrev;
+	SK_TIMER	*pTm;
 
 	/*
 	 * remove timer from queue
 	 */
-	pTimer->TmActive = SK_FALSE ;
+	pTimer->TmActive = SK_FALSE;
+	
 	if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
-		SkHwtStop(pAC,Ioc) ;
+		SkHwtStop(pAC, Ioc);
 	}
-	for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
+	
+	for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
 		ppTimPrev = &pTm->TmNext ) {
+		
 		if (pTm == pTimer) {
 			/*
 			 * Timer found in queue
 			 * - dequeue it and
 			 * - correct delta of the next timer
 			 */
-			*ppTimPrev = pTm->TmNext ;
+			*ppTimPrev = pTm->TmNext;
 
 			if (pTm->TmNext) {
 				/* correct delta of next timer in queue */
-				pTm->TmNext->TmDelta += pTm->TmDelta ;
+				pTm->TmNext->TmDelta += pTm->TmDelta;
 			}
-			return ;
+			return;
 		}
 	}
 }
@@ -175,65 +179,67 @@
 SK_U32		Event,		/* Event Value for this timer */
 SK_EVPARA	Para)		/* Event Parameter for this timer */
 {
-	SK_TIMER	**ppTimPrev ;
-	SK_TIMER	*pTm ;
-	SK_U32		Delta ;
+	SK_TIMER	**ppTimPrev;
+	SK_TIMER	*pTm;
+	SK_U32		Delta;
 
-	Time /= 16 ;		/* input is uS, clock ticks are 16uS */
+	Time /= 16;		/* input is uS, clock ticks are 16uS */
+	
 	if (!Time)
-		Time = 1 ;
+		Time = 1;
 
-	SkTimerStop(pAC,Ioc,pTimer) ;
+	SkTimerStop(pAC, Ioc, pTimer);
 
-	pTimer->TmClass = Class ;
-	pTimer->TmEvent = Event ;
-	pTimer->TmPara = Para ;
-	pTimer->TmActive = SK_TRUE ;
+	pTimer->TmClass = Class;
+	pTimer->TmEvent = Event;
+	pTimer->TmPara = Para;
+	pTimer->TmActive = SK_TRUE;
 
 	if (!pAC->Tim.StQueue) {
 		/* First Timer to be started */
-		pAC->Tim.StQueue = pTimer ;
-		pTimer->TmNext = 0 ;
-		pTimer->TmDelta = Time ;
-		SkHwtStart(pAC,Ioc,Time) ;
-		return ;
+		pAC->Tim.StQueue = pTimer;
+		pTimer->TmNext = 0;
+		pTimer->TmDelta = Time;
+		
+		SkHwtStart(pAC, Ioc, Time);
+		
+		return;
 	}
 
 	/*
 	 * timer correction
 	 */
-	timer_done(pAC,Ioc,0) ;
+	timer_done(pAC, Ioc, 0);
 
 	/*
 	 * find position in queue
 	 */
-	Delta = 0 ;
-	for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
+	Delta = 0;
+	for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev);
 		ppTimPrev = &pTm->TmNext ) {
+		
 		if (Delta + pTm->TmDelta > Time) {
 			/* Position found */
 			/* Here the timer needs to be inserted. */
-			break ;
+			break;
 		}
-		Delta += pTm->TmDelta ;
+		Delta += pTm->TmDelta;
 	}
 
 	/* insert in queue */
-	*ppTimPrev = pTimer ;
-	pTimer->TmNext = pTm ;
-	pTimer->TmDelta = Time - Delta ;
+	*ppTimPrev = pTimer;
+	pTimer->TmNext = pTm;
+	pTimer->TmDelta = Time - Delta;
 
 	if (pTm) {
 		/* There is a next timer
 		 * -> correct its Delta value.
 		 */
-		pTm->TmDelta -= pTimer->TmDelta ;
+		pTm->TmDelta -= pTimer->TmDelta;
 	}
 
-	/*
-	 * start new with first
-	 */
-	SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
+	/* restart with first */
+	SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
 }
 
 
@@ -241,55 +247,56 @@
 SK_AC	*pAC,		/* Adapters context */
 SK_IOC	Ioc)		/* IoContext */
 {
-	timer_done(pAC,Ioc,1) ;
+	timer_done(pAC, Ioc, 1);
 }
 
 
 static void	timer_done(
 SK_AC	*pAC,		/* Adapters context */
 SK_IOC	Ioc,		/* IoContext */
-int	Restart)	/* Do we need to restart the Hardware timer ? */
+int		Restart)	/* Do we need to restart the Hardware timer ? */
 {
-	SK_U32		Delta ;
-	SK_TIMER	*pTm ;
-	SK_TIMER	*pTComp ;	/* Timer completed now now */
-	SK_TIMER	**ppLast ;	/* Next field of Last timer to be deq */
-	int		Done = 0 ;
-
-	Delta = SkHwtRead(pAC,Ioc) ;
-	ppLast = &pAC->Tim.StQueue ;
-	pTm = pAC->Tim.StQueue ;
+	SK_U32		Delta;
+	SK_TIMER	*pTm;
+	SK_TIMER	*pTComp;	/* Timer completed now now */
+	SK_TIMER	**ppLast;	/* Next field of Last timer to be deq */
+	int		Done = 0;
+
+	Delta = SkHwtRead(pAC, Ioc);
+	
+	ppLast = &pAC->Tim.StQueue;
+	pTm = pAC->Tim.StQueue;
 	while (pTm && !Done) {
 		if (Delta >= pTm->TmDelta) {
 			/* Timer ran out */
-			pTm->TmActive = SK_FALSE ;
-			Delta -= pTm->TmDelta ;
-			ppLast = &pTm->TmNext ;
-			pTm = pTm->TmNext ;
-		} else {
+			pTm->TmActive = SK_FALSE;
+			Delta -= pTm->TmDelta;
+			ppLast = &pTm->TmNext;
+			pTm = pTm->TmNext;
+		}
+		else {
 			/* We found the first timer that did not run out */
-			pTm->TmDelta -= Delta ;
-			Delta = 0 ;
-			Done = 1 ;
+			pTm->TmDelta -= Delta;
+			Delta = 0;
+			Done = 1;
 		}
 	}
-	*ppLast = 0 ;
+	*ppLast = 0;
 	/*
 	 * pTm points to the first Timer that did not run out.
 	 * StQueue points to the first Timer that run out.
 	 */
 
-	for ( pTComp = pAC->Tim.StQueue ; pTComp ; pTComp = pTComp->TmNext) {
-		SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent,
-			pTComp->TmPara) ;
+	for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) {
+		SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara);
 	}
 
 	/* Set head of timer queue to the first timer that did not run out */
-	pAC->Tim.StQueue = pTm ;
+	pAC->Tim.StQueue = pTm;
 
 	if (Restart && pAC->Tim.StQueue) {
 		/* Restart HW timer */
-		SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
+		SkHwtStart(pAC, Ioc, pAC->Tim.StQueue->TmDelta);
 	}
 }
 
diff -urN linux-2.4.24-pre1/drivers/net/sk98lin/skxmac2.c linux-2.4.24-pre2/drivers/net/sk98lin/skxmac2.c
--- linux-2.4.24-pre1/drivers/net/sk98lin/skxmac2.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/sk98lin/skxmac2.c	2003-12-22 11:34:35.000000000 -0800
@@ -2,8 +2,8 @@
  *
  * Name:	skxmac2.c
  * Project:	Gigabit Ethernet Adapters, Common Modules
- * Version:	$Revision: 1.99 $
- * Date:	$Date: 2003/07/11 12:19:33 $
+ * Version:	$Revision: 1.102 $
+ * Date:	$Date: 2003/10/02 16:53:58 $
  * Purpose:	Contains functions to initialize the MACs and PHYs
  *
  ******************************************************************************/
@@ -27,6 +27,23 @@
  * History:
  *
  *	$Log: skxmac2.c,v $
+ *	Revision 1.102  2003/10/02 16:53:58  rschmidt
+ *	Changed setting of GMAC parameters with new macros.
+ *	Added define SLIM around SkGm...LowPowerMode().
+ *	Editorial changes.
+ *	
+ *	Revision 1.101  2003/09/16 14:49:07  rschmidt
+ *	Added routines SkGmClearRst(), SkXmClearRst, SkMacClearRst().
+ *	Added WA code for Yukon-Lite's COMA mode in SkGmHardRst().
+ *	Replaced PCI-Config R/W through internal access.
+ *	Fixed return from coma mode in SkGmLeaveLowPowerMode().
+ *	Fixed compiler warnings for different types.
+ *	Editorial changes.
+ *	
+ *	Revision 1.100  2003/09/16 07:09:11  mschmid
+ *	Added functions SkGmEnterLowPowerMode() and
+ *	SkGmLeaveLowPowerMode()
+ *	
  *	Revision 1.99  2003/07/11 12:19:33  rschmidt
  *	Reduced init values for Master & Slave downshift counters to
  *	minimum values.
@@ -164,7 +181,7 @@
  *	Revision 1.74  2002/08/12 14:00:17  rschmidt
  *	Replaced usage of Broadcom PHY Ids with defines.
  *	Corrected error messages in SkGmMacStatistic().
- *	Made SkMacPromiscMode() public for ADDR-Modul.
+ *	Made SkMacPromiscMode() public for ADDR-Module.
  *	Editorial changes.
  *	
  *	Revision 1.73  2002/08/08 16:26:24  rschmidt
@@ -475,7 +492,7 @@
 
 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
 static const char SysKonnectFileId[] =
-	"@(#) $Id: skxmac2.c,v 1.99 2003/07/11 12:19:33 rschmidt Exp $ (C) Marvell.";
+	"@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell.";
 #endif
 
 #ifdef GENESIS
@@ -1343,7 +1360,7 @@
  * Description:
  *	The XMAC of the specified 'Port' and all connected devices
  *	(PHY and SERDES) will receive a reset signal on its *Reset pins.
- *	External PHYs must be reset be clearing a bit in the GPIO register
+ *	External PHYs must be reset by clearing a bit in the GPIO register
  *  (Timing requirements: Broadcom: 400ns, Level One: none, National: 80ns).
  *
  * ATTENTION:
@@ -1386,23 +1403,62 @@
 
 	/* For external PHYs there must be special handling */
 	if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
-		/* reset external PHY */
+		
 		SK_IN32(IoC, B2_GP_IO, &Reg);
+		
 		if (Port == 0) {
-			Reg |= GP_DIR_0; /* set to output */
-			Reg &= ~GP_IO_0;
+			Reg |= GP_DIR_0; 	/* set to output */
+			Reg &= ~GP_IO_0;	/* set PHY reset (active low) */
 		}
 		else {
-			Reg |= GP_DIR_2; /* set to output */
-			Reg &= ~GP_IO_2;
+			Reg |= GP_DIR_2;	/* set to output */
+			Reg &= ~GP_IO_2;	/* set PHY reset (active low) */
 		}
+		/* reset external PHY */
 		SK_OUT32(IoC, B2_GP_IO, Reg);
 
 		/* short delay */
 		SK_IN32(IoC, B2_GP_IO, &Reg);
 	}
-
 }	/* SkXmHardRst */
+
+
+/******************************************************************************
+ *
+ *	SkXmClearRst() - Release the PHY & XMAC reset
+ *
+ * Description:
+ *
+ * Returns:
+ *	nothing
+ */
+static void SkXmClearRst(
+SK_AC	*pAC,	/* adapter context */
+SK_IOC	IoC,	/* IO context */
+int		Port)	/* Port Index (MAC_1 + n) */
+{
+	SK_U32	DWord;
+	
+	/* clear HW reset */
+	SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+
+	if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
+
+		SK_IN32(IoC, B2_GP_IO, &DWord);
+
+		if (Port == 0) {
+			DWord |= (GP_DIR_0 | GP_IO_0); /* set to output */
+		}
+		else {
+			DWord |= (GP_DIR_2 | GP_IO_2); /* set to output */
+		}
+		/* Clear PHY reset */
+		SK_OUT32(IoC, B2_GP_IO, DWord);
+
+		/* Enable GMII interface */
+		XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
+	}
+}	/* SkXmClearRst */
 #endif /* GENESIS */
 
 
@@ -1452,10 +1508,6 @@
  *
  * Description:
  *
- * ATTENTION:
- * 	It is absolutely necessary to reset the SW_RST Bit first
- *	before calling this function.
- *
  * Returns:
  *	nothing
  */
@@ -1464,6 +1516,20 @@
 SK_IOC	IoC,	/* IO context */
 int		Port)	/* Port Index (MAC_1 + n) */
 {
+	SK_U32	DWord;
+	
+	/* WA code for COMA mode */
+	if (pAC->GIni.GIYukonLite &&
+		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+		
+		SK_IN32(IoC, B2_GP_IO, &DWord);
+
+		DWord |= (GP_DIR_9 | GP_IO_9);
+
+		/* set PHY reset */
+		SK_OUT32(IoC, B2_GP_IO, DWord);
+	}
+
 	/* set GPHY Control reset */
 	SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
 
@@ -1471,6 +1537,73 @@
 	SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
 
 }	/* SkGmHardRst */
+
+
+/******************************************************************************
+ *
+ *	SkGmClearRst() - Release the GPHY & GMAC reset
+ *
+ * Description:
+ *
+ * Returns:
+ *	nothing
+ */
+static void SkGmClearRst(
+SK_AC	*pAC,	/* adapter context */
+SK_IOC	IoC,	/* IO context */
+int		Port)	/* Port Index (MAC_1 + n) */
+{
+	SK_U32	DWord;
+	
+#ifdef XXX
+		/* clear GMAC Control reset */
+		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
+
+		/* set GMAC Control reset */
+		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
+#endif /* XXX */
+
+	/* WA code for COMA mode */
+	if (pAC->GIni.GIYukonLite &&
+		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+		
+		SK_IN32(IoC, B2_GP_IO, &DWord);
+
+		DWord |= GP_DIR_9;		/* set to output */
+		DWord &= ~GP_IO_9;		/* clear PHY reset (active high) */
+
+		/* clear PHY reset */
+		SK_OUT32(IoC, B2_GP_IO, DWord);
+	}
+
+	/* set HWCFG_MODE */
+	DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
+		GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
+		(pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
+		GPC_HWCFG_GMII_FIB);
+
+	/* set GPHY Control reset */
+	SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
+
+	/* release GPHY Control reset */
+	SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
+
+#ifdef VCPU
+	VCpuWait(9000);
+#endif /* VCPU */
+
+	/* clear GMAC Control reset */
+	SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
+
+#ifdef VCPU
+	VCpuWait(2000);
+	
+	SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord);
+			
+	SK_IN32(IoC, B0_ISRC, &DWord);
+#endif /* VCPU */
+
+}	/* SkGmClearRst */
 #endif /* YUKON */
 
 
@@ -1553,6 +1686,38 @@
 }	/* SkMacHardRst */
 
 
+/******************************************************************************
+ *
+ *	SkMacClearRst() - Clear the MAC reset
+ *
+ * Description:	calls a clear MAC reset routine dep. on board type
+ *
+ * Returns:
+ *	nothing
+ */
+void SkMacClearRst(
+SK_AC	*pAC,	/* adapter context */
+SK_IOC	IoC,	/* IO context */
+int		Port)	/* Port Index (MAC_1 + n) */
+{
+	
+#ifdef GENESIS
+	if (pAC->GIni.GIGenesis) {
+		
+		SkXmClearRst(pAC, IoC, Port);
+	}
+#endif /* GENESIS */
+	
+#ifdef YUKON
+	if (pAC->GIni.GIYukon) {
+		
+		SkGmClearRst(pAC, IoC, Port);
+	}
+#endif /* YUKON */
+
+}	/* SkMacClearRst */
+
+
 #ifdef GENESIS
 /******************************************************************************
  *
@@ -1574,7 +1739,6 @@
 int		Port)		/* Port Index (MAC_1 + n) */
 {
 	SK_GEPORT	*pPrt;
-	SK_U32		Reg;
 	int			i;
 	SK_U16		SWord;
 
@@ -1594,32 +1758,10 @@
 	}
 
 	if (pPrt->PState == SK_PRT_RESET) {
-		/*
-		 * clear HW reset
-		 * Note: The SW reset is self clearing, therefore there is
-		 *	 nothing to do here.
-		 */
-		SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
 
-		/* Ensure that XMAC reset release is done (errata from LReinbold?) */
-		SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord);
+		SkXmClearRst(pAC, IoC, Port);
 
-		/* Clear PHY reset */
 		if (pPrt->PhyType != SK_PHY_XMAC) {
-
-			SK_IN32(IoC, B2_GP_IO, &Reg);
-			
-			if (Port == 0) {
-				Reg |= (GP_DIR_0 | GP_IO_0); /* set to output */
-			}
-			else {
-				Reg |= (GP_DIR_2 | GP_IO_2); /* set to output */
-			}
-			SK_OUT32(IoC, B2_GP_IO, Reg);
-
-			/* Enable GMII interface */
-			XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD);
-
 			/* read Id from external PHY (all have the same address) */
 			SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_ID1, &pPrt->PhyId1);
 
@@ -1831,43 +1973,11 @@
 	}
 
 	if (pPrt->PState == SK_PRT_RESET) {
-		/* set GPHY Control reset */
-		SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET);
-
-		/* set GMAC Control reset */
-		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-
-#ifdef XXX
-		/* clear GMAC Control reset */
-		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR);
-
-		/* set GMAC Control reset */
-		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET);
-#endif /* XXX */
-
-		/* set HWCFG_MODE */
-		DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
-			GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE |
-			(pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP :
-			GPC_HWCFG_GMII_FIB);
-
-		/* set GPHY Control reset */
-		SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET);
-
-		/* release GPHY Control reset */
-		SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR);
-
-#ifdef VCPU
-		VCpuWait(9000);
-#endif /* VCPU */
-
-		/* clear GMAC Control reset */
-		SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
-
-#ifdef VCPU
-		VCpuWait(2000);
-#endif /* VCPU */
+		
+		SkGmHardRst(pAC, IoC, Port);
 
+		SkGmClearRst(pAC, IoC, Port);
+		
 		/* Auto-negotiation ? */
 		if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
 			/* Auto-negotiation disabled */
@@ -1906,6 +2016,7 @@
 			SWord |= GM_GPCR_DUP_FULL;
 		}
 
+		/* flow-control settings */
 		switch (pPrt->PFlowCtrlMode) {
 		case SK_FLOW_MODE_NONE:
 			/* set Pause Off */
@@ -1940,7 +2051,7 @@
 	(void)SkGmResetCounter(pAC, IoC, Port);
 
 	/* setup Transmit Control Register */
-	GM_OUT16(IoC, Port, GM_TX_CTRL, GM_TXCR_COL_THR);
+	GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres));
 
 	/* setup Receive Control Register */
 	GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA |
@@ -1954,7 +2065,9 @@
 	GM_IN16(IoC, Port, GM_TX_PARAM, &SWord);
 #endif /* VCPU */
 
-    SWord = (SK_U16)(JAM_LEN_VAL(3) | JAM_IPG_VAL(11) | IPG_JAM_DATA(26));
+    SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) |
+			TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) |
+			TX_IPG_JAM_DATA(pPrt->PMacJamIpgData);
 	
 	GM_OUT16(IoC, Port, GM_TX_PARAM, SWord);
 
@@ -1963,7 +2076,12 @@
 	GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord);
 #endif /* VCPU */
 	
-	SWord = GM_SMOD_VLAN_ENA | IPG_VAL_FAST_ETH;
+	SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData);
+
+	if (pPrt->PMacLimit4) {
+		/* reset of collision counter after 4 consecutive collisions */
+		SWord |= GM_SMOD_LIMIT_4;
+	}
 
 	if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
 		/* enable jumbo mode (Max. Frame Length = 9018) */
@@ -2021,11 +2139,13 @@
 	GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0);
 	GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0);
 
+#if defined(SK_DIAG) || defined(DEBUG)
 	/* read General Purpose Status */
 	GM_IN16(IoC, Port, GM_GP_STAT, &SWord);
 	
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("MAC Stat Reg=0x%04X\n", SWord));
+		("MAC Stat Reg.=0x%04X\n", SWord));
+#endif /* SK_DIAG || DEBUG */
 
 #ifdef SK_DIAG
 	c_print("MAC Stat Reg=0x%04X\n", SWord);
@@ -2226,6 +2346,7 @@
 				SKERR_HWI_E015MSG);
 		}
 
+		/* Set Flow-control capabilities */
 		switch (pPrt->PFlowCtrlMode) {
 		case SK_FLOW_MODE_NONE:
 			Ctrl |= PHY_X_P_NO_PAUSE;
@@ -2306,7 +2427,9 @@
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 			("InitPhyBcom: no auto-negotiation Port %d\n", Port));
 		/* Set DuplexMode in Config register */
-		Ctrl1 |= (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
+		if (pPrt->PLinkMode == SK_LMODE_FULL) {
+			Ctrl1 |= PHY_CT_DUP_MD;
+		}
 
 		/* Determine Master/Slave manually if not already done */
 		if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
@@ -2346,6 +2469,7 @@
 				SKERR_HWI_E015MSG);
 		}
 
+		/* Set Flow-control capabilities */
 		switch (pPrt->PFlowCtrlMode) {
 		case SK_FLOW_MODE_NONE:
 			Ctrl3 |= PHY_B_P_NO_PAUSE;
@@ -2375,12 +2499,12 @@
 	/* Write 1000Base-T Control Register */
 	SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
+		("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2));
 	
 	/* Write AutoNeg Advertisement Register */
 	SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
+		("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3));
 	
 	if (DoLoop) {
 		/* Set the Phy Loopback bit, too */
@@ -2409,6 +2533,281 @@
 
 
 #ifdef YUKON
+#ifndef SK_SLIM
+/******************************************************************************
+ *
+ *	SkGmEnterLowPowerMode()
+ *
+ * Description:	
+ *	This function sets the Marvell Alaska PHY to the low power mode
+ *	given by parameter mode.
+ *	The following low power modes are available:
+ *		
+ *		- Coma Mode (Deep Sleep):
+ *			Power consumption: ~15 - 30 mW
+ *			The PHY cannot wake up on its own.
+ *
+ *		- IEEE 22.2.4.1.5 compatible power down mode
+ *			Power consumption: ~240 mW
+ *			The PHY cannot wake up on its own.
+ *
+ *		- energy detect mode
+ *			Power consumption: ~160 mW
+ *			The PHY can wake up on its own by detecting activity
+ *			on the CAT 5 cable.
+ *
+ *		- energy detect plus mode
+ *			Power consumption: ~150 mW
+ *			The PHY can wake up on its own by detecting activity
+ *			on the CAT 5 cable.
+ *			Connected devices can be woken up by sending normal link
+ *			pulses every one second.
+ *
+ * Note:
+ *
+ * Returns:
+ *		0: ok
+ *		1: error
+ */
+int SkGmEnterLowPowerMode(
+SK_AC	*pAC,		/* adapter context */
+SK_IOC	IoC,		/* IO context */
+int		Port,		/* Port Index (e.g. MAC_1) */
+SK_U8	Mode)		/* low power mode */
+{
+	SK_U16	Word;
+	SK_U32	DWord;
+	SK_U8	LastMode;
+	int		Ret = 0;
+
+	if (pAC->GIni.GIYukonLite &&
+	    pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+
+		/* save current power mode */
+		LastMode = pAC->GIni.GP[Port].PPhyPowerState;
+		pAC->GIni.GP[Port].PPhyPowerState = Mode;
+
+		switch (Mode) {
+			/* coma mode (deep sleep) */
+			case PHY_PM_DEEP_SLEEP:
+				/* setup General Purpose Control Register */
+				GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS |
+					GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
+
+				/* apply COMA mode workaround */
+				SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f);
+				SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3);
+
+				SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
+
+				SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+				
+				/* Set PHY to Coma Mode */
+				SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA);
+				
+				SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+			break;
+			
+			/* IEEE 22.2.4.1.5 compatible power down mode */
+			case PHY_PM_IEEE_POWER_DOWN:
+				/*
+				 * - disable MAC 125 MHz clock
+				 * - allow MAC power down
+				 */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+				Word |= PHY_M_PC_DIS_125CLK;
+				Word &=	~PHY_M_PC_MAC_POW_UP;
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+				/*
+				 * register changes must be followed by a software
+				 * reset to take effect
+				 */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+				Word |= PHY_CT_RESET;
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+
+				/* switch IEEE compatible power down mode on */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+				Word |= PHY_CT_PDOWN;
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+			break;
+
+			/* energy detect and energy detect plus mode */
+			case PHY_PM_ENERGY_DETECT:
+			case PHY_PM_ENERGY_DETECT_PLUS:
+				/*
+				 * - disable MAC 125 MHz clock
+				 */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+				Word |= PHY_M_PC_DIS_125CLK;
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+				
+				/* activate energy detect mode 1 */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+
+				/* energy detect mode */
+				if (Mode == PHY_PM_ENERGY_DETECT) {
+					Word |= PHY_M_PC_EN_DET;
+				}
+				/* energy detect plus mode */
+				else {
+					Word |= PHY_M_PC_EN_DET_PLUS;
+				}
+
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+				/*
+				 * reinitialize the PHY to force a software reset
+				 * which is necessary after the register settings
+				 * for the energy detect modes.
+				 * Furthermore reinitialisation prevents that the
+				 * PHY is running out of a stable state.
+				 */
+				SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+			break;
+
+			/* don't change current power mode */
+			default:
+				pAC->GIni.GP[Port].PPhyPowerState = LastMode;
+				Ret = 1;
+			break;
+		}
+	}
+	/* low power modes are not supported by this chip */
+	else {
+		Ret = 1;
+	}
+
+	return(Ret);
+
+}	/* SkGmEnterLowPowerMode */
+
+/******************************************************************************
+ *
+ *	SkGmLeaveLowPowerMode()
+ *
+ * Description:	
+ *	Leave the current low power mode and switch to normal mode
+ *
+ * Note:
+ *
+ * Returns:
+ *		0:	ok
+ *		1:	error
+ */
+int SkGmLeaveLowPowerMode(
+SK_AC	*pAC,		/* adapter context */
+SK_IOC	IoC,		/* IO context */
+int		Port)		/* Port Index (e.g. MAC_1) */
+{
+	SK_U32	DWord;
+	SK_U16	Word;
+	SK_U8	LastMode;
+	int		Ret = 0;
+
+	if (pAC->GIni.GIYukonLite &&
+		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+
+		/* save current power mode */
+		LastMode = pAC->GIni.GP[Port].PPhyPowerState;
+		pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE;
+
+		switch (LastMode) {
+			/* coma mode (deep sleep) */
+			case PHY_PM_DEEP_SLEEP:
+				SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord);
+
+				SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+				
+				/* Release PHY from Coma Mode */
+				SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA);
+				
+				SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+				
+				SK_IN32(IoC, B2_GP_IO, &DWord);
+
+				/* set to output */
+				DWord |= (GP_DIR_9 | GP_IO_9);
+
+				/* set PHY reset */
+				SK_OUT32(IoC, B2_GP_IO, DWord);
+
+				DWord &= ~GP_IO_9; /* clear PHY reset (active high) */
+
+				/* clear PHY reset */
+				SK_OUT32(IoC, B2_GP_IO, DWord);
+			break;
+			
+			/* IEEE 22.2.4.1.5 compatible power down mode */
+			case PHY_PM_IEEE_POWER_DOWN:
+				/*
+				 * - enable MAC 125 MHz clock
+				 * - set MAC power up
+				 */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+				Word &= ~PHY_M_PC_DIS_125CLK;
+				Word |=	PHY_M_PC_MAC_POW_UP;
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+				/*
+				 * register changes must be followed by a software
+				 * reset to take effect
+				 */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+				Word |= PHY_CT_RESET;
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+
+				/* switch IEEE compatible power down mode off */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word);
+				Word &= ~PHY_CT_PDOWN;
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word);
+			break;
+
+			/* energy detect and energy detect plus mode */
+			case PHY_PM_ENERGY_DETECT:
+			case PHY_PM_ENERGY_DETECT_PLUS:
+				/*
+				 * - enable MAC 125 MHz clock
+				 */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+				Word &= ~PHY_M_PC_DIS_125CLK;
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+				
+				/* disable energy detect mode */
+				SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word);
+				Word &= ~PHY_M_PC_EN_DET_MSK;
+				SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word);
+
+				/*
+				 * reinitialize the PHY to force a software reset
+				 * which is necessary after the register settings
+				 * for the energy detect modes.
+				 * Furthermore reinitialisation prevents that the
+				 * PHY is running out of a stable state.
+				 */
+				SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE);
+			break;
+
+			/* don't change current power mode */
+			default:
+				pAC->GIni.GP[Port].PPhyPowerState = LastMode;
+				Ret = 1;
+			break;
+		}
+	}
+	/* low power modes are not supported by this chip */
+	else {
+		Ret = 1;
+	}
+
+	return(Ret);
+
+}	/* SkGmLeaveLowPowerMode */
+#endif /* !SK_SLIM */
+
+
 /******************************************************************************
  *
  *	SkGmInitPhyMarv() - Initialize the Marvell Phy registers
@@ -2457,7 +2856,6 @@
 	VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n",
 		Port, DoLoop);
 #else /* VCPU */
-	
 	if (DoLoop) {
 		/* Set 'MAC Power up'-bit, set Manual MDI configuration */
 		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL,
@@ -2475,16 +2873,20 @@
 	
 		SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl);
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-			("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
+			("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl));
 	}
 
 	/* Read PHY Control */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl);
 
+	if (!AutoNeg) {
+		/* Disable Auto-negotiation */
+		PhyCtrl &= ~PHY_CT_ANE;
+	}
+
 	PhyCtrl |= PHY_CT_RESET;
 	/* Assert software reset */
 	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
-
 #endif /* VCPU */
 
 	PhyCtrl = 0 /* PHY_CT_COL_TST */;
@@ -2533,13 +2935,9 @@
 		if (!DoLoop) {
 			PhyCtrl |= PHY_CT_RESET;
 		}
-		/*
-		 * Do NOT enable Auto-negotiation here. This would hold
-		 * the link down because no IDLES are transmitted
-		 */
 	}
 	else {
-		PhyCtrl |= PHY_CT_ANE;
+		/* Set Auto-negotiation advertisement */
 		
 		if (pAC->GIni.GICopperType) {
 			/* Set Speed capabilities */
@@ -2554,6 +2952,7 @@
 				break;
 			case SK_LSPEED_100MBPS:
 				AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD |
+					/* advertise 10Base-T also */
 					PHY_M_AN_10_FD | PHY_M_AN_10_HD;
 				break;
 			case SK_LSPEED_10MBPS:
@@ -2581,7 +2980,7 @@
 					SKERR_HWI_E015MSG);
 			}
 			
-			/* Set Auto-negotiation advertisement */
+			/* Set Flow-control capabilities */
 			switch (pPrt->PFlowCtrlMode) {
 			case SK_FLOW_MODE_NONE:
 				AutoNegAdv |= PHY_B_P_NO_PAUSE;
@@ -2618,7 +3017,7 @@
 					SKERR_HWI_E015MSG);
 			}
 			
-			/* Set Auto-negotiation advertisement */
+			/* Set Flow-control capabilities */
 			switch (pPrt->PFlowCtrlMode) {
 			case SK_FLOW_MODE_NONE:
 				AutoNegAdv |= PHY_M_P_NO_PAUSE_X;
@@ -2640,7 +3039,7 @@
 
 		if (!DoLoop) {
 			/* Restart Auto-negotiation */
-			PhyCtrl |= PHY_CT_RE_CFG;
+			PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
 		}
 	}
 	
@@ -2659,12 +3058,12 @@
 	/* Write 1000Base-T Control Register */
 	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("1000B-T Ctrl=0x%04X\n", C1000BaseT));
+		("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT));
 	
 	/* Write AutoNeg Advertisement Register */
 	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("Auto-Neg.Ad.=0x%04X\n", AutoNegAdv));
+		("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
 #endif /* VCPU */
 	
 	if (DoLoop) {
@@ -2694,6 +3093,8 @@
 
 	/* Write to the PHY Control register */
 	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl);
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl));
 
 #ifdef VCPU
 	VCpuWait(2000);
@@ -2712,7 +3113,7 @@
 	SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl);
 
 	if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) {
-		/* only in forced 100Mbps mode */
+		/* only in forced 100 Mbps mode */
 		if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) {
 
 			SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER,
@@ -2741,7 +3142,7 @@
 	/* Read AutoNeg Advertisement Register */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv);
 	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
-		("Auto-Neg. Ad.=0x%04X\n", AutoNegAdv));
+		("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv));
 	
 	/* Read Ext. PHY Specific Control */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl);
@@ -2818,13 +3219,15 @@
 	/* Auto-negotiation ? */
 	if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) {
 		/*
-		 * level one spec say: "1000Mbps: manual mode not allowed"
+		 * level one spec say: "1000 Mbps: manual mode not allowed"
 		 * but lets see what happens...
 		 */
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 			("InitPhyLone: no auto-negotiation Port %d\n", Port));
 		/* Set DuplexMode in Config register */
-		Ctrl1 = (pPrt->PLinkMode == SK_LMODE_FULL ? PHY_CT_DUP_MD : 0);
+		if (pPrt->PLinkMode == SK_LMODE_FULL) {
+			Ctrl1 |= PHY_CT_DUP_MD;
+		}
 
 		/* Determine Master/Slave manually if not already done */
 		if (pPrt->PMSMode == SK_MS_MODE_AUTO) {
@@ -2857,6 +3260,7 @@
 				SKERR_HWI_E015MSG);
 		}
 
+		/* Set Flow-control capabilities */
 		switch (pPrt->PFlowCtrlMode) {
 		case SK_FLOW_MODE_NONE:
 			Ctrl3 |= PHY_L_P_NO_PAUSE;
@@ -2877,7 +3281,6 @@
 
 		/* Restart Auto-negotiation */
 		Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG;
-
 	}
 	
 	/* Write 1000Base-T Control Register */
@@ -3019,10 +3422,10 @@
 
 	/* Check Duplex mismatch */
 	if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_FD) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
 	}
 	else if ((ResAb & (PHY_X_RS_HD | PHY_X_RS_FD)) == PHY_X_RS_HD) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
 	}
 	else {
 		/* Error */
@@ -3055,7 +3458,7 @@
 		/* PAUSE mismatch -> no PAUSE */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
 	}
-	pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+	pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
 
 	return(SK_AND_OK);
 }	/* SkXmAutoNegDoneXmac */
@@ -3110,10 +3513,10 @@
 
 	/* Check Duplex mismatch */
 	if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000FD) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
 	}
 	else if ((AuxStat & PHY_B_AS_AN_RES_MSK) == PHY_B_RES_1000HD) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
 	}
 	else {
 		/* Error */
@@ -3156,7 +3559,7 @@
 		/* PAUSE mismatch -> no PAUSE */
 		pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
 	}
-	pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+	pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
 
 	return(SK_AND_OK);
 }	/* SkXmAutoNegDoneBcom */
@@ -3192,6 +3595,8 @@
 
 	/* Get PHY parameters */
 	SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb);
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		("Link P.Abil.=0x%04X\n", LPAb));
 	
 	if ((LPAb & PHY_M_AN_RF) != 0) {
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
@@ -3222,15 +3627,15 @@
 		SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
 			("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port));
 		pPrt->PAutoNegFail = SK_TRUE;
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_UNKNOWN;
+		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN;
 		return(SK_AND_DUP_CAP);
 	}
 	
 	if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
 	}
 	else {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
 	}
 	
 	/* Check PAUSE mismatch ??? */
@@ -3255,13 +3660,13 @@
 	/* set used link speed */
 	switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) {
 	case (unsigned)PHY_M_PS_SPEED_1000:
-		pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_1000MBPS;
+		pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS;
 		break;
 	case PHY_M_PS_SPEED_100:
-		pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_100MBPS;
+		pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS;
 		break;
 	default:
-		pPrt->PLinkSpeedUsed = SK_LSPEED_STAT_10MBPS;
+		pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS;
 	}
 
 	return(SK_AND_OK);
@@ -3312,10 +3717,10 @@
 
 	/* Check Duplex mismatch */
 	if ((QuickStat & PHY_L_QS_DUP_MOD) != 0) {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOFULL;
+		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL;
 	}
 	else {
-		pPrt->PLinkModeStatus = SK_LMODE_STAT_AUTOHALF;
+		pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF;
 	}
 	
 	/* Check Master/Slave resolution */
@@ -3338,6 +3743,7 @@
 	/* We are using IEEE 802.3z/D5.0 Table 37-4 */
 	/* we must manually resolve the abilities here */
 	pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE;
+	
 	switch (pPrt->PFlowCtrlMode) {
 	case SK_FLOW_MODE_NONE:
 		/* default */
@@ -3457,6 +3863,9 @@
 		return(Rtv);
 	}
 
+	SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+		("AutoNeg done Port %d\n", Port));
+	
 	/* We checked everything and may now enable the link */
 	pPrt->PAutoNegFail = SK_FALSE;
 
diff -urN linux-2.4.24-pre1/drivers/net/starfire.c linux-2.4.24-pre2/drivers/net/starfire.c
--- linux-2.4.24-pre1/drivers/net/starfire.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/starfire.c	2003-12-22 11:34:35.000000000 -0800
@@ -130,7 +130,6 @@
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
-#include <asm/io.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
diff -urN linux-2.4.24-pre1/drivers/net/typhoon.c linux-2.4.24-pre2/drivers/net/typhoon.c
--- linux-2.4.24-pre1/drivers/net/typhoon.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.24-pre2/drivers/net/typhoon.c	2003-12-22 11:34:35.000000000 -0800
@@ -85,8 +85,8 @@
 #define PKT_BUF_SZ		1536
 
 #define DRV_MODULE_NAME		"typhoon"
-#define DRV_MODULE_VERSION 	"1.4.1"
-#define DRV_MODULE_RELDATE	"03/06/26"
+#define DRV_MODULE_VERSION 	"1.4.2"
+#define DRV_MODULE_RELDATE	"03/11/25"
 #define PFX			DRV_MODULE_NAME ": "
 #define ERR_PFX			KERN_ERR PFX
 
@@ -127,7 +127,7 @@
 static char version[] __devinitdata =
     "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
-MODULE_AUTHOR("David Dillow <dillowd@y12.doe.gov>");
+MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
 MODULE_PARM(rx_copybreak, "i");
@@ -146,11 +146,12 @@
 	int capabilities;
 };
 
-#define TYPHOON_CRYPTO_NONE		0
-#define TYPHOON_CRYPTO_DES		1
-#define TYPHOON_CRYPTO_3DES		2
-#define	TYPHOON_CRYPTO_VARIABLE		4
-#define TYPHOON_FIBER			8
+#define TYPHOON_CRYPTO_NONE		0x00
+#define TYPHOON_CRYPTO_DES		0x01
+#define TYPHOON_CRYPTO_3DES		0x02
+#define	TYPHOON_CRYPTO_VARIABLE		0x04
+#define TYPHOON_FIBER			0x08
+#define TYPHOON_WAKEUP_NEEDS_RESET	0x10
 
 enum typhoon_cards {
 	TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR,
@@ -307,7 +308,8 @@
 /* We'll wait up to six seconds for a reset, and half a second normally.
  */
 #define TYPHOON_UDELAY			50
-#define TYPHOON_RESET_TIMEOUT		(6 * HZ)
+#define TYPHOON_RESET_TIMEOUT_SLEEP	(6 * HZ)
+#define TYPHOON_RESET_TIMEOUT_NOSLEEP	((6 * 1000000) / TYPHOON_UDELAY)
 #define TYPHOON_WAIT_TIMEOUT		((1000000 / 2) / TYPHOON_UDELAY)
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28)
@@ -375,10 +377,12 @@
 typhoon_reset(unsigned long ioaddr, int wait_type)
 {
 	int i, err = 0;
-	int timeout = TYPHOON_RESET_TIMEOUT;
+	int timeout;
 
 	if(wait_type == WaitNoSleep)
-		timeout = (timeout * 1000000) / (HZ * TYPHOON_UDELAY);
+		timeout = TYPHOON_RESET_TIMEOUT_NOSLEEP;
+	else
+		timeout = TYPHOON_RESET_TIMEOUT_SLEEP;
 
 	writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
 	writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS);
@@ -1857,6 +1861,11 @@
 	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_SLEEPING) < 0)
 		return -ETIMEDOUT;
 
+	/* Since we cannot monitor the status of the link while sleeping,
+	 * tell the world it went away.
+	 */
+	netif_carrier_off(tp->dev);
+
 	pci_enable_wake(tp->pdev, state, 1);
 	pci_disable_device(pdev);
 	return pci_set_power_state(pdev, state);
@@ -1871,8 +1880,13 @@
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev, tp->pci_state);
 
+	/* Post 2.x.x versions of the Sleep Image require a reset before
+	 * we can download the Runtime Image. But let's not make users of
+	 * the old firmware pay for the reset.
+	 */
 	writel(TYPHOON_BOOTCMD_WAKEUP, ioaddr + TYPHOON_REG_COMMAND);
-	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0)
+	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0 ||
+			(tp->capabilities & TYPHOON_WAKEUP_NEEDS_RESET))
 		return typhoon_reset(ioaddr, wait_type);
 
 	return 0;
@@ -2250,7 +2264,7 @@
 	void *shared;
 	dma_addr_t shared_dma;
 	struct cmd_desc xp_cmd;
-	struct resp_desc xp_resp;
+	struct resp_desc xp_resp[3];
 	int i;
 	int err = 0;
 
@@ -2378,15 +2392,15 @@
 	}
 
 	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS);
-	if(typhoon_issue_command(tp, 1, &xp_cmd, 1, &xp_resp) < 0) {
+	if(typhoon_issue_command(tp, 1, &xp_cmd, 1, xp_resp) < 0) {
 		printk(ERR_PFX "%s: cannot read MAC address\n",
 		       pdev->slot_name);
 		err = -EIO;
 		goto error_out_reset;
 	}
 
-	*(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp.parm1));
-	*(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp.parm2));
+	*(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp[0].parm1));
+	*(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2));
 
 	if(!is_valid_ether_addr(dev->dev_addr)) {
 		printk(ERR_PFX "%s: Could not obtain valid ethernet address, "
@@ -2394,6 +2408,28 @@
 		goto error_out_reset;
 	}
 
+	/* Read the Sleep Image version last, so the response is valid
+	 * later when we print out the version reported.
+	 */
+	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS);
+	if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) {
+		printk(ERR_PFX "%s: Could not get Sleep Image version\n",
+			pdev->slot_name);
+		goto error_out_reset;
+	}
+
+	tp->capabilities = typhoon_card_info[card_id].capabilities;
+	tp->xcvr_select = TYPHOON_XCVR_AUTONEG;
+
+	/* Typhoon 1.0 Sleep Images return one response descriptor to the
+	 * READ_VERSIONS command. Those versions are OK after waking up
+	 * from sleep without needing a reset. Typhoon 1.1+ Sleep Images
+	 * seem to need a little extra help to get started. Since we don't
+	 * know how to nudge it along, just kick it.
+	 */
+	if(xp_resp[0].numDesc != 0)
+		tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET;
+
 	if(typhoon_sleep(tp, 3, 0) < 0) {
 		printk(ERR_PFX "%s: cannot put adapter to sleep\n",
 		       pdev->slot_name);
@@ -2401,9 +2437,6 @@
 		goto error_out_reset;
 	}
 
-	tp->capabilities = typhoon_card_info[card_id].capabilities;
-	tp->xcvr_select = TYPHOON_XCVR_AUTONEG;
-
 	/* The chip-specific entries in the device structure. */
 	dev->open		= typhoon_open;
 	dev->hard_start_xmit	= typhoon_start_tx;
@@ -2440,6 +2473,32 @@
 		printk("%2.2x:", dev->dev_addr[i]);
 	printk("%2.2x\n", dev->dev_addr[i]);
 
+	/* xp_resp still contains the response to the READ_VERSIONS command.
+	 * For debugging, let the user know what version he has.
+	 */
+	if(xp_resp[0].numDesc == 0) {
+		/* This is the Typhoon 1.0 type Sleep Image, last 16 bits
+		 * of version is Month/Day of build.
+		 */
+		u16 monthday = le32_to_cpu(xp_resp[0].parm2) & 0xffff;
+		printk(KERN_INFO "%s: Typhoon 1.0 Sleep Image built "
+			"%02u/%02u/2000\n", dev->name, monthday >> 8,
+			monthday & 0xff);
+	} else if(xp_resp[0].numDesc == 2) {
+		/* This is the Typhoon 1.1+ type Sleep Image
+		 */
+		u32 sleep_ver = le32_to_cpu(xp_resp[0].parm2);
+		u8 *ver_string = (u8 *) &xp_resp[1];
+		ver_string[25] = 0;
+		printk(KERN_INFO "%s: Typhoon 1.1+ Sleep Image version "
+			"%u.%u.%u.%u %s\n", dev->name, HIPQUAD(sleep_ver),
+			ver_string);
+	} else {
+		printk(KERN_WARNING "%s: Unknown Sleep Image version "
+			"(%u:%04x)\n", dev->name, xp_resp[0].numDesc,
+			le32_to_cpu(xp_resp[0].parm2));
+	}
+		
 	return 0;
 
 error_out_reset:
diff -urN linux-2.4.24-pre1/drivers/net/wan/Config.in linux-2.4.24-pre2/drivers/net/wan/Config.in
--- linux-2.4.24-pre1/drivers/net/wan/Config.in	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/wan/Config.in	2003-12-22 11:34:35.000000000 -0800
@@ -77,6 +77,17 @@
       else
 	 comment '    X.25/LAPB support is disabled'
       fi
+      if [ "$CONFIG_PCI" != "n" ]; then
+         dep_tristate '    Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)' CONFIG_PC300 $CONFIG_HDLC
+         if [ "$CONFIG_PC300" != "n" ]; then
+               if [ "$CONFIG_PPP" != "n" -a "$CONFIG_PPP_MULTLINK" != "n" -a "$CONFIG_PPP_SYNCTTY" != "n" -a "$CONFIG_HDLC_PPP" = "y" ]; then
+                       bool '      Cyclades-PC300 MLPPP support' CONFIG_PC300_MLPPP
+               else
+                       comment '     Cyclades-PC300 MLPPP support is disabled.'
+                       comment '     Refer to the file README.mlppp, provided by PC300 package.'
+               fi
+         fi
+      fi
       dep_tristate '    SDL RISCom/N2 support' CONFIG_N2 $CONFIG_HDLC
       dep_tristate '    Moxa C101 support' CONFIG_C101 $CONFIG_HDLC
       dep_tristate '    FarSync T-Series support' CONFIG_FARSYNC $CONFIG_HDLC
diff -urN linux-2.4.24-pre1/drivers/net/wan/Makefile linux-2.4.24-pre2/drivers/net/wan/Makefile
--- linux-2.4.24-pre1/drivers/net/wan/Makefile	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/wan/Makefile	2003-12-22 11:34:35.000000000 -0800
@@ -9,7 +9,7 @@
 
 O_TARGET := wan.o
 
-export-objs =	z85230.o syncppp.o comx.o sdladrv.o cycx_drv.o hdlc_generic.o
+export-objs =	z85230.o syncppp.o comx.o sdladrv.o cycx_drv.o hdlc_generic.o pc300_drv.o
 list-multi =	wanpipe.o cyclomx.o
 
 wanpipe-objs = sdlamain.o sdla_ft1.o $(wanpipe-y)
@@ -31,6 +31,8 @@
 hdlc-$(CONFIG_HDLC_X25)		+= hdlc_x25.o
 hdlc-objs			:= $(hdlc-y)
 
+pc300-$(CONFIG_PC300_MLPPP)	+= pc300_tty.o
+
 obj-$(CONFIG_HOSTESS_SV11)	+= z85230.o	syncppp.o	hostess_sv11.o
 obj-$(CONFIG_SEALEVEL_4021)	+= z85230.o	syncppp.o	sealevel.o
 obj-$(CONFIG_COMX)		+= 				comx.o
@@ -71,6 +73,7 @@
 obj-$(CONFIG_CYCLADES_SYNC)	+= cycx_drv.o cyclomx.o
 obj-$(CONFIG_LAPBETHER)		+= lapbether.o
 obj-$(CONFIG_SBNI)		+= sbni.o
+obj-$(CONFIG_PC300)		+= pc300.o
 obj-$(CONFIG_HDLC)		+= hdlc.o
 ifeq ($(CONFIG_HDLC_PPP),y)
   obj-$(CONFIG_HDLC)		+= syncppp.o
@@ -80,6 +83,9 @@
 
 include $(TOPDIR)/Rules.make
 
+pc300.o: pc300_drv.o $(pc300-y)
+	$(LD) -r -o $@ pc300_drv.o $(pc300-y)
+
 hdlc.o: $(hdlc-objs)
 	$(LD) -r -o $@ $(hdlc-objs)
 
diff -urN linux-2.4.24-pre1/drivers/net/wan/hd64572.h linux-2.4.24-pre2/drivers/net/wan/hd64572.h
--- linux-2.4.24-pre1/drivers/net/wan/hd64572.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/wan/hd64572.h	2003-12-22 11:34:35.000000000 -0800
@@ -0,0 +1,433 @@
+/*
+ * hd64572.h	Description of the Hitachi HD64572 (SCA-II), valid for 
+ * 		CPU modes 0 & 2.
+ *
+ * Author:	Ivan Passos <ivan.passos@cyclades.com>
+ *
+ * Copyright:   (c) 2000-2003 Cyclades Corp.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef _HD64572_H
+#define _HD64572_H
+
+/* Illegal Access Register */
+#define	ILAR	0x00
+
+/* Wait Controller Registers */
+#define PABR0L	0x20	/* Physical Addr Boundary Register 0 L */
+#define PABR0H	0x21	/* Physical Addr Boundary Register 0 H */
+#define PABR1L	0x22	/* Physical Addr Boundary Register 1 L */
+#define PABR1H	0x23	/* Physical Addr Boundary Register 1 H */
+#define WCRL	0x24	/* Wait Control Register L */
+#define WCRM	0x25	/* Wait Control Register M */
+#define WCRH	0x26	/* Wait Control Register H */
+
+/* Interrupt Registers */
+#define IVR	0x60	/* Interrupt Vector Register */
+#define IMVR	0x64	/* Interrupt Modified Vector Register */
+#define ITCR	0x68	/* Interrupt Control Register */
+#define ISR0	0x6c	/* Interrupt Status Register 0 */
+#define ISR1	0x70	/* Interrupt Status Register 1 */
+#define IER0	0x74	/* Interrupt Enable Register 0 */
+#define IER1	0x78	/* Interrupt Enable Register 1 */
+
+/* Register Access Macros (chan is 0 or 1 in _any_ case) */
+#define	M_REG(reg, chan)	(reg + 0x80*chan)		/* MSCI */
+#define	DRX_REG(reg, chan)	(reg + 0x40*chan)		/* DMA Rx */
+#define	DTX_REG(reg, chan)	(reg + 0x20*(2*chan + 1))	/* DMA Tx */
+#define	TRX_REG(reg, chan)	(reg + 0x20*chan)		/* Timer Rx */
+#define	TTX_REG(reg, chan)	(reg + 0x10*(2*chan + 1))	/* Timer Tx */
+#define	ST_REG(reg, chan)	(reg + 0x80*chan)		/* Status Cnt */
+#define IR0_DRX(val, chan)	((val)<<(8*(chan)))		/* Int DMA Rx */
+#define IR0_DTX(val, chan)	((val)<<(4*(2*chan + 1)))	/* Int DMA Tx */
+#define IR0_M(val, chan)	((val)<<(8*(chan)))		/* Int MSCI */
+
+/* MSCI Channel Registers */
+#define MD0	0x138	/* Mode reg 0 */
+#define MD1	0x139	/* Mode reg 1 */
+#define MD2	0x13a	/* Mode reg 2 */
+#define MD3	0x13b	/* Mode reg 3 */
+#define CTL	0x130	/* Control reg */
+#define RXS	0x13c	/* RX clock source */
+#define TXS	0x13d	/* TX clock source */
+#define EXS	0x13e	/* External clock input selection */
+#define TMCT	0x144	/* Time constant (Tx) */
+#define TMCR	0x145	/* Time constant (Rx) */
+#define CMD	0x128	/* Command reg */
+#define ST0	0x118	/* Status reg 0 */
+#define ST1	0x119	/* Status reg 1 */
+#define ST2	0x11a	/* Status reg 2 */
+#define ST3	0x11b	/* Status reg 3 */
+#define ST4	0x11c	/* Status reg 4 */
+#define FST	0x11d	/* frame Status reg  */
+#define IE0	0x120	/* Interrupt enable reg 0 */
+#define IE1	0x121	/* Interrupt enable reg 1 */
+#define IE2	0x122	/* Interrupt enable reg 2 */
+#define IE4	0x124	/* Interrupt enable reg 4 */
+#define FIE	0x125	/* Frame Interrupt enable reg  */
+#define SA0	0x140	/* Syn Address reg 0 */
+#define SA1	0x141	/* Syn Address reg 1 */
+#define IDL	0x142	/* Idle register */
+#define TRBL	0x100	/* TX/RX buffer reg L */ 
+#define TRBK	0x101	/* TX/RX buffer reg K */ 
+#define TRBJ	0x102	/* TX/RX buffer reg J */ 
+#define TRBH	0x103	/* TX/RX buffer reg H */ 
+#define TRC0	0x148	/* TX Ready control reg 0 */ 
+#define TRC1	0x149	/* TX Ready control reg 1 */ 
+#define RRC	0x14a	/* RX Ready control reg */ 
+#define CST0	0x108	/* Current Status Register 0 */ 
+#define CST1	0x109	/* Current Status Register 1 */ 
+#define CST2	0x10a	/* Current Status Register 2 */ 
+#define CST3	0x10b	/* Current Status Register 3 */ 
+#define GPO	0x131	/* General Purpose Output Pin Ctl Reg */
+#define TFS	0x14b	/* Tx Start Threshold Ctl Reg */
+#define TFN	0x143	/* Inter-transmit-frame Time Fill Ctl Reg */
+#define TBN	0x110	/* Tx Buffer Number Reg */
+#define RBN	0x111	/* Rx Buffer Number Reg */
+#define TNR0	0x150	/* Tx DMA Request Ctl Reg 0 */
+#define TNR1	0x151	/* Tx DMA Request Ctl Reg 1 */
+#define TCR	0x152	/* Tx DMA Critical Request Reg */
+#define RNR	0x154	/* Rx DMA Request Ctl Reg */
+#define RCR	0x156	/* Rx DMA Critical Request Reg */
+
+/* Timer Registers */
+#define TCNTL	0x200	/* Timer Upcounter L */
+#define TCNTH	0x201	/* Timer Upcounter H */
+#define TCONRL	0x204	/* Timer Constant Register L */
+#define TCONRH	0x205	/* Timer Constant Register H */
+#define TCSR	0x206	/* Timer Control/Status Register */
+#define TEPR	0x207	/* Timer Expand Prescale Register */
+
+/* DMA registers */
+#define PCR		0x40		/* DMA priority control reg */
+#define DRR		0x44		/* DMA reset reg */
+#define DMER		0x07		/* DMA Master Enable reg */
+#define BTCR		0x08		/* Burst Tx Ctl Reg */
+#define BOLR		0x0c		/* Back-off Length Reg */
+#define DSR_RX(chan)	(0x48 + 2*chan)	/* DMA Status Reg (Rx) */
+#define DSR_TX(chan)	(0x49 + 2*chan)	/* DMA Status Reg (Tx) */
+#define DIR_RX(chan)	(0x4c + 2*chan)	/* DMA Interrupt Enable Reg (Rx) */
+#define DIR_TX(chan)	(0x4d + 2*chan)	/* DMA Interrupt Enable Reg (Tx) */
+#define FCT_RX(chan)	(0x50 + 2*chan)	/* Frame End Interrupt Counter (Rx) */
+#define FCT_TX(chan)	(0x51 + 2*chan)	/* Frame End Interrupt Counter (Tx) */
+#define DMR_RX(chan)	(0x54 + 2*chan)	/* DMA Mode Reg (Rx) */
+#define DMR_TX(chan)	(0x55 + 2*chan)	/* DMA Mode Reg (Tx) */
+#define DCR_RX(chan)	(0x58 + 2*chan)	/* DMA Command Reg (Rx) */
+#define DCR_TX(chan)	(0x59 + 2*chan)	/* DMA Command Reg (Tx) */
+
+/* DMA Channel Registers */
+#define DARL	0x80	/* Dest Addr Register L (single-block, RX only) */
+#define DARH	0x81	/* Dest Addr Register H (single-block, RX only) */
+#define DARB	0x82	/* Dest Addr Register B (single-block, RX only) */
+#define DARBH	0x83	/* Dest Addr Register BH (single-block, RX only) */
+#define SARL	0x80	/* Source Addr Register L (single-block, TX only) */
+#define SARH	0x81	/* Source Addr Register H (single-block, TX only) */
+#define SARB	0x82	/* Source Addr Register B (single-block, TX only) */
+#define DARBH	0x83	/* Source Addr Register BH (single-block, TX only) */
+#define BARL	0x80	/* Buffer Addr Register L (chained-block) */
+#define BARH	0x81	/* Buffer Addr Register H (chained-block) */
+#define BARB	0x82	/* Buffer Addr Register B (chained-block) */
+#define BARBH	0x83	/* Buffer Addr Register BH (chained-block) */
+#define CDAL	0x84	/* Current Descriptor Addr Register L */
+#define CDAH	0x85	/* Current Descriptor Addr Register H */
+#define CDAB	0x86	/* Current Descriptor Addr Register B */
+#define CDABH	0x87	/* Current Descriptor Addr Register BH */
+#define EDAL	0x88	/* Error Descriptor Addr Register L */
+#define EDAH	0x89	/* Error Descriptor Addr Register H */
+#define EDAB	0x8a	/* Error Descriptor Addr Register B */
+#define EDABH	0x8b	/* Error Descriptor Addr Register BH */
+#define BFLL	0x90	/* RX Buffer Length L (only RX) */
+#define BFLH	0x91	/* RX Buffer Length H (only RX) */
+#define BCRL	0x8c	/* Byte Count Register L */
+#define BCRH	0x8d	/* Byte Count Register H */
+
+/* Block Descriptor Structure */
+typedef struct {
+	unsigned long	next;		/* pointer to next block descriptor */
+	unsigned long	ptbuf;		/* buffer pointer */
+	unsigned short	len;		/* data length */
+	unsigned char	status;		/* status */
+	unsigned char	filler[5];	/* alignment filler (16 bytes) */ 
+} pcsca_bd_t;
+
+/* 
+	Descriptor Status definitions:
+
+	Bit	Transmission	Reception
+
+	7	EOM		EOM
+	6	-		Short Frame
+	5	-		Abort
+	4	-		Residual bit
+	3	Underrun	Overrun	
+	2	-		CRC
+	1	Ownership	Ownership
+	0	EOT		-
+*/
+#define DST_EOT		0x01	/* End of transmit command */
+#define DST_OSB		0x02	/* Ownership bit */
+#define DST_CRC		0x04	/* CRC Error */
+#define DST_OVR		0x08	/* Overrun */
+#define DST_UDR		0x08	/* Underrun */
+#define DST_RBIT	0x10	/* Residual bit */
+#define DST_ABT		0x20	/* Abort */
+#define DST_SHRT	0x40	/* Short Frame  */
+#define DST_EOM		0x80	/* End of Message  */
+
+/* Status Counter Registers */
+#define CMCR	0x158	/* Counter Master Ctl Reg */
+#define TECNTL	0x160	/* Tx EOM Counter L */
+#define TECNTM	0x161	/* Tx EOM Counter M */
+#define TECNTH	0x162	/* Tx EOM Counter H */
+#define TECCR	0x163	/* Tx EOM Counter Ctl Reg */
+#define URCNTL	0x164	/* Underrun Counter L */
+#define URCNTH	0x165	/* Underrun Counter H */
+#define URCCR	0x167	/* Underrun Counter Ctl Reg */
+#define RECNTL	0x168	/* Rx EOM Counter L */
+#define RECNTM	0x169	/* Rx EOM Counter M */
+#define RECNTH	0x16a	/* Rx EOM Counter H */
+#define RECCR	0x16b	/* Rx EOM Counter Ctl Reg */
+#define ORCNTL	0x16c	/* Overrun Counter L */
+#define ORCNTH	0x16d	/* Overrun Counter H */
+#define ORCCR	0x16f	/* Overrun Counter Ctl Reg */
+#define CECNTL	0x170	/* CRC Counter L */
+#define CECNTH	0x171	/* CRC Counter H */
+#define CECCR	0x173	/* CRC Counter Ctl Reg */
+#define ABCNTL	0x174	/* Abort frame Counter L */
+#define ABCNTH	0x175	/* Abort frame Counter H */
+#define ABCCR	0x177	/* Abort frame Counter Ctl Reg */
+#define SHCNTL	0x178	/* Short frame Counter L */
+#define SHCNTH	0x179	/* Short frame Counter H */
+#define SHCCR	0x17b	/* Short frame Counter Ctl Reg */
+#define RSCNTL	0x17c	/* Residual bit Counter L */
+#define RSCNTH	0x17d	/* Residual bit Counter H */
+#define RSCCR	0x17f	/* Residual bit Counter Ctl Reg */
+
+/* Register Programming Constants */
+
+#define IR0_DMIC	0x00000001
+#define IR0_DMIB	0x00000002
+#define IR0_DMIA	0x00000004
+#define IR0_EFT		0x00000008
+#define IR0_DMAREQ	0x00010000
+#define IR0_TXINT	0x00020000
+#define IR0_RXINTB	0x00040000
+#define IR0_RXINTA	0x00080000
+#define IR0_TXRDY	0x00100000
+#define IR0_RXRDY	0x00200000
+
+#define MD0_CRC16_0	0x00
+#define MD0_CRC16_1	0x01
+#define MD0_CRC32	0x02
+#define MD0_CRC_CCITT	0x03
+#define MD0_CRCC0	0x04
+#define MD0_CRCC1	0x08
+#define MD0_AUTO_ENA	0x10
+#define MD0_ASYNC	0x00
+#define MD0_BY_MSYNC	0x20
+#define MD0_BY_BISYNC	0x40
+#define MD0_BY_EXT	0x60
+#define MD0_BIT_SYNC	0x80
+#define MD0_TRANSP	0xc0
+
+#define MD1_NOADDR	0x00
+#define MD1_SADDR1	0x40
+#define MD1_SADDR2	0x80
+#define MD1_DADDR	0xc0
+
+#define MD2_F_DUPLEX	0x00
+#define MD2_AUTO_ECHO	0x01
+#define MD2_LOOP_HI_Z	0x02
+#define MD2_LOOP_MIR	0x03
+#define MD2_ADPLL_X8	0x00
+#define MD2_ADPLL_X16	0x08
+#define MD2_ADPLL_X32	0x10
+#define MD2_NRZ		0x00
+#define MD2_NRZI	0x20
+#define MD2_NRZ_IEEE	0x40
+#define MD2_MANCH	0x00
+#define MD2_FM1		0x20
+#define MD2_FM0		0x40
+#define MD2_FM		0x80
+
+#define CTL_RTS		0x01
+#define CTL_DTR		0x02
+#define CTL_SYN		0x04
+#define CTL_IDLC	0x10
+#define CTL_UDRNC	0x20
+#define CTL_URSKP	0x40
+#define CTL_URCT	0x80
+
+#define	RXS_BR0		0x01
+#define	RXS_BR1		0x02
+#define	RXS_BR2		0x04
+#define	RXS_BR3		0x08
+#define	RXS_ECLK	0x00
+#define	RXS_ECLK_NS	0x20
+#define	RXS_IBRG	0x40
+#define	RXS_PLL1	0x50
+#define	RXS_PLL2	0x60
+#define	RXS_PLL3	0x70
+#define	RXS_DRTXC	0x80
+
+#define	TXS_BR0		0x01
+#define	TXS_BR1		0x02
+#define	TXS_BR2		0x04
+#define	TXS_BR3		0x08
+#define	TXS_ECLK	0x00
+#define	TXS_IBRG	0x40
+#define	TXS_RCLK	0x60
+#define	TXS_DTRXC	0x80
+
+#define	EXS_RES0	0x01
+#define	EXS_RES1	0x02
+#define	EXS_RES2	0x04
+#define	EXS_TES0	0x10
+#define	EXS_TES1	0x20
+#define	EXS_TES2	0x40
+
+#define CMD_RX_RST	0x11
+#define CMD_RX_ENA	0x12
+#define CMD_RX_DIS	0x13
+#define CMD_RX_CRC_INIT	0x14
+#define CMD_RX_MSG_REJ	0x15
+#define CMD_RX_MP_SRCH	0x16
+#define CMD_RX_CRC_EXC	0x17
+#define CMD_RX_CRC_FRC	0x18
+#define CMD_TX_RST	0x01
+#define CMD_TX_ENA	0x02
+#define CMD_TX_DISA	0x03
+#define CMD_TX_CRC_INIT	0x04
+#define CMD_TX_CRC_EXC	0x05
+#define CMD_TX_EOM	0x06
+#define CMD_TX_ABORT	0x07
+#define CMD_TX_MP_ON	0x08
+#define CMD_TX_BUF_CLR	0x09
+#define CMD_TX_DISB	0x0b
+#define CMD_CH_RST	0x21
+#define CMD_SRCH_MODE	0x31
+#define CMD_NOP		0x00
+
+#define ST0_RXRDY	0x01
+#define ST0_TXRDY	0x02
+#define ST0_RXINTB	0x20
+#define ST0_RXINTA	0x40
+#define ST0_TXINT	0x80
+
+#define ST1_IDLE	0x01
+#define ST1_ABORT	0x02
+#define ST1_CDCD	0x04
+#define ST1_CCTS	0x08
+#define ST1_SYN_FLAG	0x10
+#define ST1_CLMD	0x20
+#define ST1_TXIDLE	0x40
+#define ST1_UDRN	0x80
+
+#define ST2_CRCE	0x04
+#define ST2_ONRN	0x08
+#define ST2_RBIT	0x10
+#define ST2_ABORT	0x20
+#define ST2_SHORT	0x40
+#define ST2_EOM		0x80
+
+#define ST3_RX_ENA	0x01
+#define ST3_TX_ENA	0x02
+#define ST3_DCD		0x04
+#define ST3_CTS		0x08
+#define ST3_SRCH_MODE	0x10
+#define ST3_SLOOP	0x20
+#define ST3_GPI		0x80
+
+#define ST4_RDNR	0x01
+#define ST4_RDCR	0x02
+#define ST4_TDNR	0x04
+#define ST4_TDCR	0x08
+#define ST4_OCLM	0x20
+#define ST4_CFT		0x40
+#define ST4_CGPI	0x80
+
+#define FST_CRCEF	0x04
+#define FST_OVRNF	0x08
+#define FST_RBIF	0x10
+#define FST_ABTF	0x20
+#define FST_SHRTF	0x40
+#define FST_EOMF	0x80
+
+#define IE0_RXRDY	0x01
+#define IE0_TXRDY	0x02
+#define IE0_RXINTB	0x20
+#define IE0_RXINTA	0x40
+#define IE0_TXINT	0x80
+
+#define IE1_IDLD	0x01
+#define IE1_ABTD	0x02
+#define IE1_CDCD	0x04
+#define IE1_CCTS	0x08
+#define IE1_SYNCD	0x10
+#define IE1_CLMD	0x20
+#define IE1_IDL		0x40
+#define IE1_UDRN	0x80
+
+#define IE2_CRCE	0x04
+#define IE2_OVRN	0x08
+#define IE2_RBIT	0x10
+#define IE2_ABT		0x20
+#define IE2_SHRT	0x40
+#define IE2_EOM		0x80
+
+#define IE4_RDNR	0x01
+#define IE4_RDCR	0x02
+#define IE4_TDNR	0x04
+#define IE4_TDCR	0x08
+#define IE4_OCLM	0x20
+#define IE4_CFT		0x40
+#define IE4_CGPI	0x80
+
+#define FIE_CRCEF	0x04
+#define FIE_OVRNF	0x08
+#define FIE_RBIF	0x10
+#define FIE_ABTF	0x20
+#define FIE_SHRTF	0x40
+#define FIE_EOMF	0x80
+
+#define DSR_DWE		0x01
+#define DSR_DE		0x02
+#define DSR_REF		0x04
+#define DSR_UDRF	0x04
+#define DSR_COA		0x08
+#define DSR_COF		0x10
+#define DSR_BOF		0x20
+#define DSR_EOM		0x40
+#define DSR_EOT		0x80
+
+#define DIR_REF		0x04
+#define DIR_UDRF	0x04
+#define DIR_COA		0x08
+#define DIR_COF		0x10
+#define DIR_BOF		0x20
+#define DIR_EOM		0x40
+#define DIR_EOT		0x80
+
+#define DMR_CNTE	0x02
+#define DMR_NF		0x04
+#define DMR_SEOME	0x08
+#define DMR_TMOD	0x10
+
+#define DCR_SW_ABT	0x01
+#define DCR_FCT_CLR	0x02
+
+#define PCR_PR0		0x01
+#define PCR_PR1		0x02
+#define PCR_PR2		0x04
+#define PCR_CCC		0x08
+#define PCR_BRC		0x10
+#define PCR_OSB		0x40
+#define PCR_BURST	0x80
+
+#endif /* (_HD64572_H) */
diff -urN linux-2.4.24-pre1/drivers/net/wan/pc300.h linux-2.4.24-pre2/drivers/net/wan/pc300.h
--- linux-2.4.24-pre1/drivers/net/wan/pc300.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/wan/pc300.h	2003-12-22 11:34:35.000000000 -0800
@@ -0,0 +1,424 @@
+/*
+ * pc300.h	Cyclades-PC300(tm) Kernel API Definitions.
+ *
+ * Author:	Ivan Passos <ivan.passos@cyclades.com>
+ *
+ * Copyright:	(c) 1999-2003 Cyclades Corp.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef	_PC300_H
+#define	_PC300_H
+
+#ifndef __HDLC_H
+#include <linux/hdlc.h>
+#endif
+
+#ifndef _HD64572_H
+#include "hd64572.h"
+#endif
+#ifndef _FALC_LH_H
+#include "pc300_falc-lh.h"
+#endif
+
+#ifndef CY_TYPES
+#define CY_TYPES
+#if defined(__alpha__)
+typedef	unsigned long	ucdouble;	/* 64 bits, unsigned */
+typedef	unsigned int	uclong;		/* 32 bits, unsigned */
+#else
+typedef	unsigned long	uclong;		/* 32 bits, unsigned */
+#endif
+typedef	unsigned short	ucshort;	/* 16 bits, unsigned */
+typedef	unsigned char	ucchar;		/* 8 bits, unsigned */
+#endif /* CY_TYPES */
+
+#define PC300_PROTO_MLPPP 1		
+
+#define PC300_KERNEL	"2.4.x"	/* Kernel supported by this driver */
+
+#define	PC300_DEVNAME	"hdlc"	/* Dev. name base (for hdlc0, hdlc1, etc.) */
+#define PC300_MAXINDEX	100	/* Max dev. name index (the '0' in hdlc0) */
+
+#define	PC300_MAXCARDS	4	/* Max number of cards per system */
+#define	PC300_MAXCHAN	2	/* Number of channels per card */
+
+#define	PC300_PLX_WIN	0x80    /* PLX control window size (128b) */
+#define	PC300_RAMSIZE	0x40000 /* RAM window size (256Kb) */
+#define	PC300_SCASIZE	0x400   /* SCA window size (1Kb) */
+#define	PC300_FALCSIZE	0x400	/* FALC window size (1Kb) */
+
+#define PC300_OSC_CLOCK	24576000
+#define PC300_PCI_CLOCK	33000000
+
+#define BD_DEF_LEN	0x0800	/* DMA buffer length (2KB) */
+#define DMA_TX_MEMSZ	0x8000	/* Total DMA Tx memory size (32KB/ch) */
+#define DMA_RX_MEMSZ	0x10000	/* Total DMA Rx memory size (64KB/ch) */
+
+#define N_DMA_TX_BUF	(DMA_TX_MEMSZ / BD_DEF_LEN)	/* DMA Tx buffers */
+#define N_DMA_RX_BUF	(DMA_RX_MEMSZ / BD_DEF_LEN)	/* DMA Rx buffers */
+
+/* DMA Buffer Offsets */
+#define DMA_TX_BASE	((N_DMA_TX_BUF + N_DMA_RX_BUF) *	\
+			 PC300_MAXCHAN * sizeof(pcsca_bd_t))
+#define DMA_RX_BASE	(DMA_TX_BASE + PC300_MAXCHAN*DMA_TX_MEMSZ)
+
+/* DMA Descriptor Offsets */
+#define DMA_TX_BD_BASE	0x0000
+#define DMA_RX_BD_BASE	(DMA_TX_BD_BASE + ((PC300_MAXCHAN*DMA_TX_MEMSZ / \
+				BD_DEF_LEN) * sizeof(pcsca_bd_t)))
+
+/* DMA Descriptor Macros */
+#define TX_BD_ADDR(chan, n)	(DMA_TX_BD_BASE + \
+				 ((N_DMA_TX_BUF*chan) + n) * sizeof(pcsca_bd_t))
+#define RX_BD_ADDR(chan, n)	(DMA_RX_BD_BASE + \
+				 ((N_DMA_RX_BUF*chan) + n) * sizeof(pcsca_bd_t))
+
+/* Macro to access the FALC registers (TE only) */
+#define F_REG(reg, chan)	(0x200*(chan) + ((reg)<<2))
+
+/***************************************
+ * Memory access functions/macros      *
+ * (required to support Alpha systems) *
+ ***************************************/
+#ifdef __KERNEL__
+#define cpc_writeb(port,val)	{writeb((ucchar)(val),(ulong)(port)); mb();}
+#define cpc_writew(port,val)	{writew((ushort)(val),(ulong)(port)); mb();}
+#define cpc_writel(port,val)	{writel((uclong)(val),(ulong)(port)); mb();}
+
+#define cpc_readb(port)		readb(port)
+#define cpc_readw(port)		readw(port)
+#define cpc_readl(port)		readl(port)
+
+#else /* __KERNEL__ */
+#define cpc_writeb(port,val)	(*(volatile ucchar *)(port) = (ucchar)(val))
+#define cpc_writew(port,val)	(*(volatile ucshort *)(port) = (ucshort)(val))
+#define cpc_writel(port,val)	(*(volatile uclong *)(port) = (uclong)(val))
+
+#define cpc_readb(port)		(*(volatile ucchar *)(port))
+#define cpc_readw(port)		(*(volatile ucshort *)(port))
+#define cpc_readl(port)		(*(volatile uclong *)(port))
+
+#endif /* __KERNEL__ */
+
+/****** Data Structures *****************************************************/
+
+/*
+ *      RUNTIME_9050 - PLX PCI9050-1 local configuration and shared runtime
+ *      registers. This structure can be used to access the 9050 registers
+ *      (memory mapped).
+ */
+struct RUNTIME_9050 {
+	uclong	loc_addr_range[4];	/* 00-0Ch : Local Address Ranges */
+	uclong	loc_rom_range;		/* 10h : Local ROM Range */
+	uclong	loc_addr_base[4];	/* 14-20h : Local Address Base Addrs */
+	uclong	loc_rom_base;		/* 24h : Local ROM Base */
+	uclong	loc_bus_descr[4];	/* 28-34h : Local Bus Descriptors */
+	uclong	rom_bus_descr;		/* 38h : ROM Bus Descriptor */
+	uclong	cs_base[4];		/* 3C-48h : Chip Select Base Addrs */
+	uclong	intr_ctrl_stat;		/* 4Ch : Interrupt Control/Status */
+	uclong	init_ctrl;		/* 50h : EEPROM ctrl, Init Ctrl, etc */
+};
+
+#define PLX_9050_LINT1_ENABLE	0x01
+#define PLX_9050_LINT1_POL	0x02
+#define PLX_9050_LINT1_STATUS	0x04
+#define PLX_9050_LINT2_ENABLE	0x08
+#define PLX_9050_LINT2_POL	0x10
+#define PLX_9050_LINT2_STATUS	0x20
+#define PLX_9050_INTR_ENABLE	0x40
+#define PLX_9050_SW_INTR	0x80
+
+/* Masks to access the init_ctrl PLX register */
+#define	PC300_CLKSEL_MASK		(0x00000004UL)
+#define	PC300_CHMEDIA_MASK(chan)	(0x00000020UL<<(chan*3))
+#define	PC300_CTYPE_MASK		(0x00000800UL)
+
+/* CPLD Registers (base addr = falcbase, TE only) */
+/* CPLD v. 0 */
+#define CPLD_REG1	0x140	/* Chip resets, DCD/CTS status */
+#define CPLD_REG2	0x144	/* Clock enable , LED control */
+/* CPLD v. 2 or higher */
+#define CPLD_V2_REG1	0x100	/* Chip resets, DCD/CTS status */
+#define CPLD_V2_REG2	0x104	/* Clock enable , LED control */
+#define CPLD_ID_REG	0x108	/* CPLD version */
+
+/* CPLD Register bit description: for the FALC bits, they should always be 
+   set based on the channel (use (bit<<(2*ch)) to access the correct bit for 
+   that channel) */
+#define CPLD_REG1_FALC_RESET	0x01
+#define CPLD_REG1_SCA_RESET	0x02
+#define CPLD_REG1_GLOBAL_CLK	0x08
+#define CPLD_REG1_FALC_DCD	0x10
+#define CPLD_REG1_FALC_CTS	0x20
+
+#define CPLD_REG2_FALC_TX_CLK	0x01
+#define CPLD_REG2_FALC_RX_CLK	0x02
+#define CPLD_REG2_FALC_LED1	0x10
+#define CPLD_REG2_FALC_LED2	0x20
+
+/* Structure with FALC-related fields (TE only) */
+#define PC300_FALC_MAXLOOP	0x0000ffff	/* for falc_issue_cmd() */
+
+typedef struct falc {
+	ucchar sync;		/* If true FALC is synchronized */
+	ucchar active;		/* if TRUE then already active */
+	ucchar loop_active;	/* if TRUE a line loopback UP was received */
+	ucchar loop_gen;	/* if TRUE a line loopback UP was issued */
+
+	ucchar num_channels;
+	ucchar offset;		/* 1 for T1, 0 for E1 */
+	ucchar full_bandwidth;
+
+	ucchar xmb_cause;
+	ucchar multiframe_mode;
+
+	/* Statistics */
+	ucshort pden;	/* Pulse Density violation count */
+	ucshort los;	/* Loss of Signal count */
+	ucshort losr;	/* Loss of Signal recovery count */
+	ucshort lfa;	/* Loss of frame alignment count */
+	ucshort farec;	/* Frame Alignment Recovery count */
+	ucshort lmfa;	/* Loss of multiframe alignment count */
+	ucshort ais;	/* Remote Alarm indication Signal count */
+	ucshort sec;	/* One-second timer */
+	ucshort es;	/* Errored second */
+	ucshort rai;	/* remote alarm received */
+	ucshort bec;
+	ucshort fec;
+	ucshort cvc;
+	ucshort cec;
+	ucshort ebc;
+
+	/* Status */
+	ucchar red_alarm;
+	ucchar blue_alarm;
+	ucchar loss_fa;
+	ucchar yellow_alarm;
+	ucchar loss_mfa;
+	ucchar prbs;
+} falc_t;
+
+typedef struct falc_status {
+	ucchar sync;  /* If true FALC is synchronized */
+	ucchar red_alarm;
+	ucchar blue_alarm;
+	ucchar loss_fa;
+	ucchar yellow_alarm;
+	ucchar loss_mfa;
+	ucchar prbs;
+} falc_status_t;
+
+typedef struct rsv_x21_status {
+	ucchar dcd;
+	ucchar dsr;
+	ucchar cts;
+	ucchar rts;
+	ucchar dtr;
+} rsv_x21_status_t;
+
+typedef struct pc300stats {
+	int hw_type;
+	uclong line_on;
+	uclong line_off;
+	struct net_device_stats gen_stats;
+	falc_t te_stats;
+} pc300stats_t;
+
+typedef struct pc300status {
+	int hw_type;
+	rsv_x21_status_t gen_status;
+	falc_status_t te_status;
+} pc300status_t;
+
+typedef struct pc300loopback {
+	char loop_type;
+	char loop_on;
+} pc300loopback_t;
+
+typedef struct pc300patterntst {
+	char patrntst_on;       /* 0 - off; 1 - on; 2 - read num_errors */
+	ucshort num_errors;
+} pc300patterntst_t;
+
+typedef struct pc300dev {
+	void *if_ptr;		/* General purpose pointer */
+	struct pc300ch *chan;
+	ucchar trace_on;
+	uclong line_on;		/* DCD(X.21, RSV) / sync(TE) change counters */
+	uclong line_off;
+#ifdef __KERNEL__
+	char name[16];
+	hdlc_device *hdlc;
+
+	void *private;
+	struct sk_buff *tx_skb;
+	union {	/* This union has all the protocol-specific structures */
+		struct ppp_device pppdev;
+	}ifu;
+#ifdef CONFIG_PC300_MLPPP
+	void *cpc_tty;	/* information to PC300 TTY driver */
+#endif
+#endif /* __KERNEL__ */
+}pc300dev_t;
+
+typedef struct pc300hw {
+	int type;		/* RSV, X21, etc. */
+	int bus;		/* Bus (PCI, PMC, etc.) */
+	int nchan;		/* number of channels */
+	int irq;		/* interrupt request level */
+	uclong clock;		/* Board clock */
+	ucchar cpld_id;		/* CPLD ID (TE only) */
+	ucshort cpld_reg1;	/* CPLD reg 1 (TE only) */
+	ucshort cpld_reg2;	/* CPLD reg 2 (TE only) */
+	ucshort gpioc_reg;	/* PLX GPIOC reg */
+	ucshort intctl_reg;	/* PLX Int Ctrl/Status reg */
+	uclong iophys;		/* PLX registers I/O base */
+	uclong iosize;		/* PLX registers I/O size */
+	uclong plxphys;		/* PLX registers MMIO base (physical) */
+	uclong plxbase;		/* PLX registers MMIO base (virtual) */
+	uclong plxsize;		/* PLX registers MMIO size */
+	uclong scaphys;		/* SCA registers MMIO base (physical) */
+	uclong scabase;		/* SCA registers MMIO base (virtual) */
+	uclong scasize;		/* SCA registers MMIO size */
+	uclong ramphys;		/* On-board RAM MMIO base (physical) */
+	uclong rambase;		/* On-board RAM MMIO base (virtual) */
+	uclong alloc_ramsize;	/* RAM MMIO size allocated by the PCI bridge */
+	uclong ramsize;		/* On-board RAM MMIO size */
+	uclong falcphys;	/* FALC registers MMIO base (physical) */
+	uclong falcbase;	/* FALC registers MMIO base (virtual) */
+	uclong falcsize;	/* FALC registers MMIO size */
+} pc300hw_t;
+
+typedef struct pc300chconf {
+	sync_serial_settings	phys_settings;	/* Clock type/rate (in bps), 
+						   loopback mode */
+	raw_hdlc_proto		proto_settings;	/* Encoding, parity (CRC) */
+	uclong media;		/* HW media (RS232, V.35, etc.) */
+	uclong proto;		/* Protocol (PPP, X.25, etc.) */
+	ucchar monitor;		/* Monitor mode (0 = off, !0 = on) */
+
+	/* TE-specific parameters */
+	ucchar lcode;		/* Line Code (AMI, B8ZS, etc.) */
+	ucchar fr_mode;		/* Frame Mode (ESF, D4, etc.) */
+	ucchar lbo;		/* Line Build Out */
+	ucchar rx_sens;		/* Rx Sensitivity (long- or short-haul) */
+	uclong tslot_bitmap;	/* bit[i]=1  =>  timeslot _i_ is active */
+} pc300chconf_t;
+
+typedef struct pc300ch {
+	struct pc300 *card;
+	int channel;
+	pc300dev_t d;
+	pc300chconf_t conf;
+	ucchar tx_first_bd;	/* First TX DMA block descr. w/ data */
+	ucchar tx_next_bd;	/* Next free TX DMA block descriptor */
+	ucchar rx_first_bd;	/* First free RX DMA block descriptor */
+	ucchar rx_last_bd;	/* Last free RX DMA block descriptor */
+	ucchar nfree_tx_bd;	/* Number of free TX DMA block descriptors */
+	falc_t falc;		/* FALC structure (TE only) */
+} pc300ch_t;
+
+typedef struct pc300 {
+	pc300hw_t hw;			/* hardware config. */
+	pc300ch_t chan[PC300_MAXCHAN];
+#ifdef __KERNEL__
+	spinlock_t card_lock;
+#endif /* __KERNEL__ */
+} pc300_t;
+
+typedef struct pc300conf {
+	pc300hw_t hw;
+	pc300chconf_t conf;
+} pc300conf_t;
+
+/* DEV ioctl() commands */
+#define	N_SPPP_IOCTLS	2
+
+enum pc300_ioctl_cmds {
+	SIOCCPCRESERVED = (SIOCDEVPRIVATE + N_SPPP_IOCTLS),
+	SIOCGPC300CONF,
+	SIOCSPC300CONF,
+	SIOCGPC300STATUS,
+	SIOCGPC300FALCSTATUS,
+	SIOCGPC300UTILSTATS,
+	SIOCGPC300UTILSTATUS,
+	SIOCSPC300TRACE,
+	SIOCSPC300LOOPBACK,
+	SIOCSPC300PATTERNTEST,
+};
+
+/* Loopback types - PC300/TE boards */
+enum pc300_loopback_cmds {
+	PC300LOCLOOP = 1,
+	PC300REMLOOP,
+	PC300PAYLOADLOOP,
+	PC300GENLOOPUP,
+	PC300GENLOOPDOWN,
+};
+
+/* Control Constant Definitions */
+#define	PC300_RSV	0x01
+#define	PC300_X21	0x02
+#define	PC300_TE	0x03
+
+#define	PC300_PCI	0x00
+#define	PC300_PMC	0x01
+
+#define PC300_LC_AMI	0x01
+#define PC300_LC_B8ZS	0x02
+#define PC300_LC_NRZ	0x03
+#define PC300_LC_HDB3	0x04
+
+/* Framing (T1) */
+#define PC300_FR_ESF		0x01
+#define PC300_FR_D4		0x02
+#define PC300_FR_ESF_JAPAN	0x03
+
+/* Framing (E1) */
+#define PC300_FR_MF_CRC4	0x04
+#define PC300_FR_MF_NON_CRC4	0x05
+#define PC300_FR_UNFRAMED	0x06
+
+#define PC300_LBO_0_DB		0x00
+#define PC300_LBO_7_5_DB	0x01
+#define PC300_LBO_15_DB		0x02
+#define PC300_LBO_22_5_DB	0x03
+
+#define PC300_RX_SENS_SH	0x01
+#define PC300_RX_SENS_LH	0x02
+
+#define PC300_TX_TIMEOUT	(2*HZ)
+#define PC300_TX_QUEUE_LEN	100
+#define	PC300_DEF_MTU		1600
+
+#ifdef __KERNEL__
+/* Function Prototypes */
+int dma_buf_write(pc300_t *, int, ucchar *, int);
+int dma_buf_read(pc300_t *, int, struct sk_buff *);
+void tx_dma_start(pc300_t *, int);
+void rx_dma_start(pc300_t *, int);
+void tx_dma_stop(pc300_t *, int);
+void rx_dma_stop(pc300_t *, int);
+int cpc_queue_xmit(struct sk_buff *, struct net_device *);
+void cpc_net_rx(hdlc_device *);
+void cpc_sca_status(pc300_t *, int);
+int cpc_change_mtu(struct net_device *, int);
+int cpc_ioctl(struct net_device *, struct ifreq *, int);
+int ch_config(pc300dev_t *);
+int rx_config(pc300dev_t *);
+int tx_config(pc300dev_t *);
+void cpc_opench(pc300dev_t *);
+void cpc_closech(pc300dev_t *);
+int cpc_open(struct net_device *dev);
+int cpc_close(struct net_device *dev);
+int cpc_set_media(hdlc_device *, int);
+#endif /* __KERNEL__ */
+
+#endif	/* _PC300_H */
+
diff -urN linux-2.4.24-pre1/drivers/net/wan/pc300_drv.c linux-2.4.24-pre2/drivers/net/wan/pc300_drv.c
--- linux-2.4.24-pre1/drivers/net/wan/pc300_drv.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/wan/pc300_drv.c	2003-12-22 11:34:35.000000000 -0800
@@ -0,0 +1,3487 @@
+#define	USE_PCI_CLOCK
+static char rcsid[] = 
+// Important note:
+// This string must have this exact format, including the space on its end
+"Revision: 4.1.0 Date: 2003/11/19 ";
+
+/*
+ * pc300.c	Cyclades-PC300(tm) Driver.
+ *
+ * Author:	Ivan Passos <ivan.passos@cyclades.com>
+ * Maintainer:	PC300 Maintainer <pc300@cyclades.com>
+ *
+ * Copyright:	(c) 1999-2003 Cyclades Corp.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/net.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+#include <linux/if.h>
+#include <linux/version.h>
+#include <net/arp.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <net/syncppp.h>
+
+#include "pc300.h"
+
+#define	CPC_LOCK(card,flags)		\
+		do {						\
+		spin_lock_irqsave(&card->card_lock, flags);	\
+		} while (0)
+
+#define CPC_UNLOCK(card,flags)			\
+		do {							\
+		spin_unlock_irqrestore(&card->card_lock, flags);	\
+		} while (0)
+
+#undef	PC300_DEBUG_PCI
+#undef	PC300_DEBUG_INTR
+#undef	PC300_DEBUG_TX
+#undef	PC300_DEBUG_RX
+#undef	PC300_DEBUG_OTHER
+
+static struct pci_device_id cpc_pci_dev_id[] __devinitdata = {
+	/* PC300/RSV or PC300/X21, 2 chan */
+	{0x120e, 0x300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x300},
+	/* PC300/RSV or PC300/X21, 1 chan */
+	{0x120e, 0x301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x301},
+	/* PC300/TE, 2 chan */
+	{0x120e, 0x310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x310},
+	/* PC300/TE, 1 chan */
+	{0x120e, 0x311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x311},
+	/* PC300/TE-M, 2 chan */
+	{0x120e, 0x320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x320},
+	/* PC300/TE-M, 1 chan */
+	{0x120e, 0x321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x321},
+	/* End of table */
+	{0,},
+};
+MODULE_DEVICE_TABLE(pci, cpc_pci_dev_id);
+
+#ifndef cpc_min
+#define	cpc_min(a,b)	(((a)<(b))?(a):(b))
+#endif
+#ifndef cpc_max
+#define	cpc_max(a,b)	(((a)>(b))?(a):(b))
+#endif
+
+/* prototypes */
+static void tx_dma_buf_pt_init(pc300_t *, int);
+static void tx_dma_buf_init(pc300_t *, int);
+static void rx_dma_buf_pt_init(pc300_t *, int);
+static void rx_dma_buf_init(pc300_t *, int);
+static void tx_dma_buf_check(pc300_t *, int);
+static void rx_dma_buf_check(pc300_t *, int);
+static void cpc_intr(int, void *, struct pt_regs *);
+static struct net_device_stats *cpc_get_stats(struct net_device *);
+static int clock_rate_calc(uclong, uclong, int *);
+static uclong detect_ram(pc300_t *);
+static void plx_init(pc300_t *);
+static void cpc_trace(struct net_device *, struct sk_buff *, char);
+static int cpc_attach(hdlc_device *, unsigned short, unsigned short);
+
+#ifdef CONFIG_PC300_MLPPP
+void cpc_tty_init(pc300dev_t * dev);
+void cpc_tty_unregister_service(pc300dev_t * pc300dev);
+void cpc_tty_receive(pc300dev_t * pc300dev);
+void cpc_tty_trigger_poll(pc300dev_t * pc300dev);
+void cpc_tty_reset_var(void);
+#endif
+
+/************************/
+/***   DMA Routines   ***/
+/************************/
+static void tx_dma_buf_pt_init(pc300_t * card, int ch)
+{
+	int i;
+	int ch_factor = ch * N_DMA_TX_BUF;
+	volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *) (card->hw.rambase
+			               + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
+
+	for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) {
+		cpc_writel(&ptdescr->next, (uclong) (DMA_TX_BD_BASE +
+			(ch_factor + ((i + 1) & (N_DMA_TX_BUF - 1))) * sizeof(pcsca_bd_t)));
+		cpc_writel(&ptdescr->ptbuf, 
+						(uclong) (DMA_TX_BASE + (ch_factor + i) * BD_DEF_LEN));
+	}
+}
+
+static void tx_dma_buf_init(pc300_t * card, int ch)
+{
+	int i;
+	int ch_factor = ch * N_DMA_TX_BUF;
+	volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *) (card->hw.rambase
+			       + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
+
+	for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) {
+		memset_io(ptdescr, 0, sizeof(pcsca_bd_t));
+		cpc_writew(&ptdescr->len, 0);
+		cpc_writeb(&ptdescr->status, DST_OSB);
+	}
+	tx_dma_buf_pt_init(card, ch);
+}
+
+static void rx_dma_buf_pt_init(pc300_t * card, int ch)
+{
+	int i;
+	int ch_factor = ch * N_DMA_RX_BUF;
+	volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *) (card->hw.rambase
+				       + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
+
+	for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) {
+		cpc_writel(&ptdescr->next, (uclong) (DMA_RX_BD_BASE +
+	     	(ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * sizeof(pcsca_bd_t)));
+		cpc_writel(&ptdescr->ptbuf,
+			   (uclong) (DMA_RX_BASE + (ch_factor + i) * BD_DEF_LEN));
+	}
+}
+
+static void rx_dma_buf_init(pc300_t * card, int ch)
+{
+	int i;
+	int ch_factor = ch * N_DMA_RX_BUF;
+	volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *) (card->hw.rambase
+				       + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
+
+	for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) {
+		memset_io(ptdescr, 0, sizeof(pcsca_bd_t));
+		cpc_writew(&ptdescr->len, 0);
+		cpc_writeb(&ptdescr->status, 0);
+	}
+	rx_dma_buf_pt_init(card, ch);
+}
+
+static void tx_dma_buf_check(pc300_t * card, int ch)
+{
+	volatile pcsca_bd_t *ptdescr;
+	int i;
+	ucshort first_bd = card->chan[ch].tx_first_bd;
+	ucshort next_bd = card->chan[ch].tx_next_bd;
+
+	printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch,
+	       first_bd, TX_BD_ADDR(ch, first_bd),
+	       next_bd, TX_BD_ADDR(ch, next_bd));
+	for (i = first_bd,
+	     ptdescr = (pcsca_bd_t *) (card->hw.rambase + TX_BD_ADDR(ch, first_bd));
+	     i != ((next_bd + 1) & (N_DMA_TX_BUF - 1));
+	     i = (i + 1) & (N_DMA_TX_BUF - 1), 
+		 ptdescr = (pcsca_bd_t *) (card->hw.rambase + TX_BD_ADDR(ch, i))) {
+		printk("\n CH%d TX%d: next=0x%lx, ptbuf=0x%lx, ST=0x%x, len=%d",
+		       ch, i, (uclong) cpc_readl(&ptdescr->next),
+		       (uclong) cpc_readl(&ptdescr->ptbuf),
+		       cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len));
+	}
+	printk("\n");
+}
+
+#ifdef	PC300_DEBUG_OTHER
+/* Show all TX buffer descriptors */
+static void tx1_dma_buf_check(pc300_t * card, int ch)
+{
+	volatile pcsca_bd_t *ptdescr;
+	int i;
+	ucshort first_bd = card->chan[ch].tx_first_bd;
+	ucshort next_bd = card->chan[ch].tx_next_bd;
+	uclong scabase = card->hw.scabase;
+
+	printk ("\nnfree_tx_bd = %d \n", card->chan[ch].nfree_tx_bd);
+	printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch,
+	       first_bd, TX_BD_ADDR(ch, first_bd),
+	       next_bd, TX_BD_ADDR(ch, next_bd));
+	printk("TX_CDA=0x%08lx, TX_EDA=0x%08lx\n",
+	       (uclong) cpc_readl(scabase + DTX_REG(CDAL, ch)),
+	       (uclong) cpc_readl(scabase + DTX_REG(EDAL, ch)));
+	for (i = 0; i < N_DMA_TX_BUF; i++) {
+		ptdescr = (pcsca_bd_t *) (card->hw.rambase + TX_BD_ADDR(ch, i));
+		printk("\n CH%d TX%d: next=0x%lx, ptbuf=0x%lx, ST=0x%x, len=%d",
+		       ch, i, (uclong) cpc_readl(&ptdescr->next),
+		       (uclong) cpc_readl(&ptdescr->ptbuf),
+		       cpc_readb(&ptdescr->status), cpc_readw(&ptdescr->len));
+	}
+	printk("\n");
+}
+#endif
+			 
+static void rx_dma_buf_check(pc300_t * card, int ch)
+{
+	volatile pcsca_bd_t *ptdescr;
+	int i;
+	ucshort first_bd = card->chan[ch].rx_first_bd;
+	ucshort last_bd = card->chan[ch].rx_last_bd;
+	int ch_factor;
+
+	ch_factor = ch * N_DMA_RX_BUF;
+	printk("#CH%d: f_bd = %d, l_bd = %d\n", ch, first_bd, last_bd);
+	for (i = 0, ptdescr = (pcsca_bd_t *) (card->hw.rambase +
+					      DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
+	     i < N_DMA_RX_BUF; i++, ptdescr++) {
+		if (cpc_readb(&ptdescr->status) & DST_OSB)
+			printk ("\n CH%d RX%d: next=0x%lx, ptbuf=0x%lx, ST=0x%x, len=%d",
+				 ch, i, (uclong) cpc_readl(&ptdescr->next),
+				 (uclong) cpc_readl(&ptdescr->ptbuf),
+				 cpc_readb(&ptdescr->status),
+				 cpc_readw(&ptdescr->len));
+	}
+	printk("\n");
+}
+
+int dma_get_rx_frame_size(pc300_t * card, int ch)
+{
+	volatile pcsca_bd_t *ptdescr;
+	ucshort first_bd = card->chan[ch].rx_first_bd;
+	int rcvd = 0;
+	volatile ucchar status;
+
+	ptdescr = (pcsca_bd_t *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd));
+	while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
+		rcvd += cpc_readw(&ptdescr->len);
+		first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1);
+		if ((status & DST_EOM) || (first_bd == card->chan[ch].rx_last_bd)) {
+			/* Return the size of a good frame or incomplete bad frame 
+			* (dma_buf_read will clean the buffer descriptors in this case). */
+			return (rcvd);
+		}
+		ptdescr = (pcsca_bd_t *)(card->hw.rambase + cpc_readl(&ptdescr->next));
+	}
+	return (-1);
+}
+
+/*
+ * dma_buf_write: writes a frame to the Tx DMA buffers
+ * NOTE: this function writes one frame at a time.
+ */
+int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
+{
+	int i, nchar;
+	volatile pcsca_bd_t *ptdescr;
+	int tosend = len;
+	ucchar nbuf = ((len - 1) / BD_DEF_LEN) + 1;
+
+	if (nbuf >= card->chan[ch].nfree_tx_bd) {
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < nbuf; i++) {
+		ptdescr = (pcsca_bd_t *) (card->hw.rambase +
+					  TX_BD_ADDR(ch, card->chan[ch].tx_next_bd));
+		nchar = cpc_min(BD_DEF_LEN, tosend);
+		if (cpc_readb(&ptdescr->status) & DST_OSB) {
+			memcpy_toio((void *)(card->hw.rambase + cpc_readl(&ptdescr->ptbuf)),
+				    &ptdata[len - tosend], nchar);
+			cpc_writew(&ptdescr->len, nchar);
+			card->chan[ch].nfree_tx_bd--;
+			if ((i + 1) == nbuf) {
+				/* This must be the last BD to be used */
+				cpc_writeb(&ptdescr->status, DST_EOM);
+			} else {
+				cpc_writeb(&ptdescr->status, 0);
+			}
+		} else {
+			return -ENOMEM;
+		}
+		tosend -= nchar;
+		card->chan[ch].tx_next_bd =
+			(card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1);
+	}
+	/* If it gets to here, it means we have sent the whole frame */
+	return 0;
+}
+
+/*
+ * dma_buf_read: reads a frame from the Rx DMA buffers
+ * NOTE: this function reads one frame at a time.
+ */
+int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
+{
+	int nchar;
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	volatile pcsca_bd_t *ptdescr;
+	int rcvd = 0;
+	volatile ucchar status;
+
+	ptdescr = (pcsca_bd_t *) (card->hw.rambase +
+				  RX_BD_ADDR(ch, chan->rx_first_bd));
+	while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
+		nchar = cpc_readw(&ptdescr->len);
+		if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT))
+		    || (nchar > BD_DEF_LEN)) {
+
+			if (nchar > BD_DEF_LEN)
+				status |= DST_RBIT;
+			rcvd = -status;
+			/* Discard remaining descriptors used by the bad frame */
+			while (chan->rx_first_bd != chan->rx_last_bd) {
+				cpc_writeb(&ptdescr->status, 0);
+				chan->rx_first_bd = (chan->rx_first_bd+1) & (N_DMA_RX_BUF-1);
+				if (status & DST_EOM)
+					break;
+				ptdescr = (pcsca_bd_t *) (card->hw.rambase +
+							  cpc_readl(&ptdescr->next));
+				status = cpc_readb(&ptdescr->status);
+			}
+			break;
+		}
+		if (nchar != 0) {
+			if (skb) {
+				memcpy_fromio(skb_put(skb, nchar),
+				 (void *)(card->hw.rambase+cpc_readl(&ptdescr->ptbuf)),nchar);
+			}
+			rcvd += nchar;
+		}
+		cpc_writeb(&ptdescr->status, 0);
+		cpc_writeb(&ptdescr->len, 0);
+		chan->rx_first_bd = (chan->rx_first_bd + 1) & (N_DMA_RX_BUF - 1);
+
+		if (status & DST_EOM)
+			break;
+
+		ptdescr = (pcsca_bd_t *) (card->hw.rambase + cpc_readl(&ptdescr->next));
+	}
+
+	if (rcvd != 0) {
+		/* Update pointer */
+		chan->rx_last_bd = (chan->rx_first_bd - 1) & (N_DMA_RX_BUF - 1);
+		/* Update EDA */
+		cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch),
+			   RX_BD_ADDR(ch, chan->rx_last_bd));
+	}
+	return (rcvd);
+}
+
+void tx_dma_stop(pc300_t * card, int ch)
+{
+	uclong scabase = card->hw.scabase;
+	ucchar drr_ena_bit = 1 << (5 + 2 * ch);
+	ucchar drr_rst_bit = 1 << (1 + 2 * ch);
+
+	/* Disable DMA */
+	cpc_writeb(scabase + DRR, drr_ena_bit);
+	cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
+}
+
+void rx_dma_stop(pc300_t * card, int ch)
+{
+	uclong scabase = card->hw.scabase;
+	ucchar drr_ena_bit = 1 << (4 + 2 * ch);
+	ucchar drr_rst_bit = 1 << (2 * ch);
+
+	/* Disable DMA */
+	cpc_writeb(scabase + DRR, drr_ena_bit);
+	cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
+}
+
+void rx_dma_start(pc300_t * card, int ch)
+{
+	uclong scabase = card->hw.scabase;
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	
+	/* Start DMA */
+	cpc_writel(scabase + DRX_REG(CDAL, ch),
+		   RX_BD_ADDR(ch, chan->rx_first_bd));
+	if (cpc_readl(scabase + DRX_REG(CDAL,ch)) !=
+				  RX_BD_ADDR(ch, chan->rx_first_bd)) {
+		cpc_writel(scabase + DRX_REG(CDAL, ch),
+				   RX_BD_ADDR(ch, chan->rx_first_bd));
+	}
+	cpc_writel(scabase + DRX_REG(EDAL, ch),
+		   RX_BD_ADDR(ch, chan->rx_last_bd));
+	cpc_writew(scabase + DRX_REG(BFLL, ch), BD_DEF_LEN);
+	cpc_writeb(scabase + DSR_RX(ch), DSR_DE);
+	if (!(cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) {
+	cpc_writeb(scabase + DSR_RX(ch), DSR_DE);
+	}
+}
+
+/*************************/
+/***   FALC Routines   ***/
+/*************************/
+void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
+{
+	uclong falcbase = card->hw.falcbase;
+	unsigned long i = 0;
+
+	while (cpc_readb(falcbase + F_REG(SIS, ch)) & SIS_CEC) {
+		if (i++ >= PC300_FALC_MAXLOOP) {
+			printk("%s: FALC command locked(cmd=0x%x).\n",
+			       card->chan[ch].d.name, cmd);
+			break;
+		}
+	}
+	cpc_writeb(falcbase + F_REG(CMDR, ch), cmd);
+}
+
+void falc_intr_enable(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	/* Interrupt pins are open-drain */
+	cpc_writeb(falcbase + F_REG(IPC, ch),
+		   cpc_readb(falcbase + F_REG(IPC, ch)) & ~IPC_IC0);
+	/* Conters updated each second */
+	cpc_writeb(falcbase + F_REG(FMR1, ch),
+		   cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_ECM);
+	/* Enable SEC and ES interrupts  */
+	cpc_writeb(falcbase + F_REG(IMR3, ch),
+		   cpc_readb(falcbase + F_REG(IMR3, ch)) & ~(IMR3_SEC | IMR3_ES));
+	if (conf->fr_mode == PC300_FR_UNFRAMED) {
+		cpc_writeb(falcbase + F_REG(IMR4, ch),
+			   cpc_readb(falcbase + F_REG(IMR4, ch)) & ~(IMR4_LOS));
+	} else {
+		cpc_writeb(falcbase + F_REG(IMR4, ch),
+			   cpc_readb(falcbase + F_REG(IMR4, ch)) &
+			   ~(IMR4_LFA | IMR4_AIS | IMR4_LOS | IMR4_SLIP));
+	}
+	if (conf->media == IF_IFACE_T1) {
+		cpc_writeb(falcbase + F_REG(IMR3, ch),
+			   cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC);
+	} else {
+		cpc_writeb(falcbase + F_REG(IPC, ch),
+			   cpc_readb(falcbase + F_REG(IPC, ch)) | IPC_SCI);
+		if (conf->fr_mode == PC300_FR_UNFRAMED) {
+			cpc_writeb(falcbase + F_REG(IMR2, ch),
+				   cpc_readb(falcbase + F_REG(IMR2, ch)) & ~(IMR2_LOS));
+		} else {
+			cpc_writeb(falcbase + F_REG(IMR2, ch),
+				   cpc_readb(falcbase + F_REG(IMR2, ch)) &
+				   ~(IMR2_FAR | IMR2_LFA | IMR2_AIS | IMR2_LOS));
+			if (pfalc->multiframe_mode) {
+				cpc_writeb(falcbase + F_REG(IMR2, ch),
+					   cpc_readb(falcbase + F_REG(IMR2, ch)) & 
+					   ~(IMR2_T400MS | IMR2_MFAR));
+			} else {
+				cpc_writeb(falcbase + F_REG(IMR2, ch),
+					   cpc_readb(falcbase + F_REG(IMR2, ch)) | 
+					   IMR2_T400MS | IMR2_MFAR);
+			}
+		}
+	}
+}
+
+void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
+{
+	uclong falcbase = card->hw.falcbase;
+	ucchar tshf = card->chan[ch].falc.offset;
+
+	cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch),
+		   cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) & 
+		   	~(0x80 >> ((timeslot - tshf) & 0x07)));
+	cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch),
+		   cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) | 
+   			(0x80 >> (timeslot & 0x07)));
+	cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch),
+		   cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) | 
+			(0x80 >> (timeslot & 0x07)));
+}
+
+void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
+{
+	uclong falcbase = card->hw.falcbase;
+	ucchar tshf = card->chan[ch].falc.offset;
+
+	cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch),
+		   cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) | 
+		   (0x80 >> ((timeslot - tshf) & 0x07)));
+	cpc_writeb(falcbase + F_REG((TTR1 + timeslot / 8), ch),
+		   cpc_readb(falcbase + F_REG((TTR1 + timeslot / 8), ch)) & 
+		   ~(0x80 >> (timeslot & 0x07)));
+	cpc_writeb(falcbase + F_REG((RTR1 + timeslot / 8), ch),
+		   cpc_readb(falcbase + F_REG((RTR1 + timeslot / 8), ch)) & 
+		   ~(0x80 >> (timeslot & 0x07)));
+}
+
+void falc_close_all_timeslots(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	uclong falcbase = card->hw.falcbase;
+
+	cpc_writeb(falcbase + F_REG(ICB1, ch), 0xff);
+	cpc_writeb(falcbase + F_REG(TTR1, ch), 0);
+	cpc_writeb(falcbase + F_REG(RTR1, ch), 0);
+	cpc_writeb(falcbase + F_REG(ICB2, ch), 0xff);
+	cpc_writeb(falcbase + F_REG(TTR2, ch), 0);
+	cpc_writeb(falcbase + F_REG(RTR2, ch), 0);
+	cpc_writeb(falcbase + F_REG(ICB3, ch), 0xff);
+	cpc_writeb(falcbase + F_REG(TTR3, ch), 0);
+	cpc_writeb(falcbase + F_REG(RTR3, ch), 0);
+	if (conf->media == IF_IFACE_E1) {
+		cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff);
+		cpc_writeb(falcbase + F_REG(TTR4, ch), 0);
+		cpc_writeb(falcbase + F_REG(RTR4, ch), 0);
+	}
+}
+
+void falc_open_all_timeslots(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	uclong falcbase = card->hw.falcbase;
+
+	cpc_writeb(falcbase + F_REG(ICB1, ch), 0);
+	if (conf->fr_mode == PC300_FR_UNFRAMED) {
+		cpc_writeb(falcbase + F_REG(TTR1, ch), 0xff);
+		cpc_writeb(falcbase + F_REG(RTR1, ch), 0xff);
+	} else {
+		/* Timeslot 0 is never enabled */
+		cpc_writeb(falcbase + F_REG(TTR1, ch), 0x7f);
+		cpc_writeb(falcbase + F_REG(RTR1, ch), 0x7f);
+	}
+	cpc_writeb(falcbase + F_REG(ICB2, ch), 0);
+	cpc_writeb(falcbase + F_REG(TTR2, ch), 0xff);
+	cpc_writeb(falcbase + F_REG(RTR2, ch), 0xff);
+	cpc_writeb(falcbase + F_REG(ICB3, ch), 0);
+	cpc_writeb(falcbase + F_REG(TTR3, ch), 0xff);
+	cpc_writeb(falcbase + F_REG(RTR3, ch), 0xff);
+	if (conf->media == IF_IFACE_E1) {
+		cpc_writeb(falcbase + F_REG(ICB4, ch), 0);
+		cpc_writeb(falcbase + F_REG(TTR4, ch), 0xff);
+		cpc_writeb(falcbase + F_REG(RTR4, ch), 0xff);
+	} else {
+		cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff);
+		cpc_writeb(falcbase + F_REG(TTR4, ch), 0x80);
+		cpc_writeb(falcbase + F_REG(RTR4, ch), 0x80);
+	}
+}
+
+void falc_init_timeslot(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	int tslot;
+
+	for (tslot = 0; tslot < pfalc->num_channels; tslot++) {
+		if (conf->tslot_bitmap & (1 << tslot)) {
+			// Channel enabled
+			falc_open_timeslot(card, ch, tslot + 1);
+		} else {
+			// Channel disabled
+			falc_close_timeslot(card, ch, tslot + 1);
+		}
+	}
+}
+
+void falc_enable_comm(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	falc_t *pfalc = (falc_t *) & chan->falc;
+
+	if (pfalc->full_bandwidth) {
+		falc_open_all_timeslots(card, ch);
+	} else {
+		falc_init_timeslot(card, ch);
+	}
+	// CTS/DCD ON
+	cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1,
+		   cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) &
+		   ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
+}
+
+void falc_disable_comm(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	falc_t *pfalc = (falc_t *) & chan->falc;
+
+	if (pfalc->loop_active != 2) {
+		falc_close_all_timeslots(card, ch);
+	}
+	// CTS/DCD OFF
+	cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1,
+		   cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) |
+		   ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
+}
+
+void falc_init_t1(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+	ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0);
+
+	/* Switch to T1 mode (PCM 24) */
+	cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD);
+
+	/* Wait 20 us for setup */
+	udelay(20);
+
+	/* Transmit Buffer Size (1 frame) */
+	cpc_writeb(falcbase + F_REG(SIC1, ch), SIC1_XBS0);
+
+	/* Clock mode */
+	if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */
+		cpc_writeb(falcbase + F_REG(LIM0, ch),
+			   cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS);
+	} else { /* Slave mode */
+		cpc_writeb(falcbase + F_REG(LIM0, ch),
+			   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS);
+		cpc_writeb(falcbase + F_REG(LOOP, ch),
+			   cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_RTM);
+	}
+
+	cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI);
+	cpc_writeb(falcbase + F_REG(FMR0, ch),
+		   cpc_readb(falcbase + F_REG(FMR0, ch)) &
+		   ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1));
+
+	switch (conf->lcode) {
+		case PC300_LC_AMI:
+			cpc_writeb(falcbase + F_REG(FMR0, ch),
+				   cpc_readb(falcbase + F_REG(FMR0, ch)) |
+				   FMR0_XC1 | FMR0_RC1);
+			/* Clear Channel register to ON for all channels */
+			cpc_writeb(falcbase + F_REG(CCB1, ch), 0xff);
+			cpc_writeb(falcbase + F_REG(CCB2, ch), 0xff);
+			cpc_writeb(falcbase + F_REG(CCB3, ch), 0xff);
+			break;
+
+		case PC300_LC_B8ZS:
+			cpc_writeb(falcbase + F_REG(FMR0, ch),
+				   cpc_readb(falcbase + F_REG(FMR0, ch)) |
+				   FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1);
+			break;
+
+		case PC300_LC_NRZ:
+			cpc_writeb(falcbase + F_REG(FMR0, ch),
+				   cpc_readb(falcbase + F_REG(FMR0, ch)) | 0x00);
+			break;
+	}
+
+	cpc_writeb(falcbase + F_REG(LIM0, ch),
+		   cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_ELOS);
+	cpc_writeb(falcbase + F_REG(LIM0, ch),
+		   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0));
+	/* Set interface mode to 2 MBPS */
+	cpc_writeb(falcbase + F_REG(FMR1, ch),
+		   cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD);
+
+	switch (conf->fr_mode) {
+		case PC300_FR_ESF:
+			pfalc->multiframe_mode = 0;
+			cpc_writeb(falcbase + F_REG(FMR4, ch),
+				   cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_FM1);
+			cpc_writeb(falcbase + F_REG(FMR1, ch),
+				   cpc_readb(falcbase + F_REG(FMR1, ch)) | 
+				   FMR1_CRC | FMR1_EDL);
+			cpc_writeb(falcbase + F_REG(XDL1, ch), 0);
+			cpc_writeb(falcbase + F_REG(XDL2, ch), 0);
+			cpc_writeb(falcbase + F_REG(XDL3, ch), 0);
+			cpc_writeb(falcbase + F_REG(FMR0, ch),
+				   cpc_readb(falcbase + F_REG(FMR0, ch)) & ~FMR0_SRAF);
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2,ch)) | FMR2_MCSP | FMR2_SSP);
+			break;
+
+		case PC300_FR_D4:
+			pfalc->multiframe_mode = 1;
+			cpc_writeb(falcbase + F_REG(FMR4, ch),
+				   cpc_readb(falcbase + F_REG(FMR4, ch)) &
+				   ~(FMR4_FM1 | FMR4_FM0));
+			cpc_writeb(falcbase + F_REG(FMR0, ch),
+				   cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_SRAF);
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_SSP);
+			break;
+	}
+
+	/* Enable Automatic Resynchronization */
+	cpc_writeb(falcbase + F_REG(FMR4, ch),
+		   cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_AUTO);
+
+	/* Transmit Automatic Remote Alarm */
+	cpc_writeb(falcbase + F_REG(FMR2, ch),
+		   cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA);
+
+	/* Channel translation mode 1 : one to one */
+	cpc_writeb(falcbase + F_REG(FMR1, ch),
+		   cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_CTM);
+
+	/* No signaling */
+	cpc_writeb(falcbase + F_REG(FMR1, ch),
+		   cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_SIGM);
+	cpc_writeb(falcbase + F_REG(FMR5, ch),
+		   cpc_readb(falcbase + F_REG(FMR5, ch)) &
+		   ~(FMR5_EIBR | FMR5_SRS));
+	cpc_writeb(falcbase + F_REG(CCR1, ch), 0);
+
+	cpc_writeb(falcbase + F_REG(LIM1, ch),
+		   cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1);
+
+	switch (conf->lbo) {
+			/* Provides proper Line Build Out */
+		case PC300_LBO_0_DB:
+			cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja));
+			cpc_writeb(falcbase + F_REG(XPM0, ch), 0x5a);
+			cpc_writeb(falcbase + F_REG(XPM1, ch), 0x8f);
+			cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20);
+			break;
+		case PC300_LBO_7_5_DB:
+			cpc_writeb(falcbase + F_REG(LIM2, ch), (0x40 | LIM2_LOS1 | dja));
+			cpc_writeb(falcbase + F_REG(XPM0, ch), 0x11);
+			cpc_writeb(falcbase + F_REG(XPM1, ch), 0x02);
+			cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20);
+			break;
+		case PC300_LBO_15_DB:
+			cpc_writeb(falcbase + F_REG(LIM2, ch), (0x80 | LIM2_LOS1 | dja));
+			cpc_writeb(falcbase + F_REG(XPM0, ch), 0x8e);
+			cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01);
+			cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20);
+			break;
+		case PC300_LBO_22_5_DB:
+			cpc_writeb(falcbase + F_REG(LIM2, ch), (0xc0 | LIM2_LOS1 | dja));
+			cpc_writeb(falcbase + F_REG(XPM0, ch), 0x09);
+			cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01);
+			cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20);
+			break;
+	}
+
+	/* Transmit Clock-Slot Offset */
+	cpc_writeb(falcbase + F_REG(XC0, ch),
+		   cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01);
+	/* Transmit Time-slot Offset */
+	cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e);
+	/* Receive  Clock-Slot offset */
+	cpc_writeb(falcbase + F_REG(RC0, ch), 0x05);
+	/* Receive  Time-slot offset */
+	cpc_writeb(falcbase + F_REG(RC1, ch), 0x00);
+
+	/* LOS Detection after 176 consecutive 0s */
+	cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a);
+	/* LOS Recovery after 22 ones in the time window of PCD */
+	cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15);
+
+	cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f);
+
+	if (conf->fr_mode == PC300_FR_ESF_JAPAN) {
+		cpc_writeb(falcbase + F_REG(RC1, ch),
+			   cpc_readb(falcbase + F_REG(RC1, ch)) | 0x80);
+	}
+
+	falc_close_all_timeslots(card, ch);
+}
+
+void falc_init_e1(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+	ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0);
+
+	/* Switch to E1 mode (PCM 30) */
+	cpc_writeb(falcbase + F_REG(FMR1, ch),
+		   cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_PMOD);
+
+	/* Clock mode */
+	if (conf->phys_settings.clock_type == CLOCK_INT) { /* Master mode */
+		cpc_writeb(falcbase + F_REG(LIM0, ch),
+			   cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS);
+	} else { /* Slave mode */
+		cpc_writeb(falcbase + F_REG(LIM0, ch),
+			   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS);
+	}
+	cpc_writeb(falcbase + F_REG(LOOP, ch),
+		   cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_SFM);
+
+	cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI);
+	cpc_writeb(falcbase + F_REG(FMR0, ch),
+		   cpc_readb(falcbase + F_REG(FMR0, ch)) &
+		   ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1));
+
+	switch (conf->lcode) {
+		case PC300_LC_AMI:
+			cpc_writeb(falcbase + F_REG(FMR0, ch),
+				   cpc_readb(falcbase + F_REG(FMR0, ch)) |
+				   FMR0_XC1 | FMR0_RC1);
+			break;
+
+		case PC300_LC_HDB3:
+			cpc_writeb(falcbase + F_REG(FMR0, ch),
+				   cpc_readb(falcbase + F_REG(FMR0, ch)) |
+				   FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1);
+			break;
+
+		case PC300_LC_NRZ:
+			break;
+	}
+
+	cpc_writeb(falcbase + F_REG(LIM0, ch),
+		   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~(LIM0_SCL1 | LIM0_SCL0));
+	/* Set interface mode to 2 MBPS */
+	cpc_writeb(falcbase + F_REG(FMR1, ch),
+		   cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD);
+
+	cpc_writeb(falcbase + F_REG(XPM0, ch), 0x18);
+	cpc_writeb(falcbase + F_REG(XPM1, ch), 0x03);
+	cpc_writeb(falcbase + F_REG(XPM2, ch), 0x00);
+
+	switch (conf->fr_mode) {
+		case PC300_FR_MF_CRC4:
+			pfalc->multiframe_mode = 1;
+			cpc_writeb(falcbase + F_REG(FMR1, ch),
+				   cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_XFS);
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_RFS1);
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_RFS0);
+			cpc_writeb(falcbase + F_REG(FMR3, ch),
+				   cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_EXTIW);
+
+			/* MultiFrame Resynchronization */
+			cpc_writeb(falcbase + F_REG(FMR1, ch),
+				   cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_MFCS);
+
+			/* Automatic Loss of Multiframe > 914 CRC errors */
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_ALMF);
+
+			/* S1 and SI1/SI2 spare Bits set to 1 */
+			cpc_writeb(falcbase + F_REG(XSP, ch),
+				   cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_AXS);
+			cpc_writeb(falcbase + F_REG(XSP, ch),
+				   cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_EBP);
+			cpc_writeb(falcbase + F_REG(XSP, ch),
+				   cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XS13 | XSP_XS15);
+
+			/* Automatic Force Resynchronization */
+			cpc_writeb(falcbase + F_REG(FMR1, ch),
+				   cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR);
+
+			/* Transmit Automatic Remote Alarm */
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA);
+
+			/* Transmit Spare Bits for National Use (Y, Sn, Sa) */
+			cpc_writeb(falcbase + F_REG(XSW, ch),
+				   cpc_readb(falcbase + F_REG(XSW, ch)) |
+				   XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4);
+			break;
+
+		case PC300_FR_MF_NON_CRC4:
+		case PC300_FR_D4:
+			pfalc->multiframe_mode = 0;
+			cpc_writeb(falcbase + F_REG(FMR1, ch),
+				   cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS);
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) & 
+				   ~(FMR2_RFS1 | FMR2_RFS0));
+			cpc_writeb(falcbase + F_REG(XSW, ch),
+				   cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XSIS);
+			cpc_writeb(falcbase + F_REG(XSP, ch),
+				   cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XSIF);
+
+			/* Automatic Force Resynchronization */
+			cpc_writeb(falcbase + F_REG(FMR1, ch),
+				   cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR);
+
+			/* Transmit Automatic Remote Alarm */
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA);
+
+			/* Transmit Spare Bits for National Use (Y, Sn, Sa) */
+			cpc_writeb(falcbase + F_REG(XSW, ch),
+				   cpc_readb(falcbase + F_REG(XSW, ch)) |
+				   XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4);
+			break;
+
+		case PC300_FR_UNFRAMED:
+			pfalc->multiframe_mode = 0;
+			cpc_writeb(falcbase + F_REG(FMR1, ch),
+				   cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS);
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) & 
+				   ~(FMR2_RFS1 | FMR2_RFS0));
+			cpc_writeb(falcbase + F_REG(XSP, ch),
+				   cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_TT0);
+			cpc_writeb(falcbase + F_REG(XSW, ch),
+				   cpc_readb(falcbase + F_REG(XSW, ch)) & 
+				   ~(XSW_XTM|XSW_XY0|XSW_XY1|XSW_XY2|XSW_XY3|XSW_XY4));
+			cpc_writeb(falcbase + F_REG(TSWM, ch), 0xff);
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) |
+				   (FMR2_RTM | FMR2_DAIS));
+			cpc_writeb(falcbase + F_REG(FMR2, ch),
+				   cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_AXRA);
+			cpc_writeb(falcbase + F_REG(FMR1, ch),
+				   cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_AFR);
+			pfalc->sync = 1;
+			cpc_writeb(falcbase + card->hw.cpld_reg2,
+				   cpc_readb(falcbase + card->hw.cpld_reg2) |
+				   (CPLD_REG2_FALC_LED2 << (2 * ch)));
+			break;
+	}
+
+	/* No signaling */
+	cpc_writeb(falcbase + F_REG(XSP, ch),
+		   cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_CASEN);
+	cpc_writeb(falcbase + F_REG(CCR1, ch), 0);
+
+	cpc_writeb(falcbase + F_REG(LIM1, ch),
+		   cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1);
+	cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja));
+
+	/* Transmit Clock-Slot Offset */
+	cpc_writeb(falcbase + F_REG(XC0, ch),
+		   cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01);
+	/* Transmit Time-slot Offset */
+	cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e);
+	/* Receive  Clock-Slot offset */
+	cpc_writeb(falcbase + F_REG(RC0, ch), 0x05);
+	/* Receive  Time-slot offset */
+	cpc_writeb(falcbase + F_REG(RC1, ch), 0x00);
+
+	/* LOS Detection after 176 consecutive 0s */
+	cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a);
+	/* LOS Recovery after 22 ones in the time window of PCD */
+	cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15);
+
+	cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f);
+
+	falc_close_all_timeslots(card, ch);
+}
+
+void falc_init_hdlc(pc300_t * card, int ch)
+{
+	uclong falcbase = card->hw.falcbase;
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+
+	/* Enable transparent data transfer */
+	if (conf->fr_mode == PC300_FR_UNFRAMED) {
+		cpc_writeb(falcbase + F_REG(MODE, ch), 0);
+	} else {
+		cpc_writeb(falcbase + F_REG(MODE, ch),
+			   cpc_readb(falcbase + F_REG(MODE, ch)) |
+			   (MODE_HRAC | MODE_MDS2));
+		cpc_writeb(falcbase + F_REG(RAH2, ch), 0xff);
+		cpc_writeb(falcbase + F_REG(RAH1, ch), 0xff);
+		cpc_writeb(falcbase + F_REG(RAL2, ch), 0xff);
+		cpc_writeb(falcbase + F_REG(RAL1, ch), 0xff);
+	}
+
+	/* Tx/Rx reset  */
+	falc_issue_cmd(card, ch, CMDR_RRES | CMDR_XRES | CMDR_SRES);
+
+	/* Enable interrupt sources */
+	falc_intr_enable(card, ch);
+}
+
+void te_config(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+	ucchar dummy;
+	unsigned long flags;
+
+	memset(pfalc, 0, sizeof(falc_t));
+	switch (conf->media) {
+		case IF_IFACE_T1:
+			pfalc->num_channels = NUM_OF_T1_CHANNELS;
+			pfalc->offset = 1;
+			break;
+		case IF_IFACE_E1:
+			pfalc->num_channels = NUM_OF_E1_CHANNELS;
+			pfalc->offset = 0;
+			break;
+	}
+	if (conf->tslot_bitmap == 0xffffffffUL)
+		pfalc->full_bandwidth = 1;
+	else
+		pfalc->full_bandwidth = 0;
+
+	CPC_LOCK(card, flags);
+	/* Reset the FALC chip */
+	cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1,
+		   cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) |
+		   (CPLD_REG1_FALC_RESET << (2 * ch)));
+	udelay(10000);
+	cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1,
+		   cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) &
+		   ~(CPLD_REG1_FALC_RESET << (2 * ch)));
+
+	if (conf->media == IF_IFACE_T1) {
+		falc_init_t1(card, ch);
+	} else {
+		falc_init_e1(card, ch);
+	}
+	falc_init_hdlc(card, ch);
+	if (conf->rx_sens == PC300_RX_SENS_SH) {
+		cpc_writeb(falcbase + F_REG(LIM0, ch),
+			   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_EQON);
+	} else {
+		cpc_writeb(falcbase + F_REG(LIM0, ch),
+			   cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_EQON);
+	}
+	cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,
+		   cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) |
+		   ((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK) << (2 * ch)));
+
+	/* Clear all interrupt registers */
+	dummy = cpc_readb(falcbase + F_REG(FISR0, ch)) +
+		cpc_readb(falcbase + F_REG(FISR1, ch)) +
+		cpc_readb(falcbase + F_REG(FISR2, ch)) +
+		cpc_readb(falcbase + F_REG(FISR3, ch));
+	CPC_UNLOCK(card, flags);
+}
+
+void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	/* Verify LOS */
+	if (frs0 & FRS0_LOS) {
+		if (!pfalc->red_alarm) {
+			pfalc->red_alarm = 1;
+			pfalc->los++;
+			if (!pfalc->blue_alarm) {
+				// EVENT_FALC_ABNORMAL
+				if (conf->media == IF_IFACE_T1) {
+					/* Disable this interrupt as it may otherwise interfere 
+					 * with other working boards. */
+					cpc_writeb(falcbase + F_REG(IMR0, ch), 
+						   cpc_readb(falcbase + F_REG(IMR0, ch))
+						   | IMR0_PDEN);
+				}
+				falc_disable_comm(card, ch);
+				// EVENT_FALC_ABNORMAL
+			}
+		}
+	} else {
+		if (pfalc->red_alarm) {
+			pfalc->red_alarm = 0;
+			pfalc->losr++;
+		}
+	}
+
+	if (conf->fr_mode != PC300_FR_UNFRAMED) {
+		/* Verify AIS alarm */
+		if (frs0 & FRS0_AIS) {
+			if (!pfalc->blue_alarm) {
+				pfalc->blue_alarm = 1;
+				pfalc->ais++;
+				// EVENT_AIS
+				if (conf->media == IF_IFACE_T1) {
+					/* Disable this interrupt as it may otherwise interfere with                       other working boards. */
+					cpc_writeb(falcbase + F_REG(IMR0, ch),
+						   cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN);
+				}
+				falc_disable_comm(card, ch);
+				// EVENT_AIS
+			}
+		} else {
+			pfalc->blue_alarm = 0;
+		}
+
+		/* Verify LFA */
+		if (frs0 & FRS0_LFA) {
+			if (!pfalc->loss_fa) {
+				pfalc->loss_fa = 1;
+				pfalc->lfa++;
+				if (!pfalc->blue_alarm && !pfalc->red_alarm) {
+					// EVENT_FALC_ABNORMAL
+					if (conf->media == IF_IFACE_T1) {
+						/* Disable this interrupt as it may otherwise 
+						 * interfere with other working boards. */
+						cpc_writeb(falcbase + F_REG(IMR0, ch),
+							   cpc_readb(falcbase + F_REG(IMR0, ch))
+							   | IMR0_PDEN);
+					}
+					falc_disable_comm(card, ch);
+					// EVENT_FALC_ABNORMAL
+				}
+			}
+		} else {
+			if (pfalc->loss_fa) {
+				pfalc->loss_fa = 0;
+				pfalc->farec++;
+			}
+		}
+
+		/* Verify LMFA */
+		if (pfalc->multiframe_mode && (frs0 & FRS0_LMFA)) {
+			/* D4 or CRC4 frame mode */
+			if (!pfalc->loss_mfa) {
+				pfalc->loss_mfa = 1;
+				pfalc->lmfa++;
+				if (!pfalc->blue_alarm && !pfalc->red_alarm &&
+				    !pfalc->loss_fa) {
+					// EVENT_FALC_ABNORMAL
+					if (conf->media == IF_IFACE_T1) {
+						/* Disable this interrupt as it may otherwise 
+						 * interfere with other working boards. */
+						cpc_writeb(falcbase + F_REG(IMR0, ch),
+							   cpc_readb(falcbase + F_REG(IMR0, ch))
+							   | IMR0_PDEN);
+					}
+					falc_disable_comm(card, ch);
+					// EVENT_FALC_ABNORMAL
+				}
+			}
+		} else {
+			pfalc->loss_mfa = 0;
+		}
+
+		/* Verify Remote Alarm */
+		if (frs0 & FRS0_RRA) {
+			if (!pfalc->yellow_alarm) {
+				pfalc->yellow_alarm = 1;
+				pfalc->rai++;
+				if (pfalc->sync) {
+					// EVENT_RAI
+					falc_disable_comm(card, ch);
+					// EVENT_RAI
+				}
+			}
+		} else {
+			pfalc->yellow_alarm = 0;
+		}
+	} /* if !PC300_UNFRAMED */
+
+	if (pfalc->red_alarm || pfalc->loss_fa ||
+	    pfalc->loss_mfa || pfalc->blue_alarm) {
+		if (pfalc->sync) {
+			pfalc->sync = 0;
+			chan->d.line_off++;
+			cpc_writeb(falcbase + card->hw.cpld_reg2,
+				   cpc_readb(falcbase + card->hw.cpld_reg2) &
+				   ~(CPLD_REG2_FALC_LED2 << (2 * ch)));
+		}
+	} else {
+		if (!pfalc->sync) {
+			pfalc->sync = 1;
+			chan->d.line_on++;
+			cpc_writeb(falcbase + card->hw.cpld_reg2,
+				   cpc_readb(falcbase + card->hw.cpld_reg2) |
+				   (CPLD_REG2_FALC_LED2 << (2 * ch)));
+		}
+	}
+
+	if (pfalc->sync && !pfalc->yellow_alarm) {
+		if (!pfalc->active) {
+			// EVENT_FALC_NORMAL
+			if (pfalc->loop_active) {
+				return;
+			}
+			if (conf->media == IF_IFACE_T1) {
+				cpc_writeb(falcbase + F_REG(IMR0, ch),
+					   cpc_readb(falcbase + F_REG(IMR0, ch)) & ~IMR0_PDEN);
+			}
+			falc_enable_comm(card, ch);
+			// EVENT_FALC_NORMAL
+			pfalc->active = 1;
+		}
+	} else {
+		if (pfalc->active) {
+			pfalc->active = 0;
+		}
+	}
+}
+
+void falc_update_stats(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+	ucshort counter;
+
+	counter = cpc_readb(falcbase + F_REG(FECL, ch));
+	counter |= cpc_readb(falcbase + F_REG(FECH, ch)) << 8;
+	pfalc->fec += counter;
+
+	counter = cpc_readb(falcbase + F_REG(CVCL, ch));
+	counter |= cpc_readb(falcbase + F_REG(CVCH, ch)) << 8;
+	pfalc->cvc += counter;
+
+	counter = cpc_readb(falcbase + F_REG(CECL, ch));
+	counter |= cpc_readb(falcbase + F_REG(CECH, ch)) << 8;
+	pfalc->cec += counter;
+
+	counter = cpc_readb(falcbase + F_REG(EBCL, ch));
+	counter |= cpc_readb(falcbase + F_REG(EBCH, ch)) << 8;
+	pfalc->ebc += counter;
+
+	if (cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) {
+		mdelay(10);
+		counter = cpc_readb(falcbase + F_REG(BECL, ch));
+		counter |= cpc_readb(falcbase + F_REG(BECH, ch)) << 8;
+		pfalc->bec += counter;
+
+		if (((conf->media == IF_IFACE_T1) &&
+		     (cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_LLBAD) &&
+		     (!(cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_PDEN)))
+		    ||
+		    ((conf->media == IF_IFACE_E1) &&
+		     (cpc_readb(falcbase + F_REG(RSP, ch)) & RSP_LLBAD))) {
+			pfalc->prbs = 2;
+		} else {
+			pfalc->prbs = 1;
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * falc_remote_loop
+ *----------------------------------------------------------------------------
+ * Description:	In the remote loopback mode the clock and data recovered
+ *		from the line inputs RL1/2 or RDIP/RDIN are routed back
+ *		to the line outputs XL1/2 or XDOP/XDON via the analog
+ *		transmitter. As in normal mode they are processsed by
+ *		the synchronizer and then sent to the system interface.
+ *----------------------------------------------------------------------------
+ */
+void falc_remote_loop(pc300_t * card, int ch, int loop_on)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	if (loop_on) {
+		// EVENT_FALC_ABNORMAL
+		if (conf->media == IF_IFACE_T1) {
+			/* Disable this interrupt as it may otherwise interfere with 
+			 * other working boards. */
+			cpc_writeb(falcbase + F_REG(IMR0, ch),
+				   cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN);
+		}
+		falc_disable_comm(card, ch);
+		// EVENT_FALC_ABNORMAL
+		cpc_writeb(falcbase + F_REG(LIM1, ch),
+			   cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RL);
+		pfalc->loop_active = 1;
+	} else {
+		cpc_writeb(falcbase + F_REG(LIM1, ch),
+			   cpc_readb(falcbase + F_REG(LIM1, ch)) & ~LIM1_RL);
+		pfalc->sync = 0;
+		cpc_writeb(falcbase + card->hw.cpld_reg2,
+			   cpc_readb(falcbase + card->hw.cpld_reg2) &
+			   ~(CPLD_REG2_FALC_LED2 << (2 * ch)));
+		pfalc->active = 0;
+		falc_issue_cmd(card, ch, CMDR_XRES);
+		pfalc->loop_active = 0;
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * falc_local_loop
+ *----------------------------------------------------------------------------
+ * Description: The local loopback mode disconnects the receive lines 
+ *		RL1/RL2 resp. RDIP/RDIN from the receiver. Instead of the
+ *		signals coming from the line the data provided by system
+ *		interface are routed through the analog receiver back to
+ *		the system interface. The unipolar bit stream will be
+ *		undisturbed transmitted on the line. Receiver and transmitter
+ *		coding must be identical.
+ *----------------------------------------------------------------------------
+ */
+void falc_local_loop(pc300_t * card, int ch, int loop_on)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	if (loop_on) {
+		cpc_writeb(falcbase + F_REG(LIM0, ch),
+			   cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_LL);
+		pfalc->loop_active = 1;
+	} else {
+		cpc_writeb(falcbase + F_REG(LIM0, ch),
+			   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_LL);
+		pfalc->loop_active = 0;
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * falc_payload_loop
+ *----------------------------------------------------------------------------
+ * Description: This routine allows to enable/disable payload loopback.
+ *		When the payload loop is activated, the received 192 bits
+ *		of payload data will be looped back to the transmit
+ *		direction. The framing bits, CRC6 and DL bits are not 
+ *		looped. They are originated by the FALC-LH transmitter.
+ *----------------------------------------------------------------------------
+ */
+void falc_payload_loop(pc300_t * card, int ch, int loop_on)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	if (loop_on) {
+		// EVENT_FALC_ABNORMAL
+		if (conf->media == IF_IFACE_T1) {
+			/* Disable this interrupt as it may otherwise interfere with 
+			 * other working boards. */
+			cpc_writeb(falcbase + F_REG(IMR0, ch),
+				   cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN);
+		}
+		falc_disable_comm(card, ch);
+		// EVENT_FALC_ABNORMAL
+		cpc_writeb(falcbase + F_REG(FMR2, ch),
+			   cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_PLB);
+		if (conf->media == IF_IFACE_T1) {
+			cpc_writeb(falcbase + F_REG(FMR4, ch),
+				   cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_TM);
+		} else {
+			cpc_writeb(falcbase + F_REG(FMR5, ch),
+				   cpc_readb(falcbase + F_REG(FMR5, ch)) | XSP_TT0);
+		}
+		falc_open_all_timeslots(card, ch);
+		pfalc->loop_active = 2;
+	} else {
+		cpc_writeb(falcbase + F_REG(FMR2, ch),
+			   cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_PLB);
+		if (conf->media == IF_IFACE_T1) {
+			cpc_writeb(falcbase + F_REG(FMR4, ch),
+				   cpc_readb(falcbase + F_REG(FMR4, ch)) & ~FMR4_TM);
+		} else {
+			cpc_writeb(falcbase + F_REG(FMR5, ch),
+				   cpc_readb(falcbase + F_REG(FMR5, ch)) & ~XSP_TT0);
+		}
+		pfalc->sync = 0;
+		cpc_writeb(falcbase + card->hw.cpld_reg2,
+			   cpc_readb(falcbase + card->hw.cpld_reg2) &
+			   ~(CPLD_REG2_FALC_LED2 << (2 * ch)));
+		pfalc->active = 0;
+		falc_issue_cmd(card, ch, CMDR_XRES);
+		pfalc->loop_active = 0;
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * turn_off_xlu
+ *----------------------------------------------------------------------------
+ * Description:	Turns XLU bit off in the proper register
+ *----------------------------------------------------------------------------
+ */
+void turn_off_xlu(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	uclong falcbase = card->hw.falcbase;
+
+	if (conf->media == IF_IFACE_T1) {
+		cpc_writeb(falcbase + F_REG(FMR5, ch),
+			   cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLU);
+	} else {
+		cpc_writeb(falcbase + F_REG(FMR3, ch),
+			   cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLU);
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * turn_off_xld
+ *----------------------------------------------------------------------------
+ * Description: Turns XLD bit off in the proper register
+ *----------------------------------------------------------------------------
+ */
+void turn_off_xld(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	uclong falcbase = card->hw.falcbase;
+
+	if (conf->media == IF_IFACE_T1) {
+		cpc_writeb(falcbase + F_REG(FMR5, ch),
+			   cpc_readb(falcbase + F_REG(FMR5, ch)) & ~FMR5_XLD);
+	} else {
+		cpc_writeb(falcbase + F_REG(FMR3, ch),
+			   cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_XLD);
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * falc_generate_loop_up_code
+ *----------------------------------------------------------------------------
+ * Description:	This routine writes the proper FALC chip register in order
+ *		to generate a LOOP activation code over a T1/E1 line.
+ *----------------------------------------------------------------------------
+ */
+void falc_generate_loop_up_code(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	if (conf->media == IF_IFACE_T1) {
+		cpc_writeb(falcbase + F_REG(FMR5, ch),
+			   cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLU);
+	} else {
+		cpc_writeb(falcbase + F_REG(FMR3, ch),
+			   cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLU);
+	}
+	// EVENT_FALC_ABNORMAL
+	if (conf->media == IF_IFACE_T1) {
+		/* Disable this interrupt as it may otherwise interfere with 
+		 * other working boards. */
+		cpc_writeb(falcbase + F_REG(IMR0, ch),
+			   cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN);
+	}
+	falc_disable_comm(card, ch);
+	// EVENT_FALC_ABNORMAL
+	pfalc->loop_gen = 1;
+}
+
+/*----------------------------------------------------------------------------
+ * falc_generate_loop_down_code
+ *----------------------------------------------------------------------------
+ * Description:	This routine writes the proper FALC chip register in order
+ *		to generate a LOOP deactivation code over a T1/E1 line.
+ *----------------------------------------------------------------------------
+ */
+void falc_generate_loop_down_code(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	if (conf->media == IF_IFACE_T1) {
+		cpc_writeb(falcbase + F_REG(FMR5, ch),
+			   cpc_readb(falcbase + F_REG(FMR5, ch)) | FMR5_XLD);
+	} else {
+		cpc_writeb(falcbase + F_REG(FMR3, ch),
+			   cpc_readb(falcbase + F_REG(FMR3, ch)) | FMR3_XLD);
+	}
+	pfalc->sync = 0;
+	cpc_writeb(falcbase + card->hw.cpld_reg2,
+		   cpc_readb(falcbase + card->hw.cpld_reg2) &
+		   ~(CPLD_REG2_FALC_LED2 << (2 * ch)));
+	pfalc->active = 0;
+//	falc_issue_cmd(card, ch, CMDR_XRES);
+	pfalc->loop_gen = 0;
+}
+
+/*----------------------------------------------------------------------------
+ * falc_pattern_test
+ *----------------------------------------------------------------------------
+ * Description:	This routine generates a pattern code and checks
+ *		it on the reception side.
+ *----------------------------------------------------------------------------
+ */
+void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	if (activate) {
+		pfalc->prbs = 1;
+		pfalc->bec = 0;
+		if (conf->media == IF_IFACE_T1) {
+			/* Disable local loop activation/deactivation detect */
+			cpc_writeb(falcbase + F_REG(IMR3, ch),
+				   cpc_readb(falcbase + F_REG(IMR3, ch)) | IMR3_LLBSC);
+		} else {
+			/* Disable local loop activation/deactivation detect */
+			cpc_writeb(falcbase + F_REG(IMR1, ch),
+				   cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_LLBSC);
+		}
+		/* Activates generation and monitoring of PRBS 
+		 * (Pseudo Random Bit Sequence) */
+		cpc_writeb(falcbase + F_REG(LCR1, ch),
+			   cpc_readb(falcbase + F_REG(LCR1, ch)) | LCR1_EPRM | LCR1_XPRBS);
+	} else {
+		pfalc->prbs = 0;
+		/* Deactivates generation and monitoring of PRBS 
+		 * (Pseudo Random Bit Sequence) */
+		cpc_writeb(falcbase + F_REG(LCR1, ch),
+			   cpc_readb(falcbase+F_REG(LCR1,ch)) & ~(LCR1_EPRM | LCR1_XPRBS));
+		if (conf->media == IF_IFACE_T1) {
+			/* Enable local loop activation/deactivation detect */
+			cpc_writeb(falcbase + F_REG(IMR3, ch),
+				   cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC);
+		} else {
+			/* Enable local loop activation/deactivation detect */
+			cpc_writeb(falcbase + F_REG(IMR1, ch),
+				   cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_LLBSC);
+		}
+	}
+}
+
+/*----------------------------------------------------------------------------
+ * falc_pattern_test_error
+ *----------------------------------------------------------------------------
+ * Description:	This routine returns the bit error counter value
+ *----------------------------------------------------------------------------
+ */
+ucshort falc_pattern_test_error(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	falc_t *pfalc = (falc_t *) & chan->falc;
+
+	return (pfalc->bec);
+}
+
+/**********************************/
+/***   Net Interface Routines   ***/
+/**********************************/
+
+static void
+cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx)
+{
+	struct sk_buff *skb;
+
+	if ((skb = dev_alloc_skb(10 + skb_main->len)) == NULL) {
+		printk("%s: out of memory\n", dev->name);
+		return;
+	}
+	skb_put(skb, 10 + skb_main->len);
+
+	skb->dev = dev;
+	skb->protocol = htons(ETH_P_CUST);
+	skb->mac.raw = skb->data;
+	skb->pkt_type = PACKET_HOST;
+	skb->len = 10 + skb_main->len;
+
+	memcpy(skb->data, dev->name, 5);
+	skb->data[5] = '[';
+	skb->data[6] = rx_tx;
+	skb->data[7] = ']';
+	skb->data[8] = ':';
+	skb->data[9] = ' ';
+	memcpy(&skb->data[10], skb_main->data, skb_main->len);
+
+	netif_rx(skb);
+}
+
+void cpc_tx_timeout(struct net_device *dev)
+{
+	pc300dev_t *d = (pc300dev_t *) dev->priv;
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300_t *card = (pc300_t *) chan->card;
+	struct net_device_stats *stats = &d->hdlc->stats;
+	int ch = chan->channel;
+	uclong flags;
+	ucchar ilar;
+
+	stats->tx_errors++;
+	stats->tx_aborted_errors++;
+	CPC_LOCK(card, flags);
+	if ((ilar = cpc_readb(card->hw.scabase + ILAR)) != 0) {
+		printk("%s: ILAR=0x%x\n", dev->name, ilar);
+		cpc_writeb(card->hw.scabase + ILAR, ilar);
+		cpc_writeb(card->hw.scabase + DMER, 0x80);
+	}
+	if (card->hw.type == PC300_TE) {
+		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,
+			   cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) &
+			   ~(CPLD_REG2_FALC_LED1 << (2 * ch)));
+	}
+	dev->trans_start = jiffies;
+	CPC_UNLOCK(card, flags);
+	netif_wake_queue(dev);
+}
+
+int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	pc300dev_t *d = (pc300dev_t *) dev->priv;
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300_t *card = (pc300_t *) chan->card;
+	struct net_device_stats *stats = &d->hdlc->stats;
+	int ch = chan->channel;
+	uclong flags;
+#ifdef PC300_DEBUG_TX
+	int i;
+#endif
+
+	if (chan->conf.monitor) {
+		/* In monitor mode no Tx is done: ignore packet */
+		dev_kfree_skb(skb);
+		return 0;
+	} else if (!netif_carrier_ok(dev)) {
+		/* DCD must be OFF: drop packet */
+		dev_kfree_skb(skb);
+		stats->tx_errors++;
+		stats->tx_carrier_errors++;
+		return 0;
+	} else if (cpc_readb(card->hw.scabase + M_REG(ST3, ch)) & ST3_DCD) {
+		printk("%s: DCD is OFF. Going administrative down.\n", dev->name);
+		stats->tx_errors++;
+		stats->tx_carrier_errors++;
+		dev_kfree_skb(skb);
+		netif_carrier_off(dev);
+		CPC_LOCK(card, flags);
+		cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR);
+		if (card->hw.type == PC300_TE) {
+			cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,
+				   cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & 
+				   			~(CPLD_REG2_FALC_LED1 << (2 * ch)));
+		}
+		CPC_UNLOCK(card, flags);
+		netif_wake_queue(dev);
+		return 0;
+	}
+
+	/* Write buffer to DMA buffers */
+	if (dma_buf_write(card, ch, (ucchar *) skb->data, skb->len) != 0) {
+//		printk("%s: write error. Dropping TX packet.\n", dev->name);
+		netif_stop_queue(dev);
+		dev_kfree_skb(skb);
+		stats->tx_errors++;
+		stats->tx_dropped++;
+		return 0;
+	}
+#ifdef PC300_DEBUG_TX
+	printk("%s T:", dev->name);
+	for (i = 0; i < skb->len; i++)
+		printk(" %02x", *(skb->data + i));
+	printk("\n");
+#endif
+
+	if (d->trace_on) {
+		cpc_trace(dev, skb, 'T');
+	}
+	dev->trans_start = jiffies;
+
+	/* Start transmission */
+	CPC_LOCK(card, flags);
+	/* verify if it has more than one free descriptor */
+	if (card->chan[ch].nfree_tx_bd <= 1) {
+		/* don't have so stop the queue */
+		netif_stop_queue(dev);
+	}
+	cpc_writel(card->hw.scabase + DTX_REG(EDAL, ch),
+		   TX_BD_ADDR(ch, chan->tx_next_bd));
+	cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA);
+	cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE);
+	if (card->hw.type == PC300_TE) {
+		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,
+			   cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) |
+			   (CPLD_REG2_FALC_LED1 << (2 * ch)));
+	}
+	CPC_UNLOCK(card, flags);
+	dev_kfree_skb(skb);
+
+	return 0;
+}
+
+void cpc_net_rx(hdlc_device * hdlc)
+{
+	struct net_device *dev = hdlc_to_dev(hdlc);
+	pc300dev_t *d = (pc300dev_t *) dev->priv;
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300_t *card = (pc300_t *) chan->card;
+	struct net_device_stats *stats = &d->hdlc->stats;
+	int ch = chan->channel;
+#ifdef PC300_DEBUG_RX
+	int i;
+#endif
+	int rxb;
+	struct sk_buff *skb;
+
+	while (1) {
+		if ((rxb = dma_get_rx_frame_size(card, ch)) == -1)
+			return;
+
+		if (!netif_carrier_ok(dev)) {
+			/* DCD must be OFF: drop packet */
+		    printk("%s : DCD is OFF - drop %d rx bytes\n", dev->name, rxb); 
+			skb = NULL;
+		} else {
+			if (rxb > (dev->mtu + 40)) { /* add headers */
+				printk("%s : MTU exceeded %d\n", dev->name, rxb); 
+				skb = NULL;
+			} else {
+				skb = dev_alloc_skb(rxb);
+				if (skb == NULL) {
+					printk("%s: Memory squeeze!!\n", dev->name);
+					return;
+				}
+				skb->dev = dev;
+			}
+		}
+
+		if (((rxb = dma_buf_read(card, ch, skb)) <= 0) || (skb == NULL)) {
+#ifdef PC300_DEBUG_RX
+			printk("%s: rxb = %x\n", dev->name, rxb);
+#endif
+			if ((skb == NULL) && (rxb > 0)) {
+				/* rxb > dev->mtu */
+				stats->rx_errors++;
+				stats->rx_length_errors++;
+				continue;
+			}
+
+			if (rxb < 0) {	/* Invalid frame */
+				rxb = -rxb;
+				if (rxb & DST_OVR) {
+					stats->rx_errors++;
+					stats->rx_fifo_errors++;
+				}
+				if (rxb & DST_CRC) {
+					stats->rx_errors++;
+					stats->rx_crc_errors++;
+				}
+				if (rxb & (DST_RBIT | DST_SHRT | DST_ABT)) {
+					stats->rx_errors++;
+					stats->rx_frame_errors++;
+				}
+			}
+			if (skb) {
+				dev_kfree_skb_irq(skb);
+			}
+			continue;
+		}
+
+		stats->rx_bytes += rxb;
+
+#ifdef PC300_DEBUG_RX
+		printk("%s R:", dev->name);
+		for (i = 0; i < skb->len; i++)
+			printk(" %02x", *(skb->data + i));
+		printk("\n");
+#endif
+		if (d->trace_on) {
+			cpc_trace(dev, skb, 'R');
+		}
+		stats->rx_packets++;
+		skb->mac.raw = skb->data;
+		skb->protocol = hdlc_type_trans(skb, dev);
+		netif_rx(skb);
+	}
+}
+
+/************************************/
+/***   PC300 Interrupt Routines   ***/
+/************************************/
+static void sca_tx_intr(pc300dev_t *dev)
+{
+	pc300ch_t *chan = (pc300ch_t *)dev->chan; 
+	pc300_t *card = (pc300_t *)chan->card; 
+	int ch = chan->channel; 
+	volatile pcsca_bd_t * ptdescr; 
+	struct net_device_stats *stats = &dev->hdlc->stats; 
+
+    /* Clean up descriptors from previous transmission */
+	ptdescr = (pcsca_bd_t *)(card->hw.rambase +
+						TX_BD_ADDR(ch,chan->tx_first_bd));
+	while ((cpc_readl(card->hw.scabase + DTX_REG(CDAL,ch)) != 
+							TX_BD_ADDR(ch,chan->tx_first_bd)) && 
+			(cpc_readb(&ptdescr->status) & DST_OSB)) {
+		stats->tx_packets++;
+		stats->tx_bytes += cpc_readw(&ptdescr->len);
+		cpc_writeb(&ptdescr->status, DST_OSB);
+		cpc_writew(&ptdescr->len, 0);
+		chan->nfree_tx_bd++;
+		chan->tx_first_bd = (chan->tx_first_bd + 1) & (N_DMA_TX_BUF - 1);
+		ptdescr = (pcsca_bd_t *)(card->hw.rambase +
+						TX_BD_ADDR(ch,chan->tx_first_bd));
+    }
+
+#ifdef CONFIG_PC300_MLPPP
+	if (chan->conf.proto == PC300_PROTO_MLPPP) {
+			cpc_tty_trigger_poll(dev);
+	} else {
+#endif
+	/* Tell the upper layer we are ready to transmit more packets */
+		netif_wake_queue((struct net_device*)dev->hdlc);
+#ifdef CONFIG_PC300_MLPPP
+	}
+#endif
+}
+
+static void sca_intr(pc300_t * card)
+{
+	uclong scabase = card->hw.scabase;
+	volatile uclong status;
+	int ch;
+	int intr_count = 0;
+	unsigned char dsr_rx;
+
+	while ((status = cpc_readl(scabase + ISR0)) != 0) {
+		for (ch = 0; ch < card->hw.nchan; ch++) {
+			pc300ch_t *chan = &card->chan[ch];
+			pc300dev_t *d = &chan->d;
+			hdlc_device *hdlc = d->hdlc;
+			struct net_device *dev = hdlc_to_dev(hdlc);
+
+			spin_lock(&card->card_lock);
+
+	    /**** Reception ****/
+			if (status & IR0_DRX((IR0_DMIA | IR0_DMIB), ch)) {
+				ucchar drx_stat = cpc_readb(scabase + DSR_RX(ch));
+
+				/* Clear RX interrupts */
+				cpc_writeb(scabase + DSR_RX(ch), drx_stat | DSR_DWE);
+
+#ifdef PC300_DEBUG_INTR
+				printk ("sca_intr: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n",
+					 ch, status, drx_stat);
+#endif
+				if (status & IR0_DRX(IR0_DMIA, ch)) {
+					if (drx_stat & DSR_BOF) {
+#ifdef CONFIG_PC300_MLPPP
+						if (chan->conf.proto == PC300_PROTO_MLPPP) {
+							/* verify if driver is TTY */
+							if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) {
+								rx_dma_stop(card, ch);
+							}
+							cpc_tty_receive(d);
+							rx_dma_start(card, ch);
+						} else 
+#endif
+						{
+							if ((cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) {
+								rx_dma_stop(card, ch);
+							}
+							cpc_net_rx(hdlc);
+							/* Discard invalid frames */
+							hdlc->stats.rx_errors++;
+							hdlc->stats.rx_over_errors++;
+							chan->rx_first_bd = 0;
+							chan->rx_last_bd = N_DMA_RX_BUF - 1;
+							rx_dma_start(card, ch);
+						}
+					}
+				}
+				if (status & IR0_DRX(IR0_DMIB, ch)) {
+					if (drx_stat & DSR_EOM) {
+						if (card->hw.type == PC300_TE) {
+							cpc_writeb(card->hw.falcbase +
+								   card->hw.cpld_reg2,
+								   cpc_readb (card->hw.falcbase +
+								    	card->hw.cpld_reg2) |
+								   (CPLD_REG2_FALC_LED1 << (2 * ch)));
+						}
+#ifdef CONFIG_PC300_MLPPP
+						if (chan->conf.proto == PC300_PROTO_MLPPP) {
+							/* verify if driver is TTY */
+							cpc_tty_receive(d);
+						} else {
+							cpc_net_rx(hdlc);
+						}
+#else
+						cpc_net_rx(hdlc);
+#endif
+						if (card->hw.type == PC300_TE) {
+							cpc_writeb(card->hw.falcbase +
+								   card->hw.cpld_reg2,
+								   cpc_readb (card->hw.falcbase +
+								    		card->hw.cpld_reg2) &
+								   ~ (CPLD_REG2_FALC_LED1 << (2 * ch)));
+						}
+					}
+				}
+				if (!(dsr_rx = cpc_readb(scabase + DSR_RX(ch)) & DSR_DE)) {
+#ifdef PC300_DEBUG_INTR
+		printk("%s: RX intr chan[%d] (st=0x%08lx, dsr=0x%02x, dsr2=0x%02x)\n", 
+					dev->name, ch, status, drx_stat, dsr_rx);
+#endif
+					cpc_writeb(scabase + DSR_RX(ch), (dsr_rx | DSR_DE) & 0xfe);
+				}
+			}
+
+	    /**** Transmission ****/
+			if (status & IR0_DTX((IR0_EFT | IR0_DMIA | IR0_DMIB), ch)) {
+				ucchar dtx_stat = cpc_readb(scabase + DSR_TX(ch));
+
+				/* Clear TX interrupts */
+				cpc_writeb(scabase + DSR_TX(ch), dtx_stat | DSR_DWE);
+
+#ifdef PC300_DEBUG_INTR
+				printk ("sca_intr: TX intr chan[%d] (st=0x%08lx, dsr=0x%02x)\n",
+					 ch, status, dtx_stat);
+#endif
+				if (status & IR0_DTX(IR0_EFT, ch)) {
+					if (dtx_stat & DSR_UDRF) {
+						if (cpc_readb (scabase + M_REG(TBN, ch)) != 0) {
+							cpc_writeb(scabase + M_REG(CMD,ch), CMD_TX_BUF_CLR);
+						}
+						if (card->hw.type == PC300_TE) {
+							cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,
+								   cpc_readb (card->hw.falcbase + 
+										   card->hw.cpld_reg2) &
+								   ~ (CPLD_REG2_FALC_LED1 << (2 * ch)));
+						}
+						hdlc->stats.tx_errors++;
+						hdlc->stats.tx_fifo_errors++;
+						sca_tx_intr(d);
+					}
+				}
+				if (status & IR0_DTX(IR0_DMIA, ch)) {
+					if (dtx_stat & DSR_BOF) {
+					}
+				}
+				if (status & IR0_DTX(IR0_DMIB, ch)) {
+					if (dtx_stat & DSR_EOM) {
+						if (card->hw.type == PC300_TE) {
+							cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,
+								   cpc_readb (card->hw.falcbase +
+								    			card->hw.cpld_reg2) &
+								   ~ (CPLD_REG2_FALC_LED1 << (2 * ch)));
+						}
+						sca_tx_intr(d);
+					}
+				}
+			}
+
+	    /**** MSCI ****/
+			if (status & IR0_M(IR0_RXINTA, ch)) {
+				ucchar st1 = cpc_readb(scabase + M_REG(ST1, ch));
+
+				/* Clear MSCI interrupts */
+				cpc_writeb(scabase + M_REG(ST1, ch), st1);
+
+#ifdef PC300_DEBUG_INTR
+				printk("sca_intr: MSCI intr chan[%d] (st=0x%08lx, st1=0x%02x)\n",
+					 ch, status, st1);
+#endif
+				if (st1 & ST1_CDCD) {	/* DCD changed */
+					if (cpc_readb(scabase + M_REG(ST3, ch)) & ST3_DCD) {
+						printk ("%s: DCD is OFF. Going administrative down.\n",
+							 dev->name);
+#ifdef CONFIG_PC300_MLPPP
+						if (chan->conf.proto != PC300_PROTO_MLPPP) {
+							netif_carrier_off(dev);
+						}
+#else
+						netif_carrier_off(dev);
+
+#endif
+						card->chan[ch].d.line_off++;
+					} else {	/* DCD = 1 */
+						printk ("%s: DCD is ON. Going administrative up.\n",
+							 dev->name);
+#ifdef CONFIG_PC300_MLPPP
+						if (chan->conf.proto != PC300_PROTO_MLPPP)
+							/* verify if driver is not TTY */
+#endif
+							netif_carrier_on(dev);
+						card->chan[ch].d.line_on++;
+					}
+				}
+			}
+			spin_unlock(&card->card_lock);
+		}
+		if (++intr_count == 10)
+			/* Too much work at this board. Force exit */
+			break;
+	}
+}
+
+static void falc_t1_loop_detection(pc300_t * card, int ch, ucchar frs1)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) &&
+	    !pfalc->loop_gen) {
+		if (frs1 & FRS1_LLBDD) {
+			// A Line Loop Back Deactivation signal detected
+			if (pfalc->loop_active) {
+				falc_remote_loop(card, ch, 0);
+			}
+		} else {
+			if ((frs1 & FRS1_LLBAD) &&
+			    ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) {
+				// A Line Loop Back Activation signal detected  
+				if (!pfalc->loop_active) {
+					falc_remote_loop(card, ch, 1);
+				}
+			}
+		}
+	}
+}
+
+static void falc_e1_loop_detection(pc300_t * card, int ch, ucchar rsp)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+
+	if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) &&
+	    !pfalc->loop_gen) {
+		if (rsp & RSP_LLBDD) {
+			// A Line Loop Back Deactivation signal detected
+			if (pfalc->loop_active) {
+				falc_remote_loop(card, ch, 0);
+			}
+		} else {
+			if ((rsp & RSP_LLBAD) &&
+			    ((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) {
+				// A Line Loop Back Activation signal detected  
+				if (!pfalc->loop_active) {
+					falc_remote_loop(card, ch, 1);
+				}
+			}
+		}
+	}
+}
+
+static void falc_t1_intr(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+	ucchar isr0, isr3, gis;
+	ucchar dummy;
+
+	while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) {
+		if (gis & GIS_ISR0) {
+			isr0 = cpc_readb(falcbase + F_REG(FISR0, ch));
+			if (isr0 & FISR0_PDEN) {
+				/* Read the bit to clear the situation */
+				if (cpc_readb(falcbase + F_REG(FRS1, ch)) &
+				    FRS1_PDEN) {
+					pfalc->pden++;
+				}
+			}
+		}
+
+		if (gis & GIS_ISR1) {
+			dummy = cpc_readb(falcbase + F_REG(FISR1, ch));
+		}
+
+		if (gis & GIS_ISR2) {
+			dummy = cpc_readb(falcbase + F_REG(FISR2, ch));
+		}
+
+		if (gis & GIS_ISR3) {
+			isr3 = cpc_readb(falcbase + F_REG(FISR3, ch));
+			if (isr3 & FISR3_SEC) {
+				pfalc->sec++;
+				falc_update_stats(card, ch);
+				falc_check_status(card, ch,
+						  cpc_readb(falcbase + F_REG(FRS0, ch)));
+			}
+			if (isr3 & FISR3_ES) {
+				pfalc->es++;
+			}
+			if (isr3 & FISR3_LLBSC) {
+				falc_t1_loop_detection(card, ch,
+						       cpc_readb(falcbase + F_REG(FRS1, ch)));
+			}
+		}
+	}
+}
+
+static void falc_e1_intr(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong falcbase = card->hw.falcbase;
+	ucchar isr1, isr2, isr3, gis, rsp;
+	ucchar dummy;
+
+	while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) {
+		rsp = cpc_readb(falcbase + F_REG(RSP, ch));
+
+		if (gis & GIS_ISR0) {
+			dummy = cpc_readb(falcbase + F_REG(FISR0, ch));
+		}
+		if (gis & GIS_ISR1) {
+			isr1 = cpc_readb(falcbase + F_REG(FISR1, ch));
+			if (isr1 & FISR1_XMB) {
+				if ((pfalc->xmb_cause & 2)
+				    && pfalc->multiframe_mode) {
+					if (cpc_readb (falcbase + F_REG(FRS0, ch)) & 
+									(FRS0_LOS | FRS0_AIS | FRS0_LFA)) {
+						cpc_writeb(falcbase + F_REG(XSP, ch),
+							   cpc_readb(falcbase + F_REG(XSP, ch))
+							   & ~XSP_AXS);
+					} else {
+						cpc_writeb(falcbase + F_REG(XSP, ch),
+							   cpc_readb(falcbase + F_REG(XSP, ch))
+							   | XSP_AXS);
+					}
+				}
+				pfalc->xmb_cause = 0;
+				cpc_writeb(falcbase + F_REG(IMR1, ch),
+					   cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_XMB);
+			}
+			if (isr1 & FISR1_LLBSC) {
+				falc_e1_loop_detection(card, ch, rsp);
+			}
+		}
+		if (gis & GIS_ISR2) {
+			isr2 = cpc_readb(falcbase + F_REG(FISR2, ch));
+			if (isr2 & FISR2_T400MS) {
+				cpc_writeb(falcbase + F_REG(XSW, ch),
+					   cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XRA);
+			}
+			if (isr2 & FISR2_MFAR) {
+				cpc_writeb(falcbase + F_REG(XSW, ch),
+					   cpc_readb(falcbase + F_REG(XSW, ch)) & ~XSW_XRA);
+			}
+			if (isr2 & (FISR2_FAR | FISR2_LFA | FISR2_AIS | FISR2_LOS)) {
+				pfalc->xmb_cause |= 2;
+				cpc_writeb(falcbase + F_REG(IMR1, ch),
+					   cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_XMB);
+			}
+		}
+		if (gis & GIS_ISR3) {
+			isr3 = cpc_readb(falcbase + F_REG(FISR3, ch));
+			if (isr3 & FISR3_SEC) {
+				pfalc->sec++;
+				falc_update_stats(card, ch);
+				falc_check_status(card, ch,
+						  cpc_readb(falcbase + F_REG(FRS0, ch)));
+			}
+			if (isr3 & FISR3_ES) {
+				pfalc->es++;
+			}
+		}
+	}
+}
+
+static void falc_intr(pc300_t * card)
+{
+	int ch;
+
+	for (ch = 0; ch < card->hw.nchan; ch++) {
+		pc300ch_t *chan = &card->chan[ch];
+		pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+
+		if (conf->media == IF_IFACE_T1) {
+			falc_t1_intr(card, ch);
+		} else {
+			falc_e1_intr(card, ch);
+		}
+	}
+}
+
+static void cpc_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	pc300_t *card;
+	volatile ucchar plx_status;
+
+	if ((card = (pc300_t *) dev_id) == 0) {
+#ifdef PC300_DEBUG_INTR
+		printk("cpc_intr: spurious intr %d\n", irq);
+#endif
+		return;		/* spurious intr */
+	}
+
+	if (card->hw.rambase == 0) {
+#ifdef PC300_DEBUG_INTR
+		printk("cpc_intr: spurious intr2 %d\n", irq);
+#endif
+		return;		/* spurious intr */
+	}
+
+	switch (card->hw.type) {
+		case PC300_RSV:
+		case PC300_X21:
+			sca_intr(card);
+			break;
+
+		case PC300_TE:
+			while ( (plx_status = (cpc_readb(card->hw.plxbase + card->hw.intctl_reg) &
+				 (PLX_9050_LINT1_STATUS | PLX_9050_LINT2_STATUS))) != 0) {
+				if (plx_status & PLX_9050_LINT1_STATUS) {	/* SCA Interrupt */
+					sca_intr(card);
+				}
+				if (plx_status & PLX_9050_LINT2_STATUS) {	/* FALC Interrupt */
+					falc_intr(card);
+				}
+			}
+			break;
+	}
+}
+
+void cpc_sca_status(pc300_t * card, int ch)
+{
+	ucchar ilar;
+	uclong scabase = card->hw.scabase;
+	uclong flags;
+
+	tx_dma_buf_check(card, ch);
+	rx_dma_buf_check(card, ch);
+	ilar = cpc_readb(scabase + ILAR);
+	printk ("ILAR=0x%02x, WCRL=0x%02x, PCR=0x%02x, BTCR=0x%02x, BOLR=0x%02x\n",
+		 ilar, cpc_readb(scabase + WCRL), cpc_readb(scabase + PCR),
+		 cpc_readb(scabase + BTCR), cpc_readb(scabase + BOLR));
+	printk("TX_CDA=0x%08lx, TX_EDA=0x%08lx\n",
+	       (uclong) cpc_readl(scabase + DTX_REG(CDAL, ch)),
+	       (uclong) cpc_readl(scabase + DTX_REG(EDAL, ch)));
+	printk("RX_CDA=0x%08lx, RX_EDA=0x%08lx, BFL=0x%04x\n",
+	       (uclong) cpc_readl(scabase + DRX_REG(CDAL, ch)),
+	       (uclong) cpc_readl(scabase + DRX_REG(EDAL, ch)),
+	       cpc_readw(scabase + DRX_REG(BFLL, ch)));
+	printk("DMER=0x%02x, DSR_TX=0x%02x, DSR_RX=0x%02x\n",
+	       cpc_readb(scabase + DMER), cpc_readb(scabase + DSR_TX(ch)),
+	       cpc_readb(scabase + DSR_RX(ch)));
+	printk("DMR_TX=0x%02x, DMR_RX=0x%02x, DIR_TX=0x%02x, DIR_RX=0x%02x\n",
+	       cpc_readb(scabase + DMR_TX(ch)), cpc_readb(scabase + DMR_RX(ch)),
+	       cpc_readb(scabase + DIR_TX(ch)),
+	       cpc_readb(scabase + DIR_RX(ch)));
+	printk("DCR_TX=0x%02x, DCR_RX=0x%02x, FCT_TX=0x%02x, FCT_RX=0x%02x\n",
+	       cpc_readb(scabase + DCR_TX(ch)), cpc_readb(scabase + DCR_RX(ch)),
+	       cpc_readb(scabase + FCT_TX(ch)),
+	       cpc_readb(scabase + FCT_RX(ch)));
+	printk("MD0=0x%02x, MD1=0x%02x, MD2=0x%02x, MD3=0x%02x, IDL=0x%02x\n",
+	       cpc_readb(scabase + M_REG(MD0, ch)),
+	       cpc_readb(scabase + M_REG(MD1, ch)),
+	       cpc_readb(scabase + M_REG(MD2, ch)),
+	       cpc_readb(scabase + M_REG(MD3, ch)),
+	       cpc_readb(scabase + M_REG(IDL, ch)));
+	printk("CMD=0x%02x, SA0=0x%02x, SA1=0x%02x, TFN=0x%02x, CTL=0x%02x\n",
+	       cpc_readb(scabase + M_REG(CMD, ch)),
+	       cpc_readb(scabase + M_REG(SA0, ch)),
+	       cpc_readb(scabase + M_REG(SA1, ch)),
+	       cpc_readb(scabase + M_REG(TFN, ch)),
+	       cpc_readb(scabase + M_REG(CTL, ch)));
+	printk("ST0=0x%02x, ST1=0x%02x, ST2=0x%02x, ST3=0x%02x, ST4=0x%02x\n",
+	       cpc_readb(scabase + M_REG(ST0, ch)),
+	       cpc_readb(scabase + M_REG(ST1, ch)),
+	       cpc_readb(scabase + M_REG(ST2, ch)),
+	       cpc_readb(scabase + M_REG(ST3, ch)),
+	       cpc_readb(scabase + M_REG(ST4, ch)));
+	printk ("CST0=0x%02x, CST1=0x%02x, CST2=0x%02x, CST3=0x%02x, FST=0x%02x\n",
+		 cpc_readb(scabase + M_REG(CST0, ch)),
+		 cpc_readb(scabase + M_REG(CST1, ch)),
+		 cpc_readb(scabase + M_REG(CST2, ch)),
+		 cpc_readb(scabase + M_REG(CST3, ch)),
+		 cpc_readb(scabase + M_REG(FST, ch)));
+	printk("TRC0=0x%02x, TRC1=0x%02x, RRC=0x%02x, TBN=0x%02x, RBN=0x%02x\n",
+	       cpc_readb(scabase + M_REG(TRC0, ch)),
+	       cpc_readb(scabase + M_REG(TRC1, ch)),
+	       cpc_readb(scabase + M_REG(RRC, ch)),
+	       cpc_readb(scabase + M_REG(TBN, ch)),
+	       cpc_readb(scabase + M_REG(RBN, ch)));
+	printk("TFS=0x%02x, TNR0=0x%02x, TNR1=0x%02x, RNR=0x%02x\n",
+	       cpc_readb(scabase + M_REG(TFS, ch)),
+	       cpc_readb(scabase + M_REG(TNR0, ch)),
+	       cpc_readb(scabase + M_REG(TNR1, ch)),
+	       cpc_readb(scabase + M_REG(RNR, ch)));
+	printk("TCR=0x%02x, RCR=0x%02x, TNR1=0x%02x, RNR=0x%02x\n",
+	       cpc_readb(scabase + M_REG(TCR, ch)),
+	       cpc_readb(scabase + M_REG(RCR, ch)),
+	       cpc_readb(scabase + M_REG(TNR1, ch)),
+	       cpc_readb(scabase + M_REG(RNR, ch)));
+	printk("TXS=0x%02x, RXS=0x%02x, EXS=0x%02x, TMCT=0x%02x, TMCR=0x%02x\n",
+	       cpc_readb(scabase + M_REG(TXS, ch)),
+	       cpc_readb(scabase + M_REG(RXS, ch)),
+	       cpc_readb(scabase + M_REG(EXS, ch)),
+	       cpc_readb(scabase + M_REG(TMCT, ch)),
+	       cpc_readb(scabase + M_REG(TMCR, ch)));
+	printk("IE0=0x%02x, IE1=0x%02x, IE2=0x%02x, IE4=0x%02x, FIE=0x%02x\n",
+	       cpc_readb(scabase + M_REG(IE0, ch)),
+	       cpc_readb(scabase + M_REG(IE1, ch)),
+	       cpc_readb(scabase + M_REG(IE2, ch)),
+	       cpc_readb(scabase + M_REG(IE4, ch)),
+	       cpc_readb(scabase + M_REG(FIE, ch)));
+	printk("IER0=0x%08lx\n", (uclong) cpc_readl(scabase + IER0));
+
+	if (ilar != 0) {
+		CPC_LOCK(card, flags);
+		cpc_writeb(scabase + ILAR, ilar);
+		cpc_writeb(scabase + DMER, 0x80);
+		CPC_UNLOCK(card, flags);
+	}
+}
+
+void cpc_falc_status(pc300_t * card, int ch)
+{
+	pc300ch_t *chan = &card->chan[ch];
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	uclong flags;
+
+	CPC_LOCK(card, flags);
+	printk("CH%d:   %s %s  %d channels\n",
+	       ch, (pfalc->sync ? "SYNC" : ""), (pfalc->active ? "ACTIVE" : ""),
+	       pfalc->num_channels);
+
+	printk("        pden=%d,  los=%d,  losr=%d,  lfa=%d,  farec=%d\n",
+	       pfalc->pden, pfalc->los, pfalc->losr, pfalc->lfa, pfalc->farec);
+	printk("        lmfa=%d,  ais=%d,  sec=%d,  es=%d,  rai=%d\n",
+	       pfalc->lmfa, pfalc->ais, pfalc->sec, pfalc->es, pfalc->rai);
+	printk("        bec=%d,  fec=%d,  cvc=%d,  cec=%d,  ebc=%d\n",
+	       pfalc->bec, pfalc->fec, pfalc->cvc, pfalc->cec, pfalc->ebc);
+
+	printk("\n");
+	printk("        STATUS: %s  %s  %s  %s  %s  %s\n",
+	       (pfalc->red_alarm ? "RED" : ""),
+	       (pfalc->blue_alarm ? "BLU" : ""),
+	       (pfalc->yellow_alarm ? "YEL" : ""),
+	       (pfalc->loss_fa ? "LFA" : ""),
+	       (pfalc->loss_mfa ? "LMF" : ""), (pfalc->prbs ? "PRB" : ""));
+	CPC_UNLOCK(card, flags);
+}
+
+int cpc_change_mtu(struct net_device *dev, int new_mtu)
+{
+	if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU))
+		return -EINVAL;
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	hdlc_device *hdlc = dev_to_hdlc(dev);
+	pc300dev_t *d = (pc300dev_t *) dev->priv;
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300_t *card = (pc300_t *) chan->card;
+	pc300conf_t conf_aux;
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	int ch = chan->channel;
+	void *arg = (void *) ifr->ifr_data;
+	uclong scabase = card->hw.scabase;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	switch (cmd) {
+		case SIOCGPC300CONF:
+#ifdef CONFIG_PC300_MLPPP
+			if (conf->proto != PC300_PROTO_MLPPP) {
+				conf->proto = hdlc->proto;
+			}
+#else
+			conf->proto = hdlc->proto;
+#endif
+			memcpy(&conf_aux.conf, conf, sizeof(pc300chconf_t));
+			memcpy(&conf_aux.hw, &card->hw, sizeof(pc300hw_t));
+			if (!arg || 
+				copy_to_user(arg, &conf_aux, sizeof(pc300conf_t))) 
+				return -EINVAL;
+			return 0;
+		case SIOCSPC300CONF:
+			if (!suser())
+				return -EPERM;
+			if (!arg || 
+				copy_from_user(&conf_aux.conf, arg, sizeof(pc300chconf_t)))
+				return -EINVAL;
+			if (card->hw.cpld_id < 0x02 &&
+			    conf_aux.conf.fr_mode == PC300_FR_UNFRAMED) {
+				/* CPLD_ID < 0x02 doesn't support Unframed E1 */
+				return -EINVAL;
+			}
+#ifdef CONFIG_PC300_MLPPP
+			if (conf_aux.conf.proto == PC300_PROTO_MLPPP) {
+				if (conf->proto != PC300_PROTO_MLPPP) {
+					memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t));
+					cpc_tty_init(d);	/* init TTY driver */
+				}
+			} else {
+				if (conf_aux.conf.proto == 0xffff) {
+					if (conf->proto == PC300_PROTO_MLPPP){ 
+						/* ifdown interface */
+						cpc_close(dev);
+					}
+				} else {
+					memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t));
+					hdlc->proto = conf->proto;
+				}
+			}
+#else
+			memcpy(conf, &conf_aux.conf, sizeof(pc300chconf_t));
+			hdlc->proto = conf->proto;
+#endif
+			return 0;
+		case SIOCGPC300STATUS:
+			cpc_sca_status(card, ch);
+			return 0;
+		case SIOCGPC300FALCSTATUS:
+			cpc_falc_status(card, ch);
+			return 0;
+
+		case SIOCGPC300UTILSTATS:
+			{
+				if (!arg) {	/* clear statistics */
+					memset(&hdlc->stats, 0, sizeof(struct net_device_stats));
+					if (card->hw.type == PC300_TE) {
+						memset(&chan->falc, 0, sizeof(falc_t));
+					}
+				} else {
+					pc300stats_t pc300stats;
+
+					memset(&pc300stats, 0, sizeof(pc300stats_t));
+					pc300stats.hw_type = card->hw.type;
+					pc300stats.line_on = card->chan[ch].d.line_on;
+					pc300stats.line_off = card->chan[ch].d.line_off;
+					memcpy(&pc300stats.gen_stats, &hdlc->stats,
+					       sizeof(struct net_device_stats));
+					if (card->hw.type == PC300_TE)
+						memcpy(&pc300stats.te_stats,&chan->falc,sizeof(falc_t));
+				    copy_to_user(arg, &pc300stats, sizeof(pc300stats_t));
+				}
+				return 0;
+			}
+
+		case SIOCGPC300UTILSTATUS:
+			{
+				struct pc300status pc300status;
+
+				pc300status.hw_type = card->hw.type;
+				if (card->hw.type == PC300_TE) {
+					pc300status.te_status.sync = chan->falc.sync;
+					pc300status.te_status.red_alarm = chan->falc.red_alarm;
+					pc300status.te_status.blue_alarm = chan->falc.blue_alarm;
+					pc300status.te_status.loss_fa = chan->falc.loss_fa;
+					pc300status.te_status.yellow_alarm =chan->falc.yellow_alarm;
+					pc300status.te_status.loss_mfa = chan->falc.loss_mfa;
+					pc300status.te_status.prbs = chan->falc.prbs;
+				} else {
+					pc300status.gen_status.dcd =
+						!(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_DCD);
+					pc300status.gen_status.cts =
+						!(cpc_readb (scabase + M_REG(ST3, ch)) & ST3_CTS);
+					pc300status.gen_status.rts =
+						!(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_RTS);
+					pc300status.gen_status.dtr =
+						!(cpc_readb (scabase + M_REG(CTL, ch)) & CTL_DTR);
+					/* There is no DSR in HD64572 */
+				}
+				if (!arg
+				    || copy_to_user(arg, &pc300status, sizeof(pc300status_t)))
+						return -EINVAL;
+				return 0;
+			}
+
+		case SIOCSPC300TRACE:
+			/* Sets/resets a trace_flag for the respective device */
+			if (!arg || copy_from_user(&d->trace_on, arg,sizeof(unsigned char)))
+					return -EINVAL;
+			return 0;
+
+		case SIOCSPC300LOOPBACK:
+			{
+				struct pc300loopback pc300loop;
+
+				/* TE boards only */
+				if (card->hw.type != PC300_TE)
+					return -EINVAL;
+
+				if (!arg || 
+					copy_from_user(&pc300loop, arg, sizeof(pc300loopback_t)))
+						return -EINVAL;
+				switch (pc300loop.loop_type) {
+					case PC300LOCLOOP:	/* Turn the local loop on/off */
+						falc_local_loop(card, ch, pc300loop.loop_on);
+						return 0;
+
+					case PC300REMLOOP:	/* Turn the remote loop on/off */
+						falc_remote_loop(card, ch, pc300loop.loop_on);
+						return 0;
+
+					case PC300PAYLOADLOOP:	/* Turn the payload loop on/off */
+						falc_payload_loop(card, ch, pc300loop.loop_on);
+						return 0;
+
+					case PC300GENLOOPUP:	/* Generate loop UP */
+						if (pc300loop.loop_on) {
+							falc_generate_loop_up_code (card, ch);
+						} else {
+							turn_off_xlu(card, ch);
+						}
+						return 0;
+
+					case PC300GENLOOPDOWN:	/* Generate loop DOWN */
+						if (pc300loop.loop_on) {
+							falc_generate_loop_down_code (card, ch);
+						} else {
+							turn_off_xld(card, ch);
+						}
+						return 0;
+
+					default:
+						return -EINVAL;
+				}
+			}
+
+		case SIOCSPC300PATTERNTEST:
+			/* Turn the pattern test on/off and show the errors counter */
+			{
+				struct pc300patterntst pc300patrntst;
+
+				/* TE boards only */
+				if (card->hw.type != PC300_TE)
+					return -EINVAL;
+
+				if (card->hw.cpld_id < 0x02) {
+					/* CPLD_ID < 0x02 doesn't support pattern test */
+					return -EINVAL;
+				}
+
+				if (!arg || 
+					copy_from_user(&pc300patrntst,arg,sizeof(pc300patterntst_t)))
+						return -EINVAL;
+				if (pc300patrntst.patrntst_on == 2) {
+					if (chan->falc.prbs == 0) {
+						falc_pattern_test(card, ch, 1);
+					}
+					pc300patrntst.num_errors =
+						falc_pattern_test_error(card, ch);
+					if (!arg
+					    || copy_to_user(arg, &pc300patrntst,
+							    sizeof (pc300patterntst_t)))
+							return -EINVAL;
+				} else {
+					falc_pattern_test(card, ch, pc300patrntst.patrntst_on);
+				}
+				return 0;
+			}
+
+		case SIOCWANDEV:
+			switch (ifr->ifr_settings.type) {
+				case IF_GET_IFACE: 
+				{
+					const size_t size = sizeof(sync_serial_settings);
+					sync_serial_settings *line = ifr->ifr_settings.ifs_ifsu.sync;
+
+					ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
+					if (ifr->ifr_settings.size < size) {
+						ifr->ifr_settings.size = size; /* data size wanted */
+						return -ENOBUFS;
+					}
+					if (copy_to_user(line, &conf->phys_settings, size))
+						return -EFAULT;
+					return 0;
+				}
+
+				case IF_IFACE_V35:
+				case IF_IFACE_V24:
+				case IF_IFACE_X21:
+				{
+					const size_t size = sizeof(sync_serial_settings);
+					sync_serial_settings *line = ifr->ifr_settings.ifs_ifsu.sync;
+
+					if (!capable(CAP_NET_ADMIN)) {
+						return -EPERM;
+					}
+					if (ifr->ifr_settings.size != size) {
+						return -ENOMEM; //incorrect data len
+					}
+					if (copy_from_user(&conf->phys_settings, line, size)) {
+						return -EFAULT;
+					}
+					if (conf->phys_settings.loopback) {
+						cpc_writeb(card->hw.scabase + M_REG(MD2, ch),
+							cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | 
+							MD2_LOOP_MIR);
+					}
+					conf->media = ifr->ifr_settings.type;
+					return 0;
+				}
+
+				case IF_IFACE_T1:
+				case IF_IFACE_E1:
+				{
+					const size_t te_size = sizeof(te1_settings);
+					const size_t size = sizeof(sync_serial_settings);
+					sync_serial_settings *line = ifr->ifr_settings.ifs_ifsu.sync;
+
+					if (!capable(CAP_NET_ADMIN)) {
+						return -EPERM;
+					}
+					if (ifr->ifr_settings.size != te_size) {
+						return -ENOMEM; //incorrect data len
+					}
+					if (copy_from_user(&conf->phys_settings, line, size)) {
+						return -EFAULT;
+					}/* Ignoring HDLC slot_map for a while */
+					if (conf->phys_settings.loopback) {
+						cpc_writeb(card->hw.scabase + M_REG(MD2, ch),
+							cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | 
+							MD2_LOOP_MIR);
+					}
+					conf->media = ifr->ifr_settings.type;
+					return 0;
+				}
+
+				default:
+					return hdlc_ioctl(dev, ifr, cmd);
+			}
+
+		default:
+			return hdlc_ioctl(dev, ifr, cmd);
+	}
+}
+
+static struct net_device_stats *cpc_get_stats(struct net_device *dev)
+{
+	pc300dev_t *d = (pc300dev_t *) dev->priv;
+
+	if (d)
+		return &d->hdlc->stats;
+	else
+		return NULL;
+}
+
+static int clock_rate_calc(uclong rate, uclong clock, int *br_io)
+{
+	int br, tc;
+	int br_pwr, error;
+
+	if (rate == 0)
+		return (0);
+
+	for (br = 0, br_pwr = 1; br <= 9; br++, br_pwr <<= 1) {
+		if ((tc = clock / br_pwr / rate) <= 0xff) {
+			*br_io = br;
+			break;
+		}
+	}
+
+	if (tc <= 0xff) {
+		error = ((rate - (clock / br_pwr / rate)) / rate) * 1000;
+		/* Errors bigger than +/- 1% won't be tolerated */
+		if (error < -10 || error > 10)
+			return (-1);
+		else
+			return (tc);
+	} else {
+		return (-1);
+	}
+}
+
+int ch_config(pc300dev_t * d)
+{
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
+	pc300_t *card = (pc300_t *) chan->card;
+	uclong scabase = card->hw.scabase;
+	uclong plxbase = card->hw.plxbase;
+	int ch = chan->channel;
+	uclong clkrate = chan->conf.phys_settings.clock_rate;
+	uclong clktype = chan->conf.phys_settings.clock_type;
+	ucshort encoding = chan->conf.proto_settings.encoding;
+	ucshort parity = chan->conf.proto_settings.parity;   
+	int tmc, br;
+	ucchar md0, md2;
+    
+	/* Reset the channel */
+	cpc_writeb(scabase + M_REG(CMD, ch), CMD_CH_RST);
+
+	/* Configure the SCA registers */
+	switch (parity) {
+		case PARITY_NONE:
+			md0 = MD0_BIT_SYNC;
+			break;
+		case PARITY_CRC16_PR0:
+			md0 = MD0_CRC16_0|MD0_CRCC0|MD0_BIT_SYNC;
+			break;
+		case PARITY_CRC16_PR1:
+			md0 = MD0_CRC16_1|MD0_CRCC0|MD0_BIT_SYNC;
+			break;
+		case PARITY_CRC32_PR1_CCITT:
+			md0 = MD0_CRC32|MD0_CRCC0|MD0_BIT_SYNC;
+			break;
+		case PARITY_CRC16_PR1_CCITT:
+		default:
+			md0 = MD0_CRC_CCITT|MD0_CRCC0|MD0_BIT_SYNC;
+			break;
+	}
+	switch (encoding) {
+		case ENCODING_NRZI:
+			md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZI;
+			break;
+		case ENCODING_FM_MARK:	/* FM1 */
+			md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM1;
+			break;
+		case ENCODING_FM_SPACE:	/* FM0 */
+			md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_FM0;
+			break;
+		case ENCODING_MANCHESTER: /* It's not working... */
+			md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_FM|MD2_MANCH;
+			break;
+		case ENCODING_NRZ:
+		default:
+			md2 = MD2_F_DUPLEX|MD2_ADPLL_X8|MD2_NRZ;
+			break;
+	}
+	cpc_writeb(scabase + M_REG(MD0, ch), md0);
+	cpc_writeb(scabase + M_REG(MD1, ch), 0);
+	cpc_writeb(scabase + M_REG(MD2, ch), md2);
+ 	cpc_writeb(scabase + M_REG(IDL, ch), 0x7e);
+	cpc_writeb(scabase + M_REG(CTL, ch), CTL_URSKP | CTL_IDLC);
+
+	/* Configure HW media */
+	switch (card->hw.type) {
+		case PC300_RSV:
+			if (conf->media == IF_IFACE_V35) {
+				cpc_writel((plxbase + card->hw.gpioc_reg),
+					   cpc_readl(plxbase + card->hw.gpioc_reg) | PC300_CHMEDIA_MASK(ch));
+			} else {
+				cpc_writel((plxbase + card->hw.gpioc_reg),
+					   cpc_readl(plxbase + card->hw.gpioc_reg) & ~PC300_CHMEDIA_MASK(ch));
+			}
+			break;
+
+		case PC300_X21:
+			break;
+
+		case PC300_TE:
+			te_config(card, ch);
+			break;
+	}
+
+	switch (card->hw.type) {
+		case PC300_RSV:
+		case PC300_X21:
+			if (clktype == CLOCK_INT || clktype == CLOCK_TXINT) {
+				/* Calculate the clkrate parameters */
+				tmc = clock_rate_calc(clkrate, card->hw.clock, &br);
+				cpc_writeb(scabase + M_REG(TMCT, ch), tmc);
+				cpc_writeb(scabase + M_REG(TXS, ch),
+					   (TXS_DTRXC | TXS_IBRG | br));
+				if (clktype == CLOCK_INT) {
+					cpc_writeb(scabase + M_REG(TMCR, ch), tmc);
+					cpc_writeb(scabase + M_REG(RXS, ch), 
+						   (RXS_IBRG | br));
+				} else {
+					cpc_writeb(scabase + M_REG(TMCR, ch), 1);
+					cpc_writeb(scabase + M_REG(RXS, ch), 0);
+				}
+	    			if (card->hw.type == PC300_X21) {
+					cpc_writeb(scabase + M_REG(GPO, ch), 1);
+					cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1);
+				} else {
+					cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1);
+				}
+			} else {
+				cpc_writeb(scabase + M_REG(TMCT, ch), 1);
+				if (clktype == CLOCK_EXT) {
+					cpc_writeb(scabase + M_REG(TXS, ch), 
+						   TXS_DTRXC);
+				} else {
+					cpc_writeb(scabase + M_REG(TXS, ch), 
+						   TXS_DTRXC|TXS_RCLK);
+				}
+	    			cpc_writeb(scabase + M_REG(TMCR, ch), 1);
+				cpc_writeb(scabase + M_REG(RXS, ch), 0);
+				if (card->hw.type == PC300_X21) {
+					cpc_writeb(scabase + M_REG(GPO, ch), 0);
+					cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1 | EXS_RES1);
+				} else {
+					cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1);
+				}
+			}
+			break;
+
+		case PC300_TE:
+			/* SCA always receives clock from the FALC chip */
+			cpc_writeb(scabase + M_REG(TMCT, ch), 1);
+			cpc_writeb(scabase + M_REG(TXS, ch), 0);
+			cpc_writeb(scabase + M_REG(TMCR, ch), 1);
+			cpc_writeb(scabase + M_REG(RXS, ch), 0);
+			cpc_writeb(scabase + M_REG(EXS, ch), 0);
+			break;
+	}
+
+	/* Enable Interrupts */
+	cpc_writel(scabase + IER0,
+		   cpc_readl(scabase + IER0) |
+		   IR0_M(IR0_RXINTA, ch) |
+		   IR0_DRX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch) |
+		   IR0_DTX(IR0_EFT | IR0_DMIA | IR0_DMIB, ch));
+	cpc_writeb(scabase + M_REG(IE0, ch),
+		   cpc_readl(scabase + M_REG(IE0, ch)) | IE0_RXINTA);
+	cpc_writeb(scabase + M_REG(IE1, ch),
+		   cpc_readl(scabase + M_REG(IE1, ch)) | IE1_CDCD);
+
+	return 0;
+}
+
+int rx_config(pc300dev_t * d)
+{
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300_t *card = (pc300_t *) chan->card;
+	uclong scabase = card->hw.scabase;
+	int ch = chan->channel;
+
+	cpc_writeb(scabase + DSR_RX(ch), 0);
+
+	/* General RX settings */
+	cpc_writeb(scabase + M_REG(RRC, ch), 0);
+	cpc_writeb(scabase + M_REG(RNR, ch), 16);
+
+	/* Enable reception */
+	cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_CRC_INIT);
+	cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_ENA);
+
+	/* Initialize DMA stuff */
+	chan->rx_first_bd = 0;
+	chan->rx_last_bd = N_DMA_RX_BUF - 1;
+	rx_dma_buf_init(card, ch);
+	cpc_writeb(scabase + DCR_RX(ch), DCR_FCT_CLR);
+	cpc_writeb(scabase + DMR_RX(ch), (DMR_TMOD | DMR_NF));
+	cpc_writeb(scabase + DIR_RX(ch), (DIR_EOM | DIR_BOF));
+
+	/* Start DMA */
+	rx_dma_start(card, ch);
+
+	return 0;
+}
+
+int tx_config(pc300dev_t * d)
+{
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300_t *card = (pc300_t *) chan->card;
+	uclong scabase = card->hw.scabase;
+	int ch = chan->channel;
+
+	cpc_writeb(scabase + DSR_TX(ch), 0);
+
+	/* General TX settings */
+	cpc_writeb(scabase + M_REG(TRC0, ch), 0);
+	cpc_writeb(scabase + M_REG(TFS, ch), 32);
+	cpc_writeb(scabase + M_REG(TNR0, ch), 20);
+	cpc_writeb(scabase + M_REG(TNR1, ch), 48);
+	cpc_writeb(scabase + M_REG(TCR, ch), 8);
+
+	/* Enable transmission */
+	cpc_writeb(scabase + M_REG(CMD, ch), CMD_TX_CRC_INIT);
+
+	/* Initialize DMA stuff */
+	chan->tx_first_bd = 0;
+	chan->tx_next_bd = 0;
+	tx_dma_buf_init(card, ch);
+	cpc_writeb(scabase + DCR_TX(ch), DCR_FCT_CLR);
+	cpc_writeb(scabase + DMR_TX(ch), (DMR_TMOD | DMR_NF));
+	cpc_writeb(scabase + DIR_TX(ch), (DIR_EOM | DIR_BOF | DIR_UDRF));
+	cpc_writel(scabase + DTX_REG(CDAL, ch), TX_BD_ADDR(ch, chan->tx_first_bd));
+	cpc_writel(scabase + DTX_REG(EDAL, ch), TX_BD_ADDR(ch, chan->tx_next_bd));
+
+	return 0;
+}
+
+static int cpc_attach(hdlc_device * hdlc, unsigned short encoding,
+		      unsigned short parity)
+{
+	struct net_device * dev = hdlc_to_dev(hdlc);
+	pc300dev_t *d = (pc300dev_t *)dev->priv;
+	pc300ch_t *chan = (pc300ch_t *)d->chan;
+	pc300_t *card = (pc300_t *)chan->card;
+	pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+
+	if (card->hw.type == PC300_TE) {
+		if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI) {
+			return -EINVAL;
+		}
+	} else {
+		if (encoding != ENCODING_NRZ && encoding != ENCODING_NRZI &&
+		    encoding != ENCODING_FM_MARK && encoding != ENCODING_FM_SPACE) {
+			/* Driver doesn't support ENCODING_MANCHESTER yet */
+			return -EINVAL;
+		}
+	}
+
+	if (parity != PARITY_NONE && parity != PARITY_CRC16_PR0 &&
+	    parity != PARITY_CRC16_PR1 && parity != PARITY_CRC32_PR1_CCITT &&
+	    parity != PARITY_CRC16_PR1_CCITT) {
+		return -EINVAL;
+	}
+
+	conf->proto_settings.encoding = encoding;
+	conf->proto_settings.parity = parity;
+	return 0;
+}
+
+void cpc_opench(pc300dev_t * d)
+{
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300_t *card = (pc300_t *) chan->card;
+	int ch = chan->channel;
+	uclong scabase = card->hw.scabase;
+
+	ch_config(d);
+
+	rx_config(d);
+
+	tx_config(d);
+
+	/* Assert RTS and DTR */
+	cpc_writeb(scabase + M_REG(CTL, ch),
+		   cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
+}
+
+void cpc_closech(pc300dev_t * d)
+{
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300_t *card = (pc300_t *) chan->card;
+	falc_t *pfalc = (falc_t *) & chan->falc;
+	int ch = chan->channel;
+
+	cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_CH_RST);
+	rx_dma_stop(card, ch);
+	tx_dma_stop(card, ch);
+
+	if (card->hw.type == PC300_TE) {
+		memset(pfalc, 0, sizeof(falc_t));
+		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2,
+			   cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) &
+			   ~((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK |
+			      CPLD_REG2_FALC_LED2) << (2 * ch)));
+		/* Reset the FALC chip */
+		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1,
+			   cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) |
+			   (CPLD_REG1_FALC_RESET << (2 * ch)));
+		udelay(10000);
+		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1,
+			   cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) &
+			   ~(CPLD_REG1_FALC_RESET << (2 * ch)));
+	}
+}
+
+int cpc_open(struct net_device *dev)
+{
+	hdlc_device *hdlc = dev_to_hdlc(dev);
+	pc300dev_t *d = (pc300dev_t *) dev->priv;
+	struct ifreq ifr;
+	int result;
+
+#ifdef	PC300_DEBUG_OTHER
+	printk("pc300: cpc_open");
+#endif
+
+	if (hdlc->proto == IF_PROTO_PPP) {
+		d->if_ptr = &hdlc->state.ppp.pppdev;
+	}
+
+	result = hdlc_open(hdlc);
+	if (hdlc->proto == IF_PROTO_PPP) {
+		dev->priv = d;
+	}
+	if (result) {
+		return result;
+	}
+
+	MOD_INC_USE_COUNT;
+	sprintf(ifr.ifr_name, "%s", dev->name);
+	cpc_opench(d);
+	netif_start_queue(dev);
+	return 0;
+}
+
+int cpc_close(struct net_device *dev)
+{
+	hdlc_device *hdlc = dev_to_hdlc(dev);
+	pc300dev_t *d = (pc300dev_t *) dev->priv;
+	pc300ch_t *chan = (pc300ch_t *) d->chan;
+	pc300_t *card = (pc300_t *) chan->card;
+	uclong flags;
+
+#ifdef	PC300_DEBUG_OTHER
+	printk("pc300: cpc_close");
+#endif
+
+	netif_stop_queue(dev);
+
+	CPC_LOCK(card, flags);
+	cpc_closech(d);
+	CPC_UNLOCK(card, flags);
+
+	hdlc_close(hdlc);
+	if (hdlc->proto == IF_PROTO_PPP) {
+		d->if_ptr = NULL;
+	}
+#ifdef CONFIG_PC300_MLPPP
+	if (chan->conf.proto == PC300_PROTO_MLPPP) {
+		cpc_tty_unregister_service(d);
+		chan->conf.proto = 0xffff;
+	}
+#endif
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static uclong detect_ram(pc300_t * card)
+{
+	uclong i;
+	ucchar data;
+	uclong rambase = card->hw.rambase;
+
+	card->hw.ramsize = PC300_RAMSIZE;
+	/* Let's find out how much RAM is present on this board */
+	for (i = 0; i < card->hw.ramsize; i++) {
+		data = (ucchar) (i & 0xff);
+		cpc_writeb(rambase + i, data);
+		if (cpc_readb(rambase + i) != data) {
+			break;
+		}
+	}
+	return (i);
+}
+
+static void plx_init(pc300_t * card)
+{
+	struct RUNTIME_9050 *plx_ctl = (struct RUNTIME_9050 *) card->hw.plxbase;
+
+	/* Reset PLX */
+	cpc_writel(&plx_ctl->init_ctrl,
+		   cpc_readl(&plx_ctl->init_ctrl) | 0x40000000);
+	udelay(10000L);
+	cpc_writel(&plx_ctl->init_ctrl,
+		   cpc_readl(&plx_ctl->init_ctrl) & ~0x40000000);
+
+	/* Reload Config. Registers from EEPROM */
+	cpc_writel(&plx_ctl->init_ctrl,
+		   cpc_readl(&plx_ctl->init_ctrl) | 0x20000000);
+	udelay(10000L);
+	cpc_writel(&plx_ctl->init_ctrl,
+		   cpc_readl(&plx_ctl->init_ctrl) & ~0x20000000);
+
+}
+
+static inline void show_version(void)
+{
+	char *rcsvers, *rcsdate, *tmp;
+
+	rcsvers = strchr(rcsid, ' ');
+	rcsvers++;
+	tmp = strchr(rcsvers, ' ');
+	*tmp++ = '\0';
+	rcsdate = strchr(tmp, ' ');
+	rcsdate++;
+	tmp = strrchr(rcsdate, ' ');
+	*tmp = '\0';
+	printk(KERN_INFO "Cyclades-PC300 driver %s %s (built %s %s)\n", 
+		rcsvers, rcsdate, __DATE__, __TIME__);
+}				/* show_version */
+
+static void cpc_init_card(pc300_t * card)
+{
+	int i, devcount = 0;
+	static int board_nbr = 1;
+
+	/* Enable interrupts on the PCI bridge */
+	plx_init(card);
+	cpc_writew(card->hw.plxbase + card->hw.intctl_reg,
+		   cpc_readw(card->hw.plxbase + card->hw.intctl_reg) | 0x0040);
+
+#ifdef USE_PCI_CLOCK
+	/* Set board clock to PCI clock */
+	cpc_writel(card->hw.plxbase + card->hw.gpioc_reg,
+		   cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) | 0x00000004UL);
+	card->hw.clock = PC300_PCI_CLOCK;
+#else
+	/* Set board clock to internal oscillator clock */
+	cpc_writel(card->hw.plxbase + card->hw.gpioc_reg,
+		   cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & ~0x00000004UL);
+	card->hw.clock = PC300_OSC_CLOCK;
+#endif
+
+	/* Detect actual on-board RAM size */
+	card->hw.ramsize = detect_ram(card);
+
+	/* Set Global SCA-II registers */
+	cpc_writeb(card->hw.scabase + PCR, PCR_PR2);
+	cpc_writeb(card->hw.scabase + BTCR, 0x10);
+	cpc_writeb(card->hw.scabase + WCRL, 0);
+	cpc_writeb(card->hw.scabase + DMER, 0x80);
+
+	if (card->hw.type == PC300_TE) {
+		ucchar reg1;
+
+		/* Check CPLD version */
+		reg1 = cpc_readb(card->hw.falcbase + CPLD_REG1);
+		cpc_writeb(card->hw.falcbase + CPLD_REG1, (reg1 + 0x5a));
+		if (cpc_readb(card->hw.falcbase + CPLD_REG1) == reg1) {
+			/* New CPLD */
+			card->hw.cpld_id = cpc_readb(card->hw.falcbase + CPLD_ID_REG);
+			card->hw.cpld_reg1 = CPLD_V2_REG1;
+			card->hw.cpld_reg2 = CPLD_V2_REG2;
+		} else {
+			/* old CPLD */
+			card->hw.cpld_id = 0;
+			card->hw.cpld_reg1 = CPLD_REG1;
+			card->hw.cpld_reg2 = CPLD_REG2;
+			cpc_writeb(card->hw.falcbase + CPLD_REG1, reg1);
+		}
+
+		/* Enable the board's global clock */
+		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg1,
+			   cpc_readb(card->hw.falcbase + card->hw.cpld_reg1) |
+			   CPLD_REG1_GLOBAL_CLK);
+
+	}
+
+	for (i = 0; i < card->hw.nchan; i++) {
+		pc300ch_t *chan = &card->chan[i];
+		pc300dev_t *d = &chan->d;
+		hdlc_device *hdlc;
+		struct net_device *dev;
+
+		chan->card = card;
+		chan->channel = i;
+		chan->conf.phys_settings.clock_rate = 0;
+		chan->conf.phys_settings.clock_type = CLOCK_EXT;
+		chan->conf.proto_settings.encoding = ENCODING_NRZ;
+		chan->conf.proto_settings.parity = PARITY_CRC16_PR1_CCITT;
+		switch (card->hw.type) {
+			case PC300_TE:
+				chan->conf.media = IF_IFACE_T1;
+				chan->conf.lcode = PC300_LC_B8ZS;
+				chan->conf.fr_mode = PC300_FR_ESF;
+				chan->conf.lbo = PC300_LBO_0_DB;
+				chan->conf.rx_sens = PC300_RX_SENS_SH;
+				chan->conf.tslot_bitmap = 0xffffffffUL;
+				break;
+
+			case PC300_X21:
+				chan->conf.media = IF_IFACE_X21;
+				break;
+
+			case PC300_RSV:
+			default:
+				chan->conf.media = IF_IFACE_V35;
+				break;
+		}
+		chan->conf.proto = IF_PROTO_PPP;
+		chan->tx_first_bd = 0;
+		chan->tx_next_bd = 0;
+		chan->rx_first_bd = 0;
+		chan->rx_last_bd = N_DMA_RX_BUF - 1;
+		chan->nfree_tx_bd = N_DMA_TX_BUF;
+
+		d->chan = chan;
+		d->tx_skb = NULL;
+		d->trace_on = 0;
+		d->line_on = 0;
+		d->line_off = 0;
+
+		d->hdlc = (hdlc_device *) kmalloc(sizeof(hdlc_device), GFP_KERNEL);
+		if (d->hdlc == NULL)
+			continue;
+		memset(d->hdlc, 0, sizeof(hdlc_device));
+
+		hdlc = d->hdlc;
+		hdlc->xmit = cpc_queue_xmit;
+		hdlc->attach = cpc_attach;
+
+		dev = hdlc_to_dev(hdlc);
+
+		dev->mem_start = card->hw.ramphys;
+		dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1;
+		dev->irq = card->hw.irq;
+		dev->init = NULL;
+		dev->tx_queue_len = PC300_TX_QUEUE_LEN;
+		dev->mtu = PC300_DEF_MTU;
+
+		dev->open = cpc_open;
+		dev->stop = cpc_close;
+		dev->tx_timeout = cpc_tx_timeout;
+		dev->watchdog_timeo = PC300_TX_TIMEOUT;
+		dev->get_stats = cpc_get_stats;
+		dev->set_multicast_list = NULL;
+		dev->set_mac_address = NULL;
+		dev->change_mtu = cpc_change_mtu;
+		dev->do_ioctl = cpc_ioctl;
+
+		if (register_hdlc_device(hdlc) == 0) {
+			dev->priv = d;	/* We need 'priv', hdlc doesn't */
+			printk("%s: Cyclades-PC300/", dev->name);
+			switch (card->hw.type) {
+				case PC300_TE:
+					if (card->hw.bus == PC300_PMC) {
+						printk("TE-M");
+					} else {
+						printk("TE  ");
+					}
+					break;
+
+				case PC300_X21:
+					printk("X21 ");
+					break;
+
+				case PC300_RSV:
+				default:
+					printk("RSV ");
+					break;
+			}
+			printk (" #%d, %ldKB of RAM at 0x%08lx, IRQ%d, channel %d.\n",
+				 board_nbr, card->hw.ramsize / 1024,
+				 card->hw.ramphys, card->hw.irq, i + 1);
+			devcount++;
+		} else {
+			printk ("Dev%d on card(0x%08lx): unable to allocate i/f name.\n",
+				 i + 1, card->hw.ramphys);
+			*(dev->name) = 0;
+			kfree(d->hdlc);
+			continue;
+		}
+	}
+	spin_lock_init(&card->card_lock);
+
+	board_nbr++;
+}
+
+static int __devinit
+cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	static int first_time = 1;
+	ucchar cpc_rev_id;
+	int err = 0, eeprom_outdated = 0;
+	ucshort device_id;
+	pc300_t *card;
+
+	if (first_time) {
+		first_time = 0;
+		show_version();
+#ifdef CONFIG_PC300_MLPPP
+		cpc_tty_reset_var();
+#endif
+	}
+
+	card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL);
+	if (card == NULL) {
+		printk("PC300 found at RAM 0x%08lx, "
+		       "but could not allocate card structure.\n",
+		       pci_resource_start(pdev, 3));
+		return -ENOMEM;
+	}
+	memset(card, 0, sizeof(pc300_t));
+
+	/* read PCI configuration area */
+	device_id = ent->device;
+	card->hw.irq = pdev->irq;
+	card->hw.iophys = pci_resource_start(pdev, 1);
+	card->hw.iosize = pci_resource_len(pdev, 1);
+	card->hw.scaphys = pci_resource_start(pdev, 2);
+	card->hw.scasize = pci_resource_len(pdev, 2);
+	card->hw.ramphys = pci_resource_start(pdev, 3);
+	card->hw.alloc_ramsize = pci_resource_len(pdev, 3);
+	card->hw.falcphys = pci_resource_start(pdev, 4);
+	card->hw.falcsize = pci_resource_len(pdev, 4);
+	card->hw.plxphys = pci_resource_start(pdev, 5);
+	card->hw.plxsize = pci_resource_len(pdev, 5);
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &cpc_rev_id);
+
+	switch (device_id) {
+		case PCI_DEVICE_ID_PC300_RX_1:
+		case PCI_DEVICE_ID_PC300_TE_1:
+			card->hw.nchan = 1;
+			break;
+
+		case PCI_DEVICE_ID_PC300_RX_2:
+		case PCI_DEVICE_ID_PC300_TE_2:
+		default:
+			card->hw.nchan = PC300_MAXCHAN;
+			break;
+	}
+#ifdef PC300_DEBUG_PCI
+	printk("cpc (bus=0x0%x,pci_id=0x%x,", pdev->bus->number, pdev->devfn);
+	printk("rev_id=%d) IRQ%d\n", cpc_rev_id, card->hw.irq);
+	printk("cpc:found  ramaddr=0x%08lx plxaddr=0x%08lx "
+	       "ctladdr=0x%08lx falcaddr=0x%08lx\n",
+	       card->hw.ramphys, card->hw.plxphys, card->hw.scaphys,
+	       card->hw.falcphys);
+#endif
+	/* Although we don't use this I/O region, we should
+	 * request it from the kernel anyway, to avoid problems
+	 * with other drivers accessing it. */
+	if (!request_region(card->hw.iophys, card->hw.iosize, "PLX Registers")) {
+		/* In case we can't allocate it, warn user */
+		printk("WARNING: couldn't allocate I/O region for PC300 board "
+		       "at 0x%08lx!\n", card->hw.ramphys);
+	}
+
+	if (card->hw.plxphys) {
+		pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, card->hw.plxphys);
+	} else {
+		eeprom_outdated = 1;
+		card->hw.plxphys = pci_resource_start(pdev, 0);
+		card->hw.plxsize = pci_resource_len(pdev, 0);
+	}
+
+	if (!request_mem_region(card->hw.plxphys, card->hw.plxsize,
+				"PLX Registers")) {
+		printk("PC300 found at RAM 0x%08lx, "
+		       "but could not allocate PLX mem region.\n",
+		       card->hw.ramphys);
+		err = -ENODEV;
+		goto err_release_io;
+	}
+	if (!request_mem_region(card->hw.ramphys, card->hw.alloc_ramsize,
+				"On-board RAM")) {
+		printk("PC300 found at RAM 0x%08lx, "
+		       "but could not allocate RAM mem region.\n",
+		       card->hw.ramphys);
+		err = -ENODEV;
+		goto err_release_plx;
+	}
+	if (!request_mem_region(card->hw.scaphys, card->hw.scasize,
+				"SCA-II Registers")) {
+		printk("PC300 found at RAM 0x%08lx, "
+		       "but could not allocate SCA mem region.\n",
+		       card->hw.ramphys);
+		err = -ENODEV;
+		goto err_release_ram;
+	}
+
+	if ((err = pci_enable_device(pdev)) != 0)
+		goto err_release_sca;
+
+	card->hw.plxbase = (uclong) ioremap(card->hw.plxphys, card->hw.plxsize);
+	card->hw.rambase = (uclong) ioremap(card->hw.ramphys,
+					    card->hw.alloc_ramsize);
+	card->hw.scabase = (uclong) ioremap(card->hw.scaphys, card->hw.scasize);
+	switch (device_id) {
+		case PCI_DEVICE_ID_PC300_TE_1:
+		case PCI_DEVICE_ID_PC300_TE_2:
+			request_mem_region(card->hw.falcphys, card->hw.falcsize,
+					   "FALC Registers");
+			card->hw.falcbase = (uclong) ioremap(card->hw.falcphys,
+							     card->hw.falcsize);
+			break;
+
+		case PCI_DEVICE_ID_PC300_RX_1:
+		case PCI_DEVICE_ID_PC300_RX_2:
+		default:
+			card->hw.falcbase = 0;
+			break;
+	}
+
+#ifdef PC300_DEBUG_PCI
+	printk("cpc: relocate ramaddr=0x%08lx plxaddr=0x%08lx "
+	       "ctladdr=0x%08lx falcaddr=0x%08lx\n",
+	       card->hw.rambase, card->hw.plxbase, card->hw.scabase,
+	       card->hw.falcbase);
+#endif
+
+	/* Set PCI drv pointer to the card structure */
+	pdev->driver_data = card;
+
+	/* Set board type */
+	switch (device_id) {
+		case PCI_DEVICE_ID_PC300_TE_1:
+		case PCI_DEVICE_ID_PC300_TE_2:
+			card->hw.type = PC300_TE;
+			card->hw.bus = PC300_PCI;
+			/* Set PLX register offsets */
+			card->hw.gpioc_reg = 0x50;
+			card->hw.intctl_reg = 0x4c;
+			break;
+		case PCI_DEVICE_ID_PC300_RX_1:
+		case PCI_DEVICE_ID_PC300_RX_2:
+		default:
+			card->hw.bus = PC300_PCI;
+			/* Set PLX register offsets */
+			card->hw.gpioc_reg = 0x50;
+			card->hw.intctl_reg = 0x4c;
+
+			if ((cpc_readl(card->hw.plxbase + card->hw.gpioc_reg) & PC300_CTYPE_MASK)) {
+				card->hw.type = PC300_X21;
+			} else {
+				card->hw.type = PC300_RSV;
+			}
+			break;
+	}
+
+	/* Allocate IRQ */
+	if (request_irq(card->hw.irq, cpc_intr, SA_SHIRQ, "Cyclades-PC300", card)) {
+		printk ("PC300 found at RAM 0x%08lx, but could not allocate IRQ%d.\n",
+			 card->hw.ramphys, card->hw.irq);
+		goto err_io_unmap;
+	}
+
+	cpc_init_card(card);
+
+	if (eeprom_outdated)
+		printk("WARNING: PC300 with outdated EEPROM.\n");
+	return 0;
+
+err_io_unmap:
+	iounmap((void *) card->hw.plxbase);
+	iounmap((void *) card->hw.scabase);
+	iounmap((void *) card->hw.rambase);
+	if (card->hw.type == PC300_TE) {
+		iounmap((void *) card->hw.falcbase);
+		release_mem_region(card->hw.falcphys, card->hw.falcsize);
+	}
+err_release_sca:
+	release_mem_region(card->hw.scaphys, card->hw.scasize);
+err_release_ram:
+	release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize);
+err_release_plx:
+	release_mem_region(card->hw.plxphys, card->hw.plxsize);
+err_release_io:
+	release_region(card->hw.iophys, card->hw.iosize);
+	kfree(card);
+	return -ENODEV;
+}
+
+static void __devexit cpc_remove_one(struct pci_dev *pdev)
+{
+	pc300_t *card = (pc300_t *) pdev->driver_data;
+
+	if (card->hw.rambase != 0) {
+		int i;
+
+		/* Disable interrupts on the PCI bridge */
+		cpc_writew(card->hw.plxbase + card->hw.intctl_reg,
+			   cpc_readw(card->hw.plxbase + card->hw.intctl_reg) & ~(0x0040));
+
+		for (i = 0; i < card->hw.nchan; i++) {
+			unregister_hdlc_device(card->chan[i].d.hdlc);
+		}
+		iounmap((void *) card->hw.plxbase);
+		iounmap((void *) card->hw.scabase);
+		iounmap((void *) card->hw.rambase);
+		release_mem_region(card->hw.plxphys, card->hw.plxsize);
+		release_mem_region(card->hw.ramphys, card->hw.alloc_ramsize);
+		release_mem_region(card->hw.scaphys, card->hw.scasize);
+		release_region(card->hw.iophys, card->hw.iosize);
+		if (card->hw.type == PC300_TE) {
+			iounmap((void *) card->hw.falcbase);
+			release_mem_region(card->hw.falcphys, card->hw.falcsize);
+		}
+		if (card->hw.irq)
+			free_irq(card->hw.irq, card);
+		kfree(card);
+	}
+}
+
+static struct pci_driver cpc_driver = {
+	name:"pc300",
+	id_table:cpc_pci_dev_id,
+	probe:cpc_init_one,
+	remove:cpc_remove_one,
+	suspend:NULL,
+	resume:NULL,
+};
+
+static int __init cpc_init(void)
+{
+	return pci_module_init(&cpc_driver);
+}
+
+static void __exit cpc_cleanup_module(void)
+{
+	pci_unregister_driver(&cpc_driver);
+}
+
+module_init(cpc_init);
+module_exit(cpc_cleanup_module);
+
+MODULE_DESCRIPTION("Cyclades-PC300 cards driver");
+MODULE_AUTHOR(	"Author: Ivan Passos <ivan.passos@cyclades.com>\r\n"
+				"Maintainer: PC300 Maintainer <pc300@cyclades.com");
+MODULE_LICENSE("GPL");
+					
diff -urN linux-2.4.24-pre1/drivers/net/wan/pc300_falc-lh.h linux-2.4.24-pre2/drivers/net/wan/pc300_falc-lh.h
--- linux-2.4.24-pre1/drivers/net/wan/pc300_falc-lh.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/wan/pc300_falc-lh.h	2003-12-22 11:34:35.000000000 -0800
@@ -0,0 +1,1225 @@
+/*
+ * falc.h	Description of the Siemens FALC T1/E1 framer.
+ *
+ * Author:	Ivan Passos <ivan.passos@cyclades.com>
+ *
+ * Copyright:	(c) 2000-2003 Cyclades Corp.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ */
+
+#ifndef _FALC_LH_H
+#define _FALC_LH_H
+
+#define NUM_OF_T1_CHANNELS	24
+#define NUM_OF_E1_CHANNELS	32
+
+/*>>>>>>>>>>>>>>>>>  FALC Register Bits (Transmit Mode)  <<<<<<<<<<<<<<<<<<< */
+
+/* CMDR (Command Register)
+   ---------------- E1 & T1 ------------------------------ */
+#define CMDR_RMC	0x80
+#define CMDR_RRES	0x40
+#define CMDR_XREP	0x20
+#define CMDR_XRES	0x10
+#define CMDR_XHF	0x08
+#define CMDR_XTF	0x04
+#define CMDR_XME	0x02
+#define CMDR_SRES	0x01
+
+/* MODE (Mode Register)
+   ----------------- E1 & T1 ----------------------------- */
+#define MODE_MDS2	0x80
+#define MODE_MDS1	0x40
+#define MODE_MDS0	0x20
+#define MODE_BRAC	0x10
+#define MODE_HRAC	0x08
+
+/* IPC (Interrupt Port Configuration)
+   ----------------- E1 & T1 ----------------------------- */
+#define IPC_VIS		0x80
+#define IPC_SCI		0x04
+#define IPC_IC1		0x02
+#define IPC_IC0		0x01
+
+/* CCR1 (Common Configuration Register 1)
+   ----------------- E1 & T1 ----------------------------- */
+#define CCR1_SFLG       0x80
+#define CCR1_XTS16RA    0x40
+#define CCR1_BRM        0x40
+#define CCR1_CASSYM     0x20
+#define CCR1_EDLX       0x20
+#define CCR1_EITS       0x10
+#define CCR1_ITF        0x08
+#define CCR1_RFT1       0x02
+#define CCR1_RFT0       0x01
+
+/* CCR3 (Common Configuration Register 3)
+   ---------------- E1 & T1 ------------------------------ */
+
+#define CCR3_PRE1       0x80
+#define CCR3_PRE0       0x40
+#define CCR3_EPT        0x20
+#define CCR3_RADD       0x10
+#define CCR3_RCRC       0x04
+#define CCR3_XCRC       0x02
+
+
+/* RTR1-4 (Receive Timeslot Register 1-4)
+   ---------------- E1 & T1 ------------------------------ */
+
+#define RTR1_TS0        0x80
+#define RTR1_TS1        0x40
+#define RTR1_TS2        0x20
+#define RTR1_TS3        0x10
+#define RTR1_TS4        0x08
+#define RTR1_TS5        0x04
+#define RTR1_TS6        0x02
+#define RTR1_TS7        0x01
+
+#define RTR2_TS8        0x80
+#define RTR2_TS9        0x40
+#define RTR2_TS10       0x20
+#define RTR2_TS11       0x10
+#define RTR2_TS12       0x08
+#define RTR2_TS13       0x04
+#define RTR2_TS14       0x02
+#define RTR2_TS15       0x01
+
+#define RTR3_TS16       0x80
+#define RTR3_TS17       0x40
+#define RTR3_TS18       0x20
+#define RTR3_TS19       0x10
+#define RTR3_TS20       0x08
+#define RTR3_TS21       0x04
+#define RTR3_TS22       0x02
+#define RTR3_TS23       0x01
+
+#define RTR4_TS24       0x80
+#define RTR4_TS25       0x40
+#define RTR4_TS26       0x20
+#define RTR4_TS27       0x10
+#define RTR4_TS28       0x08
+#define RTR4_TS29       0x04
+#define RTR4_TS30       0x02
+#define RTR4_TS31       0x01
+
+
+/* TTR1-4 (Transmit Timeslot Register 1-4)
+   ---------------- E1 & T1 ------------------------------ */
+
+#define TTR1_TS0        0x80
+#define TTR1_TS1        0x40
+#define TTR1_TS2        0x20
+#define TTR1_TS3        0x10
+#define TTR1_TS4        0x08
+#define TTR1_TS5        0x04
+#define TTR1_TS6        0x02
+#define TTR1_TS7        0x01
+
+#define TTR2_TS8        0x80
+#define TTR2_TS9        0x40
+#define TTR2_TS10       0x20
+#define TTR2_TS11       0x10
+#define TTR2_TS12       0x08
+#define TTR2_TS13       0x04
+#define TTR2_TS14       0x02
+#define TTR2_TS15       0x01
+
+#define TTR3_TS16       0x80
+#define TTR3_TS17       0x40
+#define TTR3_TS18       0x20
+#define TTR3_TS19       0x10
+#define TTR3_TS20       0x08
+#define TTR3_TS21       0x04
+#define TTR3_TS22       0x02
+#define TTR3_TS23       0x01
+
+#define TTR4_TS24       0x80
+#define TTR4_TS25       0x40
+#define TTR4_TS26       0x20
+#define TTR4_TS27       0x10
+#define TTR4_TS28       0x08
+#define TTR4_TS29       0x04
+#define TTR4_TS30       0x02
+#define TTR4_TS31       0x01
+
+
+
+/* IMR0-4 (Interrupt Mask Register 0-4)
+
+   ----------------- E1 & T1 ----------------------------- */
+
+#define IMR0_RME        0x80
+#define IMR0_RFS        0x40
+#define IMR0_T8MS       0x20
+#define IMR0_ISF        0x20
+#define IMR0_RMB        0x10
+#define IMR0_CASC       0x08
+#define IMR0_RSC        0x08
+#define IMR0_CRC6       0x04
+#define IMR0_CRC4       0x04
+#define IMR0_PDEN	0x02
+#define IMR0_RPF        0x01
+
+#define IMR1_CASE       0x80
+#define IMR1_RDO        0x40
+#define IMR1_ALLS       0x20
+#define IMR1_XDU        0x10
+#define IMR1_XMB        0x08
+#define IMR1_XLSC       0x02
+#define IMR1_XPR        0x01
+#define IMR1_LLBSC	0x80
+
+#define IMR2_FAR        0x80
+#define IMR2_LFA        0x40
+#define IMR2_MFAR       0x20
+#define IMR2_T400MS     0x10
+#define IMR2_LMFA       0x10
+#define IMR2_AIS        0x08
+#define IMR2_LOS        0x04
+#define IMR2_RAR        0x02
+#define IMR2_RA         0x01
+
+#define IMR3_ES         0x80
+#define IMR3_SEC        0x40
+#define IMR3_LMFA16     0x20
+#define IMR3_AIS16      0x10
+#define IMR3_RA16       0x08
+#define IMR3_API        0x04
+#define IMR3_XSLP       0x20
+#define IMR3_XSLN       0x10
+#define IMR3_LLBSC      0x08
+#define IMR3_XRS        0x04
+#define IMR3_SLN        0x02
+#define IMR3_SLP        0x01
+
+#define IMR4_LFA        0x80
+#define IMR4_FER        0x40
+#define IMR4_CER        0x20
+#define IMR4_AIS        0x10
+#define IMR4_LOS        0x08
+#define IMR4_CVE        0x04
+#define IMR4_SLIP       0x02
+#define IMR4_EBE        0x01
+
+/* FMR0-5 for E1 and T1  (Framer Mode Register ) */
+
+#define FMR0_XC1        0x80
+#define FMR0_XC0        0x40
+#define FMR0_RC1        0x20
+#define FMR0_RC0        0x10
+#define FMR0_EXTD       0x08
+#define FMR0_ALM        0x04
+#define E1_FMR0_FRS     0x02
+#define T1_FMR0_FRS     0x08
+#define FMR0_SRAF       0x04
+#define FMR0_EXLS       0x02
+#define FMR0_SIM        0x01
+
+#define FMR1_MFCS       0x80
+#define FMR1_AFR        0x40
+#define FMR1_ENSA       0x20
+#define FMR1_CTM        0x80
+#define FMR1_SIGM       0x40
+#define FMR1_EDL        0x20
+#define FMR1_PMOD       0x10
+#define FMR1_XFS        0x08
+#define FMR1_CRC        0x08
+#define FMR1_ECM        0x04
+#define FMR1_IMOD       0x02
+#define FMR1_XAIS       0x01
+
+#define FMR2_RFS1       0x80
+#define FMR2_RFS0       0x40
+#define FMR2_MCSP	0x40
+#define FMR2_RTM        0x20
+#define FMR2_SSP        0x20
+#define FMR2_DAIS       0x10
+#define FMR2_SAIS       0x08
+#define FMR2_PLB        0x04
+#define FMR2_AXRA       0x02
+#define FMR2_ALMF       0x01
+#define FMR2_EXZE       0x01
+
+#define LOOP_RTM	0x40
+#define LOOP_SFM	0x40
+#define LOOP_ECLB	0x20
+#define LOOP_CLA	0x1f
+
+/*--------------------- E1 ----------------------------*/
+#define FMR3_XLD	0x20
+#define FMR3_XLU	0x10
+
+/*--------------------- T1 ----------------------------*/
+#define FMR4_AIS3       0x80
+#define FMR4_TM         0x40
+#define FMR4_XRA        0x20
+#define FMR4_SSC1       0x10
+#define FMR4_SSC0       0x08
+#define FMR4_AUTO       0x04
+#define FMR4_FM1        0x02
+#define FMR4_FM0        0x01
+
+#define FMR5_SRS        0x80
+#define FMR5_EIBR       0x40
+#define FMR5_XLD        0x20
+#define FMR5_XLU        0x10
+
+
+/* LOOP (Channel Loop Back)
+
+   ------------------ E1 & T1 ---------------------------- */
+
+#define LOOP_SFM        0x40
+#define LOOP_ECLB       0x20
+#define LOOP_CLA4       0x10
+#define LOOP_CLA3       0x08
+#define LOOP_CLA2       0x04
+#define LOOP_CLA1       0x02
+#define LOOP_CLA0       0x01
+
+
+
+/* XSW (Transmit Service Word Pulseframe)
+
+   ------------------- E1 --------------------------- */
+
+#define XSW_XSIS        0x80
+#define XSW_XTM         0x40
+#define XSW_XRA         0x20
+#define XSW_XY0         0x10
+#define XSW_XY1         0x08
+#define XSW_XY2         0x04
+#define XSW_XY3         0x02
+#define XSW_XY4         0x01
+
+
+/* XSP (Transmit Spare Bits)
+
+   ------------------- E1 --------------------------- */
+
+#define XSP_XAP         0x80
+#define XSP_CASEN       0x40
+#define XSP_TT0         0x20
+#define XSP_EBP         0x10
+#define XSP_AXS         0x08
+#define XSP_XSIF        0x04
+#define XSP_XS13        0x02
+#define XSP_XS15        0x01
+
+
+/* XC0/1 (Transmit Control 0/1)
+   ------------------ E1 & T1 ---------------------------- */
+
+#define XC0_SA8E        0x80
+#define XC0_SA7E        0x40
+#define XC0_SA6E        0x20
+#define XC0_SA5E        0x10
+#define XC0_SA4E        0x08
+#define XC0_BRM         0x80
+#define XC0_MFBS        0x40
+#define XC0_SFRZ        0x10
+#define XC0_XCO2        0x04
+#define XC0_XCO1        0x02
+#define XC0_XCO0        0x01
+
+#define XC1_XTO5        0x20
+#define XC1_XTO4        0x10
+#define XC1_XTO3        0x08
+#define XC1_XTO2        0x04
+#define XC1_XTO1        0x02
+#define XC1_XTO0        0x01
+
+
+/* RC0/1 (Receive Control 0/1)
+   ------------------ E1 & T1 ---------------------------- */
+
+#define RC0_SICS        0x40
+#define RC0_CRCI        0x20
+#define RC0_XCRCI       0x10
+#define RC0_RDIS        0x08
+#define RC0_RCO2        0x04
+#define RC0_RCO1        0x02
+#define RC0_RCO0        0x01
+
+#define RC1_SWD         0x80
+#define RC1_ASY4        0x40
+#define RC1_RRAM        0x40
+#define RC1_RTO5        0x20
+#define RC1_RTO4        0x10
+#define RC1_RTO3        0x08
+#define RC1_RTO2        0x04
+#define RC1_RTO1        0x02
+#define RC1_RTO0        0x01
+
+
+
+/* XPM0-2 (Transmit Pulse Mask 0-2)
+   --------------------- E1 & T1 ------------------------- */
+
+#define XPM0_XP12       0x80
+#define XPM0_XP11       0x40
+#define XPM0_XP10       0x20
+#define XPM0_XP04       0x10
+#define XPM0_XP03       0x08
+#define XPM0_XP02       0x04
+#define XPM0_XP01       0x02
+#define XPM0_XP00       0x01
+
+#define XPM1_XP30       0x80
+#define XPM1_XP24       0x40
+#define XPM1_XP23       0x20
+#define XPM1_XP22       0x10
+#define XPM1_XP21       0x08
+#define XPM1_XP20       0x04
+#define XPM1_XP14       0x02
+#define XPM1_XP13       0x01
+
+#define XPM2_XLHP       0x80
+#define XPM2_XLT        0x40
+#define XPM2_DAXLT      0x20
+#define XPM2_XP34       0x08
+#define XPM2_XP33       0x04
+#define XPM2_XP32       0x02
+#define XPM2_XP31       0x01
+
+
+/* TSWM (Transparent Service Word Mask)
+   ------------------ E1 ---------------------------- */
+
+#define TSWM_TSIS       0x80
+#define TSWM_TSIF       0x40
+#define TSWM_TRA        0x20
+#define TSWM_TSA4       0x10
+#define TSWM_TSA5       0x08
+#define TSWM_TSA6       0x04
+#define TSWM_TSA7       0x02
+#define TSWM_TSA8       0x01
+
+/* IDLE <Idle Channel Code Register>
+
+   ------------------ E1 & T1 ----------------------- */
+
+#define IDLE_IDL7       0x80
+#define IDLE_IDL6       0x40
+#define IDLE_IDL5       0x20
+#define IDLE_IDL4       0x10
+#define IDLE_IDL3       0x08
+#define IDLE_IDL2       0x04
+#define IDLE_IDL1       0x02
+#define IDLE_IDL0       0x01
+
+
+/* XSA4-8 <Transmit SA4-8 Register(Read/Write) >
+   -------------------E1 ----------------------------- */
+
+#define XSA4_XS47       0x80
+#define XSA4_XS46       0x40
+#define XSA4_XS45       0x20
+#define XSA4_XS44       0x10
+#define XSA4_XS43       0x08
+#define XSA4_XS42       0x04
+#define XSA4_XS41       0x02
+#define XSA4_XS40       0x01
+
+#define XSA5_XS57       0x80
+#define XSA5_XS56       0x40
+#define XSA5_XS55       0x20
+#define XSA5_XS54       0x10
+#define XSA5_XS53       0x08
+#define XSA5_XS52       0x04
+#define XSA5_XS51       0x02
+#define XSA5_XS50       0x01
+
+#define XSA6_XS67       0x80
+#define XSA6_XS66       0x40
+#define XSA6_XS65       0x20
+#define XSA6_XS64       0x10
+#define XSA6_XS63       0x08
+#define XSA6_XS62       0x04
+#define XSA6_XS61       0x02
+#define XSA6_XS60       0x01
+
+#define XSA7_XS77       0x80
+#define XSA7_XS76       0x40
+#define XSA7_XS75       0x20
+#define XSA7_XS74       0x10
+#define XSA7_XS73       0x08
+#define XSA7_XS72       0x04
+#define XSA7_XS71       0x02
+#define XSA7_XS70       0x01
+
+#define XSA8_XS87       0x80
+#define XSA8_XS86       0x40
+#define XSA8_XS85       0x20
+#define XSA8_XS84       0x10
+#define XSA8_XS83       0x08
+#define XSA8_XS82       0x04
+#define XSA8_XS81       0x02
+#define XSA8_XS80       0x01
+
+
+/* XDL1-3 (Transmit DL-Bit Register1-3 (read/write))
+   ----------------------- T1 --------------------- */
+
+#define XDL1_XDL17      0x80
+#define XDL1_XDL16      0x40
+#define XDL1_XDL15      0x20
+#define XDL1_XDL14      0x10
+#define XDL1_XDL13      0x08
+#define XDL1_XDL12      0x04
+#define XDL1_XDL11      0x02
+#define XDL1_XDL10      0x01
+
+#define XDL2_XDL27      0x80
+#define XDL2_XDL26      0x40
+#define XDL2_XDL25      0x20
+#define XDL2_XDL24      0x10
+#define XDL2_XDL23      0x08
+#define XDL2_XDL22      0x04
+#define XDL2_XDL21      0x02
+#define XDL2_XDL20      0x01
+
+#define XDL3_XDL37      0x80
+#define XDL3_XDL36      0x40
+#define XDL3_XDL35      0x20
+#define XDL3_XDL34      0x10
+#define XDL3_XDL33      0x08
+#define XDL3_XDL32      0x04
+#define XDL3_XDL31      0x02
+#define XDL3_XDL30      0x01
+
+
+/* ICB1-4 (Idle Channel Register 1-4)
+   ------------------ E1 ---------------------------- */
+
+#define E1_ICB1_IC0	0x80
+#define E1_ICB1_IC1	0x40
+#define E1_ICB1_IC2	0x20
+#define E1_ICB1_IC3	0x10
+#define E1_ICB1_IC4	0x08
+#define E1_ICB1_IC5	0x04
+#define E1_ICB1_IC6	0x02
+#define E1_ICB1_IC7	0x01
+
+#define E1_ICB2_IC8	0x80
+#define E1_ICB2_IC9	0x40
+#define E1_ICB2_IC10	0x20
+#define E1_ICB2_IC11	0x10
+#define E1_ICB2_IC12	0x08
+#define E1_ICB2_IC13	0x04
+#define E1_ICB2_IC14	0x02
+#define E1_ICB2_IC15	0x01
+
+#define E1_ICB3_IC16	0x80
+#define E1_ICB3_IC17	0x40
+#define E1_ICB3_IC18	0x20
+#define E1_ICB3_IC19	0x10
+#define E1_ICB3_IC20	0x08
+#define E1_ICB3_IC21	0x04
+#define E1_ICB3_IC22	0x02
+#define E1_ICB3_IC23	0x01
+
+#define E1_ICB4_IC24	0x80
+#define E1_ICB4_IC25	0x40
+#define E1_ICB4_IC26	0x20
+#define E1_ICB4_IC27	0x10
+#define E1_ICB4_IC28	0x08
+#define E1_ICB4_IC29	0x04
+#define E1_ICB4_IC30	0x02
+#define E1_ICB4_IC31	0x01
+
+/* ICB1-4 (Idle Channel Register 1-4)
+   ------------------ T1 ---------------------------- */
+
+#define T1_ICB1_IC1	0x80
+#define T1_ICB1_IC2	0x40
+#define T1_ICB1_IC3	0x20
+#define T1_ICB1_IC4	0x10
+#define T1_ICB1_IC5	0x08
+#define T1_ICB1_IC6	0x04
+#define T1_ICB1_IC7	0x02
+#define T1_ICB1_IC8	0x01
+
+#define T1_ICB2_IC9	0x80
+#define T1_ICB2_IC10	0x40
+#define T1_ICB2_IC11	0x20
+#define T1_ICB2_IC12	0x10
+#define T1_ICB2_IC13	0x08
+#define T1_ICB2_IC14	0x04
+#define T1_ICB2_IC15	0x02
+#define T1_ICB2_IC16	0x01
+
+#define T1_ICB3_IC17	0x80
+#define T1_ICB3_IC18	0x40
+#define T1_ICB3_IC19	0x20
+#define T1_ICB3_IC20	0x10
+#define T1_ICB3_IC21	0x08
+#define T1_ICB3_IC22	0x04
+#define T1_ICB3_IC23	0x02
+#define T1_ICB3_IC24	0x01
+
+/* FMR3 (Framer Mode Register 3)
+   --------------------E1------------------------ */
+
+#define FMR3_CMI        0x08
+#define FMR3_SYNSA      0x04
+#define FMR3_CFRZ       0x02
+#define FMR3_EXTIW      0x01
+
+
+
+/* CCB1-3 (Clear Channel Register)
+   ------------------- T1 ----------------------- */
+
+#define CCB1_CH1        0x80
+#define CCB1_CH2        0x40
+#define CCB1_CH3        0x20
+#define CCB1_CH4        0x10
+#define CCB1_CH5        0x08
+#define CCB1_CH6        0x04
+#define CCB1_CH7        0x02
+#define CCB1_CH8        0x01
+
+#define CCB2_CH9        0x80
+#define CCB2_CH10       0x40
+#define CCB2_CH11       0x20
+#define CCB2_CH12       0x10
+#define CCB2_CH13       0x08
+#define CCB2_CH14       0x04
+#define CCB2_CH15       0x02
+#define CCB2_CH16       0x01
+
+#define CCB3_CH17       0x80
+#define CCB3_CH18       0x40
+#define CCB3_CH19       0x20
+#define CCB3_CH20       0x10
+#define CCB3_CH21       0x08
+#define CCB3_CH22       0x04
+#define CCB3_CH23       0x02
+#define CCB3_CH24       0x01
+
+
+/* LIM0/1 (Line Interface Mode 0/1)
+   ------------------- E1 & T1 --------------------------- */
+
+#define LIM0_XFB        0x80
+#define LIM0_XDOS       0x40
+#define LIM0_SCL1       0x20
+#define LIM0_SCL0       0x10
+#define LIM0_EQON       0x08
+#define LIM0_ELOS       0x04
+#define LIM0_LL         0x02
+#define LIM0_MAS        0x01
+
+#define LIM1_EFSC       0x80
+#define LIM1_RIL2       0x40
+#define LIM1_RIL1       0x20
+#define LIM1_RIL0       0x10
+#define LIM1_DCOC       0x08
+#define LIM1_JATT       0x04
+#define LIM1_RL         0x02
+#define LIM1_DRS        0x01
+
+
+/* PCDR (Pulse Count Detection Register(Read/Write))
+   ------------------ E1 & T1 ------------------------- */
+
+#define PCDR_PCD7	0x80
+#define PCDR_PCD6	0x40
+#define PCDR_PCD5	0x20
+#define PCDR_PCD4	0x10
+#define PCDR_PCD3	0x08
+#define PCDR_PCD2	0x04
+#define PCDR_PCD1	0x02
+#define PCDR_PCD0	0x01
+
+#define PCRR_PCR7	0x80
+#define PCRR_PCR6	0x40
+#define PCRR_PCR5	0x20
+#define PCRR_PCR4	0x10
+#define PCRR_PCR3	0x08
+#define PCRR_PCR2	0x04
+#define PCRR_PCR1	0x02
+#define PCRR_PCR0	0x01
+
+
+/* LIM2 (Line Interface Mode 2)
+
+   ------------------ E1 & T1 ---------------------------- */
+
+#define LIM2_DJA2	0x20
+#define LIM2_DJA1	0x10
+#define LIM2_LOS2	0x02
+#define LIM2_LOS1	0x01
+
+/* LCR1 (Loop Code Register 1) */
+
+#define LCR1_EPRM	0x80
+#define	LCR1_XPRBS	0x40
+
+/* SIC1 (System Interface Control 1) */
+#define SIC1_SRSC	0x80
+#define SIC1_RBS1	0x20
+#define SIC1_RBS0	0x10
+#define SIC1_SXSC	0x08
+#define SIC1_XBS1	0x02
+#define SIC1_XBS0	0x01
+
+/* DEC (Disable Error Counter)
+   ------------------ E1 & T1 ---------------------------- */
+
+#define DEC_DCEC3       0x20
+#define DEC_DBEC        0x10
+#define DEC_DCEC1       0x08
+#define DEC_DCEC        0x08
+#define DEC_DEBC        0x04
+#define DEC_DCVC        0x02
+#define DEC_DFEC        0x01
+
+
+/* FALC Register Bits (Receive Mode)
+   ---------------------------------------------------------------------------- */
+
+
+/* FRS0/1 (Framer Receive Status Register 0/1)
+   ----------------- E1 & T1 ---------------------------------- */
+
+#define FRS0_LOS        0x80
+#define FRS0_AIS        0x40
+#define FRS0_LFA        0x20
+#define FRS0_RRA        0x10
+#define FRS0_API        0x08
+#define FRS0_NMF        0x04
+#define FRS0_LMFA       0x02
+#define FRS0_FSRF       0x01
+
+#define FRS1_TS16RA     0x40
+#define FRS1_TS16LOS    0x20
+#define FRS1_TS16AIS    0x10
+#define FRS1_TS16LFA    0x08
+#define FRS1_EXZD       0x80
+#define FRS1_LLBDD      0x10
+#define FRS1_LLBAD      0x08
+#define FRS1_XLS        0x02
+#define FRS1_XLO        0x01
+#define FRS1_PDEN	0x40
+
+/* FRS2/3 (Framer Receive Status Register 2/3)
+   ----------------- T1 ---------------------------------- */
+
+#define FRS2_ESC2       0x80
+#define FRS2_ESC1       0x40
+#define FRS2_ESC0       0x20
+
+#define FRS3_FEH5       0x20
+#define FRS3_FEH4       0x10
+#define FRS3_FEH3       0x08
+#define FRS3_FEH2       0x04
+#define FRS3_FEH1       0x02
+#define FRS3_FEH0       0x01
+
+
+/* RSW (Receive Service Word Pulseframe)
+   ----------------- E1 ------------------------------ */
+
+#define RSW_RSI         0x80
+#define RSW_RRA         0x20
+#define RSW_RYO         0x10
+#define RSW_RY1         0x08
+#define RSW_RY2         0x04
+#define RSW_RY3         0x02
+#define RSW_RY4         0x01
+
+
+/* RSP (Receive Spare Bits / Additional Status)
+   ---------------- E1 ------------------------------- */
+
+#define RSP_SI1         0x80
+#define RSP_SI2         0x40
+#define RSP_LLBDD	0x10
+#define RSP_LLBAD	0x08
+#define RSP_RSIF        0x04
+#define RSP_RS13        0x02
+#define RSP_RS15        0x01
+
+
+/* FECL (Framing Error Counter)
+   ---------------- E1 & T1 -------------------------- */
+
+#define FECL_FE7        0x80
+#define FECL_FE6        0x40
+#define FECL_FE5        0x20
+#define FECL_FE4        0x10
+#define FECL_FE3        0x08
+#define FECL_FE2        0x04
+#define FECL_FE1        0x02
+#define FECL_FE0        0x01
+
+#define FECH_FE15       0x80
+#define FECH_FE14       0x40
+#define FECH_FE13       0x20
+#define FECH_FE12       0x10
+#define FECH_FE11       0x08
+#define FECH_FE10       0x04
+#define FECH_FE9        0x02
+#define FECH_FE8        0x01
+
+
+/* CVCl (Code Violation Counter)
+   ----------------- E1 ------------------------- */
+
+#define CVCL_CV7        0x80
+#define CVCL_CV6        0x40
+#define CVCL_CV5        0x20
+#define CVCL_CV4        0x10
+#define CVCL_CV3        0x08
+#define CVCL_CV2        0x04
+#define CVCL_CV1        0x02
+#define CVCL_CV0        0x01
+
+#define CVCH_CV15       0x80
+#define CVCH_CV14       0x40
+#define CVCH_CV13       0x20
+#define CVCH_CV12       0x10
+#define CVCH_CV11       0x08
+#define CVCH_CV10       0x04
+#define CVCH_CV9        0x02
+#define CVCH_CV8        0x01
+
+
+/* CEC1-3L (CRC Error Counter)
+   ------------------ E1 ----------------------------- */
+
+#define CEC1L_CR7       0x80
+#define CEC1L_CR6       0x40
+#define CEC1L_CR5       0x20
+#define CEC1L_CR4       0x10
+#define CEC1L_CR3       0x08
+#define CEC1L_CR2       0x04
+#define CEC1L_CR1       0x02
+#define CEC1L_CR0       0x01
+
+#define CEC1H_CR15      0x80
+#define CEC1H_CR14      0x40
+#define CEC1H_CR13      0x20
+#define CEC1H_CR12      0x10
+#define CEC1H_CR11      0x08
+#define CEC1H_CR10      0x04
+#define CEC1H_CR9       0x02
+#define CEC1H_CR8       0x01
+
+#define CEC2L_CR7       0x80
+#define CEC2L_CR6       0x40
+#define CEC2L_CR5       0x20
+#define CEC2L_CR4       0x10
+#define CEC2L_CR3       0x08
+#define CEC2L_CR2       0x04
+#define CEC2L_CR1       0x02
+#define CEC2L_CR0       0x01
+
+#define CEC2H_CR15      0x80
+#define CEC2H_CR14      0x40
+#define CEC2H_CR13      0x20
+#define CEC2H_CR12      0x10
+#define CEC2H_CR11      0x08
+#define CEC2H_CR10      0x04
+#define CEC2H_CR9       0x02
+#define CEC2H_CR8       0x01
+
+#define CEC3L_CR7       0x80
+#define CEC3L_CR6       0x40
+#define CEC3L_CR5       0x20
+#define CEC3L_CR4       0x10
+#define CEC3L_CR3       0x08
+#define CEC3L_CR2       0x04
+#define CEC3L_CR1       0x02
+#define CEC3L_CR0       0x01
+
+#define CEC3H_CR15      0x80
+#define CEC3H_CR14      0x40
+#define CEC3H_CR13      0x20
+#define CEC3H_CR12      0x10
+#define CEC3H_CR11      0x08
+#define CEC3H_CR10      0x04
+#define CEC3H_CR9       0x02
+#define CEC3H_CR8       0x01
+
+
+/* CECL (CRC Error Counter)
+
+   ------------------ T1 ----------------------------- */
+
+#define CECL_CR7        0x80
+#define CECL_CR6        0x40
+#define CECL_CR5        0x20
+#define CECL_CR4        0x10
+#define CECL_CR3        0x08
+#define CECL_CR2        0x04
+#define CECL_CR1        0x02
+#define CECL_CR0        0x01
+
+#define CECH_CR15       0x80
+#define CECH_CR14       0x40
+#define CECH_CR13       0x20
+#define CECH_CR12       0x10
+#define CECH_CR11       0x08
+#define CECH_CR10       0x04
+#define CECH_CR9        0x02
+#define CECH_CR8        0x01
+
+/* EBCL (E Bit Error Counter)
+   ------------------- E1 & T1 ------------------------- */
+
+#define EBCL_EB7        0x80
+#define EBCL_EB6        0x40
+#define EBCL_EB5        0x20
+#define EBCL_EB4        0x10
+#define EBCL_EB3        0x08
+#define EBCL_EB2        0x04
+#define EBCL_EB1        0x02
+#define EBCL_EB0        0x01
+
+#define EBCH_EB15       0x80
+#define EBCH_EB14       0x40
+#define EBCH_EB13       0x20
+#define EBCH_EB12       0x10
+#define EBCH_EB11       0x08
+#define EBCH_EB10       0x04
+#define EBCH_EB9        0x02
+#define EBCH_EB8        0x01
+
+
+/* RSA4-8 (Receive Sa4-8-Bit Register)
+   -------------------- E1 --------------------------- */
+
+#define RSA4_RS47       0x80
+#define RSA4_RS46       0x40
+#define RSA4_RS45       0x20
+#define RSA4_RS44       0x10
+#define RSA4_RS43       0x08
+#define RSA4_RS42       0x04
+#define RSA4_RS41       0x02
+#define RSA4_RS40       0x01
+
+#define RSA5_RS57       0x80
+#define RSA5_RS56       0x40
+#define RSA5_RS55       0x20
+#define RSA5_RS54       0x10
+#define RSA5_RS53       0x08
+#define RSA5_RS52       0x04
+#define RSA5_RS51       0x02
+#define RSA5_RS50       0x01
+
+#define RSA6_RS67       0x80
+#define RSA6_RS66       0x40
+#define RSA6_RS65       0x20
+#define RSA6_RS64       0x10
+#define RSA6_RS63       0x08
+#define RSA6_RS62       0x04
+#define RSA6_RS61       0x02
+#define RSA6_RS60       0x01
+
+#define RSA7_RS77       0x80
+#define RSA7_RS76       0x40
+#define RSA7_RS75       0x20
+#define RSA7_RS74       0x10
+#define RSA7_RS73       0x08
+#define RSA7_RS72       0x04
+#define RSA7_RS71       0x02
+#define RSA7_RS70       0x01
+
+#define RSA8_RS87       0x80
+#define RSA8_RS86       0x40
+#define RSA8_RS85       0x20
+#define RSA8_RS84       0x10
+#define RSA8_RS83       0x08
+#define RSA8_RS82       0x04
+#define RSA8_RS81       0x02
+#define RSA8_RS80       0x01
+
+/* RSA6S (Receive Sa6 Bit Status Register)
+   ------------------------ T1 ------------------------- */
+
+#define RSA6S_SX        0x20
+#define RSA6S_SF        0x10
+#define RSA6S_SE        0x08
+#define RSA6S_SC        0x04
+#define RSA6S_SA        0x02
+#define RSA6S_S8        0x01
+
+
+/* RDL1-3 Receive DL-Bit Register1-3)
+   ------------------------ T1 ------------------------- */
+
+#define RDL1_RDL17      0x80
+#define RDL1_RDL16      0x40
+#define RDL1_RDL15      0x20
+#define RDL1_RDL14      0x10
+#define RDL1_RDL13      0x08
+#define RDL1_RDL12      0x04
+#define RDL1_RDL11      0x02
+#define RDL1_RDL10      0x01
+
+#define RDL2_RDL27      0x80
+#define RDL2_RDL26      0x40
+#define RDL2_RDL25      0x20
+#define RDL2_RDL24      0x10
+#define RDL2_RDL23      0x08
+#define RDL2_RDL22      0x04
+#define RDL2_RDL21      0x02
+#define RDL2_RDL20      0x01
+
+#define RDL3_RDL37      0x80
+#define RDL3_RDL36      0x40
+#define RDL3_RDL35      0x20
+#define RDL3_RDL34      0x10
+#define RDL3_RDL33      0x08
+#define RDL3_RDL32      0x04
+#define RDL3_RDL31      0x02
+#define RDL3_RDL30      0x01
+
+
+/* SIS (Signaling Status Register)
+
+   -------------------- E1 & T1 -------------------------- */
+
+#define SIS_XDOV        0x80
+#define SIS_XFW         0x40
+#define SIS_XREP        0x20
+#define SIS_RLI         0x08
+#define SIS_CEC         0x04
+#define SIS_BOM         0x01
+
+
+/* RSIS (Receive Signaling Status Register)
+
+   -------------------- E1 & T1 --------------------------- */
+
+#define RSIS_VFR        0x80
+#define RSIS_RDO        0x40
+#define RSIS_CRC16      0x20
+#define RSIS_RAB        0x10
+#define RSIS_HA1        0x08
+#define RSIS_HA0        0x04
+#define RSIS_HFR        0x02
+#define RSIS_LA         0x01
+
+
+/* RBCL/H (Receive Byte Count Low/High)
+
+   ------------------- E1 & T1 ----------------------- */
+
+#define RBCL_RBC7       0x80
+#define RBCL_RBC6       0x40
+#define RBCL_RBC5       0x20
+#define RBCL_RBC4       0x10
+#define RBCL_RBC3       0x08
+#define RBCL_RBC2       0x04
+#define RBCL_RBC1       0x02
+#define RBCL_RBC0       0x01
+
+#define RBCH_OV         0x10
+#define RBCH_RBC11      0x08
+#define RBCH_RBC10      0x04
+#define RBCH_RBC9       0x02
+#define RBCH_RBC8       0x01
+
+
+/* ISR1-3  (Interrupt Status Register 1-3)
+
+   ------------------ E1 & T1 ------------------------------ */
+
+#define  FISR0_RME	0x80
+#define  FISR0_RFS	0x40
+#define  FISR0_T8MS	0x20
+#define  FISR0_ISF	0x20
+#define  FISR0_RMB	0x10
+#define  FISR0_CASC	0x08
+#define  FISR0_RSC	0x08
+#define  FISR0_CRC6	0x04
+#define  FISR0_CRC4	0x04
+#define  FISR0_PDEN	0x02
+#define  FISR0_RPF	0x01
+
+#define  FISR1_CASE	0x80
+#define  FISR1_LLBSC	0x80
+#define  FISR1_RDO	0x40
+#define  FISR1_ALLS	0x20
+#define  FISR1_XDU	0x10
+#define  FISR1_XMB	0x08
+#define  FISR1_XLSC	0x02
+#define  FISR1_XPR	0x01
+
+#define  FISR2_FAR	0x80
+#define  FISR2_LFA	0x40
+#define  FISR2_MFAR	0x20
+#define  FISR2_T400MS	0x10
+#define  FISR2_LMFA	0x10
+#define  FISR2_AIS	0x08
+#define  FISR2_LOS	0x04
+#define  FISR2_RAR	0x02
+#define  FISR2_RA	0x01
+
+#define  FISR3_ES	0x80
+#define  FISR3_SEC	0x40
+#define  FISR3_LMFA16	0x20
+#define  FISR3_AIS16	0x10
+#define  FISR3_RA16	0x08
+#define  FISR3_API	0x04
+#define  FISR3_XSLP	0x20
+#define  FISR3_XSLN	0x10
+#define  FISR3_LLBSC	0x08
+#define  FISR3_XRS	0x04
+#define  FISR3_SLN	0x02
+#define  FISR3_SLP	0x01
+
+
+/* GIS  (Global Interrupt Status Register)
+
+   --------------------- E1 & T1 --------------------- */
+
+#define  GIS_ISR3	0x08
+#define  GIS_ISR2	0x04
+#define  GIS_ISR1	0x02
+#define  GIS_ISR0	0x01
+
+
+/* VSTR  (Version Status Register)
+
+   --------------------- E1 & T1 --------------------- */
+
+#define  VSTR_VN3	0x08
+#define  VSTR_VN2	0x04
+#define  VSTR_VN1	0x02
+#define  VSTR_VN0	0x01
+
+
+/*>>>>>>>>>>>>>>>>>>>>>  Local Control Structures  <<<<<<<<<<<<<<<<<<<<<<<<< */
+
+/* Write-only Registers (E1/T1 control mode write registers) */
+#define XFIFOH	0x00		/* Tx FIFO High Byte */
+#define XFIFOL	0x01		/* Tx FIFO Low Byte */
+#define CMDR	0x02		/* Command Reg */
+#define DEC	0x60		/* Disable Error Counter */
+#define TEST2	0x62		/* Manuf. Test Reg 2 */
+#define XS(nbr)	(0x70 + (nbr))	/* Tx CAS Reg (0 to 15) */
+
+/* Read-write Registers (E1/T1 status mode read registers) */
+#define MODE	0x03	/* Mode Reg */
+#define RAH1	0x04	/* Receive Address High 1 */
+#define RAH2	0x05	/* Receive Address High 2 */
+#define RAL1	0x06	/* Receive Address Low 1 */
+#define RAL2	0x07	/* Receive Address Low 2 */
+#define IPC	0x08	/* Interrupt Port Configuration */
+#define CCR1	0x09	/* Common Configuration Reg 1 */
+#define CCR3	0x0A	/* Common Configuration Reg 3 */
+#define PRE	0x0B	/* Preamble Reg */
+#define RTR1	0x0C	/* Receive Timeslot Reg 1 */
+#define RTR2	0x0D	/* Receive Timeslot Reg 2 */
+#define RTR3	0x0E	/* Receive Timeslot Reg 3 */
+#define RTR4	0x0F	/* Receive Timeslot Reg 4 */
+#define TTR1	0x10	/* Transmit Timeslot Reg 1 */
+#define TTR2	0x11	/* Transmit Timeslot Reg 2 */
+#define TTR3	0x12	/* Transmit Timeslot Reg 3 */
+#define TTR4	0x13	/* Transmit Timeslot Reg 4 */
+#define IMR0	0x14	/* Interrupt Mask Reg 0 */
+#define IMR1	0x15	/* Interrupt Mask Reg 1 */
+#define IMR2	0x16	/* Interrupt Mask Reg 2 */
+#define IMR3	0x17	/* Interrupt Mask Reg 3 */
+#define IMR4	0x18	/* Interrupt Mask Reg 4 */
+#define IMR5	0x19	/* Interrupt Mask Reg 5 */
+#define FMR0	0x1A	/* Framer Mode Reigster 0 */
+#define FMR1	0x1B	/* Framer Mode Reigster 1 */
+#define FMR2	0x1C	/* Framer Mode Reigster 2 */
+#define LOOP	0x1D	/* Channel Loop Back */
+#define XSW	0x1E	/* Transmit Service Word */
+#define FMR4	0x1E	/* Framer Mode Reg 4 */
+#define XSP	0x1F	/* Transmit Spare Bits */
+#define FMR5	0x1F	/* Framer Mode Reg 5 */
+#define XC0	0x20	/* Transmit Control 0 */
+#define XC1	0x21	/* Transmit Control 1 */
+#define RC0	0x22	/* Receive Control 0 */
+#define RC1	0x23	/* Receive Control 1 */
+#define XPM0	0x24	/* Transmit Pulse Mask 0 */
+#define XPM1	0x25	/* Transmit Pulse Mask 1 */
+#define XPM2	0x26	/* Transmit Pulse Mask 2 */
+#define TSWM	0x27	/* Transparent Service Word Mask */
+#define TEST1	0x28	/* Manuf. Test Reg 1 */
+#define IDLE	0x29	/* Idle Channel Code */
+#define XSA4    0x2A	/* Transmit SA4 Bit Reg */
+#define XDL1	0x2A	/* Transmit DL-Bit Reg 2 */
+#define XSA5    0x2B	/* Transmit SA4 Bit Reg */
+#define XDL2	0x2B	/* Transmit DL-Bit Reg 2 */
+#define XSA6    0x2C	/* Transmit SA4 Bit Reg */
+#define XDL3	0x2C	/* Transmit DL-Bit Reg 2 */
+#define XSA7    0x2D	/* Transmit SA4 Bit Reg */
+#define CCB1	0x2D	/* Clear Channel Reg 1 */
+#define XSA8    0x2E	/* Transmit SA4 Bit Reg */
+#define CCB2	0x2E	/* Clear Channel Reg 2 */
+#define FMR3	0x2F	/* Framer Mode Reg. 3 */
+#define CCB3	0x2F	/* Clear Channel Reg 3 */
+#define ICB1	0x30	/* Idle Channel Reg 1 */
+#define ICB2	0x31	/* Idle Channel Reg 2 */
+#define ICB3	0x32	/* Idle Channel Reg 3 */
+#define ICB4	0x33	/* Idle Channel Reg 4 */
+#define LIM0	0x34	/* Line Interface Mode 0 */
+#define LIM1	0x35	/* Line Interface Mode 1 */
+#define PCDR	0x36	/* Pulse Count Detection */
+#define PCRR	0x37	/* Pulse Count Recovery */
+#define LIM2	0x38	/* Line Interface Mode Reg 2 */
+#define LCR1	0x39	/* Loop Code Reg 1 */
+#define LCR2	0x3A	/* Loop Code Reg 2 */
+#define LCR3	0x3B	/* Loop Code Reg 3 */
+#define SIC1	0x3C	/* System Interface Control 1 */
+
+/* Read-only Registers (E1/T1 control mode read registers) */
+#define RFIFOH	0x00		/* Receive FIFO */
+#define RFIFOL	0x01		/* Receive FIFO */
+#define FRS0	0x4C		/* Framer Receive Status 0 */
+#define FRS1	0x4D		/* Framer Receive Status 1 */
+#define RSW	0x4E		/* Receive Service Word */
+#define FRS2	0x4E		/* Framer Receive Status 2 */
+#define RSP	0x4F		/* Receive Spare Bits */
+#define FRS3	0x4F		/* Framer Receive Status 3 */
+#define FECL	0x50		/* Framing Error Counter */
+#define FECH	0x51		/* Framing Error Counter */
+#define CVCL	0x52		/* Code Violation Counter */
+#define CVCH	0x53		/* Code Violation Counter */
+#define CECL	0x54		/* CRC Error Counter 1 */
+#define CECH	0x55		/* CRC Error Counter 1 */
+#define EBCL	0x56		/* E-Bit Error Counter */
+#define EBCH	0x57		/* E-Bit Error Counter */
+#define BECL	0x58		/* Bit Error Counter Low */
+#define BECH	0x59		/* Bit Error Counter Low */
+#define CEC3	0x5A		/* CRC Error Counter 3 (16-bit) */
+#define RSA4	0x5C		/* Receive SA4 Bit Reg */
+#define RDL1	0x5C		/* Receive DL-Bit Reg 1 */
+#define RSA5	0x5D		/* Receive SA5 Bit Reg */
+#define RDL2	0x5D		/* Receive DL-Bit Reg 2 */
+#define RSA6	0x5E		/* Receive SA6 Bit Reg */
+#define RDL3	0x5E		/* Receive DL-Bit Reg 3 */
+#define RSA7	0x5F		/* Receive SA7 Bit Reg */
+#define RSA8	0x60		/* Receive SA8 Bit Reg */
+#define RSA6S	0x61		/* Receive SA6 Bit Status Reg */
+#define TSR0	0x62		/* Manuf. Test Reg 0 */
+#define TSR1	0x63		/* Manuf. Test Reg 1 */
+#define SIS	0x64		/* Signaling Status Reg */
+#define RSIS	0x65		/* Receive Signaling Status Reg */
+#define RBCL	0x66		/* Receive Byte Control */
+#define RBCH	0x67		/* Receive Byte Control */
+#define FISR0	0x68		/* Interrupt Status Reg 0 */
+#define FISR1	0x69		/* Interrupt Status Reg 1 */
+#define FISR2	0x6A		/* Interrupt Status Reg 2 */
+#define FISR3	0x6B		/* Interrupt Status Reg 3 */
+#define GIS	0x6E		/* Global Interrupt Status */
+#define VSTR	0x6F		/* Version Status */
+#define RS(nbr)	(0x70 + (nbr))	/* Rx CAS Reg (0 to 15) */
+
+#endif	/* _FALC_LH_H */
+
diff -urN linux-2.4.24-pre1/drivers/net/wan/pc300_tty.c linux-2.4.24-pre2/drivers/net/wan/pc300_tty.c
--- linux-2.4.24-pre1/drivers/net/wan/pc300_tty.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/wan/pc300_tty.c	2003-12-22 11:34:35.000000000 -0800
@@ -0,0 +1,1117 @@
+/*
+ * pc300_tty.c	Cyclades-PC300(tm) TTY Driver.
+ *
+ * Author:	Regina Kodato <reginak@cyclades.com>
+ * Maintainer:	PC300 Maintainer <pc300@cyclades.com>
+ *
+ * Copyright:	(c) 1999-2003 Cyclades Corp.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *   
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/if.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/skbuff.h>
+
+/* TTY includes */
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+
+#include "pc300.h"
+
+/* defines and macros */
+/* TTY Global definitions */
+#define	CPC_TTY_NPORTS	8	/* maximum number of the sync tty connections */
+#define	CPC_TTY_MAJOR	CYCLADES_MAJOR	
+#define CPC_TTY_MINOR_START	240	/* minor of the first PC300 interface */
+
+#define CPC_TTY_MAX_MTU	2000	
+
+/* tty interface state */
+#define	CPC_TTY_ST_IDLE	0
+#define CPC_TTY_ST_INIT	1	/* configured with MLPPP and up */
+#define CPC_TTY_ST_OPEN	2	/* opened by application */
+
+#define	CPC_TTY_LOCK(card,flags)\
+	do {\
+		spin_lock_irqsave(&card->card_lock, flags);	\
+	} while (0)
+
+#define CPC_TTY_UNLOCK(card,flags)	\
+	do {\
+		spin_unlock_irqrestore(&card->card_lock, flags);	\
+	} while (0)
+
+//#define	CPC_TTY_DBG(format,a...)	printk(format,##a)
+#define	CPC_TTY_DBG(format,a...)
+
+/* data structures */
+typedef struct _st_cpc_rx_buf {
+	struct _st_cpc_rx_buf	*next;
+	int		size;
+	unsigned char	data[1];
+} st_cpc_rx_buf;
+
+struct st_cpc_rx_list {
+	st_cpc_rx_buf	*first;
+	st_cpc_rx_buf	*last;
+};
+
+typedef	struct _st_cpc_tty_area {
+	int		state;		/* state of the TTY interface */
+	int		num_open;	
+	unsigned int 	tty_minor;	/* minor this interface */
+	volatile struct st_cpc_rx_list buf_rx;	/* ptr. to reception buffer */
+	unsigned char*	buf_tx;		/* ptr. to transmission buffer */
+	pc300dev_t*	pc300dev;	/* ptr. to info struct in PC300 driver */
+	unsigned char	name[20];	/* interf. name + "-tty" */
+	struct tty_struct *tty;		
+	struct tq_struct tty_tx_task_queue; /* tx task - tx interrupt */
+	struct tq_struct tty_rx_task_queue; /* rx task - rx interrupt */
+	} st_cpc_tty_area;
+
+/* TTY data structures */
+static struct tty_struct *cpc_tty_serial_table[CPC_TTY_NPORTS];
+static struct termios *cpc_tty_serial_termios[CPC_TTY_NPORTS];
+static struct termios *cpc_tty_serial_termios_locked[CPC_TTY_NPORTS];
+static struct tty_driver serial_drv, callout_drv;
+
+/* local variables */
+st_cpc_tty_area	cpc_tty_area[CPC_TTY_NPORTS];
+
+int cpc_tty_cnt=0;	/* number of intrfaces configured with MLPPP */
+int cpc_tty_refcount;
+int cpc_tty_unreg_flag = 0;
+
+/* TTY functions prototype */
+static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
+static void cpc_tty_close(struct tty_struct *tty, struct file *flip);
+static int cpc_tty_write(struct tty_struct *tty, int from_user,
+				const unsigned char *buf, int count);
+static int cpc_tty_write_room(struct tty_struct *tty);
+static int cpc_tty_chars_in_buffer(struct tty_struct *tty);
+static int cpc_tty_ioctl(struct tty_struct *tty, struct file *file,
+				unsigned int cmd, unsigned long arg);
+static void cpc_tty_flush_buffer(struct tty_struct *tty);
+static void cpc_tty_hangup(struct tty_struct *tty);
+static void cpc_tty_rx_task(void *data);
+static void cpc_tty_tx_task(void *data);
+static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len);
+static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx);
+static void cpc_tty_dtr_off(pc300dev_t *pc300dev);
+static void cpc_tty_dtr_on(pc300dev_t *pc300dev);
+
+/* functions called by PC300 driver */
+void cpc_tty_init(pc300dev_t *dev);
+void cpc_tty_unregister_service(pc300dev_t *pc300dev);
+void cpc_tty_receive(pc300dev_t *pc300dev);
+void cpc_tty_trigger_poll(pc300dev_t *pc300dev);
+void cpc_tty_reset_var(void);
+
+/*
+ * PC300 TTY clear DTR signal
+ */
+static void cpc_tty_dtr_off(pc300dev_t *pc300dev)
+{
+	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
+	pc300_t *card = (pc300_t *) pc300chan->card; 
+	int ch = pc300chan->channel; 
+	unsigned long flags; 
+
+	CPC_TTY_DBG("%s-tty: Clear signal DTR\n",
+		((struct net_device*)(pc300dev->hdlc))->name);
+	CPC_TTY_LOCK(card, flags); 
+	cpc_writeb(card->hw.scabase + M_REG(CTL,ch), 
+		cpc_readb(card->hw.scabase+M_REG(CTL,ch))& CTL_DTR); 
+	CPC_TTY_UNLOCK(card,flags); 
+}
+
+/*
+ * PC300 TTY set DTR signal to ON
+ */
+static void cpc_tty_dtr_on(pc300dev_t *pc300dev)
+{
+	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
+	pc300_t *card = (pc300_t *) pc300chan->card; 
+	int ch = pc300chan->channel; 
+	unsigned long flags; 
+
+	CPC_TTY_DBG("%s-tty: Set signal DTR\n",
+		((struct net_device*)(pc300dev->hdlc))->name);
+	CPC_TTY_LOCK(card, flags); 
+	cpc_writeb(card->hw.scabase + M_REG(CTL,ch), 
+		cpc_readb(card->hw.scabase+M_REG(CTL,ch))& ~CTL_DTR); 
+	CPC_TTY_UNLOCK(card,flags); 
+}
+
+/*
+ * PC300 TTY initialization routine
+ *
+ * This routine is called by the PC300 driver during board configuration 
+ * (ioctl=SIOCSP300CONF). At this point the adapter is completely
+ * initialized.
+ * o verify kernel version (only 2.4.x)
+ * o register TTY driver
+ * o init cpc_tty_area struct
+ */
+void cpc_tty_init(pc300dev_t *pc300dev)
+{
+	int port, aux;
+	st_cpc_tty_area * cpc_tty;
+
+	/* hdlcX - X=interface number */
+	port = ((struct net_device*)(pc300dev->hdlc))->name[4] - '0';
+	if (port >= CPC_TTY_NPORTS) {
+		printk("%s-tty: invalid interface selected (0-%i): %i", 
+			((struct net_device*)(pc300dev->hdlc))->name,
+			CPC_TTY_NPORTS-1,port);
+		return;
+	}
+
+	if (cpc_tty_cnt == 0) { /* first TTY connection -> register driver */
+		CPC_TTY_DBG("%s-tty: driver init, major:%i, minor range:%i=%i\n",
+			((struct net_device*)(pc300dev->hdlc))->name,
+			CPC_TTY_MAJOR, CPC_TTY_MINOR_START,
+			CPC_TTY_MINOR_START+CPC_TTY_NPORTS);
+		/* initialize tty driver struct */
+		memset(&serial_drv,0,sizeof(struct tty_driver));
+		serial_drv.magic = TTY_DRIVER_MAGIC;
+		serial_drv.driver_name = "pc300_tty";
+		serial_drv.name = "ttyCP";
+		serial_drv.major = CPC_TTY_MAJOR;
+		serial_drv.minor_start = CPC_TTY_MINOR_START;
+		serial_drv.num = CPC_TTY_NPORTS;
+		serial_drv.type = TTY_DRIVER_TYPE_SERIAL;
+		serial_drv.subtype = SERIAL_TYPE_NORMAL;
+
+		serial_drv.init_termios = tty_std_termios;
+		serial_drv.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
+		serial_drv.flags = TTY_DRIVER_REAL_RAW;
+		serial_drv.refcount = &cpc_tty_refcount;
+
+		/* tty data structures */
+		serial_drv.table = cpc_tty_serial_table;
+		serial_drv.termios = cpc_tty_serial_termios;
+		serial_drv.termios_locked = cpc_tty_serial_termios_locked;
+
+		/* interface routines from the upper tty layer to the tty driver */
+		serial_drv.open = cpc_tty_open;
+		serial_drv.close = cpc_tty_close;
+		serial_drv.write = cpc_tty_write; 
+		serial_drv.write_room = cpc_tty_write_room; 
+		serial_drv.chars_in_buffer = cpc_tty_chars_in_buffer; 
+		serial_drv.ioctl = cpc_tty_ioctl; 
+		serial_drv.flush_buffer = cpc_tty_flush_buffer; 
+		serial_drv.hangup = cpc_tty_hangup;
+
+		/* the callout device is just like normal device except for major */
+	   	/* number and the subtype code */ 
+		callout_drv = serial_drv; 
+		callout_drv.name = "cucp"; 
+		callout_drv.major = CPC_TTY_MAJOR + 1;
+		callout_drv.subtype = SERIAL_TYPE_CALLOUT;
+		callout_drv.read_proc = 0;
+		callout_drv.proc_entry = 0; 
+		
+		/* register the TTY driver */
+		if (tty_register_driver(&serial_drv)) { 
+			printk("%s-tty: Failed to register serial driver! ",
+				((struct net_device*)(pc300dev->hdlc))->name);
+		   	return;
+		} 
+
+		if (tty_register_driver(&callout_drv)) {
+			CPC_TTY_DBG("%s-tty: Failed to register callout driver! ",
+				((struct net_device*)(pc300dev->hdlc))->name);
+			return;
+		}
+		memset((void *)cpc_tty_area, 0,
+								sizeof(st_cpc_tty_area) * CPC_TTY_NPORTS);
+	}
+
+	cpc_tty = &cpc_tty_area[port];
+	
+	if (cpc_tty->state != CPC_TTY_ST_IDLE) {
+		CPC_TTY_DBG("%s-tty: TTY port %i, already in use.\n",
+					((struct net_device*)(pc300dev->hdlc))->name,port);
+		return;
+	}
+
+	cpc_tty_cnt++;
+	cpc_tty->state = CPC_TTY_ST_INIT; 
+	cpc_tty->num_open= 0;
+	cpc_tty->tty_minor = port + CPC_TTY_MINOR_START;
+	cpc_tty->pc300dev = pc300dev; 
+	
+	cpc_tty->tty_tx_task_queue.routine = cpc_tty_tx_task; 
+	cpc_tty->tty_tx_task_queue.data = (void *)cpc_tty; 
+	
+	cpc_tty->tty_rx_task_queue.routine = cpc_tty_rx_task; 
+	cpc_tty->tty_rx_task_queue.data = (void *) port; 
+	
+	cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = 0;
+
+	pc300dev->cpc_tty = (void *)cpc_tty; 
+	
+	aux = strlen(((struct net_device*)(pc300dev->hdlc))->name);
+	memcpy(cpc_tty->name,((struct net_device*)(pc300dev->hdlc))->name,aux);
+	memcpy(&cpc_tty->name[aux], "-tty", 5);
+	
+	cpc_open((struct net_device *)pc300dev->hdlc);
+	cpc_tty_dtr_off(pc300dev);
+
+	CPC_TTY_DBG("%s: Initializing TTY Sync Driver, tty major#%d minor#%i\n",
+			cpc_tty->name,CPC_TTY_MAJOR,cpc_tty->tty_minor); 
+	return; 
+} 
+
+/*
+ * PC300 TTY OPEN routine
+ *
+ * This routine is called by the tty driver to open the interface 
+ * o verify minor
+ * o allocate buffer to Rx and Tx
+ */
+static int cpc_tty_open(struct tty_struct *tty, struct file *flip)
+{
+	int port ;
+	st_cpc_tty_area *cpc_tty;
+
+	if (!tty) { 
+		return -ENODEV;
+	} 
+
+	port = MINOR(tty->device) - tty->driver.minor_start; 
+
+	if ((port < 0) || (port >= CPC_TTY_NPORTS)){ 
+		CPC_TTY_DBG("pc300_tty: open invalid minor %i\n",MINOR(tty->device));
+		return -ENODEV;
+	} 
+
+	cpc_tty = &cpc_tty_area[port];
+	
+	if (cpc_tty->state == CPC_TTY_ST_IDLE){
+		CPC_TTY_DBG("%s: open - invalid interface, minor=%i\n",
+					cpc_tty->name, MINOR(tty->device));
+		return -ENODEV;
+	}
+
+	if (cpc_tty->num_open == 0) { /* first open of this tty */
+		if (!cpc_tty_area[port].buf_tx){
+			cpc_tty_area[port].buf_tx = kmalloc(CPC_TTY_MAX_MTU,GFP_KERNEL);
+			if (cpc_tty_area[port].buf_tx == 0){
+				CPC_TTY_DBG("%s: error in memory allocation\n",cpc_tty->name);
+				return -ENOMEM;
+			}
+		} 
+
+		if (cpc_tty_area[port].buf_rx.first) {
+			unsigned char * aux;
+			while (cpc_tty_area[port].buf_rx.first) {
+				aux = (unsigned char *)cpc_tty_area[port].buf_rx.first;
+				cpc_tty_area[port].buf_rx.first = cpc_tty_area[port].buf_rx.first->next;
+				kfree(aux);
+			}
+			cpc_tty_area[port].buf_rx.first = NULL;
+			cpc_tty_area[port].buf_rx.last = NULL;
+		}
+
+		cpc_tty_area[port].state = CPC_TTY_ST_OPEN;
+		cpc_tty_area[port].tty = tty;
+		tty->driver_data = &cpc_tty_area[port];
+
+		cpc_tty_dtr_on(cpc_tty->pc300dev);
+	} 
+
+	cpc_tty->num_open++;
+
+	CPC_TTY_DBG("%s: opening TTY driver\n", cpc_tty->name);
+	
+	/* avisar driver PC300 */ 
+	return 0; 
+}
+
+/*
+ * PC300 TTY CLOSE routine
+ *
+ * This routine is called by the tty driver to close the interface 
+ * o call close channel in PC300 driver (cpc_closech)
+ * o free Rx and Tx buffers
+ */
+
+static void cpc_tty_close(struct tty_struct *tty, struct file *flip)
+{
+	st_cpc_tty_area    *cpc_tty;
+	unsigned long flags;
+	int res;
+
+	if (!tty || !tty->driver_data ) {
+		CPC_TTY_DBG("hdlx-tty: no TTY in close \n");
+		return;
+	}
+
+	cpc_tty = (st_cpc_tty_area *) tty->driver_data;
+
+	if ((cpc_tty->tty != tty)|| (cpc_tty->state != CPC_TTY_ST_OPEN)) {
+		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
+		return;
+	}
+   	
+	if (!cpc_tty->num_open) {
+		CPC_TTY_DBG("%s: TTY is closed\n",cpc_tty->name);
+		return;
+	}
+
+	if (--cpc_tty->num_open > 0) {
+		CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
+		return;
+	}
+
+	cpc_tty_dtr_off(cpc_tty->pc300dev);
+
+	CPC_TTY_LOCK(cpc_tty->pc300dev->chan->card, flags);  /* lock irq */ 
+	cpc_tty->tty = NULL;
+	cpc_tty->state = CPC_TTY_ST_INIT;
+	CPC_TTY_UNLOCK(cpc_tty->pc300dev->chan->card, flags); /* unlock irq */ 
+	
+	if (cpc_tty->buf_rx.first) {
+		unsigned char * aux;
+		while (cpc_tty->buf_rx.first) {
+			aux = (unsigned char *)cpc_tty->buf_rx.first;
+			cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
+			kfree(aux);
+		}
+		cpc_tty->buf_rx.first = NULL;
+		cpc_tty->buf_rx.last = NULL;
+	}
+	
+	if (cpc_tty->buf_tx) {
+		kfree(cpc_tty->buf_tx);
+		cpc_tty->buf_tx = NULL;
+	}
+
+	CPC_TTY_DBG("%s: TTY closed\n",cpc_tty->name);
+	
+	if (!cpc_tty_refcount && cpc_tty_unreg_flag) {
+		cpc_tty_unreg_flag = 0;
+		CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
+		if ((res=tty_unregister_driver(&serial_drv))) { 
+			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
+							cpc_tty->name,res);
+		}
+		if ((res=tty_unregister_driver(&callout_drv))) { 
+			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
+							cpc_tty->name,res);
+		}
+	}
+	return; 
+} 
+
+/*
+ * PC300 TTY WRITE routine
+ *
+ * This routine is called by the tty driver to write a series of characters
+ * to the tty device. The characters may come from user or kernel space.
+ * o verify the DCD signal
+ * o send characters to board and start the transmission
+ */
+static int cpc_tty_write(struct tty_struct *tty, int from_user,
+			const unsigned char *buf, int count)
+{
+	st_cpc_tty_area    *cpc_tty; 
+	pc300ch_t *pc300chan; 
+	pc300_t *card; 
+	int ch; 
+	unsigned long flags; 
+	struct net_device_stats *stats; 
+
+	if (!tty || !tty->driver_data ) { 
+		CPC_TTY_DBG("hdlcX-tty: no TTY in write\n");
+		return -ENODEV;
+	} 
+
+	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+
+	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
+		CPC_TTY_DBG("%s: TTY is not opened\n", cpc_tty->name);
+		return -ENODEV; 
+	}
+
+	if (count > CPC_TTY_MAX_MTU) { 
+		CPC_TTY_DBG("%s: count is invalid\n",cpc_tty->name);
+		return -EINVAL;        /* frame too big */ 
+	}
+
+	CPC_TTY_DBG("%s: cpc_tty_write %s data len=%i\n",cpc_tty->name,
+		(from_user)?"from user" : "from kernel",count);
+	
+	pc300chan = (pc300ch_t *)((pc300dev_t*)cpc_tty->pc300dev)->chan; 
+	stats = &((pc300dev_t*)cpc_tty->pc300dev)->hdlc->stats;
+	card = (pc300_t *) pc300chan->card;
+	ch = pc300chan->channel; 
+
+	/* verify DCD signal*/ 
+	if (cpc_readb(card->hw.scabase + M_REG(ST3,ch)) & ST3_DCD) { 
+		/* DCD is OFF */ 
+		CPC_TTY_DBG("%s : DCD is OFF\n", cpc_tty->name);
+		stats->tx_errors++;
+		stats->tx_carrier_errors++;
+		CPC_TTY_LOCK(card, flags); 
+		cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR); 
+		
+		if (card->hw.type == PC300_TE) { 
+			cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, 
+				cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) & 
+				~(CPLD_REG2_FALC_LED1 << (2 *ch))); 
+		}
+
+		CPC_TTY_UNLOCK(card, flags); 
+
+		return -EINVAL; 
+	}
+
+	if (from_user) { 
+		unsigned char *buf_tmp; 
+
+		buf_tmp = cpc_tty->buf_tx;
+		if (copy_from_user(buf_tmp, buf, count)) { 
+			/* failed to copy from user */
+			CPC_TTY_DBG("%s: error in copy from user\n",cpc_tty->name);
+			return -EINVAL; 
+		}
+
+		if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*) buf_tmp,count)) { 
+			/* failed to send */ 
+			CPC_TTY_DBG("%s: transmission error\n",cpc_tty->name);
+			return 0; 
+		}
+	} else {
+		if (cpc_tty_send_to_card(cpc_tty->pc300dev, (void*)buf, count)) { 
+		   /* failed to send */
+		   CPC_TTY_DBG("%s: trasmition error\n", cpc_tty->name);
+		   return 0;
+		}
+	}
+	return count; 
+} 
+
+/*
+ * PC300 TTY Write Room routine
+ * 
+ * This routine returns the numbers of characteres the tty driver will accept
+ * for queuing to be written. 
+ * o return MTU
+ */
+static int cpc_tty_write_room(struct tty_struct *tty)
+{
+	st_cpc_tty_area    *cpc_tty; 
+
+	if (!tty || !tty->driver_data ) { 
+		CPC_TTY_DBG("hdlcX-tty: no TTY to write room\n");
+		return -ENODEV;
+	}
+
+	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+
+	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
+		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
+		return -ENODEV; 
+	}
+   	
+	CPC_TTY_DBG("%s: write room\n",cpc_tty->name);
+	
+	return CPC_TTY_MAX_MTU;
+} 
+
+/*
+ * PC300 TTY chars in buffer routine
+ * 
+ * This routine returns the chars number in the transmission buffer 
+ * o returns 0
+ */
+static int cpc_tty_chars_in_buffer(struct tty_struct *tty)
+{
+	st_cpc_tty_area    *cpc_tty; 
+
+	if (!tty || !tty->driver_data ) {
+		CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");
+		return -ENODEV; 
+	}
+
+	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+
+	if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
+		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
+		return -ENODEV; 
+	}
+   
+	return(0); 
+} 
+
+/*
+ * PC300 TTY IOCTL routine
+ *
+ * This routine treats TIOCMBIS (set DTR signal) and TIOCMBIC (clear DTR
+ * signal)IOCTL commands. 
+ */
+static int cpc_tty_ioctl(struct tty_struct *tty, struct file *file,
+		unsigned int cmd, unsigned long arg)
+
+{
+	st_cpc_tty_area    *cpc_tty; 
+
+	if (!tty || !tty->driver_data ) {
+	   	CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");	
+		return -ENODEV; 
+	}
+
+	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+
+	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
+		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
+		return -ENODEV; 
+	}
+
+	CPC_TTY_DBG("%s: IOCTL cmd %x\n",cpc_tty->name,cmd);
+	
+	switch (cmd) { 
+		case TIOCMBIS :    /* set DTR */
+			cpc_tty_dtr_on(cpc_tty->pc300dev);
+			break; 
+
+		case TIOCMBIC:     /* clear DTR */ 
+			cpc_tty_dtr_off(cpc_tty->pc300dev);
+			break; 
+		default :
+			return -ENOIOCTLCMD;
+	}
+	return 0;
+} 
+
+/*
+ * PC300 TTY Flush Buffer routine
+ *
+ * This routine resets the transmission buffer 
+ */
+static void cpc_tty_flush_buffer(struct tty_struct *tty)
+{ 
+	st_cpc_tty_area    *cpc_tty; 
+	
+	if (!tty || !tty->driver_data ) {
+	   	CPC_TTY_DBG("hdlcX-tty: no TTY to flush buffer\n");	
+		return; 
+	}
+
+	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+
+	if ((cpc_tty->tty != tty) ||  (cpc_tty->state != CPC_TTY_ST_OPEN)) { 
+		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
+		return; 
+	}
+
+	CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name);
+	
+	wake_up_interruptible(&tty->write_wait); 
+
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){
+		CPC_TTY_DBG("%s: call line disc. wake up\n",cpc_tty->name);
+		tty->ldisc.write_wakeup(tty); 
+	} 
+
+	return; 
+} 
+
+/*
+ * PC300 TTY Hangup routine
+ *
+ * This routine is called by the tty driver to hangup the interface 
+ * o clear DTR signal
+ */
+
+static void cpc_tty_hangup(struct tty_struct *tty)
+{ 
+	st_cpc_tty_area    *cpc_tty; 
+	int res;
+
+	if (!tty || !tty->driver_data ) {
+		CPC_TTY_DBG("hdlcX-tty: no TTY to hangup\n");	
+		return ; 
+	}
+
+	cpc_tty = (st_cpc_tty_area *) tty->driver_data; 
+
+	if ((cpc_tty->tty != tty) || (cpc_tty->state != CPC_TTY_ST_OPEN)) {
+		CPC_TTY_DBG("%s: TTY is not opened\n",cpc_tty->name);
+		return ;
+	}
+	if (!cpc_tty_refcount && cpc_tty_unreg_flag) {
+		cpc_tty_unreg_flag = 0;
+		CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
+		if ((res=tty_unregister_driver(&serial_drv))) { 
+			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
+							cpc_tty->name,res);
+		}
+		if ((res=tty_unregister_driver(&callout_drv))) { 
+			CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
+							cpc_tty->name,res);
+		}
+	}
+	cpc_tty_dtr_off(cpc_tty->pc300dev);
+}
+
+/*
+ * PC300 TTY RX task routine
+ * This routine treats RX task
+ * o verify read buffer
+ * o call the line disc. read
+ * o free memory
+ */
+static void cpc_tty_rx_task(void * data)
+{
+	int port, i, j;
+	st_cpc_tty_area *cpc_tty; 
+	volatile st_cpc_rx_buf * buf;
+	char flags=0,flg_rx=1; 
+
+	if (cpc_tty_cnt == 0) return;
+
+	for (i=0; (i < 4) && flg_rx ; i++) {
+		flg_rx = 0;
+		port = (int) data;
+		for (j=0; j < CPC_TTY_NPORTS; j++) {
+			cpc_tty = &cpc_tty_area[port];
+		
+			if ((buf=cpc_tty->buf_rx.first) != 0) {
+															
+				if (cpc_tty->tty && (cpc_tty->tty->ldisc.receive_buf)) { 
+					CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
+					cpc_tty->tty->ldisc.receive_buf(cpc_tty->tty, buf->data, 
+													&flags, buf->size);
+				}	
+				cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
+				kfree((unsigned char *)buf);
+				buf = cpc_tty->buf_rx.first;
+				flg_rx = 1;
+			}
+			if (++port == CPC_TTY_NPORTS) port = 0;
+		}
+	}
+} 
+
+/*
+ * PC300 TTY RX task routine
+ *
+ * This routine treats RX interrupt. 
+ * o read all frames in card
+ * o verify the frame size
+ * o read the frame in rx buffer
+ */
+static void cpc_tty_rx_disc_frame(pc300ch_t *pc300chan)
+{
+	volatile pcsca_bd_t * ptdescr; 
+	volatile unsigned char status; 
+	pc300_t *card = (pc300_t *)pc300chan->card; 
+	int ch = pc300chan->channel; 
+
+	/* dma buf read */ 
+	ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
+				RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
+	while (pc300chan->rx_first_bd != pc300chan->rx_last_bd) { 
+		status = cpc_readb(&ptdescr->status); 
+		cpc_writeb(&ptdescr->status, 0); 
+		cpc_writeb(&ptdescr->len, 0); 
+		pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & 
+					(N_DMA_RX_BUF - 1); 
+		if (status & DST_EOM) { 
+			break; /* end of message */
+		}
+		ptdescr = (pcsca_bd_t *)(card->hw.rambase + cpc_readl(&ptdescr->next)); 
+	}
+}
+
+void cpc_tty_receive(pc300dev_t *pc300dev)
+{
+	st_cpc_tty_area    *cpc_tty; 
+	pc300ch_t *pc300chan = (pc300ch_t *)pc300dev->chan; 
+	pc300_t *card = (pc300_t *)pc300chan->card; 
+	int ch = pc300chan->channel; 
+	volatile pcsca_bd_t * ptdescr; 
+	struct net_device_stats *stats = &pc300dev->hdlc->stats; 
+	int rx_len, rx_aux; 
+	volatile unsigned char status; 
+	unsigned short first_bd = pc300chan->rx_first_bd;
+	st_cpc_rx_buf	*new;
+	unsigned char dsr_rx;
+
+	if (pc300dev->cpc_tty == NULL) { 
+		return; 
+	}
+
+	dsr_rx = cpc_readb(card->hw.scabase + DSR_RX(ch));
+
+	cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; 
+
+	while (1) { 
+		rx_len = 0;
+		ptdescr = (pcsca_bd_t *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd));
+		while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
+			rx_len += cpc_readw(&ptdescr->len);
+			first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1);
+			if (status & DST_EOM) {
+				break;
+			}
+			ptdescr=(pcsca_bd_t*)(card->hw.rambase+cpc_readl(&ptdescr->next));
+		}
+			
+		if (!rx_len) { 
+			if (dsr_rx & DSR_BOF) {
+				/* update EDA */ 
+				cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), 
+						RX_BD_ADDR(ch, pc300chan->rx_last_bd)); 
+			}
+			return; 
+		}
+		
+		if (rx_len > CPC_TTY_MAX_MTU) { 
+			/* Free RX descriptors */ 
+			CPC_TTY_DBG("%s: frame size is invalid.\n",cpc_tty->name);
+			stats->rx_errors++; 
+			stats->rx_frame_errors++; 
+			cpc_tty_rx_disc_frame(pc300chan);
+			continue;
+		} 
+		
+		new = (st_cpc_rx_buf *) kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
+		if (new == 0) {
+			cpc_tty_rx_disc_frame(pc300chan);
+			continue;
+		}
+		
+		/* dma buf read */ 
+		ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
+				RX_BD_ADDR(ch, pc300chan->rx_first_bd)); 
+
+		rx_len = 0;	/* counter frame size */
+		
+		while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
+			rx_aux = cpc_readw(&ptdescr->len);
+			if ((status & (DST_OVR | DST_CRC | DST_RBIT |  DST_SHRT | DST_ABT))
+				|| (rx_aux > BD_DEF_LEN)) {
+				CPC_TTY_DBG("%s: reception error\n", cpc_tty->name);
+				stats->rx_errors++; 
+				if (status & DST_OVR) { 
+					stats->rx_fifo_errors++; 
+				}
+				if (status & DST_CRC) { 
+					stats->rx_crc_errors++; 
+				}
+				if ((status & (DST_RBIT | DST_SHRT | DST_ABT)) ||
+					(rx_aux > BD_DEF_LEN))	{ 
+					stats->rx_frame_errors++; 
+				} 
+				/* discard remainig descriptors used by the bad frame */ 
+				CPC_TTY_DBG("%s: reception error - discard descriptors",
+						cpc_tty->name);
+				cpc_tty_rx_disc_frame(pc300chan);
+				rx_len = 0;
+				kfree((unsigned char *)new);
+				break; /* read next frame - while(1) */
+			}
+
+			if (cpc_tty->state != CPC_TTY_ST_OPEN) {
+				/* Free RX descriptors */ 
+				cpc_tty_rx_disc_frame(pc300chan);
+				stats->rx_dropped++; 
+				rx_len = 0; 
+				kfree((unsigned char *)new);
+				break; /* read next frame - while(1) */
+			}
+
+			/* read the segment of the frame */
+			if (rx_aux != 0) {
+				memcpy_fromio((new->data + rx_len), 
+					(void *)(card->hw.rambase + 
+					 cpc_readl(&ptdescr->ptbuf)), rx_aux);
+				rx_len += rx_aux; 
+			}
+			cpc_writeb(&ptdescr->status,0); 
+			cpc_writeb(&ptdescr->len, 0); 
+			pc300chan->rx_first_bd = (pc300chan->rx_first_bd + 1) & 
+					(N_DMA_RX_BUF -1); 
+			if (status & DST_EOM)break;
+			
+			ptdescr = (pcsca_bd_t *) (card->hw.rambase + 
+					cpc_readl(&ptdescr->next)); 
+		}
+		/* update pointer */ 
+		pc300chan->rx_last_bd = (pc300chan->rx_first_bd - 1) & 
+					(N_DMA_RX_BUF - 1) ; 
+		if (!(dsr_rx & DSR_BOF)) {
+			/* update EDA */ 
+			cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), 
+					RX_BD_ADDR(ch, pc300chan->rx_last_bd)); 
+		}
+		if (rx_len != 0) { 
+			stats->rx_bytes += rx_len; 
+		
+			if (pc300dev->trace_on) { 
+				cpc_tty_trace(pc300dev, new->data,rx_len, 'R'); 
+			} 
+			new->size = rx_len;
+			new->next = 0;
+			if (cpc_tty->buf_rx.first == 0) {
+				cpc_tty->buf_rx.first = new;
+				cpc_tty->buf_rx.last = new;
+			} else {
+				cpc_tty->buf_rx.last->next = new;
+				cpc_tty->buf_rx.last = new;
+			}
+			schedule_task(&(cpc_tty->tty_rx_task_queue));
+			stats->rx_packets++;
+		}
+	} 
+} 
+
+/*
+ * PC300 TTY TX task routine
+ * 
+ * This routine treats TX interrupt. 
+ * o if need call line discipline wakeup
+ * o call wake_up_interruptible
+ */
+static void cpc_tty_tx_task(void *data)
+{
+	st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) data; 
+	struct tty_struct *tty; 
+
+	CPC_TTY_DBG("%s: cpc_tty_tx_task init\n",cpc_tty->name);
+	
+	if ((tty = cpc_tty->tty) == 0) { 
+		CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name);
+		return; 
+	}
+
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){
+		CPC_TTY_DBG("%s:call line disc. wakeup\n",cpc_tty->name);
+		tty->ldisc.write_wakeup (tty); 
+	}
+
+	wake_up_interruptible(&tty->write_wait); 
+}
+
+/*
+ * PC300 TTY send to card routine
+ * 
+ * This routine send data to card. 
+ * o clear descriptors
+ * o write data to DMA buffers
+ * o start the transmission
+ */
+static int cpc_tty_send_to_card(pc300dev_t *dev,void* buf, int len)
+{
+	pc300ch_t *chan = (pc300ch_t *)dev->chan; 
+	pc300_t *card = (pc300_t *)chan->card; 
+	int ch = chan->channel; 
+	struct net_device_stats *stats = &dev->hdlc->stats; 
+	unsigned long flags; 
+	volatile pcsca_bd_t * ptdescr; 
+	int i, nchar;
+	int tosend = len;
+	int nbuf = ((len - 1)/BD_DEF_LEN) + 1;
+	unsigned char *pdata=buf;
+
+	CPC_TTY_DBG("%s:cpc_tty_send_to_cars len=%i", 
+			(st_cpc_tty_area *)dev->cpc_tty->name,len);	
+
+	if (nbuf >= card->chan[ch].nfree_tx_bd) {
+		return 1;
+	}
+	
+	/* write buffer to DMA buffers */ 
+	CPC_TTY_DBG("%s: call dma_buf_write\n",
+			(st_cpc_tty_area *)dev->cpc_tty->name);	
+	for (i = 0 ; i < nbuf ; i++) {
+		ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
+			TX_BD_ADDR(ch, card->chan[ch].tx_next_bd));
+		nchar = (BD_DEF_LEN > tosend) ? tosend : BD_DEF_LEN;
+		if (cpc_readb(&ptdescr->status) & DST_OSB) {
+			memcpy_toio((void *)(card->hw.rambase + 
+				cpc_readl(&ptdescr->ptbuf)), 
+				&pdata[len - tosend], 
+				nchar);
+			card->chan[ch].nfree_tx_bd--;
+			if ((i + 1) == nbuf) {
+				/* This must be the last BD to be used */
+				cpc_writeb(&ptdescr->status, DST_EOM);
+			} else {
+				cpc_writeb(&ptdescr->status, 0);
+			}
+			cpc_writew(&ptdescr->len, nchar);
+		} else {
+			CPC_TTY_DBG("%s: error in dma_buf_write\n",
+					(st_cpc_tty_area *)dev->cpc_tty->name);	
+			stats->tx_dropped++;
+			return 1; 
+		}
+		tosend -= nchar;
+		card->chan[ch].tx_next_bd = 
+			(card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1);
+	}
+
+	if (dev->trace_on) { 
+		cpc_tty_trace(dev, buf, len,'T'); 
+	}
+
+	/* start transmission */ 
+	CPC_TTY_DBG("%s: start transmission\n",
+		(st_cpc_tty_area *)dev->cpc_tty->name);	
+	
+	CPC_TTY_LOCK(card, flags); 
+	cpc_writeb(card->hw.scabase + DTX_REG(EDAL, ch), 
+			TX_BD_ADDR(ch, chan->tx_next_bd)); 
+	cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA); 
+	cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE); 
+
+	if (card->hw.type == PC300_TE) { 
+		cpc_writeb(card->hw.falcbase + card->hw.cpld_reg2, 
+			cpc_readb(card->hw.falcbase + card->hw.cpld_reg2) |
+			(CPLD_REG2_FALC_LED1 << (2 * ch))); 
+	}
+	CPC_TTY_UNLOCK(card, flags); 
+	return 0; 
+} 
+
+/*
+ *	PC300 TTY trace routine
+ *
+ *  This routine send trace of connection to application. 
+ *  o clear descriptors
+ *  o write data to DMA buffers
+ *  o start the transmission
+ */
+
+static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx)
+{
+	struct sk_buff *skb; 
+
+	if ((skb = dev_alloc_skb(10 + len)) == NULL) { 
+		/* out of memory */ 
+		CPC_TTY_DBG("%s: tty_trace - out of memory\n",
+			((struct net_device *)(dev->hdlc))->name);
+		return; 
+	}
+
+	skb_put (skb, 10 + len); 
+	skb->dev = (struct net_device *) dev->hdlc; 
+	skb->protocol = htons(ETH_P_CUST); 
+	skb->mac.raw = skb->data; 
+	skb->pkt_type = PACKET_HOST; 
+	skb->len = 10 + len; 
+
+	memcpy(skb->data,((struct net_device *)(dev->hdlc))->name,5);
+	skb->data[5] = '['; 
+	skb->data[6] = rxtx; 
+	skb->data[7] = ']'; 
+	skb->data[8] = ':'; 
+	skb->data[9] = ' '; 
+	memcpy(&skb->data[10], buf, len); 
+	netif_rx(skb); 
+} 	
+
+/*
+ *	PC300 TTY unregister service routine
+ *
+ *	This routine unregister one interface. 
+ */
+void cpc_tty_unregister_service(pc300dev_t *pc300dev)
+{
+	st_cpc_tty_area *cpc_tty; 
+	ulong flags;
+	int res;
+
+	if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == 0) { 
+		CPC_TTY_DBG("%s: interface is not TTY\n",
+			((struct net_device *)(pc300dev->hdlc))->name);
+		return; 
+	}
+	CPC_TTY_DBG("%s: cpc_tty_unregister_service", cpc_tty->name);
+
+	if (cpc_tty->pc300dev != pc300dev) { 
+		CPC_TTY_DBG("%s: invalid tty ptr=%s\n", 
+		((struct net_device *)(pc300dev->hdlc))->name, cpc_tty->name);
+		return; 
+	}
+
+	if (--cpc_tty_cnt == 0) { 
+		if (cpc_tty_refcount) {
+			CPC_TTY_DBG("%s: unregister is not possible, refcount=%d",
+							cpc_tty->name, cpc_tty_refcount);
+			cpc_tty_cnt++;
+			cpc_tty_unreg_flag = 1;
+			return;
+		} else { 
+			CPC_TTY_DBG("%s: unregister the tty driver\n", cpc_tty->name);
+			if ((res=tty_unregister_driver(&serial_drv))) { 
+				CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
+								cpc_tty->name,res);
+			}
+			if ((res=tty_unregister_driver(&callout_drv))) { 
+				CPC_TTY_DBG("%s: ERROR ->unregister the tty driver error=%d\n",
+								cpc_tty->name,res);
+			}
+		}
+	}
+	CPC_TTY_LOCK(pc300dev->chan->card,flags);
+	cpc_tty->tty = NULL; 
+	CPC_TTY_UNLOCK(pc300dev->chan->card, flags);
+	cpc_tty->tty_minor = 0; 
+	cpc_tty->state = CPC_TTY_ST_IDLE; 
+} 
+
+/*
+ * PC300 TTY trigger poll routine
+ * This routine is called by pc300driver to treats Tx interrupt. 
+ */
+void cpc_tty_trigger_poll(pc300dev_t *pc300dev)
+{
+	st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *)pc300dev->cpc_tty; 
+	if (!cpc_tty) {
+		return;
+	}
+	schedule_task(&(cpc_tty->tty_tx_task_queue)); 
+} 
+
+/*
+ * PC300 TTY reset var routine
+ * This routine is called by pc300driver to init the TTY area. 
+ */
+
+void cpc_tty_reset_var(void)
+{
+	int i ; 
+
+	CPC_TTY_DBG("hdlcX-tty: reset variables\n");
+	/* reset  the tty_driver structure - serial_drv */ 
+	memset(&serial_drv, 0, sizeof(struct tty_driver));
+	memset(&callout_drv, 0, sizeof(struct tty_driver));
+	for (i=0; i < CPC_TTY_NPORTS; i++){
+		memset(&cpc_tty_area[i],0, sizeof(st_cpc_tty_area)); 
+	}
+}
diff -urN linux-2.4.24-pre1/drivers/net/wireless/airo.c linux-2.4.24-pre2/drivers/net/wireless/airo.c
--- linux-2.4.24-pre1/drivers/net/wireless/airo.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/net/wireless/airo.c	2003-12-22 11:34:35.000000000 -0800
@@ -1034,7 +1034,6 @@
 #define FLAG_802_11	7
 #define FLAG_PENDING_XMIT 9
 #define FLAG_PENDING_XMIT11 10
-#define FLAG_PCI	11
 #define JOB_MASK	0x1ff0000
 #define JOB_DIE		16
 #define JOB_XMIT	17
@@ -2476,11 +2475,8 @@
 			OUT4500( apriv, EVACK, EV_MIC );
 #ifdef MICSUPPORT
 			if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
-				if (down_trylock(&apriv->sem) != 0) {
-					set_bit(JOB_MIC, &apriv->flags);
-					wake_up_interruptible(&apriv->thr_wait);
-				} else
-					micinit (apriv);
+				set_bit(JOB_MIC, &apriv->flags);
+				wake_up_interruptible(&apriv->thr_wait);
 			}
 #endif
 		}
@@ -4642,7 +4638,6 @@
 		return -ENODEV;
 
 	pci_set_drvdata(pdev, dev);
-	set_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags);
 	return 0;
 }
 
@@ -4672,7 +4667,7 @@
 
 #ifdef CONFIG_PCI
 	printk( KERN_INFO "airo:  Probing for PCI adapters\n" );
-	pci_module_init(&airo_driver);
+	pci_register_driver(&airo_driver);
 	printk( KERN_INFO "airo:  Finished probing for PCI adapters\n" );
 #endif
 
@@ -4684,22 +4679,15 @@
 
 static void __exit airo_cleanup_module( void )
 {
-	int is_pci = 0;
 	while( airo_devices ) {
 		printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
-#ifdef CONFIG_PCI
-		if (test_bit(FLAG_PCI, &((struct airo_info *)airo_devices->dev->priv)->flags))
-			is_pci = 1;
-#endif
 		stop_airo_card( airo_devices->dev, 1 );
 	}
 	remove_proc_entry("aironet", proc_root_driver);
 
-	if (is_pci) {
 #ifdef CONFIG_PCI
-		pci_unregister_driver(&airo_driver);
+	pci_unregister_driver(&airo_driver);
 #endif
-	}
 }
 
 #ifdef WIRELESS_EXT
diff -urN linux-2.4.24-pre1/drivers/parport/init.c linux-2.4.24-pre2/drivers/parport/init.c
--- linux-2.4.24-pre1/drivers/parport/init.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/drivers/parport/init.c	2002-11-28 15:53:14.000000000 -0800
@@ -164,9 +164,6 @@
 #ifdef CONFIG_PARPORT_SUNBPP
 	parport_sunbpp_init();
 #endif
-#ifdef CONFIG_PARPORT_IP22
-	parport_ip22_init();
-#endif
 	return 0;
 }
 
diff -urN linux-2.4.24-pre1/drivers/parport/parport_ip22.c linux-2.4.24-pre2/drivers/parport/parport_ip22.c
--- linux-2.4.24-pre1/drivers/parport/parport_ip22.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/drivers/parport/parport_ip22.c	2003-12-22 11:34:35.000000000 -0800
@@ -60,8 +60,9 @@
 #include <linux/init.h>
 #include <linux/parport.h>
 #include <asm/sgi/ioc.h>
+#include <asm/sgi/pi1.h>
 
-#define DEBUG
+#undef DEBUG
 
 #ifdef DEBUG
 #define DPRINTK printk
@@ -95,8 +96,8 @@
 		sgioc->pport.ctrl,
 		sgioc->pport.status,
 		sgioc->pport.dmactrl,
-		sgioc->pport.intrstat,
-		sgioc->pport.intrmask,
+		sgioc->pport.intstat,
+		sgioc->pport.intmask,
 		sgioc->pport.timer1,
 		sgioc->pport.timer2,
 		sgioc->pport.timer3,
@@ -105,31 +106,31 @@
 #endif
 }
 
-static unsigned char parport_ip22_read_data(struct parport *p)
+static unsigned char pi1_read_data(struct parport *p)
 {
 	unsigned char data = sgioc->pport.data;
-	DPRINTK("parport_ip22_read_data: %#x\n", data);
+	DPRINTK("pi1_read_data: %#x\n", data);
 	return data;
 }
 
-static void parport_ip22_write_data(struct parport *p, unsigned char data)
+static void pi1_write_data(struct parport *p, unsigned char data)
 {
-	DPRINTK("parport_ip22_write_data: %#x\n", data);
+	DPRINTK("pi1_write_data: %#x\n", data);
 	sgioc->pport.data = data;
 }
 
-static unsigned char parport_ip22_read_control(struct parport *p)
+static unsigned char pi1_read_control(struct parport *p)
 {
 	const unsigned char mask = PARPORT_CONTROL_STROBE
 		| PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_INIT
 		| PARPORT_CONTROL_SELECT;
 	unsigned char pctrl = sgioc->pport.ctrl,
 		control = ((pctrl & mask) ^ control_invert);
-	DPRINTK("parport_ip22_read_control: %#x, %#x\n", pctrl, control);
+	DPRINTK("pi1_read_control: %#x, %#x\n", pctrl, control);
 	return control;
 }
 
-static void parport_ip22_write_control(struct parport *p, unsigned char control)
+static void pi1_write_control(struct parport *p, unsigned char control)
 {
 	const unsigned char mask = PARPORT_CONTROL_STROBE
 		| PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_INIT
@@ -137,106 +138,102 @@
 	/* we enforce some necessary bits */
 		force = 0x30;
 	unsigned char pctrl = ((control & mask) ^ control_invert) | force;
-	DPRINTK("parport_ip22_write_control: %#x, %#x\n", control, pctrl);
+	DPRINTK("pi1_write_control: %#x, %#x\n", control, pctrl);
 	sgioc->pport.ctrl = pctrl;
 }
 
-static unsigned char parport_ip22_frob_control(struct parport *p,
+static unsigned char pi1_frob_control(struct parport *p,
 	unsigned char mask, unsigned char val)
 {
 	unsigned char old;
-	DPRINTK(KERN_DEBUG "parport_ip22_frob_control mask %02x, value %02x\n",mask,val);
-	old = parport_ip22_read_control(p);
-	parport_ip22_write_control(p, (old & ~mask) ^ val);
+	DPRINTK(KERN_DEBUG "pi1_frob_control mask %02x, value %02x\n",mask,val);
+	old = pi1_read_control(p);
+	pi1_write_control(p, (old & ~mask) ^ val);
 	return old;
 }
 
-static unsigned char parport_ip22_read_status(struct parport *p)
+static unsigned char pi1_read_status(struct parport *p)
 {
 	const unsigned mask = PARPORT_STATUS_ERROR | PARPORT_STATUS_SELECT
 		| PARPORT_STATUS_PAPEROUT | PARPORT_STATUS_ACK
 		| PARPORT_STATUS_BUSY;
 	unsigned char pstat = sgioc->pport.status,
 		status = ((pstat & mask) ^ status_invert);
-	DPRINTK("parport_ip22_read_status: %#x, %#x\n", pstat, status);
+	DPRINTK("pi1_read_status: %#x, %#x\n", pstat, status);
 	return status;
 }
 
-static void parport_ip22_init_state(struct pardevice *d, struct parport_state *s)
+static void pi1_init_state(struct pardevice *d, struct parport_state *s)
 {
-	DPRINTK("parport_ip22_init_state\n");
+	DPRINTK("pi1_init_state\n");
 }
 
-static void parport_ip22_save_state(struct parport *p, struct parport_state *s)
+static void pi1_save_state(struct parport *p, struct parport_state *s)
 {
-	DPRINTK("parport_ip22_save_state\n");
+	DPRINTK("pi1_save_state\n");
 }
 
-static void parport_ip22_restore_state(struct parport *p, struct parport_state *s)
+static void pi1_restore_state(struct parport *p, struct parport_state *s)
 {
-	DPRINTK("parport_ip22_restore_state\n");
+	DPRINTK("pi1_restore_state\n");
 }
 
-static void parport_ip22_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void pi1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	DPRINTK("parport_ip22_interrupt\n");
+	DPRINTK("pi1_interrupt\n");
 	parport_generic_irq(irq, (struct parport *) dev_id, regs);
 }
 
-static void parport_ip22_enable_irq(struct parport *p)
+static void pi1_enable_irq(struct parport *p)
 {
-	DPRINTK("parport_ip22_enable_irq\n");
+	DPRINTK("pi1_enable_irq\n");
 }
 
-static void parport_ip22_disable_irq(struct parport *p)
+static void pi1_disable_irq(struct parport *p)
 {
-	DPRINTK("parport_ip22_disable_irq\n");
+	DPRINTK("pi1_disable_irq\n");
 }
 
-static void parport_ip22_data_forward(struct parport *p)
+static void pi1_data_forward(struct parport *p)
 {
-	DPRINTK("parport_ip22_data_forward\n");
-	sgioc->pport.ctrl &= ~SGIOC_PCTRL_DIRECTION;
+	DPRINTK("pi1_data_forward\n");
+	sgioc->pport.ctrl &= ~PI1_CTRL_DIR;
 }
 
-static void parport_ip22_data_reverse(struct parport *p)
+static void pi1_data_reverse(struct parport *p)
 {
-	DPRINTK("parport_ip22_data_reverse\n");
-	sgioc->pport.ctrl |= SGIOC_PCTRL_DIRECTION;
+	DPRINTK("pi1_data_reverse\n");
+	sgioc->pport.ctrl |= PI1_CTRL_DIR;
 }
 
-static void parport_ip22_inc_use_count(void)
+static void pi1_inc_use_count(void)
 {
-	DPRINTK("parport_ip22_inc_use_count\n");
-#	ifdef MODULE
+	DPRINTK("pi1_inc_use_count\n");
 	MOD_INC_USE_COUNT;
-#	endif
 }
 
-static void parport_ip22_dec_use_count(void)
+static void pi1_dec_use_count(void)
 {
-	DPRINTK("parport_ip22_dec_use_count\n");
-#	ifdef MODULE
+	DPRINTK("pi1_dec_use_count\n");
 	MOD_DEC_USE_COUNT;
-#	endif
 }
 
-static struct parport_operations parport_ip22_ops = {
-	parport_ip22_write_data,
-	parport_ip22_read_data,
-	parport_ip22_write_control,
-	parport_ip22_read_control,
-	parport_ip22_frob_control,
-	parport_ip22_read_status,
-	parport_ip22_enable_irq,
-	parport_ip22_disable_irq,
-	parport_ip22_data_forward,
-	parport_ip22_data_reverse,
-	parport_ip22_init_state,
-	parport_ip22_save_state,
-	parport_ip22_restore_state,
-	parport_ip22_inc_use_count,
-	parport_ip22_dec_use_count,
+static struct parport_operations pi1_ops = {
+	pi1_write_data,
+	pi1_read_data,
+	pi1_write_control,
+	pi1_read_control,
+	pi1_frob_control,
+	pi1_read_status,
+	pi1_enable_irq,
+	pi1_disable_irq,
+	pi1_data_forward,
+	pi1_data_reverse,
+	pi1_init_state,
+	pi1_save_state,
+	pi1_restore_state,
+	pi1_inc_use_count,
+	pi1_dec_use_count,
 	parport_ieee1284_epp_write_data,
 	parport_ieee1284_epp_read_data,
 	parport_ieee1284_epp_write_addr,
@@ -251,7 +248,7 @@
 
 static void init_hardware(void)
 {
-	sgioc->pport.intrmask = 0xfc;
+	sgioc->pport.intmask = 0xfc;
 	sgioc->pport.dmactrl = 1;
 	sgioc->pport.ctrl = 0x3f;
 	sgioc->pport.timer1 = 0;
@@ -261,13 +258,14 @@
 	sgioc->pport.data = 0;
 }
 
-int __init parport_ip22_init(void)
+static int __init pi1_init(void)
 {
 	struct parport *p;
 
-	DPRINTK("parport_ip22_init\n");
-	p = parport_register_port((unsigned long)&sgioc->pport.data, PARPORT_IRQ_NONE,
-		PARPORT_DMA_NONE, &parport_ip22_ops);
+	DPRINTK("pi1_init\n");
+	p = parport_register_port((unsigned long) &sgioc->pport.data,
+				  PARPORT_IRQ_NONE, PARPORT_DMA_NONE,
+				  &pi1_ops);
 	if (!p)
 		return -EBUSY;
 
@@ -289,16 +287,16 @@
 	/* put hardware into known initial state */
 	init_hardware();
 
-	printk(KERN_INFO "%s: SGI Indy/Indigo2 built-in port\n", p->name);
+	printk(KERN_INFO "%s: SGI PI1\n", p->name);
 	parport_proc_register(p);
 	parport_announce_port(p);
 
 	return 0;
 }
 
-void __exit parport_ip22_exit(void)
+static void __exit pi1_exit(void)
 {
-	DPRINTK("parport_ip22_exit\n");
+	DPRINTK("pi1_exit\n");
 	if (this_port->irq != PARPORT_IRQ_NONE)
 		free_irq(this_port->irq, this_port);
 
@@ -306,10 +304,10 @@
 	parport_unregister_port(this_port);
 }
 
-MODULE_AUTHOR("Vincent Stehlé <vincent.stehle@free.fr>");
+MODULE_AUTHOR("Vincent Stehle <vincent.stehle@free.fr>");
 MODULE_DESCRIPTION("Driver for SGI Indy/Indigo2 parallel port");
 MODULE_SUPPORTED_DEVICE("SGI PI1 parallel port");
 MODULE_LICENSE("GPL");
 
-module_init(parport_ip22_init);
-module_exit(parport_ip22_exit);
+module_init(pi1_init);
+module_exit(pi1_exit);
diff -urN linux-2.4.24-pre1/drivers/pci/pci.ids linux-2.4.24-pre2/drivers/pci/pci.ids
--- linux-2.4.24-pre1/drivers/pci/pci.ids	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/drivers/pci/pci.ids	2003-12-22 11:34:35.000000000 -0800
@@ -3428,8 +3428,6 @@
 		1148 5061  SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
 		1148 5071  SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
 		1148 9521  SK-9521 10/100/1000Base-T Adapter
-	4400 SK-9Dxx Gigabit Ethernet Adapter
-	4500 SK-9Mxx Gigabit Ethernet Adapter
 1149  Win System Corporation
 114a  VMIC
 	5579  VMIPCI-5579 (Reflective Memory Card)
@@ -3727,7 +3725,22 @@
 	0146  GT-64010/64010A System Controller
 	4146  GT-64011/GT-64111 System Controller
 	4320  Gigabit Ethernet Adapter
-		11ab 9521  Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter
+		1019 0f38  Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
+		1019 8001  Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
+		1043 173c  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
+		1043 811a  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
+		105b 0c19  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
+		10b8 b452  SMC EZ Card 1000 (SMC9452TXV.2)
+		11ab 0121  Marvell RDK-8001 Adapter
+		11ab 0321  Marvell RDK-8003 Adapter
+		11ab 1021  Marvell RDK-8010 Adapter
+		11ab 5021  Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
+		11ab 9521  Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
+		1458 e000  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
+		147b 1406  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
+		15d4 0047  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
+		1695 9025  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
+		17f2 1c03  Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
 	4611  GT-64115 System Controller
 	4620  GT-64120/64120A/64121A System Controller
 	4801  GT-48001
diff -urN linux-2.4.24-pre1/drivers/pcmcia/cardbus.c linux-2.4.24-pre2/drivers/pcmcia/cardbus.c
--- linux-2.4.24-pre1/drivers/pcmcia/cardbus.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.24-pre2/drivers/pcmcia/cardbus.c	2003-12-22 11:34:35.000000000 -0800
@@ -223,7 +223,6 @@
 
 struct pci_dev *cb_scan_slot(struct pci_dev *temp, struct list_head *list)
 {
-	struct pci_bus *bus = temp->bus;
 	struct pci_dev *dev;
 	struct pci_dev *first_dev = NULL;
 	int func = 0;
@@ -369,7 +368,7 @@
 	return max;
 }
 
-static int program_bridge(struct pci_dev *bridge)
+static void program_bridge(struct pci_dev *bridge)
 {
 	u32 l;
 	
diff -urN linux-2.4.24-pre1/drivers/pcmcia/cistpl.c linux-2.4.24-pre2/drivers/pcmcia/cistpl.c
--- linux-2.4.24-pre1/drivers/pcmcia/cistpl.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.24-pre2/drivers/pcmcia/cistpl.c	2003-12-22 11:34:35.000000000 -0800
@@ -351,9 +351,12 @@
 
 int verify_cis_cache(socket_info_t *s)
 {
-    char buf[256], *caddr;
+    char *buf, *caddr;
     int i;
-    
+
+    buf = kmalloc(256, GFP_KERNEL);
+    if (buf == NULL)
+	return -1;
     caddr = s->cis_cache;
     for (i = 0; i < s->cis_used; i++) {
 #ifdef CONFIG_CARDBUS
@@ -368,6 +371,7 @@
 	    break;
 	caddr += s->cis_table[i].len;
     }
+    kfree(buf);
     return (i < s->cis_used);
 }
 
@@ -1410,20 +1414,31 @@
 
 int read_tuple(client_handle_t handle, cisdata_t code, void *parse)
 {
-    tuple_t tuple;
-    cisdata_t buf[255];
+    tuple_t *tuple;
+    cisdata_t *buf;
     int ret;
-    
-    tuple.DesiredTuple = code;
-    tuple.Attributes = TUPLE_RETURN_COMMON;
-    ret = pcmcia_get_first_tuple(handle, &tuple);
-    if (ret != CS_SUCCESS) return ret;
-    tuple.TupleData = buf;
-    tuple.TupleOffset = 0;
-    tuple.TupleDataMax = sizeof(buf);
-    ret = pcmcia_get_tuple_data(handle, &tuple);
-    if (ret != CS_SUCCESS) return ret;
-    ret = pcmcia_parse_tuple(handle, &tuple, parse);
+
+    buf = kmalloc(256, GFP_KERNEL);
+    if (buf == NULL)
+	return CS_OUT_OF_RESOURCE;
+    tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
+    if (tuple == NULL) {
+	kfree(buf);
+	return CS_OUT_OF_RESOURCE;
+    }
+    tuple->DesiredTuple = code;
+    tuple->Attributes = TUPLE_RETURN_COMMON;
+    ret = pcmcia_get_first_tuple(handle, tuple);
+    if (ret != CS_SUCCESS) goto done;
+    tuple->TupleData = buf;
+    tuple->TupleOffset = 0;
+    tuple->TupleDataMax = 255;
+    ret = pcmcia_get_tuple_data(handle, tuple);
+    if (ret != CS_SUCCESS) goto done;
+    ret = pcmcia_parse_tuple(handle, tuple, parse);
+done:
+    kfree(tuple);
+    kfree(buf);
     return ret;
 }
 
@@ -1439,50 +1454,61 @@
 
 int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
 {
-    tuple_t tuple;
-    cisparse_t p;
+    tuple_t *tuple;
+    cisparse_t *p;
     int ret, reserved, dev_ok = 0, ident_ok = 0;
 
     if (CHECK_HANDLE(handle))
 	return CS_BAD_HANDLE;
+    tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
+    if (tuple == NULL)
+	return CS_OUT_OF_RESOURCE;
+    p = kmalloc(sizeof(*p), GFP_KERNEL);
+    if (p == NULL) {
+	kfree(tuple);
+	return CS_OUT_OF_RESOURCE;
+    }
 
     info->Chains = reserved = 0;
-    tuple.DesiredTuple = RETURN_FIRST_TUPLE;
-    tuple.Attributes = TUPLE_RETURN_COMMON;
-    ret = pcmcia_get_first_tuple(handle, &tuple);
+    tuple->DesiredTuple = RETURN_FIRST_TUPLE;
+    tuple->Attributes = TUPLE_RETURN_COMMON;
+    ret = pcmcia_get_first_tuple(handle, tuple);
     if (ret != CS_SUCCESS)
-	return CS_SUCCESS;
+	goto done;
 
     /* First tuple should be DEVICE; we should really have either that
        or a CFTABLE_ENTRY of some sort */
-    if ((tuple.TupleCode == CISTPL_DEVICE) ||
-	(read_tuple(handle, CISTPL_CFTABLE_ENTRY, &p) == CS_SUCCESS) ||
-	(read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, &p) == CS_SUCCESS))
+    if ((tuple->TupleCode == CISTPL_DEVICE) ||
+	(read_tuple(handle, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) ||
+	(read_tuple(handle, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS))
 	dev_ok++;
 
     /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
        tuple, for card identification.  Certain old D-Link and Linksys
        cards have only a broken VERS_2 tuple; hence the bogus test. */
-    if ((read_tuple(handle, CISTPL_MANFID, &p) == CS_SUCCESS) ||
-	(read_tuple(handle, CISTPL_VERS_1, &p) == CS_SUCCESS) ||
-	(read_tuple(handle, CISTPL_VERS_2, &p) != CS_NO_MORE_ITEMS))
+    if ((read_tuple(handle, CISTPL_MANFID, p) == CS_SUCCESS) ||
+	(read_tuple(handle, CISTPL_VERS_1, p) == CS_SUCCESS) ||
+	(read_tuple(handle, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS))
 	ident_ok++;
 
     if (!dev_ok && !ident_ok)
-	return CS_SUCCESS;
+	goto done;
 
     for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) {
-	ret = pcmcia_get_next_tuple(handle, &tuple);
+	ret = pcmcia_get_next_tuple(handle, tuple);
 	if (ret != CS_SUCCESS) break;
-	if (((tuple.TupleCode > 0x23) && (tuple.TupleCode < 0x40)) ||
-	    ((tuple.TupleCode > 0x47) && (tuple.TupleCode < 0x80)) ||
-	    ((tuple.TupleCode > 0x90) && (tuple.TupleCode < 0xff)))
+	if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
+	    ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
+	    ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
 	    reserved++;
     }
     if ((info->Chains == MAX_TUPLES) || (reserved > 5) ||
 	((!dev_ok || !ident_ok) && (info->Chains > 10)))
 	info->Chains = 0;
 
+done:
+    kfree(tuple);
+    kfree(p);
     return CS_SUCCESS;
 }
 
diff -urN linux-2.4.24-pre1/drivers/pcmcia/cs.c linux-2.4.24-pre2/drivers/pcmcia/cs.c
--- linux-2.4.24-pre1/drivers/pcmcia/cs.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.24-pre2/drivers/pcmcia/cs.c	2003-12-22 11:34:35.000000000 -0800
@@ -1862,7 +1862,7 @@
 {
     socket_info_t *s;
     config_t *c;
-    int ret = 0, irq = 0;
+    int ret = CS_IN_USE, irq = 0;
     
     if (CHECK_HANDLE(handle))
 	return CS_BAD_HANDLE;
@@ -1874,13 +1874,9 @@
 	return CS_CONFIGURATION_LOCKED;
     if (c->state & CONFIG_IRQ_REQ)
 	return CS_IN_USE;
-    
-    /* Short cut: if there are no ISA interrupts, then it is PCI */
-    if (!s->cap.irq_mask) {
-	irq = s->cap.pci_irq;
-	ret = (irq) ? 0 : CS_IN_USE;
+
 #ifdef CONFIG_ISA
-    } else if (s->irq.AssignedIRQ != 0) {
+    if (s->irq.AssignedIRQ != 0) {
 	/* If the interrupt is already assigned, it must match */
 	irq = s->irq.AssignedIRQ;
 	if (req->IRQInfo1 & IRQ_INFO2_VALID) {
@@ -1889,7 +1885,6 @@
 	} else
 	    ret = ((req->IRQInfo1&IRQ_MASK) == irq) ? 0 : CS_BAD_ARGS;
     } else {
-	ret = CS_IN_USE;
 	if (req->IRQInfo1 & IRQ_INFO2_VALID) {
 	    u_int try, mask = req->IRQInfo2 & s->cap.irq_mask;
 	    for (try = 0; try < 2; try++) {
@@ -1904,9 +1899,13 @@
 	    irq = req->IRQInfo1 & IRQ_MASK;
 	    ret = try_irq(req->Attributes, irq, 1);
 	}
+    }
 #endif
+    if (ret != 0) {
+	if (!s->cap.pci_irq)
+	    return ret;
+	irq = s->cap.pci_irq;
     }
-    if (ret != 0) return ret;
 
     if (req->Attributes & IRQ_HANDLE_PRESENT) {
 	if (bus_request_irq(s->cap.bus, irq, req->Handler,
diff -urN linux-2.4.24-pre1/drivers/pcmcia/rsrc_mgr.c linux-2.4.24-pre2/drivers/pcmcia/rsrc_mgr.c
--- linux-2.4.24-pre1/drivers/pcmcia/rsrc_mgr.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.24-pre2/drivers/pcmcia/rsrc_mgr.c	2003-12-22 11:34:35.000000000 -0800
@@ -379,7 +379,7 @@
 void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
 		  int force_low, socket_info_t *s)
 {
-    resource_map_t *m, *n;
+    resource_map_t *m, mm;
     static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
     static int hi = 0, lo = 0;
     u_long b, i, ok = 0;
@@ -393,18 +393,18 @@
 	       "available!\n");
     }
     if (lo++) return;
-    for (m = mem_db.next; m != &mem_db; m = n) {
-	n = m->next;
+    for (m = mem_db.next; m != &mem_db; m = mm.next) {
+	mm = *m;
 	/* Only probe < 1 MB */
-	if (m->base >= 0x100000) continue;
-	if ((m->base | m->num) & 0xffff) {
-	    ok += do_mem_probe(m->base, m->num, is_valid, do_cksum, s);
+	if (mm.base >= 0x100000) continue;
+	if ((mm.base | mm.num) & 0xffff) {
+	    ok += do_mem_probe(mm.base, mm.num, is_valid, do_cksum, s);
 	    continue;
 	}
 	/* Special probe for 64K-aligned block */
 	for (i = 0; i < 4; i++) {
 	    b = order[i] << 12;
-	    if ((b >= m->base) && (b+0x10000 <= m->base+m->num)) {
+	    if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
 		if (ok >= mem_limit)
 		    sub_interval(&mem_db, b, 0x10000);
 		else
diff -urN linux-2.4.24-pre1/drivers/pcmcia/sa1100_stork.c linux-2.4.24-pre2/drivers/pcmcia/sa1100_stork.c
--- linux-2.4.24-pre1/drivers/pcmcia/sa1100_stork.c	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.24-pre2/drivers/pcmcia/sa1100_stork.c	2003-12-22 11:34:35.000000000 -0800
@@ -24,7 +24,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/i2c.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
diff -urN linux-2.4.24-pre1/drivers/pcmcia/yenta.c linux-2.4.24-pre2/drivers/pcmcia/yenta.c
--- linux-2.4.24-pre1/drivers/pcmcia/yenta.c	2003-06-13 07:51:35.000000000 -0700
+++ linux-2.4.24-pre2/drivers/pcmcia/yenta.c	2003-12-22 11:34:35.000000000 -0800
@@ -26,7 +26,7 @@
 #include "i82365.h"
 
 #if 0
-#define DEBUG(x,args...)	printk(__FUNCTION__ ": " x,##args)
+#define DEBUG(x,args...)	printk(KERN_DEBUG __FUNCTION__ ": " x,##args)
 #else
 #define DEBUG(x,args...)
 #endif
@@ -576,7 +576,8 @@
 	socket->cap.cb_dev = socket->dev;
 	socket->cap.bus = NULL;
 
-	printk("Yenta IRQ list %04x, PCI irq%d\n", socket->cap.irq_mask, socket->cb_irq);
+	printk(KERN_INFO "Yenta ISA IRQ mask 0x%04x, PCI irq %d\n",
+	       socket->cap.irq_mask, socket->cb_irq);
 }
 
 extern void cardbus_register(pci_socket_t *socket);
@@ -603,7 +604,8 @@
 
 	/* Figure out what the dang thing can do for the PCMCIA layer... */
 	yenta_get_socket_capabilities(socket, isa_interrupts);
-	printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
+	printk(KERN_INFO "Socket status: %08x\n",
+	       cb_readl(socket, CB_SOCKET_STATE));
 
 	/* Register it with the pcmcia layer.. */
 	cardbus_register(socket);
@@ -889,7 +891,7 @@
 	if (pci_enable_device(dev))
 		return -1;
 	if (!pci_resource_start(dev, 0)) {
-		printk("No cardbus resource!\n");
+		printk(KERN_ERR "No cardbus resource!\n");
 		return -1;
 	}
 
diff -urN linux-2.4.24-pre1/drivers/sbus/char/rtc.c linux-2.4.24-pre2/drivers/sbus/char/rtc.c
--- linux-2.4.24-pre1/drivers/sbus/char/rtc.c	2001-10-10 23:42:47.000000000 -0700
+++ linux-2.4.24-pre2/drivers/sbus/char/rtc.c	2003-12-22 11:34:35.000000000 -0800
@@ -89,6 +89,7 @@
 	switch (cmd)
 	{
 	case RTCGET:
+		memset(&rtc_tm, 0, sizeof(struct rtc_time));
 		get_rtc_time(&rtc_tm);
 
 		if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
diff -urN linux-2.4.24-pre1/drivers/usb/pegasus.c linux-2.4.24-pre2/drivers/usb/pegasus.c
--- linux-2.4.24-pre1/drivers/usb/pegasus.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.24-pre2/drivers/usb/pegasus.c	2003-12-22 11:34:35.000000000 -0800
@@ -54,7 +54,7 @@
 			BMSR_100FULL | BMSR_ANEGCAPABLE)
 
 static int loopback = 0;
-static int mii_mode = 1;
+static int mii_mode = 0;
 static int multicast_filter_limit = 32;
 
 static struct usb_eth_dev usb_dev_id[] = {
@@ -486,7 +486,7 @@
 	if (linkpart & (ADVERTISE_100FULL | ADVERTISE_100HALF))
 		data[1] |= 0x10;	/* set 100 Mbps */
 	if (mii_mode)
-		data[1] = 0;
+		data[1] |= 1;
 	data[2] = (loopback & 1) ? 0x09 : 0x01;
 	memcpy(pegasus->eth_regs, data, sizeof(data));
 	set_registers(pegasus, EthCtrl0, 3, data);
@@ -900,6 +900,7 @@
 			info.cmd = ETHTOOL_GDRVINFO;
 			strncpy(info.driver, driver_name,
 			        sizeof (info.driver) - 1);
+			strncpy(info.driver, DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
 			strncpy(info.version, DRIVER_VERSION,
 				sizeof (info.version) - 1);
 			usb_make_path(pegasus->usb, info.bus_info,
diff -urN linux-2.4.24-pre1/drivers/usb/pegasus.h linux-2.4.24-pre2/drivers/usb/pegasus.h
--- linux-2.4.24-pre1/drivers/usb/pegasus.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.24-pre2/drivers/usb/pegasus.h	2003-12-22 11:34:35.000000000 -0800
@@ -133,8 +133,10 @@
 #define	VENDOR_LANEED		0x056e
 #define	VENDOR_LINKSYS		0x066b
 #define	VENDOR_MELCO		0x0411
+#define	VENDOR_MICROSOFT	0x045e
 #define	VENDOR_MOBILITY		0x1342
 #define VENDOR_NETGEAR		0x0846
+#define	VENDOR_OCT		0x0b39
 #define	VENDOR_SMARTBRIDGES	0x08d1
 #define	VENDOR_SMC		0x0707
 #define	VENDOR_SOHOWARE		0x15e8
@@ -170,7 +172,7 @@
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
 		VENDOR_ADMTEK, 0x8511,
-		DEFAULT_GPIO_RESET | PEGASUS_II )
+		DEFAULT_GPIO_RESET | PEGASUS_II | HAS_HOME_PNA )
 PEGASUS_DEV( "ADMtek ADM8513 \"Pegasus II\" USB Ethernet",
 		VENDOR_ADMTEK, 0x8513,
 		DEFAULT_GPIO_RESET | PEGASUS_II )	
@@ -255,8 +257,12 @@
 		DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "MELCO/BUFFALO LUA2-TX", VENDOR_MELCO, 0x0009,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "Microsoft MN-110", VENDOR_MICROSOFT, 0x007a,
+		DEFAULT_GPIO_RESET | PEGASUS_II )	
 PEGASUS_DEV( "NETGEAR FA101", VENDOR_NETGEAR, 0x1020,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "OCT Inc.", VENDOR_OCT, 0x0109,
+		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "smartNIC 2 PnP Adapter", VENDOR_SMARTBRIDGES, 0x0003,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
diff -urN linux-2.4.24-pre1/drivers/usb/printer.c linux-2.4.24-pre2/drivers/usb/printer.c
--- linux-2.4.24-pre1/drivers/usb/printer.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/printer.c	2003-12-22 11:34:35.000000000 -0800
@@ -22,8 +22,11 @@
  *	v0.7 - fixed bulk-IN read and poll (David Paschal)
  *	v0.8 - add devfs support
  *	v0.9 - fix unplug-while-open paths
- *	v0.10 - add proto_bias option (Pete Zaitcev)
- *	v0.11 - add hpoj.sourceforge.net ioctls (David Paschal)
+ *	v0.10- remove sleep_on, fix error on oom (oliver@neukum.org)
+ *	v0.11 - add proto_bias option (Pete Zaitcev)
+ *	v0.12 - add hpoj.sourceforge.net ioctls (David Paschal)
+ *	v0.13 - alloc space for statusbuf (<status> not on stack);
+ *		use usb_buffer_alloc() for read buf & write buf;
  */
 
 /*
@@ -58,12 +61,12 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.11"
+#define DRIVER_VERSION "v0.13"
 #define DRIVER_AUTHOR "Michael Gee, Pavel Machek, Vojtech Pavlik, Randy Dunlap, Pete Zaitcev, David Paschal"
 #define DRIVER_DESC "USB Printer Device Class driver"
 
 #define USBLP_BUF_SIZE		8192
-#define DEVICE_ID_SIZE		1024
+#define USBLP_DEVICE_ID_SIZE	1024
 
 /* ioctls: */
 #define LPGETSTATUS		0x060b		/* same as in drivers/char/lp.c */
@@ -115,12 +118,20 @@
 #define USBLP_LAST_PROTOCOL	3
 #define USBLP_MAX_PROTOCOLS	(USBLP_LAST_PROTOCOL+1)
 
+/*
+ * some arbitrary status buffer size;
+ * need a status buffer that is allocated via kmalloc(), not on stack
+ */
+#define STATUS_BUF_SIZE		8
+
 struct usblp {
 	struct usb_device 	*dev;			/* USB device */
 	devfs_handle_t		devfs;			/* devfs device */
 	struct semaphore	sem;			/* locks this struct, especially "dev" */
-	char			*buf;		/* writeurb.transfer_buffer */
-	struct urb		readurb, writeurb;	/* The urbs */
+	char			*writebuf;		/* write transfer_buffer */
+	char			*readbuf;		/* read transfer_buffer */
+	char			*statusbuf;		/* status transfer_buffer */
+	struct urb		*readurb, *writeurb;	/* The urbs */
 	wait_queue_head_t	wait;			/* Zzzzz ... */
 	int			readcount;		/* Counter for reads */
 	int			ifnum;			/* Interface number */
@@ -133,8 +144,11 @@
 	}			protocol[USBLP_MAX_PROTOCOLS];
 	int			current_protocol;
 	int			minor;			/* minor number of device */
+	int			wcomplete;		/* writing is completed */
+	int			rcomplete;		/* reading is completed */
 	unsigned int		quirks;			/* quirks flags */
 	unsigned char		used;			/* True if open */
+	unsigned char		present;		/* True if not disconnected */
 	unsigned char		bidir;			/* interface is bidirectional */
 	unsigned char		*device_id_string;	/* IEEE 1284 DEVICE ID string (ptr) */
 							/* first 2 bytes are (big-endian) length */
@@ -146,8 +160,11 @@
 
 	dbg("usblp=0x%p", usblp);
 	dbg("dev=0x%p", usblp->dev);
-	dbg("devfs=0x%p", usblp->devfs);
-	dbg("buf=0x%p", usblp->buf);
+	dbg("present=%d", usblp->present);
+	dbg("readbuf=0x%p", usblp->readbuf);
+	dbg("writebuf=0x%p", usblp->writebuf);
+	dbg("readurb=0x%p", usblp->readurb);
+	dbg("writeurb=0x%p", usblp->writeurb);
 	dbg("readcount=%d", usblp->readcount);
 	dbg("ifnum=%d", usblp->ifnum);
     for (p = USBLP_FIRST_PROTOCOL; p <= USBLP_LAST_PROTOCOL; p++) {
@@ -157,6 +174,8 @@
     }
 	dbg("current_protocol=%d", usblp->current_protocol);
 	dbg("minor=%d", usblp->minor);
+	dbg("wcomplete=%d", usblp->wcomplete);
+	dbg("rcomplete=%d", usblp->rcomplete);
 	dbg("quirks=%d", usblp->quirks);
 	dbg("used=%d", usblp->used);
 	dbg("bidir=%d", usblp->bidir);
@@ -239,17 +258,31 @@
  * URB callback.
  */
 
-static void usblp_bulk(struct urb *urb)
+static void usblp_bulk_read(struct urb *urb)
 {
 	struct usblp *usblp = urb->context;
 
-	if (!usblp || !usblp->dev || !usblp->used)
+	if (!usblp || !usblp->dev || !usblp->used || !usblp->present)
 		return;
 
-	if (urb->status)
+	if (unlikely(urb->status))
 		warn("usblp%d: nonzero read/write bulk status received: %d",
 			usblp->minor, urb->status);
+	usblp->rcomplete = 1;
+	wake_up_interruptible(&usblp->wait);
+}
+
+static void usblp_bulk_write(struct urb *urb)
+{
+	struct usblp *usblp = urb->context;
+
+	if (!usblp || !usblp->dev || !usblp->used || !usblp->present)
+		return;
 
+	if (unlikely(urb->status))
+		warn("usblp%d: nonzero read/write bulk status received: %d",
+			usblp->minor, urb->status);
+	usblp->wcomplete = 1;
 	wake_up_interruptible(&usblp->wait);
 }
 
@@ -257,25 +290,28 @@
  * Get and print printer errors.
  */
 
-static char *usblp_messages[] = { "ok", "out of paper", "off-line", "unknown error" };
+static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
 
 static int usblp_check_status(struct usblp *usblp, int err)
 {
 	unsigned char status, newerr = 0;
 	int error;
 
-	error = usblp_read_status (usblp, &status);
+	error = usblp_read_status (usblp, usblp->statusbuf);
 	if (error < 0) {
 		err("usblp%d: error %d reading printer status",
 			usblp->minor, error);
 		return 0;
 	}
 
-	if (~status & LP_PERRORP) {
+	status = *usblp->statusbuf;
+
+	if (~status & LP_PERRORP)
 		newerr = 3;
-		if (status & LP_POUTPA) newerr = 1;
-		if (~status & LP_PSELECD) newerr = 2;
-	}
+	if (status & LP_POUTPA)
+		newerr = 1;
+	if (~status & LP_PSELECD)
+		newerr = 2;
 
 	if (newerr != err)
 		info("usblp%d: %s", usblp->minor, usblp_messages[newerr]);
@@ -300,7 +336,7 @@
 	usblp  = usblp_table[minor];
 
 	retval = -ENODEV;
-	if (!usblp || !usblp->dev)
+	if (!usblp || !usblp->dev || !usblp->present)
 		goto out;
 
 	retval = -EBUSY;
@@ -324,13 +360,14 @@
 	usblp->used = 1;
 	file->private_data = usblp;
 
-	usblp->writeurb.transfer_buffer_length = 0;
-	usblp->writeurb.status = 0;
+	usblp->writeurb->transfer_buffer_length = 0;
+	usblp->wcomplete = 1; /* we begin writeable */
+	usblp->rcomplete = 0;
 
 	if (usblp->bidir) {
 		usblp->readcount = 0;
-		usblp->readurb.dev = usblp->dev;
-		if (usb_submit_urb(&usblp->readurb) < 0) {
+		usblp->readurb->dev = usblp->dev;
+		if (usb_submit_urb(usblp->readurb) < 0) {
 			retval = -EIO;
 			usblp->used = 0;
 			file->private_data = NULL;
@@ -347,16 +384,20 @@
 	usblp_table [usblp->minor] = NULL;
 	info("usblp%d: removed", usblp->minor);
 
-	kfree (usblp->writeurb.transfer_buffer);
+	kfree (usblp->writebuf);
+	kfree (usblp->readbuf);
 	kfree (usblp->device_id_string);
+	kfree (usblp->statusbuf);
+	usb_free_urb(usblp->writeurb);
+	usb_free_urb(usblp->readurb);
 	kfree (usblp);
 }
 
 static void usblp_unlink_urbs(struct usblp *usblp)
 {
-	usb_unlink_urb(&usblp->writeurb);
+	usb_unlink_urb(usblp->writeurb);
 	if (usblp->bidir)
-		usb_unlink_urb(&usblp->readurb);
+		usb_unlink_urb(usblp->readurb);
 }
 
 static int usblp_release(struct inode *inode, struct file *file)
@@ -366,7 +407,7 @@
 	down (&usblp->sem);
 	lock_kernel();
 	usblp->used = 0;
-	if (usblp->dev) {
+	if (usblp->present) {
 		usblp_unlink_urbs(usblp);
 		up(&usblp->sem);
 	} else 		/* finish cleanup from disconnect */
@@ -380,21 +421,21 @@
 {
 	struct usblp *usblp = file->private_data;
 	poll_wait(file, &usblp->wait, wait);
- 	return ((!usblp->bidir || usblp->readurb.status  == -EINPROGRESS) ? 0 : POLLIN  | POLLRDNORM)
- 			       | (usblp->writeurb.status == -EINPROGRESS  ? 0 : POLLOUT | POLLWRNORM);
+ 	return ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN  | POLLRDNORM)
+ 			       | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM);
 }
 
 static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct usblp *usblp = file->private_data;
 	int length, err, i;
-	unsigned char lpstatus, newChannel;
+	unsigned char newChannel;
 	int status;
 	int twoints[2];
 	int retval = 0;
 
 	down (&usblp->sem);
-	if (!usblp->dev) {
+	if (!usblp->present) {
 		retval = -ENODEV;
 		goto done;
 	}
@@ -534,24 +575,24 @@
 				break;
 
 			default:
-				retval = -EINVAL;
+				retval = -ENOTTY;
 		}
 	else	/* old-style ioctl value */
 		switch (cmd) {
 
 			case LPGETSTATUS:
-				if (usblp_read_status(usblp, &lpstatus)) {
+				if (usblp_read_status(usblp, usblp->statusbuf)) {
 					err("usblp%d: failed reading printer status", usblp->minor);
 					retval = -EIO;
 					goto done;
 				}
-				status = lpstatus;
+				status = *usblp->statusbuf;
 				if (copy_to_user ((int *)arg, &status, sizeof(int)))
 					retval = -EFAULT;
 				break;
 
 			default:
-				retval = -EINVAL;
+				retval = -ENOTTY;
 		}
 
 done:
@@ -561,41 +602,48 @@
 
 static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
 {
+	DECLARE_WAITQUEUE(wait, current);
 	struct usblp *usblp = file->private_data;
 	int timeout, err = 0;
 	size_t writecount = 0;
 
 	while (writecount < count) {
-
-		// FIXME:  only use urb->status inside completion
-		// callbacks; this way is racey...
-		if (usblp->writeurb.status == -EINPROGRESS) {
-
+		if (!usblp->wcomplete) {
+			barrier();
 			if (file->f_flags & O_NONBLOCK)
 				return -EAGAIN;
 
 			timeout = USBLP_WRITE_TIMEOUT;
-			while (timeout && usblp->writeurb.status == -EINPROGRESS) {
+			add_wait_queue(&usblp->wait, &wait);
+			while ( 1==1 ) {
 
-				if (signal_pending(current))
+				if (signal_pending(current)) {
+					remove_wait_queue(&usblp->wait, &wait);
 					return writecount ? writecount : -EINTR;
-
-				timeout = interruptible_sleep_on_timeout(&usblp->wait, timeout);
+				}
+				set_current_state(TASK_INTERRUPTIBLE);
+				if (timeout && !usblp->wcomplete) {
+					timeout = schedule_timeout(timeout);
+				} else {
+					set_current_state(TASK_RUNNING);
+					break;
+				}
 			}
+			remove_wait_queue(&usblp->wait, &wait);
 		}
 
 		down (&usblp->sem);
-		if (!usblp->dev) {
+		if (!usblp->present) {
 			up (&usblp->sem);
 			return -ENODEV;
 		}
 
-		if (usblp->writeurb.status != 0) {
+		if (usblp->writeurb->status != 0) {
 			if (usblp->quirks & USBLP_QUIRK_BIDIR) {
-				if (usblp->writeurb.status != -EINPROGRESS)
+				if (!usblp->wcomplete)
 					err("usblp%d: error %d writing to printer",
-						usblp->minor, usblp->writeurb.status);
-				err = usblp->writeurb.status;
+						usblp->minor, usblp->writeurb->status);
+				err = usblp->writeurb->status;
 			} else
 				err = usblp_check_status(usblp, err);
 			up (&usblp->sem);
@@ -607,25 +655,30 @@
 			continue;
 		}
 
-		writecount += usblp->writeurb.transfer_buffer_length;
-		usblp->writeurb.transfer_buffer_length = 0;
+		writecount += usblp->writeurb->transfer_buffer_length;
+		usblp->writeurb->transfer_buffer_length = 0;
 
 		if (writecount == count) {
 			up (&usblp->sem);
 			break;
 		}
 
-		usblp->writeurb.transfer_buffer_length = (count - writecount) < USBLP_BUF_SIZE ?
-							 (count - writecount) : USBLP_BUF_SIZE;
+		usblp->writeurb->transfer_buffer_length = (count - writecount) < USBLP_BUF_SIZE ?
+							  (count - writecount) : USBLP_BUF_SIZE;
 
-		if (copy_from_user(usblp->writeurb.transfer_buffer, buffer + writecount,
-				usblp->writeurb.transfer_buffer_length)) {
+		if (copy_from_user(usblp->writeurb->transfer_buffer, buffer + writecount,
+				usblp->writeurb->transfer_buffer_length)) {
 			up(&usblp->sem);
 			return writecount ? writecount : -EFAULT;
 		}
 
-		usblp->writeurb.dev = usblp->dev;
-		usb_submit_urb(&usblp->writeurb);
+		usblp->writeurb->dev = usblp->dev;
+		usblp->wcomplete = 0;
+		if (usb_submit_urb(usblp->writeurb)) {
+			count = -EIO;
+			up (&usblp->sem);
+			break;
+		}
 		up (&usblp->sem);
 	}
 
@@ -635,63 +688,77 @@
 static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
 {
 	struct usblp *usblp = file->private_data;
+	DECLARE_WAITQUEUE(wait, current);
 
 	if (!usblp->bidir)
 		return -EINVAL;
 
 	down (&usblp->sem);
-	if (!usblp->dev) {
+	if (!usblp->present) {
 		count = -ENODEV;
 		goto done;
 	}
 
-	if (usblp->readurb.status == -EINPROGRESS) {
+	if (!usblp->rcomplete) {
+		barrier();
 
 		if (file->f_flags & O_NONBLOCK) {
 			count = -EAGAIN;
 			goto done;
 		}
 
-		// FIXME:  only use urb->status inside completion
-		// callbacks; this way is racey...
-		while (usblp->readurb.status == -EINPROGRESS) {
+		add_wait_queue(&usblp->wait, &wait);
+		while (1==1) {
 			if (signal_pending(current)) {
 				count = -EINTR;
+				remove_wait_queue(&usblp->wait, &wait);
 				goto done;
 			}
 			up (&usblp->sem);
-			interruptible_sleep_on(&usblp->wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+			if (!usblp->rcomplete) {
+				schedule();
+			} else {
+				set_current_state(TASK_RUNNING);
+				break;
+			}
 			down (&usblp->sem);
 		}
+		remove_wait_queue(&usblp->wait, &wait);
 	}
 
-	if (!usblp->dev) {
+	if (!usblp->present) {
 		count = -ENODEV;
 		goto done;
 	}
 
-	if (usblp->readurb.status) {
+	if (usblp->readurb->status) {
 		err("usblp%d: error %d reading from printer",
-			usblp->minor, usblp->readurb.status);
-		usblp->readurb.dev = usblp->dev;
+			usblp->minor, usblp->readurb->status);
+		usblp->readurb->dev = usblp->dev;
  		usblp->readcount = 0;
-		usb_submit_urb(&usblp->readurb);
+		if (usb_submit_urb(usblp->readurb) < 0)
+			dbg("error submitting urb");
 		count = -EIO;
 		goto done;
 	}
 
-	count = count < usblp->readurb.actual_length - usblp->readcount ?
-		count :	usblp->readurb.actual_length - usblp->readcount;
+	count = count < usblp->readurb->actual_length - usblp->readcount ?
+		count :	usblp->readurb->actual_length - usblp->readcount;
 
-	if (copy_to_user(buffer, usblp->readurb.transfer_buffer + usblp->readcount, count)) {
+	if (copy_to_user(buffer, usblp->readurb->transfer_buffer + usblp->readcount, count)) {
 		count = -EFAULT;
 		goto done;
 	}
 
-	if ((usblp->readcount += count) == usblp->readurb.actual_length) {
+	if ((usblp->readcount += count) == usblp->readurb->actual_length) {
 		usblp->readcount = 0;
-		usblp->readurb.dev = usblp->dev;
-		usb_submit_urb(&usblp->readurb);
+		usblp->readurb->dev = usblp->dev;
+		usblp->rcomplete = 0;
+		if (usb_submit_urb(usblp->readurb)) {
+			count = -EIO;
+			goto done;
+		}
 	}
 
 done:
@@ -766,19 +833,42 @@
 		}
 	}
 
+	usblp->writeurb = usb_alloc_urb(0);
+	if (!usblp->writeurb) {
+		err("out of memory");
+		goto abort;
+	}
+	usblp->readurb = usb_alloc_urb(0);
+	if (!usblp->readurb) {
+		err("out of memory");
+		goto abort;
+	}
+
 	/* Malloc device ID string buffer to the largest expected length,
 	 * since we can re-query it on an ioctl and a dynamic string
 	 * could change in length. */
-	if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) {
+	if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
 		err("out of memory for device_id_string");
 		goto abort;
 	}
 
-	/* Malloc write/read buffers in one chunk.  We somewhat wastefully
+	usblp->writebuf = usblp->readbuf = NULL;
+	/* Malloc write & read buffers.  We somewhat wastefully
 	 * malloc both regardless of bidirectionality, because the
 	 * alternate setting can be changed later via an ioctl. */
-	if (!(usblp->buf = kmalloc(2 * USBLP_BUF_SIZE, GFP_KERNEL))) {
-		err("out of memory for buf");
+	if (!(usblp->writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL))) {
+		err("out of memory for write buf");
+		goto abort;
+	}
+	if (!(usblp->readbuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL))) {
+		err("out of memory for read buf");
+		goto abort;
+	}
+
+	/* Allocate buffer for printer status */
+	usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL);
+	if (!usblp->statusbuf) {
+		err("out of memory for statusbuf");
 		goto abort;
 	}
 
@@ -818,17 +908,26 @@
 
 	info("usblp%d: USB %sdirectional printer dev %d "
 		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
-		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum, ifnum,
+		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
+		usblp->ifnum,
 		usblp->protocol[usblp->current_protocol].alt_setting,
 		usblp->current_protocol, usblp->dev->descriptor.idVendor,
 		usblp->dev->descriptor.idProduct);
 
+	usblp->present = 1;
+
 	return usblp;
 
 abort:
 	if (usblp) {
-		if (usblp->buf) kfree(usblp->buf);
-		if (usblp->device_id_string) kfree(usblp->device_id_string);
+		if (usblp->writebuf)
+			kfree (usblp->writebuf);
+		if (usblp->readbuf)
+			kfree (usblp->readbuf);
+		kfree(usblp->statusbuf);
+		kfree(usblp->device_id_string);
+		usb_free_urb(usblp->writeurb);
+		usb_free_urb(usblp->readurb);
 		kfree(usblp);
 	}
 	return NULL;
@@ -943,19 +1042,19 @@
 		return r;
 	}
 
-	FILL_BULK_URB(&usblp->writeurb, usblp->dev,
+	usb_fill_bulk_urb(usblp->writeurb, usblp->dev,
 		usb_sndbulkpipe(usblp->dev,
-		 usblp->protocol[protocol].epwrite->bEndpointAddress),
-		usblp->buf, 0,
-		usblp_bulk, usblp);
+		  usblp->protocol[protocol].epwrite->bEndpointAddress),
+		usblp->writebuf, 0,
+		usblp_bulk_write, usblp);
 
 	usblp->bidir = (usblp->protocol[protocol].epread != 0);
 	if (usblp->bidir)
-		FILL_BULK_URB(&usblp->readurb, usblp->dev,
+		usb_fill_bulk_urb(usblp->readurb, usblp->dev,
 			usb_rcvbulkpipe(usblp->dev,
-			 usblp->protocol[protocol].epread->bEndpointAddress),
-			usblp->buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE,
-			usblp_bulk, usblp);
+			  usblp->protocol[protocol].epread->bEndpointAddress),
+			usblp->readbuf, USBLP_BUF_SIZE,
+			usblp_bulk_read, usblp);
 
 	usblp->current_protocol = protocol;
 	dbg("usblp%d set protocol %d", usblp->minor, protocol);
@@ -969,7 +1068,7 @@
 {
 	int err, length;
 
-	err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
+	err = usblp_get_id(usblp, 0, usblp->device_id_string, USBLP_DEVICE_ID_SIZE - 1);
 	if (err < 0) {
 		dbg("usblp%d: error = %d reading IEEE-1284 Device ID string",
 			usblp->minor, err);
@@ -983,8 +1082,8 @@
 	length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1];
 	if (length < 2)
 		length = 2;
-	else if (length >= DEVICE_ID_SIZE)
-		length = DEVICE_ID_SIZE - 1;
+	else if (length >= USBLP_DEVICE_ID_SIZE)
+		length = USBLP_DEVICE_ID_SIZE - 1;
 	usblp->device_id_string[length] = '\0';
 
 	dbg("usblp%d Device ID string [len=%d]=\"%s\"",
@@ -1004,13 +1103,13 @@
 
 	down (&usblp->sem);
 	lock_kernel();
-	usblp->dev = NULL;
+	usblp->present = 0;
 
 	usblp_unlink_urbs(usblp);
 
 	if (!usblp->used)
 		usblp_cleanup (usblp);
-	else 	/* cleanup later, on close */
+	else 	/* cleanup later, on release */
 		up (&usblp->sem);
 	unlock_kernel();
 }
diff -urN linux-2.4.24-pre1/drivers/usb/scanner.c linux-2.4.24-pre2/drivers/usb/scanner.c
--- linux-2.4.24-pre1/drivers/usb/scanner.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/scanner.c	2003-12-22 11:34:35.000000000 -0800
@@ -385,6 +385,10 @@
  *    - Use static declarations for usb_scanner_init/usb_scanner_exit 
  *      (Daniele Bellucci).
  *
+ * 0.4.16  2003-11-04
+ *    - Added vendor/product ids for Epson, Genius, Microtek, Plustek, Reflecta, and
+ *      Visioneer scanners. Removed ids for HP PSC devices as these are supported by
+ *      the hpoj userspace driver.
  *
  * TODO
  *    - Performance
diff -urN linux-2.4.24-pre1/drivers/usb/scanner.h linux-2.4.24-pre2/drivers/usb/scanner.h
--- linux-2.4.24-pre1/drivers/usb/scanner.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/scanner.h	2003-12-22 11:34:35.000000000 -0800
@@ -44,7 +44,7 @@
 
 // #define DEBUG
 
-#define DRIVER_VERSION "0.4.15"
+#define DRIVER_VERSION "0.4.16"
 #define DRIVER_DESC "USB Scanner Driver"
 
 #include <linux/usb.h>
@@ -147,7 +147,12 @@
 	{ USB_DEVICE(0x0458, 0x2015) }, /* ColorPage HR7LE */
 	{ USB_DEVICE(0x0458, 0x2016) }, /* ColorPage HR6X */
 	{ USB_DEVICE(0x0458, 0x2018) },	/* ColorPage HR7X */
+	{ USB_DEVICE(0x0458, 0x201b) },	/* Colorpage Vivid 4x */
 	/* Hewlett Packard */
+	/* IMPORTANT: Hewlett-Packard multi-function peripherals (OfficeJet, 
+	   Printer/Scanner/Copier (PSC), LaserJet, or PhotoSmart printer)
+	   should not be added to this table because they are accessed by a
+	   userspace driver (hpoj) */
 	{ USB_DEVICE(0x03f0, 0x0101) },	/* ScanJet 4100C */
 	{ USB_DEVICE(0x03f0, 0x0102) },	/* PhotoSmart S20 */
 	{ USB_DEVICE(0x03f0, 0x0105) },	/* ScanJet 4200C */
@@ -169,10 +174,10 @@
 	{ USB_DEVICE(0x03F0, 0x1105) },	/* ScanJet 5470C */
 	{ USB_DEVICE(0x03f0, 0x1205) }, /* ScanJet 5550C */
 	{ USB_DEVICE(0x03f0, 0x1305) },	/* Scanjet 4570c */
-	{ USB_DEVICE(0x03f0, 0x1411) }, /* PSC 750 */
+	//	{ USB_DEVICE(0x03f0, 0x1411) }, /* PSC 750 - NOT SUPPORTED - use hpoj userspace driver */
 	{ USB_DEVICE(0x03f0, 0x2005) },	/* ScanJet 3570c */
 	{ USB_DEVICE(0x03f0, 0x2205) },	/* ScanJet 3500c */
-	{ USB_DEVICE(0x03f0, 0x2f11) }, /* PSC 1210 */
+	//	{ USB_DEVICE(0x03f0, 0x2f11) }, /* PSC 1210 - NOT SUPPORTED - use hpoj userspace driver */
 	/* Lexmark */
 	{ USB_DEVICE(0x043d, 0x002d) }, /* X70/X73 */
 	{ USB_DEVICE(0x043d, 0x003d) }, /* X83 */
@@ -188,6 +193,7 @@
 	{ USB_DEVICE(0x05da, 0x30ce) },	/* ScanMaker 3800 */
 	{ USB_DEVICE(0x05da, 0x30cf) },	/* ScanMaker 4800 */
 	{ USB_DEVICE(0x05da, 0x30d4) },	/* ScanMaker 3830 + 3840 */
+	{ USB_DEVICE(0x05da, 0x30d8) },	/* ScanMaker 5900 */
 	{ USB_DEVICE(0x04a7, 0x0224) },	/* Scanport 3000 (actually Visioneer?)*/
 	/* The following SCSI-over-USB Microtek devices are supported by the
 	   microtek driver: Enable SCSI and USB Microtek in kernel config */
@@ -246,6 +252,7 @@
 	{ USB_DEVICE(0x07b3, 0x0400) }, /* OpticPro 1248U */
 	{ USB_DEVICE(0x07b3, 0x0401) }, /* OpticPro 1248U (another one) */
 	{ USB_DEVICE(0x07b3, 0x0403) },	/* U16B */
+	{ USB_DEVICE(0x07b3, 0x0413) },	/* OpticSlim 1200 */
 	/* Primax/Colorado */
 	{ USB_DEVICE(0x0461, 0x0300) },	/* G2-300 #1 */
 	{ USB_DEVICE(0x0461, 0x0301) },	/* G2E-300 #1 */
@@ -262,6 +269,8 @@
 	{ USB_DEVICE(0x0461, 0x0383) },	/* G2E-600 */
 	/* Prolink */
 	{ USB_DEVICE(0x06dc, 0x0014) }, /* Winscan Pro 2448U */
+	/* Reflecta  */
+	{ USB_DEVICE(0x05e3, 0x0120) },	/* iScan 1800 */
 	/* Relisis */
 	// { USB_DEVICE(0x0475, 0x0103) },	/* Episode - undetected endpoint */
 	{ USB_DEVICE(0x0475, 0x0210) }, /* Scorpio Ultra 3 */
@@ -286,6 +295,7 @@
 	{ USB_DEVICE(0x04b8, 0x011c) }, /* Perfection 3200 */
 	{ USB_DEVICE(0x04b8, 0x011d) }, /* Perfection 1260 */
 	{ USB_DEVICE(0x04b8, 0x011e) }, /* Perfection 1660 Photo */
+	{ USB_DEVICE(0x04b8, 0x011f) },	/* Perfection 1670 */
 	{ USB_DEVICE(0x04b8, 0x0801) }, /* Stylus CX5200 */
 	{ USB_DEVICE(0x04b8, 0x0802) }, /* Stylus CX3200 */
 	/* Siemens */
@@ -310,6 +320,7 @@
 	{ USB_DEVICE(0x04a7, 0x0221) },	/* OneTouch 5300 USB */
 	{ USB_DEVICE(0x04a7, 0x0224) },	/* OneTouch 4800 USB */
 	{ USB_DEVICE(0x04a7, 0x0226) },	/* OneTouch 5800 USB */
+	{ USB_DEVICE(0x04a7, 0x0229) }, /* OneTouch 7100 USB */
 	{ USB_DEVICE(0x04a7, 0x022c) },	/* OneTouch 9020 USB */
 	{ USB_DEVICE(0x04a7, 0x0231) },	/* 6100 USB */
 	{ USB_DEVICE(0x04a7, 0x0311) },	/* 6200 EPP/USB */
diff -urN linux-2.4.24-pre1/drivers/usb/serial/ftdi_sio.c linux-2.4.24-pre2/drivers/usb/serial/ftdi_sio.c
--- linux-2.4.24-pre1/drivers/usb/serial/ftdi_sio.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/ftdi_sio.c	2003-12-22 11:34:35.000000000 -0800
@@ -333,6 +333,10 @@
 	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0, 0x3ff) },
+	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0, 0x3ff) },
+	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) },
+	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) },
 	{ }						/* Terminating entry */
 };
 
@@ -407,6 +411,10 @@
 	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0x400, 0xffff) },
 	{ }						/* Terminating entry */
 };
 
@@ -496,6 +504,10 @@
 	{ USB_DEVICE(OCT_VID, OCT_US101_PID) },
 	{ USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) },
 	{ USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
+	{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_1) },
+	{ USB_DEVICE(FTDI_VID, PROTEGO_R2X0) },
+	{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) },
+	{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) },
 	{ }						/* Terminating entry */
 };
 
diff -urN linux-2.4.24-pre1/drivers/usb/serial/ftdi_sio.h linux-2.4.24-pre2/drivers/usb/serial/ftdi_sio.h
--- linux-2.4.24-pre1/drivers/usb/serial/ftdi_sio.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/ftdi_sio.h	2003-12-22 11:34:35.000000000 -0800
@@ -145,6 +145,14 @@
 /* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */
 #define OCT_US101_PID		0x0421	/* OCT US101 USB to RS-232 */
 
+/*
+ * Protego product ids
+ */
+#define PROTEGO_SPECIAL_1	0xFC70	/* special/unknown device */
+#define PROTEGO_R2X0		0xFC71	/* R200-USB TRNG unit (R210, R220, and R230) */
+#define PROTEGO_SPECIAL_3	0xFC72	/* special/unknown device */
+#define PROTEGO_SPECIAL_4	0xFC73	/* special/unknown device */ 
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
diff -urN linux-2.4.24-pre1/drivers/usb/serial/io_edgeport.c linux-2.4.24-pre2/drivers/usb/serial/io_edgeport.c
--- linux-2.4.24-pre1/drivers/usb/serial/io_edgeport.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/io_edgeport.c	2003-12-22 11:34:36.000000000 -0800
@@ -1468,15 +1468,19 @@
 	urb->transfer_flags |= USB_QUEUE_BULK;
 
 	urb->dev = edge_serial->serial->dev;
+	/* decrement the number of credits we have by the number we just sent */
+	edge_port->txCredits -= count;
+	edge_port->icount.tx += count;
+
 	status = usb_submit_urb(urb);
 	if (status) {
 		/* something went wrong */
 		dbg("%s - usb_submit_urb(write bulk) failed", __FUNCTION__);
 		edge_port->write_in_progress = FALSE;
-	} else {
-		/* decrement the number of credits we have by the number we just sent */
-		edge_port->txCredits -= count;
-		edge_port->icount.tx += count;
+
+		/*revert the count if something bad happened...*/
+		edge_port->txCredits += count;
+		edge_port->icount.tx -= count;
 	}
 	dbg("%s wrote %d byte(s) TxCredit %d, Fifo %d", __FUNCTION__, count, edge_port->txCredits, fifo->count);
 }
diff -urN linux-2.4.24-pre1/drivers/usb/serial/io_fw_boot.h linux-2.4.24-pre2/drivers/usb/serial/io_fw_boot.h
--- linux-2.4.24-pre1/drivers/usb/serial/io_fw_boot.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/io_fw_boot.h	2003-12-22 11:34:36.000000000 -0800
@@ -17,7 +17,7 @@
 		unsigned short Addr;
 		unsigned short Len;
 		unsigned char  Data[0];
-	};
+	} __attribute__ ((packed));
 
 	struct edge_firmware_version_info {
 		unsigned char	 MajorVersion;
diff -urN linux-2.4.24-pre1/drivers/usb/serial/io_fw_boot2.h linux-2.4.24-pre2/drivers/usb/serial/io_fw_boot2.h
--- linux-2.4.24-pre1/drivers/usb/serial/io_fw_boot2.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/io_fw_boot2.h	2003-12-22 11:34:36.000000000 -0800
@@ -17,7 +17,7 @@
 		unsigned short Addr;
 		unsigned short Len;
 		unsigned char  Data[0];
-	};
+	} __attribute__ ((packed));
 
 	struct edge_firmware_version_info {
 		unsigned char	 MajorVersion;
diff -urN linux-2.4.24-pre1/drivers/usb/serial/io_fw_down.h linux-2.4.24-pre2/drivers/usb/serial/io_fw_down.h
--- linux-2.4.24-pre1/drivers/usb/serial/io_fw_down.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/io_fw_down.h	2003-12-22 11:34:36.000000000 -0800
@@ -17,7 +17,7 @@
 		unsigned short	Addr;
 		unsigned short	Len;
 		unsigned char	Data[0];
-	};
+	} __attribute ((packed));
 
 	struct edge_firmware_version_info {
 		unsigned char	MajorVersion;
diff -urN linux-2.4.24-pre1/drivers/usb/serial/io_fw_down2.h linux-2.4.24-pre2/drivers/usb/serial/io_fw_down2.h
--- linux-2.4.24-pre1/drivers/usb/serial/io_fw_down2.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/io_fw_down2.h	2003-12-22 11:34:36.000000000 -0800
@@ -17,7 +17,7 @@
 		unsigned short Addr;
 		unsigned short Len;
 		unsigned char  Data[0];
-	};
+	} __attribute__ ((packed));
 
 	struct edge_firmware_version_info {
 		unsigned char  MajorVersion;
diff -urN linux-2.4.24-pre1/drivers/usb/serial/mct_u232.c linux-2.4.24-pre2/drivers/usb/serial/mct_u232.c
--- linux-2.4.24-pre1/drivers/usb/serial/mct_u232.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/mct_u232.c	2003-12-22 11:34:36.000000000 -0800
@@ -24,6 +24,11 @@
  *   Basic tests have been performed with minicom/zmodem transfers and
  *   modem dialing under Linux 2.4.0-test10 (for me it works fine).
  *
+ * 04-Nov-2003 Bill Marr <marr at flex dot com>
+ *   - Mimic Windows driver by sending 2 USB 'device request' messages
+ *     following normal 'baud rate change' message.  This allows data to be
+ *     transmitted to RS-232 devices which don't assert the 'CTS' signal.
+ *
  * 10-Nov-2001 Wolfgang Grandegger
  *   - Fixed an endianess problem with the baudrate selection for PowerPC.
  *
@@ -85,7 +90,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.1"
+#define DRIVER_VERSION "v1.2"
 #define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
 #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
 
@@ -201,6 +206,7 @@
 {
 	unsigned int divisor;
         int rc;
+        unsigned char zero_byte = 0;
 	divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value));
         rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                              MCT_U232_SET_BAUD_RATE_REQUEST,
@@ -210,6 +216,35 @@
 	if (rc < 0)
 		err("Set BAUD RATE %d failed (error = %d)", value, rc);
 	dbg("set_baud_rate: value: %d, divisor: 0x%x", value, divisor);
+
+	/* Mimic the MCT-supplied Windows driver (version 1.21P.0104), which
+	   always sends two extra USB 'device request' messages after the
+	   'baud rate change' message.  The actual functionality of the
+	   request codes in these messages is not fully understood but these
+	   particular codes are never seen in any operation besides a baud
+	   rate change.  Both of these messages send a single byte of data
+	   whose value is always zero.  The second of these two extra messages
+	   is required in order for data to be properly written to an RS-232
+	   device which does not assert the 'CTS' signal. */
+
+	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			     MCT_U232_SET_UNKNOWN1_REQUEST, 
+			     MCT_U232_SET_REQUEST_TYPE,
+			     0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE, 
+			     WDR_TIMEOUT);
+	if (rc < 0)
+		err("Sending USB device request code %d failed (error = %d)", 
+		    MCT_U232_SET_UNKNOWN1_REQUEST, rc);
+
+	rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			     MCT_U232_SET_UNKNOWN2_REQUEST, 
+			     MCT_U232_SET_REQUEST_TYPE,
+			     0, 0, &zero_byte, MCT_U232_SET_UNKNOWN2_SIZE, 
+			     WDR_TIMEOUT);
+	if (rc < 0)
+		err("Sending USB device request code %d failed (error = %d)", 
+		    MCT_U232_SET_UNKNOWN2_REQUEST, rc);
+
         return rc;
 } /* mct_u232_set_baud_rate */
 
diff -urN linux-2.4.24-pre1/drivers/usb/serial/mct_u232.h linux-2.4.24-pre2/drivers/usb/serial/mct_u232.h
--- linux-2.4.24-pre1/drivers/usb/serial/mct_u232.h	2001-12-21 09:41:55.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/mct_u232.h	2003-12-22 11:34:36.000000000 -0800
@@ -57,6 +57,21 @@
 #define MCT_U232_SET_MODEM_CTRL_REQUEST	10 /* Set Modem Control Register (MCR) */
 #define MCT_U232_SET_MODEM_CTRL_SIZE    1
 
+/* This USB device request code is not well understood.  It is transmitted by
+   the MCT-supplied Windows driver whenever the baud rate changes. 
+*/
+#define MCT_U232_SET_UNKNOWN1_REQUEST   11  /* Unknown functionality */
+#define MCT_U232_SET_UNKNOWN1_SIZE       1
+
+/* This USB device request code is not well understood.  It is transmitted by
+   the MCT-supplied Windows driver whenever the baud rate changes. 
+   
+   Without this USB device request, the USB/RS-232 adapter will not write to
+   RS-232 devices which do not assert the 'CTS' signal.
+*/
+#define MCT_U232_SET_UNKNOWN2_REQUEST   12  /* Unknown functionality */
+#define MCT_U232_SET_UNKNOWN2_SIZE       1
+
 /*
  * Baud rate (divisor)
  */
@@ -137,22 +152,31 @@
  * Baud rate (divisor)
  * -------------------
  *
- *   BmRequestType:  0x4 (0100 0000B)
- *   bRequest:       0x5
- *   wValue:         0x0
- *   wIndex:         0x0
- *   wLength:        0x4
+ *   BmRequestType:  0x40 (0100 0000B)
+ *   bRequest:       0x05
+ *   wValue:         0x0000
+ *   wIndex:         0x0000
+ *   wLength:        0x0004
  *   Data:           divisor = 115200 / baud_rate
  *
+ *   SniffUSB observations (Nov 2003): Contrary to the 'wLength' value of 4
+ *   shown above, observations with a Belkin F5U109 adapter, using the
+ *   MCT-supplied Windows98 driver (U2SPORT.VXD, "File version: 1.21P.0104 for
+ *   Win98/Me"), show this request has a length of 1 byte, presumably because
+ *   of the fact that the Belkin adapter and the 'Sitecom U232-P25' adapter
+ *   use a baud-rate code instead of a conventional RS-232 baud rate divisor.
+ *   The current source code for this driver does not reflect this fact, but
+ *   the driver works fine with this adapter/driver combination nonetheless.
+ *
  *
  * Line Control Register (LCR)
  * ---------------------------
  *
- *  BmRequestType:  0x4 (0100 0000B)    0xc (1100 0000B)
- *  bRequest:       0x7                 0x6
- *  wValue:         0x0
- *  wIndex:         0x0
- *  wLength:        0x1
+ *  BmRequestType:  0x40 (0100 0000B)    0xc0 (1100 0000B)
+ *  bRequest:       0x07                 0x06
+ *  wValue:         0x0000
+ *  wIndex:         0x0000
+ *  wLength:        0x0001
  *  Data:           LCR (see below)
  *
  *  Bit 7: Divisor Latch Access Bit (DLAB). When set, access to the data
@@ -186,18 +210,18 @@
  *
  *  SniffUSB observations: Bit 7 seems not to be used. There seem to be two bugs
  *  in the Win98 driver: the break does not work (bit 6 is not asserted) and the
- *  sticky parity bit is not cleared when set once. The LCR can also be read
+ *  stick parity bit is not cleared when set once. The LCR can also be read
  *  back with USB request 6 but this has never been observed with SniffUSB.
  *
  *
  * Modem Control Register (MCR)
  * ----------------------------
  *
- *  BmRequestType:  0x4  (0100 0000B)
- *  bRequest:       0xa
- *  wValue:         0x0
- *  wIndex:         0x0
- *  wLength:        0x1
+ *  BmRequestType:  0x40  (0100 0000B)
+ *  bRequest:       0x0a
+ *  wValue:         0x0000
+ *  wIndex:         0x0000
+ *  wLength:        0x0001
  *  Data:           MCR (Bit 4..7, see below)
  *
  *  Bit 7: Reserved, always 0.
@@ -226,11 +250,11 @@
  * Modem Status Register (MSR)
  * ---------------------------
  *
- *  BmRequestType:  0xc  (1100 0000B)
- *  bRequest:       0x2
- *  wValue:         0x0
- *  wIndex:         0x0
- *  wLength:        0x1
+ *  BmRequestType:  0xc0  (1100 0000B)
+ *  bRequest:       0x02
+ *  wValue:         0x0000
+ *  wIndex:         0x0000
+ *  wLength:        0x0001
  *  Data:           MSR (see below)
  *
  *  Bit 7: Data Carrier Detect (CD). Reflects the state of the DCD line on the
@@ -287,6 +311,41 @@
  *  minicom/zmodem transfers (CRC errors).
  *
  *
+ * Unknown #1
+ * -------------------
+ *
+ *   BmRequestType:  0x40 (0100 0000B)
+ *   bRequest:       0x0b
+ *   wValue:         0x0000
+ *   wIndex:         0x0000
+ *   wLength:        0x0001
+ *   Data:           0x00
+ *
+ *   SniffUSB observations (Nov 2003): With the MCT-supplied Windows98 driver
+ *   (U2SPORT.VXD, "File version: 1.21P.0104 for Win98/Me"), this request
+ *   occurs immediately after a "Baud rate (divisor)" message.  It was not
+ *   observed at any other time.  It is unclear what purpose this message
+ *   serves.
+ *
+ *
+ * Unknown #2
+ * -------------------
+ *
+ *   BmRequestType:  0x40 (0100 0000B)
+ *   bRequest:       0x0c
+ *   wValue:         0x0000
+ *   wIndex:         0x0000
+ *   wLength:        0x0001
+ *   Data:           0x00
+ *
+ *   SniffUSB observations (Nov 2003): With the MCT-supplied Windows98 driver
+ *   (U2SPORT.VXD, "File version: 1.21P.0104 for Win98/Me"), this request
+ *   occurs immediately after the 'Unknown #1' message (see above).  It was
+ *   not observed at any other time.  It is unclear what other purpose (if
+ *   any) this message might serve, but without it, the USB/RS-232 adapter
+ *   will not write to RS-232 devices which do not assert the 'CTS' signal.
+ *
+ *
  * Flow control
  * ------------
  *
diff -urN linux-2.4.24-pre1/drivers/usb/serial/pl2303.c linux-2.4.24-pre2/drivers/usb/serial/pl2303.c
--- linux-2.4.24-pre1/drivers/usb/serial/pl2303.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/pl2303.c	2003-12-22 11:34:36.000000000 -0800
@@ -69,6 +69,7 @@
 	{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
 	{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
 	{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
+	{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
 	{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
 	{ USB_DEVICE(ITEGNO_VENDOR_ID, ITEGNO_PRODUCT_ID) },
 	{ USB_DEVICE(MA620_VENDOR_ID, MA620_PRODUCT_ID) },
@@ -156,6 +157,7 @@
 
 struct pl2303_private {
 	spinlock_t lock;
+	wait_queue_head_t delta_msr_wait;
 	u8 line_control;
 	u8 line_status;
 	u8 termios_initialized;
@@ -173,6 +175,7 @@
 			return -ENOMEM;
 		memset (priv, 0x00, sizeof (struct pl2303_private));
 		spin_lock_init(&priv->lock);
+		init_waitqueue_head(&priv->delta_msr_wait);
 		usb_set_serial_port_data(&serial->port[i], priv);
 	}
 	return 0;
@@ -563,6 +566,42 @@
 	return 0;
 }
 
+static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
+{
+	struct pl2303_private *priv = usb_get_serial_port_data(port);
+	unsigned long flags;
+	unsigned int prevstatus;
+	unsigned int status;
+	unsigned int changed;
+
+	spin_lock_irqsave (&priv->lock, flags);
+	prevstatus = priv->line_status;
+	spin_unlock_irqrestore (&priv->lock, flags);
+
+	while (1) {
+		interruptible_sleep_on(&priv->delta_msr_wait);
+		/* see if a signal did it */
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		
+		spin_lock_irqsave (&priv->lock, flags);
+		status = priv->line_status;
+		spin_unlock_irqrestore (&priv->lock, flags);
+		
+		changed=prevstatus^status;
+		
+		if (((arg & TIOCM_RNG) && (changed & UART_RING)) ||
+		    ((arg & TIOCM_DSR) && (changed & UART_DSR)) ||
+		    ((arg & TIOCM_CD)  && (changed & UART_DCD)) ||
+		    ((arg & TIOCM_CTS) && (changed & UART_CTS)) ) {
+			return 0;
+		}
+		prevstatus = status;
+	}
+	/* NOTREACHED */
+	return 0;
+}
+
 static int pl2303_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	dbg("%s (%d) cmd = 0x%04x", __FUNCTION__, port->number, cmd);
@@ -579,6 +618,10 @@
 			dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __FUNCTION__,  port->number);
 			return set_modem_info(port, cmd, (unsigned int *) arg);
 
+		case TIOCMIWAIT:
+			dbg("%s (%d) TIOCMIWAIT", __FUNCTION__,  port->number);
+			return wait_modem_info(port, arg);
+		
 		default:
 			dbg("%s not supported = 0x%04x", __FUNCTION__, cmd);
 			break;
@@ -662,6 +705,7 @@
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->line_status = data[UART_STATE];
 	spin_unlock_irqrestore(&priv->lock, flags);
+	wake_up_interruptible (&priv->delta_msr_wait);
 
 	return;
 }
diff -urN linux-2.4.24-pre1/drivers/usb/serial/pl2303.h linux-2.4.24-pre2/drivers/usb/serial/pl2303.h
--- linux-2.4.24-pre1/drivers/usb/serial/pl2303.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/pl2303.h	2003-12-22 11:34:36.000000000 -0800
@@ -12,6 +12,7 @@
 #define PL2303_PRODUCT_ID_RSAQ2	0x04bb
 
 #define ATEN_VENDOR_ID		0x0557
+#define ATEN_VENDOR_ID2		0x0547
 #define ATEN_PRODUCT_ID		0x2008
 
 #define IODATA_VENDOR_ID	0x04bb
diff -urN linux-2.4.24-pre1/drivers/usb/serial/visor.c linux-2.4.24-pre2/drivers/usb/serial/visor.c
--- linux-2.4.24-pre1/drivers/usb/serial/visor.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/visor.c	2003-12-22 11:34:36.000000000 -0800
@@ -211,6 +211,7 @@
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) },
+	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) },
 	{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) },
 	{ USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) },
 	{ }					/* Terminating entry */
@@ -241,6 +242,7 @@
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) },
+	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) },
 	{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) },
 	{ USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) },
 	{ }					/* Terminating entry */
diff -urN linux-2.4.24-pre1/drivers/usb/serial/visor.h linux-2.4.24-pre2/drivers/usb/serial/visor.h
--- linux-2.4.24-pre1/drivers/usb/serial/visor.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/serial/visor.h	2003-12-22 11:34:36.000000000 -0800
@@ -41,6 +41,7 @@
 #define SONY_CLIE_4_1_ID		0x009A
 #define SONY_CLIE_NX60_ID		0x00DA
 #define SONY_CLIE_NZ90V_ID		0x00E9
+#define SONY_CLIE_UX50_ID		0x0144
 
 #define SAMSUNG_VENDOR_ID		0x04E8
 #define SAMSUNG_SCH_I330_ID		0x8001
diff -urN linux-2.4.24-pre1/drivers/usb/storage/unusual_devs.h linux-2.4.24-pre2/drivers/usb/storage/unusual_devs.h
--- linux-2.4.24-pre1/drivers/usb/storage/unusual_devs.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/storage/unusual_devs.h	2003-12-22 11:34:36.000000000 -0800
@@ -45,6 +45,13 @@
  *
  */
 
+/* Patch submitted by Martin Berentsen <berentsen at sent5 dot uni-duisburg dot de> */
+#define US_FL_START_STOP  0x00000004   /* ignore START_STOP commands     */
+UNUSUAL_DEV(  0x0686, 0x4014, 0x0001, 0x0001, 
+		"Minolta",
+		"Dimage S414",
+		US_SC_SCSI, US_PR_BULK, NULL, US_FL_START_STOP), 
+
 UNUSUAL_DEV(  0x03ee, 0x0000, 0x0000, 0x0245, 
 		"Mitsumi",
 		"CD-R/RW Drive",
@@ -53,7 +60,7 @@
 UNUSUAL_DEV(  0x03ee, 0x6901, 0x0000, 0x0100,
 		"Mitsumi",
 		"USB FDD",
-		US_SC_UFI, US_PR_CBI, NULL,
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_SINGLE_LUN ),
 
 UNUSUAL_DEV(  0x03f0, 0x0107, 0x0200, 0x0200, 
@@ -102,6 +109,12 @@
 		"Finecam S4",
 		US_SC_8070, US_PR_CB, NULL, US_FL_FIX_INQUIRY),
 
+/* Patch submitted by Stephane Galles <stephane.galles@free.fr> */
+UNUSUAL_DEV(  0x0482, 0x0103, 0x0100, 0x0100,
+		"Kyocera",
+		"Finecam S5",
+		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY),
+
 /* Reported by Paul Stewart <stewart@wetlogic.net>
  * This entry is needed because the device reports Sub=ff */
 UNUSUAL_DEV(  0x04a4, 0x0004, 0x0001, 0x0001,
@@ -257,7 +270,7 @@
 UNUSUAL_DEV(  0x054c, 0x002d, 0x0100, 0x0100, 
 		"Sony",
 		"Memorystick MSAC-US1",
-		US_SC_UFI, US_PR_CB, NULL,
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_SINGLE_LUN ),
 
 /* Submitted by Klaus Mueller <k.mueller@intershop.de> */
@@ -298,6 +311,12 @@
 		US_SC_DEVICE,  US_PR_DEVICE, NULL,
 		US_FL_SINGLE_LUN),
 
+/* Fabrizio Fellini <fello@libero.it> */
+UNUSUAL_DEV(  0x0595, 0x4343, 0x0000, 0x2210,
+		"Fujifilm",
+		"Digital Camera EX-20 DSC",
+		US_SC_8070, US_PR_CBI, NULL, 0 ),
+
 UNUSUAL_DEV(  0x059f, 0xa601, 0x0200, 0x0200, 
 		"LaCie",
 		"USB Hard Disk",
@@ -354,6 +373,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
+/* Submitted Alexander Oltu <alexander@all-2.com> */
+UNUSUAL_DEV(  0x05e3, 0x0701, 0x0000, 0xffff, 
+		"", 
+		"USB TO IDE",
+		US_SC_SCSI, US_PR_BULK, NULL,
+		US_FL_MODE_XLATE ), 
+
 /* Reported by Peter Marks <peter.marks@turner.com>
  * Like the SIIG unit above, this unit needs an INQUIRY to ask for exactly
  * 36 bytes of data.  No more, no less. That is the only reason this entry
@@ -400,6 +426,28 @@
                 "DIMAGE E223",
                 US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
 
+/* Following three Minolta cameras reported by Martin Pool
+ * <mbp@sourcefrog.net>.  Originally discovered by Kedar Petankar,
+ * Matthew Geier, Mikael Lofj"ard, Marcel de Boer.
+ */
+UNUSUAL_DEV( 0x0686, 0x4006, 0x0001, 0x0001,
+             "Minolta",
+             "DiMAGE 7",
+             US_SC_SCSI, US_PR_DEVICE, NULL,
+             0 ),
+
+UNUSUAL_DEV( 0x0686, 0x400b, 0x0001, 0x0001,
+             "Minolta",
+             "DiMAGE 7i",
+             US_SC_SCSI, US_PR_DEVICE, NULL,
+             0 ),
+
+UNUSUAL_DEV( 0x0686, 0x400f, 0x0001, 0x0001,
+             "Minolta",
+             "DiMAGE 7Hi",
+             US_SC_SCSI, US_PR_DEVICE, NULL,
+             0 ),
+
 UNUSUAL_DEV(  0x0693, 0x0002, 0x0100, 0x0100, 
 		"Hagiwara",
 		"FlashGate SmartMedia",
@@ -441,6 +489,11 @@
 		"Freecom",
 		"USB-IDE",
 		US_SC_QIC, US_PR_FREECOM, freecom_init, 0),
+
+UNUSUAL_DEV(  0x07ab, 0xfc84, 0x0000, 0x9999,
+		"Freecom",
+		"FX-5/FX-50",
+		US_SC_QIC, US_PR_FREECOM, freecom_init, 0),
 #endif
 
 UNUSUAL_DEV(  0x07af, 0x0004, 0x0100, 0x0133, 
@@ -528,6 +581,14 @@
 		US_SC_SCSI, US_PR_DATAFAB, NULL,
 		US_FL_MODE_XLATE ),
 #endif
+#ifdef CONFIG_USB_STORAGE_SDDR55
+/* SM part - aeb <Andries.Brouwer@cwi.nl> */
+UNUSUAL_DEV(  0x07c4, 0xa109, 0x0000, 0xffff,
+		"Datafab Systems, Inc.",
+		"USB to CF + SM Combo (LC1)",
+		US_SC_SCSI, US_PR_SDDR55, NULL,
+		US_FL_SINGLE_LUN ),
+#endif
 
 /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100
  * Only revision 1.13 tested (same for all of the above devices,
@@ -570,6 +631,14 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_MODE_XLATE ),
 
+/*Medion 6047 Digital Camera
+Davide Andrian <_nessuno_@katamail.com>
+*/
+UNUSUAL_DEV( 0x08ca, 0x2011, 0x0001, 0x0001,
+		"3MegaCam",
+		"3MegaCam",
+		US_SC_DEVICE, US_PR_BULK, NULL,
+		US_FL_MODE_XLATE ),
 /* aeb */
 UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
 		"Feiya",
@@ -605,8 +674,8 @@
 /* Submitted by Per Winkvist <per.winkvist@uk.com> */
 UNUSUAL_DEV( 0x0a17, 0x006, 0x1000, 0x9009,
                 "Pentax",
-                "Optio S",
-                US_SC_8070, US_PR_CBI, NULL,
+                "Optio S/S4",
+                US_SC_DEVICE, US_PR_DEVICE, NULL,
                 US_FL_FIX_INQUIRY ),
 		
 #ifdef CONFIG_USB_STORAGE_ISD200
@@ -617,13 +686,6 @@
 		0 ),
 #endif
 
-/* Submitted by Antoine Mairesse <antoine.mairesse@free.fr> */
-UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300,
-		"USB",
-		"Solid state disk",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_FIX_INQUIRY ),
-
 /* Submitted by Joris Struyve <joris@struyve.be> */
 UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff,
 		"Medion",
@@ -640,6 +702,13 @@
 		"Jenoptik",
 		"JD 5200 z3",
 		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY),
+
+/* Submitted by Antoine Mairesse <antoine.mairesse@free.fr> */
+UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300,
+		"USB",
+		"Solid state disk",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_FIX_INQUIRY ),
 		
 /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
  * Tested on hardware version 1.10.
diff -urN linux-2.4.24-pre1/drivers/usb/w9968cf.c linux-2.4.24-pre2/drivers/usb/w9968cf.c
--- linux-2.4.24-pre1/drivers/usb/w9968cf.c	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/w9968cf.c	2003-12-22 11:34:36.000000000 -0800
@@ -1,14 +1,14 @@
 /***************************************************************************
  * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip.       *
  *                                                                         *
- * Copyright (C) 2002 2003 by Luca Risolia <luca_ing@libero.it>            *
+ * Copyright (C) 2002 2003 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * - Memory management code from bttv driver by Ralph Metzler,             *
  *   Marcus Metzler and Gerd Knorr.                                        *
  * - I2C interface to kernel, high-level CMOS sensor control routines and  *
  *   some symbolic names from OV511 driver by Mark W. McClelland.          *
  * - Low-level I2C fast write function by Piotr Czerczak.                  *
- * - Low-level I2C read function by FrÃ©dÃ©ric Jouault.                      *
+ * - Low-level I2C read function by Frederic Jouault.                      *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
@@ -46,17 +46,19 @@
 #include "w9968cf.h"
 #include "w9968cf_decoder.h"
 
-EXPORT_NO_SYMBOLS;
-
-
 
 /****************************************************************************
- * Modules paramaters                                                       *
+ * Module macros and paramaters                                             *
  ****************************************************************************/
 
+MODULE_AUTHOR(W9968CF_MODULE_AUTHOR" "W9968CF_AUTHOR_EMAIL);
+MODULE_DESCRIPTION(W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION);
+MODULE_LICENSE(W9968CF_MODULE_LICENSE);
+MODULE_SUPPORTED_DEVICE("Video");
+
 static u8 vppmod_load = W9968CF_VPPMOD_LOAD;
 static u8 simcams = W9968CF_SIMCAMS;
-static int video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /* -1=first free */
+static s8 video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /* -1=first free */
 static u16 packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_PACKET_SIZE};
 static u8 max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BUFFERS};
 static u8 double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] = 
@@ -74,10 +76,10 @@
 static u8 lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LIGHTFREQ};
 static u8 bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]=
                              W9968CF_BANDINGFILTER};
-static int clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV};
+static s8 clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV};
 static u8 backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT};
 static u8 mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR};
-static u8 sensor_mono[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_SENSOR_MONO};
+static u8 monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME};
 static u16 brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BRIGHTNESS};
 static u16 hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE};
 static u16 colour[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR};
@@ -88,36 +90,27 @@
 static u8 specific_debug = W9968CF_SPECIFIC_DEBUG;
 #endif
 
-MODULE_AUTHOR("Luca Risolia <luca_ing@libero.it>");
-
-MODULE_DESCRIPTION("Video4Linux driver for "
-                   "W996[87]CF JPEG USB Dual Mode Camera Chip");
-
-MODULE_SUPPORTED_DEVICE("Video");
-
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(vppmod_load, "i");
+MODULE_PARM(vppmod_load, "b");
 MODULE_PARM(simcams, "i");
 MODULE_PARM(video_nr, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
 MODULE_PARM(packet_size, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
 MODULE_PARM(max_buffers, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
-MODULE_PARM(double_buffer, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
-MODULE_PARM(clamping, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
+MODULE_PARM(double_buffer, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
+MODULE_PARM(clamping, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
 MODULE_PARM(filter_type, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
-MODULE_PARM(largeview, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
+MODULE_PARM(largeview, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
 MODULE_PARM(decompression, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
-MODULE_PARM(upscaling, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
+MODULE_PARM(upscaling, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
 MODULE_PARM(force_palette, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
 MODULE_PARM(force_rgb, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
-MODULE_PARM(autobright, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
-MODULE_PARM(autoexp, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
-MODULE_PARM(lightfreq, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
-MODULE_PARM(bandingfilter, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
-MODULE_PARM(clockdiv, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
-MODULE_PARM(backlight, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
-MODULE_PARM(mirror, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
-MODULE_PARM(sensor_mono, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
+MODULE_PARM(autobright, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
+MODULE_PARM(autoexp, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
+MODULE_PARM(lightfreq, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
+MODULE_PARM(bandingfilter, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
+MODULE_PARM(clockdiv, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "i");
+MODULE_PARM(backlight, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
+MODULE_PARM(mirror, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
+MODULE_PARM(monochrome, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "b");
 MODULE_PARM(brightness, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
 MODULE_PARM(hue, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
 MODULE_PARM(colour, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
@@ -125,7 +118,7 @@
 MODULE_PARM(whiteness, "0-" __MODULE_STRING(W9968CF_MAX_DEVICES) "l");
 #ifdef W9968CF_DEBUG
 MODULE_PARM(debug, "i");
-MODULE_PARM(specific_debug, "i");
+MODULE_PARM(specific_debug, "b");
 #endif
 
 MODULE_PARM_DESC(vppmod_load, 
@@ -163,7 +156,7 @@
                  "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")."
                  "\n");
 MODULE_PARM_DESC(max_buffers,
-                 "\n<n[,...]> Only for advanced users."
+                 "\n<n[,...]> For advanced users."
                  "\nSpecify the maximum number of video frame buffers"
                  "\nto allocate for each device, from 2 to "
                  __MODULE_STRING(W9968CF_MAX_BUFFERS)
@@ -206,7 +199,8 @@
                  "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING)
                  " for every device."
                  "\nIf 'w9968cf-vpp' is not loaded, this paramater is"
-                 " set to 0.");
+                 " set to 0."
+                 "\n");
 MODULE_PARM_DESC(decompression,
                  "\n<0|1|2[,...]> Software video decompression:"
                  "\n- 0 disables decompression (doesn't allow formats needing"
@@ -221,7 +215,8 @@
                  "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION)
                  " for every device."
                  "\nIf 'w9968cf-vpp' is not loaded, forcing decompression is "
-                 "\nnot allowed; in this case this paramater is set to 2.");
+                 "\nnot allowed; in this case this paramater is set to 2."
+                 "\n");
 MODULE_PARM_DESC(force_palette,
                  "\n<0"
                  "|" __MODULE_STRING(VIDEO_PALETTE_UYVY)
@@ -255,7 +250,8 @@
                  "\nInitial palette is "
                  __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"."
                  "\nIf 'w9968cf-vpp' is not loaded, this paramater is"
-                 " set to 9 (UYVY).");
+                 " set to 9 (UYVY)."
+                 "\n");
 MODULE_PARM_DESC(force_rgb, 
                  "\n<0|1[,...]> Read RGB video data instead of BGR:"
                  "\n 1 = use RGB component ordering."
@@ -314,10 +310,11 @@
                  "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR)
                  " for every device."
                  "\n");
-MODULE_PARM_DESC(sensor_mono,
-                 "\n<0|1[,...]> The OV CMOS sensor is monochrome:"
+MODULE_PARM_DESC(monochrome,
+                 "\n<0|1[,...]> Use OV CMOS sensor as monochrome sensor:"
                  "\n 0 = no, 1 = yes"
-                 "\nDefault value is "__MODULE_STRING(W9968CF_SENSOR_MONO)
+                 "\nNot all the sensors support monochrome color."
+                 "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME)
                  " for every device."
                  "\n");
 MODULE_PARM_DESC(brightness, 
@@ -349,7 +346,7 @@
 #ifdef W9968CF_DEBUG
 MODULE_PARM_DESC(debug,
                  "\n<n> Debugging information level, from 0 to 6:"
-                 "\n0 = none (be cautious)"
+                 "\n0 = none (use carefully)"
                  "\n1 = critical errors"
                  "\n2 = significant informations"
                  "\n3 = configuration or general messages"
@@ -383,29 +380,23 @@
 static int w9968cf_release(struct inode*, struct file*);
 static ssize_t w9968cf_read(struct file*, char*, size_t, loff_t*);
 static int w9968cf_mmap(struct file*, struct vm_area_struct*);
-static int w9968cf_ioctl(struct inode*, struct file*,
-                         unsigned int, unsigned long);
-static int w9968cf_do_ioctl(struct w9968cf_device*, unsigned int, void*);
+static int w9968cf_ioctl(struct inode*, struct file*, unsigned, unsigned long);
+static int w9968cf_v4l_ioctl(struct inode*, struct file*, unsigned int, void*);
 
-/* /proc interface */
 #if defined(CONFIG_VIDEO_PROC_FS)
+/* /proc interface */
 static void w9968cf_proc_create(void);
 static void w9968cf_proc_destroy(void);
 static void w9968cf_proc_create_dev(struct w9968cf_device*);
 static void w9968cf_proc_destroy_dev(struct w9968cf_device*);
 static int w9968cf_proc_read_global(char*, char**, off_t, int, int*, void*);
 static int w9968cf_proc_read_dev(char*, char**, off_t, int, int*, void*);
-#else
-static inline void w9968cf_proc_create(void) {}
-static inline void w9968cf_proc_destroy(void) {}
-static inline void w9968cf_proc_create_dev(struct w9968cf_device* cam) {}
-static inline void w9968cf_proc_destroy_dev(struct w9968cf_device* cam) {}
 #endif
 
 /* USB-specific */
-static void w9968cf_urb_complete(struct urb *urb);
 static int w9968cf_start_transfer(struct w9968cf_device*);
 static int w9968cf_stop_transfer(struct w9968cf_device*);
+static void w9968cf_urb_complete(struct urb *urb);
 static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index);
 static int w9968cf_read_reg(struct w9968cf_device*, u16 index);
 static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
@@ -413,7 +404,6 @@
 static int w9968cf_read_sb(struct w9968cf_device*);
 static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
 
-
 /* Low-level I2C (SMBus) I/O */
 static int w9968cf_smbus_start(struct w9968cf_device*);
 static int w9968cf_smbus_stop(struct w9968cf_device*);
@@ -421,6 +411,7 @@
 static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v);
 static int w9968cf_smbus_write_ack(struct w9968cf_device*);
 static int w9968cf_smbus_read_ack(struct w9968cf_device*);
+static int w9968cf_smbus_refresh_bus(struct w9968cf_device*);
 static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
                                       u16 address, u8* value);
 static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address, 
@@ -457,12 +448,11 @@
 static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
 static inline int w9968cf_sensor_cmd(struct w9968cf_device*, 
                                      unsigned int cmd, void *arg);
-static void w9968cf_sensor_configure(struct w9968cf_device*);
-static int w9968cf_sensor_change_settings(struct w9968cf_device*);
-static int w9968cf_sensor_get_picture(struct w9968cf_device*, 
-                                      struct video_picture*);
-static int w9968cf_sensor_set_picture(struct w9968cf_device*, 
-                                      struct video_picture pict);
+static int w9968cf_sensor_init(struct w9968cf_device*);
+static int w9968cf_sensor_update_settings(struct w9968cf_device*);
+static int w9968cf_sensor_get_picture(struct w9968cf_device*);
+static int w9968cf_sensor_update_picture(struct w9968cf_device*, 
+                                         struct video_picture pict);
 
 /* Other helper functions */
 static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*,
@@ -608,8 +598,6 @@
  * Memory management functions                                              *
  ****************************************************************************/
 
-/* Shameless copy from bttv-driver.c */
-
 /* Here we want the physical address of the memory.
    This is used when initializing the contents of the area. */
 static inline unsigned long kvirt_to_pa(unsigned long adr)
@@ -660,7 +648,6 @@
 	}
 	vfree(mem);
 }
-/* End of shameless copy */
 
 
 /*--------------------------------------------------------------------------
@@ -834,7 +821,7 @@
 	list_for_each(ptr, list) {
 		cam = list_entry(ptr, struct w9968cf_device, v4llist);
 		out += sprintf(out,"/dev/video%d       : %s\n", 
-		               cam->v4ldev.minor, symbolic(camlist, cam->id));
+		               cam->v4ldev->minor, symbolic(camlist, cam->id));
 	}
 
 	up(&w9968cf_devlist_sem);
@@ -865,21 +852,18 @@
 	int len;
 	char* out = page;
 
-	static struct video_picture pict; /* it has to be static */
-	static int rc = 0;
-
 	if (down_interruptible(&cam->procfs_sem))
 		return -ERESTARTSYS;
 
 	if (offset == 0)
-		rc = w9968cf_sensor_get_picture(cam, &pict);
+		w9968cf_sensor_get_picture(cam);
 
 	out += sprintf(out,"camera_model      : %s\n",
 	               symbolic(camlist, cam->id));
 	out += sprintf(out,"sensor_model      : %s\n",
 	               symbolic(senlist, cam->sensor));
 	out += sprintf(out,"sensor_monochrome : %s\n",
-	               YES_NO(cam->sensor_mono));
+	               YES_NO(cam->monochrome));
 	if (cam->users)
 		out += sprintf(out,"user_program      : %s\n",cam->command);
 	out += sprintf(out,"packet_size_bytes : %d\n", 
@@ -920,13 +904,11 @@
 	out += sprintf(out,"banding_filter    : %s\n",YES_NO(cam->bandfilt));
 	out += sprintf(out,"back_light        : %s\n",YES_NO(cam->backlight));
 	out += sprintf(out,"mirror            : %s\n",YES_NO(cam->mirror));
-	if (!rc) {
-		out += sprintf(out,"brightness        : %d\n",pict.brightness);
-		out += sprintf(out,"colour            : %d\n",pict.colour);
-		out += sprintf(out,"contrast          : %d\n",pict.contrast);
-		out += sprintf(out,"hue               : %d\n",pict.hue);
-		out += sprintf(out,"whiteness         : %d\n",pict.whiteness);
-	}
+	out += sprintf(out,"brightness        : %d\n",cam->picture.brightness);
+	out += sprintf(out,"colour            : %d\n",cam->picture.colour);
+	out += sprintf(out,"contrast          : %d\n",cam->picture.contrast);
+	out += sprintf(out,"hue               : %d\n",cam->picture.hue);
+	out += sprintf(out,"whiteness         : %d\n",cam->picture.whiteness);
 	out += sprintf(out,"hs_polarity       : %d\n",cam->hs_polarity);
 	out += sprintf(out,"vs_polarity       : %d\n",cam->vs_polarity);
 #ifdef W9968CF_DEBUG
@@ -954,34 +936,40 @@
 
 static void w9968cf_proc_create_dev(struct w9968cf_device* cam)
 {
-	char name[5];
+	char name[6];
 
 	if (!w9968cf_proc_entry)
 		return;
 
 	/* Create per-device readable entry */
-	sprintf(name, "dev%d", cam->v4ldev.minor);
-	cam->proc_dev = create_proc_read_entry(name, S_IFREG|S_IRUGO|S_IWUSR, 
+	sprintf(name, "dev%d", cam->v4ldev->minor);
+	cam->proc_dev = create_proc_read_entry(name, S_IFREG|S_IRUGO|S_IWUSR,
 	                                       w9968cf_proc_entry,
 	                                       w9968cf_proc_read_dev,
 	                                       (void*)cam);
 	if (!cam->proc_dev)
 		return;
 	cam->proc_dev->owner = THIS_MODULE;
+
+	DBG(2, "Per-device entry /proc/video/w9968cf/dev%d created.",
+	    cam->v4ldev->minor)
 }
 
 
 static void w9968cf_proc_destroy_dev(struct w9968cf_device* cam)
 {
-	char name[5];
+	char name[6];
 
 	if (!cam->proc_dev)
 		return;
 
-	sprintf(name, "dev%d", cam->v4ldev.minor);
+	sprintf(name, "dev%d", cam->v4ldev->minor);
 
 	/* Destroy per-device entry */
 	remove_proc_entry(name, w9968cf_proc_entry);
+
+	DBG(2, "Per-device entry /proc/video/w9968cf/dev%d removed.",
+	    cam->v4ldev->minor)
 }
 
 
@@ -1010,7 +998,7 @@
 	else
 		DBG(2, "Unable to create /proc/video/w9968cf/global")
 
-	DBG(5, "/proc entries successfully created.")
+	DBG(2, "Main entry /proc/video/w9968cf/global created.")
 }
 
 
@@ -1024,7 +1012,7 @@
 
 	remove_proc_entry("w9968cf", video_proc_entry);
 
-	DBG(5, "/proc entries removed.")
+	DBG(2, "Main entry /proc/video/w9968cf/global removed.")
 }
 
 #endif /* CONFIG_VIDEO_PROC_FS */
@@ -1184,14 +1172,12 @@
 	for (i = 0; i < W9968CF_URBS; i++) {
 		urb = usb_alloc_urb(W9968CF_ISO_PACKETS);
 		cam->urb[i] = urb;
-
 		if (!urb) {
 			for (j = 0; j < i; j++)
 				usb_free_urb(cam->urb[j]);
 			DBG(1, "Couldn't allocate the URB structures.")
 			return -ENOMEM;
 		}
-
 		urb->dev = udev;
 		urb->context = (void*)cam;
 		urb->pipe = usb_rcvisocpipe(udev, 1);
@@ -1214,7 +1200,7 @@
 
 	t_size = (w*h*d)/16;
 
-	err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset  everything */
+	err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
 	err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
 
 	/* Transfer size */
@@ -1287,11 +1273,12 @@
 	spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
 
 	for (i = W9968CF_URBS-1; i >= 0; i--)
-		if (cam->urb[i])
+		if (cam->urb[i]) {
 			if (!usb_unlink_urb(cam->urb[i])) {
 				usb_free_urb(cam->urb[i]);
 				cam->urb[i] = NULL;
 			}
+		}
 
 	if (cam->disconnected)
 		goto exit;
@@ -1347,8 +1334,7 @@
 
 	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,
 	                      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-	                      0, index, (void*)buff,
-	                      2, W9968CF_USB_CTRL_TIMEOUT);
+	                      0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);
 
 	if (res < 0)
 		DBG(4, "Failed to read a register "
@@ -1360,7 +1346,7 @@
 
 
 /*--------------------------------------------------------------------------
-  Write data to the fast serial bus registers.
+  Write 64-bit data to the fast serial bus registers.
   Return 0 on success, -1 otherwise.
   --------------------------------------------------------------------------*/
 static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
@@ -1373,8 +1359,7 @@
 
 	res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
 	                      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
-	                      value, 0x06, (void*)data, 6,
-	                      W9968CF_USB_CTRL_TIMEOUT);
+	                      value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);
 
 	if (res < 0)
 		DBG(4, "Failed to write the FSB registers "
@@ -1536,6 +1521,22 @@
 }
 
 
+/* This is seems to refresh the communication through the serial bus */
+static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
+{
+	int err = 0, j;
+
+	for (j = 1; j <= 10; j++) {
+		err = w9968cf_write_reg(cam, 0x0020, 0x01);
+		err += w9968cf_write_reg(cam, 0x0000, 0x01);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+
 /* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
 static int 
 w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam, 
@@ -1544,8 +1545,10 @@
 	u16* data = cam->data_buffer;
 	int err = 0;
 
-	 /* Enable SBUS outputs */
-	err += w9968cf_write_reg(cam, 0x0020, 0x01);
+	err += w9968cf_smbus_refresh_bus(cam);
+
+	/* Enable SBUS outputs */
+	err += w9968cf_write_sb(cam, 0x0020);
 
 	data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);
 	data[0] |= (address & 0x40) ? 0x4000 : 0x0;
@@ -1589,7 +1592,7 @@
 	err += w9968cf_write_fsb(cam, data);
 
 	/* Disable SBUS outputs */
-	err += w9968cf_write_reg(cam, 0x0000, 0x01);
+	err += w9968cf_write_sb(cam, 0x0000);
 
 	if (!err)
 		DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
@@ -1626,7 +1629,7 @@
 	err += w9968cf_smbus_read_byte(cam, value);
 	err += w9968cf_smbus_write_ack(cam);
 	err += w9968cf_smbus_stop(cam);
- 
+
 	/* Serial data disable */
 	err += w9968cf_write_sb(cam, 0x0000);
 
@@ -1695,8 +1698,8 @@
                        int size, union i2c_smbus_data *data)
 {
 	struct w9968cf_device* cam = adapter->data;
-	u8 i, j;
-	int rc = 0, err = 0; 
+	u8 i;
+	int err = 0; 
 
 	switch (addr) {
 		case OV6xx0_SID:
@@ -1712,31 +1715,26 @@
 		addr <<= 1;
 
 		if (read_write == I2C_SMBUS_WRITE)
- 			rc = w9968cf_i2c_adap_write_byte(cam, addr, command);
+ 			err = w9968cf_i2c_adap_write_byte(cam, addr, command);
 		else if (read_write == I2C_SMBUS_READ) 
-			rc = w9968cf_i2c_adap_read_byte(cam,addr, &data->byte);
+			err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
 
 	} else if (size == I2C_SMBUS_BYTE_DATA) {
 		addr <<= 1;
 
 		if (read_write == I2C_SMBUS_WRITE)
- 			rc = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
+ 			err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
 			                                  command, data->byte);
 		else if (read_write == I2C_SMBUS_READ) {
 			for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
-				rc = w9968cf_i2c_adap_read_byte_data(cam, addr, 
+				err = w9968cf_i2c_adap_read_byte_data(cam,addr,
 				                         command, &data->byte);
-				if (rc < 0) {
-					/* Work around: this seems to wake up  
-					   the EEPROM from the stall state */
-					for (j = 0; j <= 10; j++) {
-					   err += w9968cf_write_sb(cam,0x0020);
-					   err += w9968cf_write_sb(cam,0x0000);
-					   if (err)
-					   	break;
+				if (err) {
+					if (w9968cf_smbus_refresh_bus(cam)) {
+						err = -EIO;
+						break;
 					}
-				}
-				else
+				} else
 					break;
 			}
 
@@ -1748,11 +1746,7 @@
 		return -EINVAL;
 	}
 
-	/* This works around a bug in the I2C core */
-	if (rc > 0)
-		rc = 0;
-
-	return rc;
+	return err;
 }
 
 
@@ -1768,41 +1762,22 @@
 {
 	struct w9968cf_device* cam = client->adapter->data;
 	const char* clientname = client->name;
-	int id = client->driver->id;
+	int id = client->driver->id, err = 0;
 
 	if (id == I2C_DRIVERID_OVCAMCHIP) {
-		int rc = 0;
-
 		cam->sensor_client = client;
-
-		rc = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE, 
-		                        &cam->sensor_mono);
-		if (rc < 0) {
-			DBG(1, "CMOS sensor initialization failed (rc=%d)",rc);
-			cam->sensor_client = NULL;
-			return rc;
-		}
-
-		if (w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE, 
-		                       &cam->sensor) < 0)
-			rc = -EIO;
-		else if (client->addr==OV7xx0_SID || client->addr==OV6xx0_SID)
-			w9968cf_sensor_configure(cam);
-		else
-			rc = -EINVAL;
-
-		if (rc < 0) {
+		err = w9968cf_sensor_init(cam);
+		if (err) {
 			cam->sensor_client = NULL;
-			cam->sensor = CC_UNKNOWN;
-			return rc;
+			return err;
 		}
-	} else	{
-		DBG(4, "Rejected client [%s] with [%s]", 
+	} else {
+		DBG(4, "Rejected client [%s] with driver [%s]", 
 		    clientname, client->driver->name)
-		return -1;
+		return -EINVAL;
 	}
 
-	DBG(2, "I2C attach client [%s] with [%s]",
+	DBG(5, "I2C attach client [%s] with driver [%s]",
 	    clientname, client->driver->name)
 
 	return 0;
@@ -1818,7 +1793,7 @@
 		cam->sensor_client = NULL;
 	}
 
-	DBG(2, "I2C detach [%s]", clientname)
+	DBG(5, "I2C detach client [%s]", clientname)
 
 	return 0;
 }
@@ -1846,7 +1821,7 @@
 
 static int w9968cf_i2c_init(struct w9968cf_device* cam)
 {
-	int rc = 0;
+	int err = 0;
 
 	static struct i2c_algorithm algo = {
 		.name =          "W996[87]CF algorithm",
@@ -1869,15 +1844,15 @@
 	strcpy(cam->i2c_adapter.name, "w9968cf");
 	cam->i2c_adapter.data = cam;
 
-	DBG(6, "Registering I2C bus with kernel...")
+	DBG(6, "Registering I2C adapter with kernel...")
 
-	rc = i2c_add_adapter(&cam->i2c_adapter);
-	if (rc)
-		DBG(5, "Failed to register the I2C bus.")
+	err = i2c_add_adapter(&cam->i2c_adapter);
+	if (err)
+		DBG(1, "Failed to register the I2C adapter.")
 	else
-		DBG(5, "I2C bus registered.")
+		DBG(5, "I2C adapter registered.")
 
-	return rc;
+	return err;
 }
 
 
@@ -1917,7 +1892,7 @@
   --------------------------------------------------------------------------*/
 static int w9968cf_init_chip(struct w9968cf_device* cam)
 {
-	int err = 0, rc = 0;
+	int err = 0;
 
 	err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
 	err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
@@ -1952,22 +1927,11 @@
 	err += w9968cf_set_window(cam, cam->window);
 
 	if (err)
-		goto error;
-
-	rc = w9968cf_sensor_change_settings(cam);
-	if (rc)
-		goto error;
-
-	DBG(5, "Chip successfully initialized.");
-	
-	return 0;
-
-error:
-	DBG(1, "Chip initialization failed.")
-	if (err)
-		return err;
+		DBG(1, "Chip initialization failed.")
 	else
-		return rc;
+		DBG(5, "Chip successfully initialized.")
+
+	return err;
 }
 
 
@@ -1979,7 +1943,7 @@
 w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
 {
 	u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
-	int err = 0, rc = 0;
+	int err = 0;
 
 	/* Make sure we are using a valid depth */
 	pict.depth = w9968cf_valid_depth(pict.palette);
@@ -2040,12 +2004,10 @@
 	else if (cam->filter_type == 2)
 		reg_v |= 0x000c;
 
-	err = w9968cf_write_reg(cam, reg_v, 0x16);
-	if (err)
+	if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
 		goto error;
 
-	rc = w9968cf_sensor_set_picture(cam, pict);
-	if (rc)
+	if ((err = w9968cf_sensor_update_picture(cam, pict)))
 		goto error;
 
 	/* If all went well, update the device data structure */
@@ -2064,10 +2026,7 @@
 
 error:
 	DBG(1, "Failed to change picture settings.")
-	if (err)
-		return err;
-	else 
-		return rc;
+	return err;
 }
 
 
@@ -2082,7 +2041,7 @@
 	u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
 	unsigned long fw, fh;
 	struct ovcamchip_window s_win;
-	int err=0, rc=0;
+	int err = 0;
 
 	/* Work around to avoid FP arithmetics */
 	#define __SC(x) ((x) << 10)
@@ -2126,8 +2085,8 @@
 		ch = h;
 	}
 
-	/* Setup the sensor window */
-	s_win.format = SENSOR_FORMAT;
+	/* Setup the window of the sensor */
+	s_win.format = VIDEO_PALETTE_UYVY;
 	s_win.width = cam->maxwidth;
 	s_win.height = cam->maxheight;
 	s_win.quarter = 0; /* full progressive video */
@@ -2156,7 +2115,7 @@
 				s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
 		}
 
-	/* We have to scale win.x and win.y offsets */	
+	/* We have to scale win.x and win.y offsets */
 	if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
 	     || (cam->vpp_flag & VPP_UPSCALE) ) {
 		ax = __SC(win.x)/fw;
@@ -2187,7 +2146,7 @@
 	y = ay + s_win.y;
 
 	/* Go ! */
-	if ((rc = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
+	if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
 		goto error;
 
 	err += w9968cf_write_reg(cam, scx + x, 0x10);
@@ -2232,10 +2191,7 @@
 
 error:
 	DBG(1, "Failed to change the capture area size.")
-	if (err)
-		return err;
-	else
-		return rc;
+	return err;
 }
 
 
@@ -2450,173 +2406,192 @@
 w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
 {
 	struct ovcamchip_control ctl;
-	int rc;
+	int err;
 
 	ctl.id = cid;
 	ctl.value = val;
 
-	rc = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
+	err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
 
-	return rc;
+	return err;
 }
 
+
 static int 
-w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int *val)
+w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
 {
 	struct ovcamchip_control ctl;
-	int rc;
+	int err;
 
 	ctl.id = cid;
 
-	rc = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
-	if (rc >= 0)
+	err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
+	if (!err)
 		*val = ctl.value;
 
-	return rc;
+	return err;
 }
 
 
 static inline int
-w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void *arg)
+w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
 {
 	struct i2c_client* c = cam->sensor_client;
+	int rc = 0;
 
-	DBG(6, "Executing CMOS sensor command...")
-
-	if (c && c->driver->command)
-		return c->driver->command(cam->sensor_client, cmd, arg);
-	else
+	if (c->driver->command) {
+		rc = c->driver->command(cam->sensor_client, cmd, arg);
+		/* The I2C driver returns -EPERM on non-supported controls */
+		return (rc < 0 && rc != -EPERM) ? rc : 0;
+	} else
 		return -ENODEV;
 }
 
 
 /*--------------------------------------------------------------------------
-  Change some settings of the CMOS sensor.
-  Returns: 0 for success, a negative number otherwise.
+  Update some settings of the CMOS sensor.
+  Returns: 0 on success, a negative number otherwise.
   --------------------------------------------------------------------------*/
-static int w9968cf_sensor_change_settings(struct w9968cf_device* cam)
+static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
 {
-	int rc;
+	int err = 0;
 
 	/* Auto brightness */
-	rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT, 
-	                                cam->auto_brt);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
+	err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT, 
+	                                 cam->auto_brt);
+	if (err)
+		return err;
 
 	/* Auto exposure */
-	rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP, 
-	                                cam->auto_exp);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
+	err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP, 
+	                                 cam->auto_exp);
+	if (err)
+		return err;
 
 	/* Banding filter */
-	rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT, 
-	                                cam->bandfilt);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
+	err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT, 
+	                                 cam->bandfilt);
+	if (err)
+		return err;
 
 	/* Light frequency */
-	rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
-	                                cam->lightfreq);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
+	err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
+	                                 cam->lightfreq);
+	if (err)
+		return err;
 
 	/* Back light */
-	rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
-	                                cam->backlight);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
+	err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
+	                                 cam->backlight);
+	if (err)
+		return err;
 
 	/* Mirror */
-	rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
-	                                cam->mirror);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
+	err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
+	                                 cam->mirror);
+	if (err)
+		return err;
 
 	return 0;
 }
 
 
 /*--------------------------------------------------------------------------
-  Get some current picture settings from the CMOS sensor.
-  Returns: 0 for success, a negative number otherwise.
+  Get some current picture settings from the CMOS sensor and update the
+  internal 'picture' structure of the camera.
+  Returns: 0 on success, a negative number otherwise.
   --------------------------------------------------------------------------*/
-static int
-w9968cf_sensor_get_picture(struct w9968cf_device* cam, 
-                           struct video_picture* pict)
+static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
 {
-	int rc, v;
+	int err, v;
 
-	/* Don't return error if a setting is unsupported, or rest of settings
-	   will not be performed */
+	err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
+	if (err)
+		return err;
+	cam->picture.contrast = v;
 
-	rc = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
-	pict->contrast = v;
-
-	rc = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
-	pict->brightness = v;
-
-	rc = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
-	pict->colour = v;
-
-	rc = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
-	pict->hue = v;
+	err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
+	if (err)
+		return err;
+	cam->picture.brightness = v;
 
-	pict->whiteness = W9968CF_WHITENESS; /* to do! */
+	err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
+	if (err)
+		return err;
+	cam->picture.colour = v;
+
+	err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
+	if (err)
+		return err;
+	cam->picture.hue = v;
 
 	DBG(5, "Got picture settings from the CMOS sensor.")
 
 	PDBGG("Brightness, contrast, hue, colour, whiteness are "
-	      "%d,%d,%d,%d,%d.", pict->brightness, pict->contrast,
-	      pict->hue, pict->colour, pict->whiteness)
+	      "%d,%d,%d,%d,%d.", cam->picture.brightness,cam->picture.contrast,
+	      cam->picture.hue, cam->picture.colour, cam->picture.whiteness)
 
 	return 0;
 }
 
 
 /*--------------------------------------------------------------------------
-  Change picture settings of the CMOS sensor.
-  Returns: 0 for success, a negative number otherwise.
+  Update picture settings of the CMOS sensor.
+  Returns: 0 on success, a negative number otherwise.
   --------------------------------------------------------------------------*/
 static int
-w9968cf_sensor_set_picture(struct w9968cf_device* cam, 
-                           struct video_picture pict)
+w9968cf_sensor_update_picture(struct w9968cf_device* cam, 
+                              struct video_picture pict)
 {
-	int rc;
-
-	rc = w9968cf_sensor_set_control(cam,OVCAMCHIP_CID_CONT, pict.contrast);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
+	int err = 0;
 
-	if (!cam->auto_brt) {
-		rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT, 
-	                                        pict.brightness);
-		if (SENSOR_FATAL_ERROR(rc))
-			return rc;
+	if ((!cam->sensor_initialized)
+	    || pict.contrast != cam->picture.contrast) {
+		err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
+		                                 pict.contrast);
+		if (err)
+			goto fail;
+		DBG(4, "Contrast changed from %d to %d.",
+		    cam->picture.contrast, pict.contrast)
+		cam->picture.contrast = pict.contrast;
 	}
 
-	rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT, pict.colour);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
+	if (((!cam->sensor_initialized) || 
+	    pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
+		err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT, 
+		                                 pict.brightness);
+		if (err)
+			goto fail;
+		DBG(4, "Brightness changed from %d to %d.",
+		    cam->picture.brightness, pict.brightness)
+		cam->picture.brightness = pict.brightness;
+	}
 
-	rc = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE, pict.hue);
-	if (SENSOR_FATAL_ERROR(rc))
-		return rc;
+	if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
+		err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT, 
+		                                 pict.colour);
+		if (err)
+			goto fail;
+		DBG(4, "Colour changed from %d to %d.",
+		    cam->picture.colour, pict.colour)
+		cam->picture.colour = pict.colour;
+	}
 
-	PDBGG("Brightness, contrast, hue, colour, whiteness are "
-	      "%d,%d,%d,%d,%d.", pict.brightness, pict.contrast,
-	      pict.hue, pict.colour, pict.whiteness)
+	if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
+		err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE, 
+		                                 pict.hue);
+		if (err)
+			goto fail;
+		DBG(4, "Hue changed from %d to %d.",
+		    cam->picture.hue, pict.hue)
+		cam->picture.hue = pict.hue;
+	}
 
 	return 0;
+
+fail:
+	DBG(4, "Failed to change sensor picture setting.")
+	return err;
 }
 
 
@@ -2626,12 +2601,22 @@
  ****************************************************************************/
 
 /*--------------------------------------------------------------------------
-  This function is called when the CMOS sensor is detected.
+  This function is called when a supported CMOS sensor is detected.
+  Return 0 if the initialization succeeds, a negative number otherwise.
   --------------------------------------------------------------------------*/
-static void w9968cf_sensor_configure(struct w9968cf_device* cam)
+static int w9968cf_sensor_init(struct w9968cf_device* cam)
 {
-	/* NOTE: Make sure width and height are a multiple of 16 */
+	int err = 0;
+
+	if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE, 
+	                              &cam->monochrome)))
+		goto error;
 
+	if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE, 
+	                              &cam->sensor)))
+		goto error;
+
+	/* NOTE: Make sure width and height are a multiple of 16 */
 	switch (cam->sensor_client->addr) {
 		case OV6xx0_SID:
 			cam->maxwidth = 352;
@@ -2645,6 +2630,10 @@
 			cam->minwidth = 64;
 			cam->minheight = 48;
 			break;
+		default:
+			DBG(1, "Not supported CMOS sensor detected for %s.",
+			    symbolic(camlist, cam->id))
+			return -EINVAL;
 	}
 
 	/* These values depend on the ones in the ovxxx0.c sources */
@@ -2663,7 +2652,24 @@
 			cam->hs_polarity = 0;
 	}
 
-	DBG(5, "CMOS sensor %s configured.", symbolic(senlist, cam->sensor))
+	if ((err = w9968cf_sensor_update_settings(cam)))
+		goto error;
+
+	if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
+		goto error;
+
+	cam->sensor_initialized = 1;
+
+	DBG(2, "%s CMOS sensor initialized.", symbolic(senlist, cam->sensor))
+	return 0;
+
+error:
+	cam->sensor_initialized = 0;
+	cam->sensor = CC_UNKNOWN;
+	DBG(1, "CMOS sensor initialization failed for %s (/dev/video%d). "
+	       "Try to detach and attach this device again.",
+	    symbolic(camlist, cam->id), cam->v4ldev->minor)
+	return err;
 }
 
 
@@ -2678,7 +2684,7 @@
                          enum w9968cf_model_id mod_id,
                          const unsigned short dev_nr)
 {
-#if defined(CONFIG_VIDEO_PROC_FS)
+#ifdef CONFIG_VIDEO_PROC_FS
 	init_MUTEX(&cam->procfs_sem);
 #endif
 	init_MUTEX(&cam->fileop_sem);
@@ -2691,13 +2697,7 @@
 	cam->usbdev = udev;
 	cam->id = mod_id;
 	cam->sensor = CC_UNKNOWN;
-
-	strcpy(cam->v4ldev.name, symbolic(camlist, mod_id));
-	cam->v4ldev.type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
-	cam->v4ldev.hardware = VID_HARDWARE_W9968CF;
-	cam->v4ldev.fops = &w9968cf_fops;
-	cam->v4ldev.priv = (void*)cam;
-	cam->v4ldev.minor = video_nr[dev_nr];
+	cam->sensor_initialized = 0;
 
 	/* Calculate the alternate setting number (from 1 to 16)
 	   according to the 'packet_size' module parameter */
@@ -2709,66 +2709,66 @@
 
 	cam->max_buffers = (max_buffers[dev_nr] < 2 || 
 	                    max_buffers[dev_nr] > W9968CF_MAX_BUFFERS)
-	                   ? W9968CF_BUFFERS : max_buffers[dev_nr];
+	                   ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr];
 
 	cam->double_buffer = (double_buffer[dev_nr] == 0 || 
 	                      double_buffer[dev_nr] == 1)
-	                     ? double_buffer[dev_nr] : W9968CF_DOUBLE_BUFFER;
+	                     ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
 
 	cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
-	                ? clamping[dev_nr] : W9968CF_CLAMPING;
+	                ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
 	
 	cam->filter_type = (filter_type[dev_nr] == 0 ||
 	                    filter_type[dev_nr] == 1 ||
 	                    filter_type[dev_nr] == 2)
-	                   ? filter_type[dev_nr] : W9968CF_FILTER_TYPE;
+	                   ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE;
 
 	cam->capture = 1;
 
 	cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
-	                 ? largeview[dev_nr] : W9968CF_LARGEVIEW;
+	                 ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
 
 	cam->decompression = (decompression[dev_nr] == 0 || 
 	                      decompression[dev_nr] == 1 ||
 	                      decompression[dev_nr] == 2)
-	                     ? decompression[dev_nr] : W9968CF_DECOMPRESSION;
+	                     ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
 
 	cam->upscaling = (upscaling[dev_nr] == 0 || 
 	                  upscaling[dev_nr] == 1)
-	                 ? upscaling[dev_nr] : W9968CF_UPSCALING;
+	                 ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
 
 	cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
-	                ? autobright[dev_nr] : W9968CF_AUTOBRIGHT;
+	                ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
 
 	cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
-	                ? autoexp[dev_nr] : W9968CF_AUTOEXP;
+	                ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
 
 	cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
-	                 ? lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
+	                 ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
 
 	cam->bandfilt = (bandingfilter[dev_nr] == 0 || 
 	                 bandingfilter[dev_nr] == 1)
-	                ? bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
+	                ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
 
 	cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
-	                 ? backlight[dev_nr] : W9968CF_BACKLIGHT;
+	                 ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
 
 	cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
-	                ? clockdiv[dev_nr] : W9968CF_CLOCKDIV;
+	                ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
 
 	cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
-	              ? mirror[dev_nr] : W9968CF_MIRROR;
+	              ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
 
-	cam->sensor_mono = (sensor_mono[dev_nr]==0 || sensor_mono[dev_nr]==1)
-	                   ? sensor_mono[dev_nr] : W9968CF_SENSOR_MONO;
+	cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
+	                  ? monochrome[dev_nr] : W9968CF_MONOCHROME;
 
-	cam->picture.brightness = brightness[dev_nr];
-	cam->picture.hue = hue[dev_nr];
-	cam->picture.colour = colour[dev_nr];
-	cam->picture.contrast = contrast[dev_nr];
-	cam->picture.whiteness = whiteness[dev_nr];
-	if (w9968cf_valid_palette(force_palette[dev_nr])) {
-		cam->picture.palette = force_palette[dev_nr];
+	cam->picture.brightness = (u16)brightness[dev_nr];
+	cam->picture.hue = (u16)hue[dev_nr];
+	cam->picture.colour = (u16)colour[dev_nr];
+	cam->picture.contrast = (u16)contrast[dev_nr];
+	cam->picture.whiteness = (u16)whiteness[dev_nr];
+	if (w9968cf_valid_palette((u16)force_palette[dev_nr])) {
+		cam->picture.palette = (u16)force_palette[dev_nr];
 		cam->force_palette = 1;
 	} else {
 		cam->force_palette = 0;
@@ -2781,7 +2781,7 @@
 	}
 
 	cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
-	                 ? force_rgb[dev_nr] : W9968CF_FORCE_RGB;
+	                 ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
 
 	cam->window.x = 0;
 	cam->window.y = 0;
@@ -2886,7 +2886,7 @@
 	else
 		DBG(3, "- Clock divisor: %d", cam->clockdiv)
 
-	if (cam->sensor_mono)
+	if (cam->monochrome)
 		DBG(3, "- CMOS sensor used as monochrome.")
 	else
 		DBG(3, "- CMOS sensor not used as monochrome.")
@@ -2902,10 +2902,12 @@
 {
 	down(&w9968cf_devlist_sem);
 
-	DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev.minor)
+	DBG(2, "V4L device deregistered: /dev/video%d", cam->v4ldev->minor)
 
+#ifdef CONFIG_VIDEO_PROC_FS
 	w9968cf_proc_destroy_dev(cam);
-	video_unregister_device(&cam->v4ldev);
+#endif
+	video_unregister_device(cam->v4ldev);
 	list_del(&cam->v4llist);
 	i2c_del_adapter(&cam->i2c_adapter);
 	w9968cf_deallocate_memory(cam);
@@ -2925,24 +2927,25 @@
 
 static int w9968cf_open(struct inode* inode, struct file* filp)
 {
-	struct w9968cf_device* cam =
-	  (struct w9968cf_device*)video_devdata(filp)->priv;    
+	struct w9968cf_device* cam;
 	int err;
 
+	cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
+
 	down(&cam->dev_sem);
 
 	if (cam->sensor == CC_UNKNOWN) {
 		DBG(2, "No supported CMOS sensor has been detected by the "
 		       "'ovcamchip' module for the %s (/dev/video%d). Make "
 		       "sure it is loaded *before* the 'w9968cf' module.", 
-		    symbolic(camlist, cam->id),cam->v4ldev.minor)
+		    symbolic(camlist, cam->id), cam->v4ldev->minor)
 		up(&cam->dev_sem);
 		return -ENODEV;
 	}
 
 	if (cam->users) {
 		DBG(2, "%s (/dev/video%d) has been already occupied by '%s'.",
-		    symbolic(camlist, cam->id),cam->v4ldev.minor, cam->command)
+		    symbolic(camlist, cam->id),cam->v4ldev->minor,cam->command)
 		if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
 			up(&cam->dev_sem);
 			return -EWOULDBLOCK;
@@ -2958,7 +2961,7 @@
 	}
 
 	DBG(5, "Opening the %s, /dev/video%d ...",
-	    symbolic(camlist, cam->id), cam->v4ldev.minor)
+	    symbolic(camlist, cam->id), cam->v4ldev->minor)
 
 	cam->streaming = 0;
 	cam->misconfigured = 0;
@@ -2975,7 +2978,7 @@
 	if ((err = w9968cf_start_transfer(cam)))
 		goto deallocate_memory;
 
-	filp->private_data = (void*)cam;
+	filp->private_data = cam;
 
 	cam->users++;
 	strcpy(cam->command, current->comm);
@@ -2997,8 +3000,9 @@
 
 static int w9968cf_release(struct inode* inode, struct file* filp)
 {
-	struct w9968cf_device* cam = 
-	  (struct w9968cf_device*)video_devdata(filp)->priv;
+	struct w9968cf_device* cam;
+
+	cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
 
 	down(&cam->dev_sem); /* prevent disconnect() to be called */
 
@@ -3026,11 +3030,12 @@
 static ssize_t
 w9968cf_read(struct file* filp, char* buf, size_t count, loff_t* f_pos)
 {
-	struct w9968cf_device* cam =
-	  (struct w9968cf_device*)video_devdata(filp)->priv;
+	struct w9968cf_device* cam;
 	struct w9968cf_frame_t* fr;
 	int err = 0;
 
+	cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
+
 	if (filp->f_flags & O_NONBLOCK)
 		return -EWOULDBLOCK;
 
@@ -3094,9 +3099,8 @@
 
 static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
 {
-	struct w9968cf_device* cam =
-	  (struct w9968cf_device*)video_devdata(filp)->priv;
-
+	struct w9968cf_device* cam = (struct w9968cf_device*)
+	                             video_get_drvdata(video_devdata(filp));
 	unsigned long vsize = vma->vm_end - vma->vm_start,
 	              psize = cam->nbuffers * w9968cf_get_max_bufsize(cam),
 	              start = vma->vm_start,
@@ -3136,10 +3140,11 @@
 w9968cf_ioctl(struct inode* inode, struct file* filp,
               unsigned int cmd, unsigned long arg)
 {
-	struct w9968cf_device* cam =
-	  (struct w9968cf_device*)video_devdata(filp)->priv;
+	struct w9968cf_device* cam;
 	int err;
 
+	cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
+
 	if (down_interruptible(&cam->fileop_sem))
 		return -ERESTARTSYS;
 
@@ -3155,7 +3160,7 @@
 		return -EIO;
 	}
 
-	err = w9968cf_do_ioctl(cam, cmd, (void*)arg);
+	err = w9968cf_v4l_ioctl(inode, filp, cmd, (void* )arg);
 
 	up(&cam->fileop_sem);
 	return err;
@@ -3163,8 +3168,10 @@
 
 
 static int 
-w9968cf_do_ioctl(struct w9968cf_device* cam, unsigned cmd, void* arg)
+w9968cf_v4l_ioctl(struct inode* inode, struct file* filp,
+                  unsigned int cmd, void* arg)
 {
+	struct w9968cf_device* cam;
 	const char* v4l1_ioctls[] = {
 		"?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", 
 		"GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
@@ -3176,7 +3183,9 @@
 
 	#define V4L1_IOCTL(cmd) \
 	        ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
-	        v4l1_ioctls[_IOC_NR((cmd))] : "???")
+	        v4l1_ioctls[_IOC_NR((cmd))] : "?")
+
+	cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
 
 	switch (cmd) {
 
@@ -3190,7 +3199,7 @@
 			.minheight = cam->minheight,
 		};
 		sprintf(cap.name, "W996[87]CF USB Camera #%d", 
-		        cam->v4ldev.minor);
+		        cam->v4ldev->minor);
 		cap.maxwidth = (cam->upscaling && w9968cf_vppmod_present)
 		               ? W9968CF_MAX_WIDTH : cam->maxwidth;
 		cap.maxheight = (cam->upscaling && w9968cf_vppmod_present)
@@ -3241,15 +3250,10 @@
 
 	case VIDIOCGPICT: /* get image properties of the picture */
 	{
-		struct video_picture pict;
-
-		if (w9968cf_sensor_get_picture(cam, &pict))
+		if (w9968cf_sensor_get_picture(cam))
 			return -EIO;
 
-		pict.depth = cam->picture.depth;
-		pict.palette = cam->picture.palette;
-
-		if (copy_to_user(arg, &pict, sizeof(pict)))
+		if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
 			return -EFAULT;
 
 		DBG(5, "VIDIOCGPICT successfully called.")
@@ -3278,13 +3282,6 @@
 			return -EINVAL;
 		}
 
-		if (pict.depth != w9968cf_valid_depth(pict.palette)) {
-			DBG(4, "Depth %d bpp is not supported for %s palette. "
-			       "VIDIOCSPICT failed.", 
-			    pict.depth, symbolic(v4l1_plist, pict.palette))
-			return -EINVAL;
-		}
-
 		if (!cam->force_palette) {
 		   if (cam->decompression == 0) {
 		      if (w9968cf_need_decompression(pict.palette)) {
@@ -3303,9 +3300,15 @@
 		   }
 		}
 
-		if (pict.palette != cam->picture.palette ||
-		    pict.depth   != cam->picture.depth)
-		{
+		if (pict.depth != w9968cf_valid_depth(pict.palette)) {
+			DBG(4, "Requested depth %d bpp is not valid for %s "
+			       "palette: ignored and changed to %d bpp.", 
+			    pict.depth, symbolic(v4l1_plist, pict.palette),
+			    w9968cf_valid_depth(pict.palette))
+			pict.depth = w9968cf_valid_depth(pict.palette);
+		}
+
+		if (pict.palette != cam->picture.palette) {
 			if(*cam->requested_frame
 			   || cam->frame_current->queued) {
 				err = wait_event_interruptible
@@ -3328,15 +3331,9 @@
 			if (w9968cf_start_transfer(cam))
 				goto ioctl_fail;
 
-		} else if ( ((pict.brightness != cam->picture.brightness) &&
-		            (!cam->auto_brt)) ||
-		            pict.hue != cam->picture.hue ||
-		            pict.colour != cam->picture.colour ||
-		            pict.contrast != cam->picture.contrast ||
-		            pict.whiteness != cam->picture.whiteness ) {
-			if (w9968cf_sensor_set_picture(cam, pict))
-				return -EIO;
-		}
+		} else if (w9968cf_sensor_update_picture(cam, pict))
+			return -EIO;
+
 
 		DBG(5, "VIDIOCSPICT successfully called.")
 		return 0;
@@ -3368,7 +3365,6 @@
 		    win.y != cam->window.y ||
 		    win.width != cam->window.width ||
 		    win.height != cam->window.height) {
-
 			if(*cam->requested_frame
 			   || cam->frame_current->queued) {
 				err = wait_event_interruptible
@@ -3479,12 +3475,12 @@
 		   }
 		}
 
-		if (w9968cf_adjust_window_size(cam, (u16*)&mmap.width, 
-		                               (u16*)&mmap.height)) {
+		if ((err = w9968cf_adjust_window_size(cam, (u16*)&mmap.width, 
+		                                      (u16*)&mmap.height))) {
 			DBG(4, "Resolution not supported (%dx%d). "
 			       "VIDIOCMCAPTURE failed.",
 			    mmap.width, mmap.height)
-			return -EINVAL;
+			return err;
 		}
 
 		fr = &cam->frame[mmap.frame];
@@ -3599,7 +3595,7 @@
 	case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
 	{
 		struct video_unit unit = {
-			.video = cam->v4ldev.minor,
+			.video = cam->v4ldev->minor,
 			.vbi = VIDEO_NO_UNIT,
 			.radio = VIDEO_NO_UNIT,
 			.audio = VIDEO_NO_UNIT,
@@ -3767,14 +3763,6 @@
 		return NULL;
 	}
 
-	err = usb_set_configuration(udev, 1);
-	err += usb_set_interface(udev, 0, 0);
-
-	if (err) {
-		DBG(1, "Device configuration failed.")
-		return NULL;
-	}
-
 	cam = (struct w9968cf_device*)
 	          kmalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
 
@@ -3806,10 +3794,24 @@
 	}
 	memset(cam->data_buffer, 0, 8);
 
-	/* Set some basic constants */
-	w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
+	/* Register the V4L device */
+	cam->v4ldev = video_device_alloc();
+	if (!cam->v4ldev) {
+		DBG(1, "Could not allocate memory for a V4L structure.")
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
+	cam->v4ldev->owner = THIS_MODULE;
+	cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
+	cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
+	cam->v4ldev->fops = &w9968cf_fops;
+	cam->v4ldev->minor = video_nr[dev_nr];
+	cam->v4ldev->release = video_device_release;
+	video_set_drvdata(cam->v4ldev, cam);
 
-	err = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER,
+	err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
 	                            video_nr[dev_nr]);
 	if (err) {
 		DBG(1, "V4L device registration failed.")
@@ -3820,22 +3822,27 @@
 		goto fail;
 	}
 
-	DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev.minor)
+	DBG(2, "V4L device registered as /dev/video%d", cam->v4ldev->minor)
+
+	/* Set some basic constants */
+	w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
 
 	/* Ok, add a new entry into the list of V4L registered devices */
 	down(&w9968cf_devlist_sem);
 	list_add(&cam->v4llist, &w9968cf_dev_list);
 	up(&w9968cf_devlist_sem);
-
 	dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
 
 	w9968cf_turn_on_led(cam);
 
 	w9968cf_i2c_init(cam);
 
+#ifdef CONFIG_VIDEO_PROC_FS
 	w9968cf_proc_create_dev(cam);
+#endif
 
 	up(&cam->dev_sem);
+
 	return (void*)cam;
 
 fail: /* Free unused memory */
@@ -3844,6 +3851,8 @@
 			kfree(cam->control_buffer);
 		if (cam->data_buffer)
 			kfree(cam->data_buffer);
+		if (cam->v4ldev)
+			video_device_release(cam->v4ldev);
 		up(&cam->dev_sem);
 		kfree(cam);
 	}
@@ -3851,7 +3860,8 @@
 }
 
 
-static void w9968cf_usb_disconnect(struct usb_device* udev, void* drv_context)
+static void
+w9968cf_usb_disconnect(struct usb_device* udev, void* drv_context)
 {
 	struct w9968cf_device* cam = (struct w9968cf_device*)drv_context;
 
@@ -3871,7 +3881,7 @@
 			DBG(2, "The device is open (/dev/video%d)! "
 			       "Process name: %s. Deregistration and memory "
 			       "deallocation are deferred on close.",
-			    cam->v4ldev.minor, cam->command)
+			    cam->v4ldev->minor, cam->command)
 
 			cam->misconfigured = 1;
 
@@ -3956,14 +3966,18 @@
 
 	init_MUTEX(&w9968cf_devlist_sem);
 
+#ifdef CONFIG_VIDEO_PROC_FS
 	w9968cf_proc_create();
+#endif
 
 	w9968cf_vppmod_detect();
 
 	if ((err = usb_register(&w9968cf_usb_driver))) {
 		if (w9968cf_vppmod_present)
 			w9968cf_vppmod_release();
+#ifdef CONFIG_VIDEO_PROC_FS
 		w9968cf_proc_destroy();
+#endif
 		return err;
 	}
 
@@ -3976,7 +3990,9 @@
 	/* w9968cf_usb_disconnect() will be called */
 	usb_deregister(&w9968cf_usb_driver);
 
+#ifdef CONFIG_VIDEO_PROC_FS
 	w9968cf_proc_destroy();	
+#endif
 
 	if (w9968cf_vppmod_present)
 		w9968cf_vppmod_release();
@@ -3987,3 +4003,5 @@
 
 module_init(w9968cf_module_init);
 module_exit(w9968cf_module_exit);
+
+EXPORT_NO_SYMBOLS;
diff -urN linux-2.4.24-pre1/drivers/usb/w9968cf.h linux-2.4.24-pre2/drivers/usb/w9968cf.h
--- linux-2.4.24-pre1/drivers/usb/w9968cf.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/w9968cf.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,7 +1,7 @@
 /***************************************************************************
  * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip.       *
  *                                                                         *
- * Copyright (C) 2002 2003 by Luca Risolia <luca_ing@libero.it>            *
+ * Copyright (C) 2002 2003 by Luca Risolia <luca.risolia@studio.unibo.it>  *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
@@ -24,11 +24,14 @@
 #include <linux/videodev.h>
 #include <linux/usb.h>
 #include <linux/i2c.h>
-#include <linux/proc_fs.h>
+#ifdef CONFIG_VIDEO_PROC_FS
+#	include <linux/proc_fs.h>
+#endif
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/wait.h>
 #include <linux/config.h>
+#include <linux/param.h>
 #include <asm/semaphore.h>
 #include <asm/types.h>
 
@@ -106,7 +109,7 @@
 #define W9968CF_LARGEVIEW      1 /* 0 disable, 1 enable */
 #define W9968CF_UPSCALING      0 /* 0 disable, 1 enable */
 
-#define W9968CF_SENSOR_MONO    0 /* 0 not monochrome, 1 monochrome sensor */
+#define W9968CF_MONOCHROME     0 /* 0 not monochrome, 1 monochrome sensor */
 #define W9968CF_BRIGHTNESS     31000 /* from 0 to 65535 */
 #define W9968CF_HUE            32768 /* from 0 to 65535 */
 #define W9968CF_COLOUR         32768 /* from 0 to 65535 */
@@ -130,9 +133,10 @@
 
 #define W9968CF_MODULE_NAME     "V4L driver for W996[87]CF JPEG USB " \
                                 "Dual Mode Camera Chip"
-#define W9968CF_MODULE_VERSION  "v1.22"
+#define W9968CF_MODULE_VERSION  "v1.24-basic"
 #define W9968CF_MODULE_AUTHOR   "(C) 2002 2003 Luca Risolia"
-#define W9968CF_AUTHOR_EMAIL    "<luca_ing@libero.it>"
+#define W9968CF_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
+#define W9968CF_MODULE_LICENSE  "GPL"
 
 static u8 w9968cf_vppmod_present; /* status flag: yes=1, no=0 */
 
@@ -172,6 +176,7 @@
 };
 
 struct w9968cf_frame_t {
+	#define W9968CF_HW_BUF_SIZE 640*480*2 /* buf.size of original frames */
 	void* buffer;
 	u32 length;
 	enum w9968cf_frame_status status;
@@ -195,8 +200,8 @@
 struct w9968cf_device {
 	enum w9968cf_model_id id;   /* private device identifier */
 
-	struct video_device v4ldev; /* V4L structure */
-	struct list_head v4llist;   /* entry of the list of V4L cameras */
+	struct video_device* v4ldev; /* -> V4L structure */
+	struct list_head v4llist;    /* entry of the list of V4L cameras */
 
 	struct usb_device* usbdev;           /* -> main USB structure */
 	struct urb* urb[W9968CF_URBS];       /* -> USB request block structs */
@@ -208,9 +213,9 @@
 	struct w9968cf_frame_t frame_tmp;  /* temporary frame */
 	struct w9968cf_frame_t* frame_current; /* -> frame being grabbed */
 	struct w9968cf_frame_t* requested_frame[W9968CF_MAX_BUFFERS];
-	void* vpp_buffer; /* -> helper buffer for post-processing routines */
+	void* vpp_buffer; /*-> helper buf.for video post-processing routines */
 
-	u8 max_buffers,   /* number of requested buffers */	   
+	u8 max_buffers,   /* number of requested buffers */
 	   force_palette, /* yes=1/no=0 */
 	   force_rgb,     /* read RGB instead of BGR, yes=1, no=0 */
 	   double_buffer, /* hardware double buffering yes=1/no=0 */
@@ -221,15 +226,17 @@
 	   decompression, /* 0=disabled, 1=forced, 2=allowed */
 	   upscaling;     /* software image scaling, 0=enabled, 1=disabled */
 
-	struct video_picture picture; /* current window settings */
-	struct video_window window;   /* current picture settings */
+	struct video_picture picture; /* current picture settings */
+	struct video_window window;   /* current window settings */
 
 	u16 hw_depth,    /* depth (used by the chip) */
 	    hw_palette,  /* palette (used by the chip) */
 	    hw_width,    /* width (used by the chip) */
 	    hw_height,   /* height (used by the chip) */
 	    hs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
-	    vs_polarity; /* 0=negative sync pulse, 1=positive sync pulse */
+	    vs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
+	    start_cropx, /* pixels from HS inactive edge to 1st cropped pixel*/
+	    start_cropy; /* pixels from VS incative edge to 1st cropped pixel*/
 
 	enum w9968cf_vpp_flag vpp_flag; /* post-processing routines in use */
 
@@ -240,16 +247,15 @@
 	   users,         /* flag: number of users holding the device */
 	   streaming;     /* flag: yes=1, no=0 */
 
-	int sensor; /* type of image CMOS sensor chip (CC_*) */
-
-	/* Determined by CMOS sensor type */
-	u16 maxwidth,
-	    maxheight,
-	    minwidth,
-	    minheight,
-	    start_cropx,
-	    start_cropy;
+	u8 sensor_initialized; /* flag: yes=1, no=0 */
 
+	/* Determined by CMOS sensor type: */
+	int sensor,       /* type of image sensor chip (CC_*) */
+	    monochrome;   /* CMOS sensor is (probably) monochrome */
+	u16 maxwidth,     /* maximum width supported by the CMOS sensor */
+	    maxheight,    /* maximum height supported by the CMOS sensor */
+	    minwidth,     /* minimum width supported by the CMOS sensor */
+	    minheight;    /* minimum height supported by the CMOS sensor */
 	u8  auto_brt,     /* auto brightness enabled flag */
 	    auto_exp,     /* auto exposure enabled flag */
 	    backlight,    /* backlight exposure algorithm flag */
@@ -257,21 +263,20 @@
 	    lightfreq,    /* power (lighting) frequency */
 	    bandfilt;     /* banding filter enabled flag */
 	s8  clockdiv;     /* clock divisor */
-	int sensor_mono;  /* CMOS sensor is (probably) monochrome */
 
 	/* I2C interface to kernel */
 	struct i2c_adapter i2c_adapter;
 	struct i2c_client* sensor_client;
 
-#if defined(CONFIG_VIDEO_PROC_FS)
+#ifdef CONFIG_VIDEO_PROC_FS
 	/* /proc entries, relative to /proc/video/w9968cf/ */
-	struct proc_dir_entry *proc_dev;   /* readable per-device entry */
+	struct proc_dir_entry *proc_dev;   /* rw per-device entry */
 #endif
 
 	/* Locks */
 	struct semaphore dev_sem,    /* for probe, disconnect,open and close */
 	                 fileop_sem; /* for read and ioctl */
-#if defined(CONFIG_VIDEO_PROC_FS)
+#ifdef CONFIG_VIDEO_PROC_FS
 	struct semaphore procfs_sem; /* for /proc read/write calls */
 #endif
 	spinlock_t urb_lock,   /* for submit_urb() and unlink_urb() */
@@ -280,14 +285,9 @@
 	wait_queue_head_t open, wait_queue;
 };
 
-#define W9968CF_HW_BUF_SIZE 640*480*2 /* buf. size for original video frames */
-
-#define SENSOR_FORMAT          VIDEO_PALETTE_UYVY
-#define SENSOR_FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM)
-
 
 /****************************************************************************
- * Macros and other constants                                               *
+ * Macros for debugging                                                     *
  ****************************************************************************/
 
 #undef DBG
@@ -303,7 +303,7 @@
 	else if ((level) == 4) \
 		warn(fmt, ## args); \
 	else if ((level) >= 5) \
-		info("[%s,%d] " fmt, \
+		info("[%s:%d] " fmt, \
 		     __PRETTY_FUNCTION__, __LINE__ , ## args); \
 } \
 }
@@ -314,7 +314,7 @@
 
 #undef PDBG
 #undef PDBGG
-#define PDBG(fmt, args...) info("[%s, %d] "fmt, \
+#define PDBG(fmt, args...) info("[%s:%d] "fmt, \
 	                        __PRETTY_FUNCTION__, __LINE__ , ## args);
 #define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */
 
diff -urN linux-2.4.24-pre1/drivers/usb/w9968cf_decoder.h linux-2.4.24-pre2/drivers/usb/w9968cf_decoder.h
--- linux-2.4.24-pre1/drivers/usb/w9968cf_decoder.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/w9968cf_decoder.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,7 +1,7 @@
 /***************************************************************************
  * Video decoder for the W996[87]CF driver for Linux.                      *
  *                                                                         *
- * Copyright (C) 2003 by Luca Risolia <luca_ing@libero.it>                 *
+ * Copyright (C) 2003 by Luca Risolia <luca.risolia@studio.unibo.it>       *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
diff -urN linux-2.4.24-pre1/drivers/usb/w9968cf_externaldef.h linux-2.4.24-pre2/drivers/usb/w9968cf_externaldef.h
--- linux-2.4.24-pre1/drivers/usb/w9968cf_externaldef.h	2003-11-28 10:26:20.000000000 -0800
+++ linux-2.4.24-pre2/drivers/usb/w9968cf_externaldef.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,8 +1,9 @@
 /***************************************************************************
- * Various definitions for compatibility with external modules.            *
+ * Various definitions for compatibility with OVCAMCHIP external module.   *
  * This file is part of the W996[87]CF driver for Linux.                   *
  *                                                                         *
- * Copyright (C) 2002 2003 by Luca Risolia <luca_ing@libero.it>            *
+ * The definitions have been taken from the OVCAMCHIP module written by    *
+ * Mark McClelland.                                                        *
  *                                                                         *
  * This program is free software; you can redistribute it and/or modify    *
  * it under the terms of the GNU General Public License as published by    *
@@ -27,10 +28,8 @@
 #include <asm/ioctl.h>
 #include <asm/types.h>
 
-/* The following values have been copied from the "ovcamchip" module. */
-
 #ifndef I2C_DRIVERID_OVCAMCHIP
-#	define I2C_DRIVERID_OVCAMCHIP	0xf00f
+#	define I2C_DRIVERID_OVCAMCHIP 0xf00f
 #endif
 
 /* Controls */
@@ -77,10 +76,10 @@
 	int width;
 	int height;
 	int format;
-	int quarter;		/* Scale width and height down 2x */
+	int quarter;  /* Scale width and height down 2x */
 
 	/* This stuff will be removed eventually */
-	int clockdiv;		/* Clock divisor setting */
+	int clockdiv; /* Clock divisor setting */
 };
 
 /* Commands. 
diff -urN linux-2.4.24-pre1/drivers/video/pmag-aa-fb.c linux-2.4.24-pre2/drivers/video/pmag-aa-fb.c
--- linux-2.4.24-pre1/drivers/video/pmag-aa-fb.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/drivers/video/pmag-aa-fb.c	2003-12-22 11:34:36.000000000 -0800
@@ -15,7 +15,7 @@
  *
  *	2002-09-28  Karsten Merker <merker@linuxtag.org>
  *		Version 0.01: First try to get a PMAG-AA running.
- * 
+ *
  *	2003-02-24  Thiemo Seufer  <seufer@csv.ica.uni-stuttgart.de>
  *		Version 0.02: Major code cleanup.
  *
@@ -296,7 +296,7 @@
 	    && cmap->transp == NULL)
 		return 0;
 	else
-	return -EINVAL;
+		return -EINVAL;
 }
 
 static int aafb_ioctl(struct inode *inode, struct file *file, u32 cmd,
@@ -492,7 +492,7 @@
 		init_one(sid);
 	}
 
-	return found ? 0 : -ENODEV;
+	return found ? 0 : -ENXIO;
 }
 
 static void __exit pmagaafb_exit(void)
diff -urN linux-2.4.24-pre1/fs/nfs/direct.c linux-2.4.24-pre2/fs/nfs/direct.c
--- linux-2.4.24-pre1/fs/nfs/direct.c	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.24-pre2/fs/nfs/direct.c	2003-12-22 11:34:36.000000000 -0800
@@ -354,7 +354,7 @@
 	size_t count = iobuf->length;
 	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
-	loff_t offset = blocknr << inode->i_blkbits;
+	loff_t offset = (loff_t) blocknr << inode->i_blkbits;
 
 	switch (rw) {
 	case READ:
diff -urN linux-2.4.24-pre1/fs/xfs/linux/xfs_aops.c linux-2.4.24-pre2/fs/xfs/linux/xfs_aops.c
--- linux-2.4.24-pre1/fs/xfs/linux/xfs_aops.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/linux/xfs_aops.c	2003-12-22 11:34:36.000000000 -0800
@@ -361,6 +361,7 @@
 	unsigned long		p_offset,
 	int			block_bits,
 	xfs_iomap_t		*iomapp,
+	int			startio,
 	int			all_bh)
 {
 	struct buffer_head	*bh = curr;
@@ -436,7 +437,7 @@
 				break;
 			nblocks += bs;
 			atomic_add(bs, &pb->pb_io_remaining);
-			convert_page(inode, page, iomapp, pb, 1, all_bh);
+			convert_page(inode, page, iomapp, pb, startio, all_bh);
 		}
 
 		if (tindex == tlast &&
@@ -446,7 +447,7 @@
 			if (page) {
 				nblocks += bs;
 				atomic_add(bs, &pb->pb_io_remaining);
-				convert_page(inode, page, iomapp, pb, 1, all_bh);
+				convert_page(inode, page, iomapp, pb, startio, all_bh);
 			}
 		}
 	}
@@ -546,7 +547,7 @@
 		if (buffer_unwritten(bh) && !bh->b_end_io) {
 			ASSERT(tmp->iomap_flags & IOMAP_UNWRITTEN);
 			map_unwritten(inode, page, head, bh,
-						offset, bbits, tmp, all_bh);
+					offset, bbits, tmp, startio, all_bh);
 		} else if (! (buffer_unwritten(bh) && buffer_locked(bh))) {
 			map_buffer_at_offset(page, bh, offset, bbits, tmp);
 			if (buffer_unwritten(bh)) {
@@ -678,8 +679,8 @@
 				if (!bh->b_end_io) {
 					err = map_unwritten(inode, page,
 							head, bh, p_offset,
-							inode->i_blkbits,
-							iomp, unmapped);
+							inode->i_blkbits, iomp,
+							startio, unmapped);
 					if (err) {
 						goto error;
 					}
@@ -796,7 +797,7 @@
 STATIC int
 linvfs_get_block_core(
 	struct inode		*inode,
-	sector_t		iblock,
+	long			iblock,
 	struct buffer_head	*bh_result,
 	int			create,
 	int			direct,
@@ -879,7 +880,7 @@
 int
 linvfs_get_block(
 	struct inode		*inode,
-	sector_t		iblock,
+	long			iblock,
 	struct buffer_head	*bh_result,
 	int			create)
 {
@@ -890,7 +891,7 @@
 STATIC int
 linvfs_get_block_sync(
 	struct inode		*inode,
-	sector_t		iblock,
+	long			iblock,
 	struct buffer_head	*bh_result,
 	int			create)
 {
@@ -901,7 +902,7 @@
 STATIC int
 linvfs_get_block_direct(
 	struct inode		*inode,
-	sector_t		iblock,
+	long			iblock,
 	struct buffer_head	*bh_result,
 	int			create)
 {
@@ -909,10 +910,10 @@
 					create, 1, BMAPI_WRITE|BMAPI_DIRECT);
 }
 
-STATIC sector_t
+STATIC int
 linvfs_bmap(
 	struct address_space	*mapping,
-	sector_t		block)
+	long			block)
 {
 	struct inode		*inode = (struct inode *)mapping->host;
 	vnode_t			*vp = LINVFS_GET_VP(inode);
@@ -1116,7 +1117,7 @@
 	int			rw,
 	struct inode		*inode,
 	struct kiobuf		*iobuf,
-	sector_t		blocknr,
+	unsigned long		blocknr,
 	int			blocksize)
 {
 	struct page		**maplist;
@@ -1138,7 +1139,7 @@
 	page_offset = iobuf->offset;
 
 	map_flags = (rw ? BMAPI_WRITE : BMAPI_READ) | BMAPI_DIRECT;
-	pb_flags = (rw ? PBF_WRITE : PBF_READ) | PBF_FORCEIO;
+	pb_flags = (rw ? PBF_WRITE : PBF_READ) | PBF_FORCEIO | PBF_DIRECTIO;
 	while (length) {
 		error = map_blocks(inode, offset, length, &iomap, map_flags);
 		if (error)
@@ -1224,21 +1225,6 @@
 }
 
 
-/* since the address_space_operations are not consitent with the type used
- * for block indexes we must cast the functions into what is expected..
- * thus the following 2 lines.
- * If running on a kernel with LBD support and hence bmap and direct_IO
- * correctly defined with sector_t params. use the second set of typedefs
- * or casts from the address space_operations
- * RMC
- */
-
-#ifndef  HAVE_SECTOR_T
-typedef int (bmap_proc)(struct address_space *, long);
-typedef int (direct_IO_proc)(int, struct inode *, struct kiobuf *,
-			     unsigned long, int);
-#endif
-
 struct address_space_operations linvfs_aops = {
 	.readpage		= linvfs_readpage,
 	.writepage		= linvfs_writepage,
@@ -1246,11 +1232,6 @@
 	.releasepage		= linvfs_release_page,
 	.prepare_write		= linvfs_prepare_write,
 	.commit_write		= generic_commit_write,
-#ifndef HAVE_SECTOR_T
-	.bmap			= (bmap_proc *)linvfs_bmap,
-	.direct_IO		= (direct_IO_proc *)linvfs_direct_IO,
-#else
 	.bmap			= linvfs_bmap,
 	.direct_IO		= linvfs_direct_IO,
-#endif
 };
diff -urN linux-2.4.24-pre1/fs/xfs/linux/xfs_file.c linux-2.4.24-pre2/fs/xfs/linux/xfs_file.c
--- linux-2.4.24-pre1/fs/xfs/linux/xfs_file.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/linux/xfs_file.c	2003-12-22 11:34:36.000000000 -0800
@@ -58,14 +58,6 @@
 
 static struct vm_operations_struct linvfs_file_vm_ops;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
-#define	do_down_read(x)	down_read(x)
-#define do_up_read(x)	up_read(x)
-#else
-#define	do_down_read(x)
-#define do_up_read(x)
-#endif
-
 STATIC inline ssize_t
 __linvfs_read(
 	struct file	*file,
@@ -80,9 +72,9 @@
 
 	if (unlikely(file->f_flags & O_DIRECT)) {
 		ioflags |= IO_ISDIRECT;
-		do_down_read(&inode->i_alloc_sem);
+		down_read(&inode->i_alloc_sem);
 		VOP_READ(vp, file, buf, size, offset, ioflags, NULL, error);
-		do_up_read(&inode->i_alloc_sem);
+		up_read(&inode->i_alloc_sem);
 	} else {
 		VOP_READ(vp, file, buf, size, offset, ioflags, NULL, error);
 	}
@@ -144,10 +136,10 @@
 	 */
 	if (unlikely(file->f_flags & O_DIRECT)) {
 		ioflags |= IO_ISDIRECT;
-		do_down_read(&inode->i_alloc_sem);
+		down_read(&inode->i_alloc_sem);
 		VOP_WRITE(vp, file, buf, count, &pos, ioflags, NULL, error);
 		*ppos = pos;
-		do_up_read(&inode->i_alloc_sem);
+		up_read(&inode->i_alloc_sem);
 	} else {
 		down(&inode->i_sem);
 		VOP_WRITE(vp, file, buf, count, &pos, ioflags, NULL, error);
diff -urN linux-2.4.24-pre1/fs/xfs/linux/xfs_globals.c linux-2.4.24-pre2/fs/xfs/linux/xfs_globals.c
--- linux-2.4.24-pre1/fs/xfs/linux/xfs_globals.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/linux/xfs_globals.c	2003-12-22 11:34:36.000000000 -0800
@@ -102,10 +102,8 @@
 
 xfs_param_t xfs_params = {
 			  /*	MIN	DFLT	MAX	*/
-#ifdef HAVE_REFCACHE
 	.refcache_size	= {	0,	128,	XFS_REFCACHE_SIZE_MAX },
 	.refcache_purge	= {	0,	32,	XFS_REFCACHE_SIZE_MAX },
-#endif
 	.restrict_chown	= {	0,	1,	1	},
 	.sgid_inherit	= {	0,	0,	1	},
 	.symlink_mode	= {	0,	0,	1	},
diff -urN linux-2.4.24-pre1/fs/xfs/linux/xfs_iops.c linux-2.4.24-pre2/fs/xfs/linux/xfs_iops.c
--- linux-2.4.24-pre1/fs/xfs/linux/xfs_iops.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/linux/xfs_iops.c	2003-12-22 11:34:36.000000000 -0800
@@ -110,7 +110,7 @@
 	vattr_t		va;
 	vnode_t		*vp = NULL, *dvp = LINVFS_GET_VP(dir);
 	xfs_acl_t	*default_acl = NULL;
-	xattr_exists_t	test_default_acl = _ACL_DEFAULT_EXISTS;
+	attrexists_t	test_default_acl = _ACL_DEFAULT_EXISTS;
 	int		error;
 
 	if (test_default_acl && test_default_acl(dvp)) {
@@ -543,61 +543,6 @@
 	block_truncate_page(inode->i_mapping, inode->i_size, linvfs_get_block);
 }
 
-
-
-/*
- * Extended attributes interfaces
- */
-
-#define SYSTEM_NAME	"system."	/* VFS shared names/values */
-#define ROOT_NAME	"trusted."	/* root's own names/values */
-#define USER_NAME	"user."		/* user's own names/values */
-STATIC xattr_namespace_t xfs_namespace_array[] = {
-	{ .name= SYSTEM_NAME,	.namelen= sizeof(SYSTEM_NAME)-1,.exists= NULL },
-	{ .name= ROOT_NAME,	.namelen= sizeof(ROOT_NAME)-1,	.exists= NULL },
-	{ .name= USER_NAME,	.namelen= sizeof(USER_NAME)-1,	.exists= NULL },
-	{ .name= NULL }
-};
-xattr_namespace_t *xfs_namespaces = &xfs_namespace_array[0];
-
-#define POSIXACL_ACCESS		"posix_acl_access"
-#define POSIXACL_ACCESS_SIZE	(sizeof(POSIXACL_ACCESS)-1)
-#define POSIXACL_DEFAULT	"posix_acl_default"
-#define POSIXACL_DEFAULT_SIZE	(sizeof(POSIXACL_DEFAULT)-1)
-#define POSIXCAP		"posix_capabilities"
-#define POSIXCAP_SIZE		(sizeof(POSIXCAP)-1)
-#define POSIXMAC		"posix_mac"
-#define POSIXMAC_SIZE		(sizeof(POSIXMAC)-1)
-STATIC xattr_namespace_t sys_namespace_array[] = {
-	{ .name= POSIXACL_ACCESS,
-		.namelen= POSIXACL_ACCESS_SIZE,	 .exists= _ACL_ACCESS_EXISTS },
-	{ .name= POSIXACL_DEFAULT,
-		.namelen= POSIXACL_DEFAULT_SIZE, .exists= _ACL_DEFAULT_EXISTS },
-	{ .name= POSIXCAP,
-		.namelen= POSIXCAP_SIZE,	 .exists= _CAP_EXISTS },
-	{ .name= POSIXMAC,
-		.namelen= POSIXMAC_SIZE,	 .exists= _MAC_EXISTS },
-	{ .name= NULL }
-};
-
-/*
- * Some checks to prevent people abusing EAs to get over quota:
- * - Don't allow modifying user EAs on devices/symlinks;
- * - Don't allow modifying user EAs if sticky bit set;
- */
-STATIC int
-capable_user_xattr(
-	struct inode	*inode)
-{
-	if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) &&
-	    !capable(CAP_SYS_ADMIN))
-		return 0;
-	if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
-	    (current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
-		return 0;
-	return 1;
-}
-
 STATIC int
 linvfs_setxattr(
 	struct dentry	*dentry,
@@ -606,59 +551,27 @@
 	size_t		size,
 	int		flags)
 {
-	struct inode	*inode = dentry->d_inode;
-	vnode_t		*vp = LINVFS_GET_VP(inode);
-	char		*p = (char *)name;
+	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
+	char		*attr = (char *)name;
+	attrnames_t	*namesp;
 	int		xflags = 0;
 	int		error;
 
-	if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name,
-			xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
-		error = -EINVAL;
-		if (flags & XATTR_CREATE)
-			 return error;
-		error = -EOPNOTSUPP;
-		p += xfs_namespaces[SYSTEM_NAMES].namelen;
-		if (strcmp(p, POSIXACL_ACCESS) == 0)
-			error = xfs_acl_vset(vp, (void *) data, size,
-						_ACL_TYPE_ACCESS);
-		else if (strcmp(p, POSIXACL_DEFAULT) == 0)
-			error = xfs_acl_vset(vp, (void *) data, size,
-						_ACL_TYPE_DEFAULT);
-		else if (strcmp(p, POSIXCAP) == 0)
-			error = xfs_cap_vset(vp, (void *) data, size);
-		if (!error)
-			error = vn_revalidate(vp);
+	namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
+	if (!namesp)
+		return -EOPNOTSUPP;
+	attr += namesp->attr_namelen;
+	error = namesp->attr_capable(vp, NULL);
+	if (error)
 		return error;
-	}
-
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		return -EPERM;
 
 	/* Convert Linux syscall to XFS internal ATTR flags */
 	if (flags & XATTR_CREATE)
 		xflags |= ATTR_CREATE;
 	if (flags & XATTR_REPLACE)
 		xflags |= ATTR_REPLACE;
-
-	if (strncmp(name, xfs_namespaces[ROOT_NAMES].name,
-			xfs_namespaces[ROOT_NAMES].namelen) == 0) {
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-		xflags |= ATTR_ROOT;
-		p += xfs_namespaces[ROOT_NAMES].namelen;
-		VOP_ATTR_SET(vp, p, (void *) data, size, xflags, NULL, error);
-		return -error;
-	}
-	if (strncmp(name, xfs_namespaces[USER_NAMES].name,
-			xfs_namespaces[USER_NAMES].namelen) == 0) {
-		if (!capable_user_xattr(inode))
-			return -EPERM;
-		p += xfs_namespaces[USER_NAMES].namelen;
-		VOP_ATTR_SET(vp, p, (void *) data, size, xflags, NULL, error);
-		return -error;
-	}
-	return -EOPNOTSUPP;
+	xflags |= namesp->attr_flag;
+	return namesp->attr_set(vp, attr, (void *)data, size, xflags);
 }
 
 STATIC ssize_t
@@ -668,96 +581,47 @@
 	void		*data,
 	size_t		size)
 {
-	struct inode	*inode = dentry->d_inode;
-	vnode_t		*vp = LINVFS_GET_VP(inode);
-	char		*p = (char *)name;
+	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
+	char		*attr = (char *)name;
+	attrnames_t	*namesp;
 	int		xflags = 0;
 	ssize_t		error;
 
-	if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name,
-			xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
-		error = -EOPNOTSUPP;
-		p += xfs_namespaces[SYSTEM_NAMES].namelen;
-		if (strcmp(p, POSIXACL_ACCESS) == 0)
-			error = xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
-		else if (strcmp(p, POSIXACL_DEFAULT) == 0)
-			error = xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
-		else if (strcmp(p, POSIXCAP) == 0)
-			error = xfs_cap_vget(vp, data, size);
+	namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
+	if (!namesp)
+		return -EOPNOTSUPP;
+	attr += namesp->attr_namelen;
+	error = namesp->attr_capable(vp, NULL);
+	if (error)
 		return error;
-	}
 
 	/* Convert Linux syscall to XFS internal ATTR flags */
 	if (!size) {
 		xflags |= ATTR_KERNOVAL;
 		data = NULL;
 	}
-
-	if (strncmp(name, xfs_namespaces[ROOT_NAMES].name,
-			xfs_namespaces[ROOT_NAMES].namelen) == 0) {
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-		xflags |= ATTR_ROOT;
-		p += xfs_namespaces[ROOT_NAMES].namelen;
-		VOP_ATTR_GET(vp, p, data, (int *)&size, xflags, NULL, error);
-		if (!error)
-			error = -size;
-		return -error;
-	}
-	if (strncmp(name, xfs_namespaces[USER_NAMES].name,
-			xfs_namespaces[USER_NAMES].namelen) == 0) {
-		p += xfs_namespaces[USER_NAMES].namelen;
-		if (!capable_user_xattr(inode))
-			return -EPERM;
-		VOP_ATTR_GET(vp, p, data, (int *)&size, xflags, NULL, error);
-		if (!error)
-			error = -size;
-		return -error;
-	}
-	return -EOPNOTSUPP;
+	xflags |= namesp->attr_flag;
+	return namesp->attr_get(vp, attr, (void *)data, size, xflags);
 }
 
-
 STATIC ssize_t
 linvfs_listxattr(
 	struct dentry		*dentry,
 	char			*data,
 	size_t			size)
 {
-	attrlist_cursor_kern_t	cursor;
-	xattr_namespace_t	*sys;
 	vnode_t			*vp = LINVFS_GET_VP(dentry->d_inode);
-	char			*k = data;
-	int			xflags = ATTR_KERNAMELS;
-	int			result = 0;
-	ssize_t			error;
+	int			error, xflags = ATTR_KERNAMELS;
+	ssize_t			result;
 
 	if (!size)
 		xflags |= ATTR_KERNOVAL;
 	if (capable(CAP_SYS_ADMIN))
 		xflags |= ATTR_KERNFULLS;
 
-	memset(&cursor, 0, sizeof(cursor));
-	VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error);
-	if (error > 0)
-		return -error;
-	result += -error;
-
-	k += result;		/* advance start of our buffer */
-	for (sys = &sys_namespace_array[0]; sys->name != NULL; sys++) {
-		if (sys->exists == NULL || !sys->exists(vp))
-			continue;
-		result += xfs_namespaces[SYSTEM_NAMES].namelen;
-		result += sys->namelen + 1;
-		if (size) {
-			if (result > size)
-				return -ERANGE;
-			strcpy(k, xfs_namespaces[SYSTEM_NAMES].name);
-			k += xfs_namespaces[SYSTEM_NAMES].namelen;
-			strcpy(k, sys->name);
-			k += sys->namelen + 1;
-		}
-	}
+	error = attr_generic_list(vp, data, size, xflags, &result);
+	if (error < 0)
+		return error;
 	return result;
 }
 
@@ -766,51 +630,25 @@
 	struct dentry	*dentry,
 	const char	*name)
 {
-	struct inode	*inode = dentry->d_inode;
-	vnode_t		*vp = LINVFS_GET_VP(inode);
-	char		*p = (char *)name;
+	vnode_t		*vp = LINVFS_GET_VP(dentry->d_inode);
+	char		*attr = (char *)name;
+	attrnames_t	*namesp;
 	int		xflags = 0;
 	int		error;
 
-	if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name,
-			xfs_namespaces[SYSTEM_NAMES].namelen) == 0) {
-		error = -EOPNOTSUPP;
-		p += xfs_namespaces[SYSTEM_NAMES].namelen;
-		if (strcmp(p, POSIXACL_ACCESS) == 0)
-			error = xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
-		else if (strcmp(p, POSIXACL_DEFAULT) == 0)
-			error = xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
-		else if (strcmp(p, POSIXCAP) == 0)
-			error = xfs_cap_vremove(vp);
+	namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
+	if (!namesp)
+		return -EOPNOTSUPP;
+	attr += namesp->attr_namelen;
+	error = namesp->attr_capable(vp, NULL);
+	if (error)
 		return error;
-	}
-
-        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		return -EPERM;
-
-	if (strncmp(name, xfs_namespaces[ROOT_NAMES].name,
-			xfs_namespaces[ROOT_NAMES].namelen) == 0) {
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-		xflags |= ATTR_ROOT;
-		p += xfs_namespaces[ROOT_NAMES].namelen;
-		VOP_ATTR_REMOVE(vp, p, xflags, NULL, error);
-		return -error;
-	}
-	if (strncmp(name, xfs_namespaces[USER_NAMES].name,
-			xfs_namespaces[USER_NAMES].namelen) == 0) {
-		p += xfs_namespaces[USER_NAMES].namelen;
-		if (!capable_user_xattr(inode))
-			return -EPERM;
-		VOP_ATTR_REMOVE(vp, p, xflags, NULL, error);
-		return -error;
-	}
-	return -EOPNOTSUPP;
+	xflags |= namesp->attr_flag;
+	return namesp->attr_remove(vp, attr, xflags);
 }
 
 
-struct inode_operations linvfs_file_inode_operations =
-{
+struct inode_operations linvfs_file_inode_operations = {
 	.permission		= linvfs_permission,
 	.truncate		= linvfs_truncate,
 	.revalidate		= linvfs_revalidate,
@@ -821,8 +659,7 @@
 	.removexattr		= linvfs_removexattr,
 };
 
-struct inode_operations linvfs_dir_inode_operations =
-{
+struct inode_operations linvfs_dir_inode_operations = {
 	.create			= linvfs_create,
 	.lookup			= linvfs_lookup,
 	.link			= linvfs_link,
@@ -841,8 +678,7 @@
 	.removexattr		= linvfs_removexattr,
 };
 
-struct inode_operations linvfs_symlink_inode_operations =
-{
+struct inode_operations linvfs_symlink_inode_operations = {
 	.readlink		= linvfs_readlink,
 	.follow_link		= linvfs_follow_link,
 	.permission		= linvfs_permission,
diff -urN linux-2.4.24-pre1/fs/xfs/linux/xfs_iops.h linux-2.4.24-pre2/fs/xfs/linux/xfs_iops.h
--- linux-2.4.24-pre1/fs/xfs/linux/xfs_iops.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/linux/xfs_iops.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -32,30 +32,6 @@
 #ifndef __XFS_IOPS_H__
 #define __XFS_IOPS_H__
 
-/*
- * Extended system attributes.
- * So far only POSIX ACLs are supported, but this will need to
- * grow in time (capabilities, mandatory access control, etc).
- */
-#define XFS_SYSTEM_NAMESPACE	SYSTEM_POSIXACL
-
-/*
- * Define a table of the namespaces XFS supports
- */
-typedef int (*xattr_exists_t)(vnode_t *);
-
-typedef struct xattr_namespace {
-	char		*name;
-	unsigned int	namelen;
-	xattr_exists_t	exists;
-} xattr_namespace_t;
-
-#define SYSTEM_NAMES	0
-#define ROOT_NAMES	1
-#define USER_NAMES	2
-extern struct xattr_namespace *xfs_namespaces;
-
-
 extern struct inode_operations linvfs_file_inode_operations;
 extern struct inode_operations linvfs_dir_inode_operations;
 extern struct inode_operations linvfs_symlink_inode_operations;
@@ -66,7 +42,7 @@
 
 extern struct address_space_operations linvfs_aops;
 
-extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
+extern int linvfs_get_block(struct inode *, long, struct buffer_head *, int);
 extern void linvfs_unwritten_done(struct buffer_head *, int);
 
 extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *,
diff -urN linux-2.4.24-pre1/fs/xfs/linux/xfs_linux.h linux-2.4.24-pre2/fs/xfs/linux/xfs_linux.h
--- linux-2.4.24-pre1/fs/xfs/linux/xfs_linux.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/linux/xfs_linux.h	2003-12-22 11:34:36.000000000 -0800
@@ -32,6 +32,34 @@
 #ifndef __XFS_LINUX__
 #define __XFS_LINUX__
 
+#include <linux/types.h>
+#include <linux/config.h>
+
+/*
+ * Some types are conditional depending on the target system.
+ * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits.
+ * XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well
+ * as requiring XFS_BIG_BLKNOS to be set.
+ */
+#define XFS_BIG_BLKNOS	0
+#define XFS_BIG_INUMS	0
+
+#include <xfs_types.h>
+#include <xfs_arch.h>
+
+#include <support/kmem.h>
+#include <support/mrlock.h>
+#include <support/qsort.h>
+#include <support/spin.h>
+#include <support/sv.h>
+#include <support/ktrace.h>
+#include <support/mutex.h>
+#include <support/sema.h>
+#include <support/debug.h>
+#include <support/move.h>
+#include <support/uuid.h>
+#include <support/time.h>
+
 #include <linux/mm.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -55,10 +83,6 @@
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
 
-#ifndef HAVE_SECTOR_T
-typedef long		sector_t;	/* offset- or number- of disk blocks */
-#endif
-
 #include <linux/xfs_behavior.h>
 #include <linux/xfs_vfs.h>
 #include <linux/xfs_cred.h>
@@ -97,10 +121,7 @@
 {
 	bh->b_end_io = linvfs_unwritten_done;
 }
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,17)
 BUFFER_FNS(Unwritten, unwritten)
-#endif
 
 #define xfs_refcache_size	xfs_params.refcache_size.val
 #define xfs_refcache_purge_count xfs_params.refcache_purge.val
@@ -220,18 +241,30 @@
 #define howmany(x, y)	(((x)+((y)-1))/(y))
 #define roundup(x, y)	((((x)+((y)-1))/(y))*(y))
 
-/* dump_stack() showed up in 2.4.20, show_stack is arch-specific */
+/*
+ * Juggle IRIX device numbers - still used in ondisk structures
+ */
+#define XFS_DEV_BITSMAJOR	14
+#define XFS_DEV_BITSMINOR	18
+#define XFS_DEV_MAXMAJ		0x1ff
+#define XFS_DEV_MAXMIN		0x3ffff
+#define XFS_DEV_MAJOR(dev)	((int)(((unsigned)(dev)>>XFS_DEV_BITSMINOR) \
+				    & XFS_DEV_MAXMAJ))
+#define XFS_DEV_MINOR(dev)	((int)((dev)&XFS_DEV_MAXMIN))
+#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<<XFS_DEV_BITSMINOR) \
+				    | (minor&XFS_DEV_MAXMIN)))
+
+#define XFS_DEV_TO_KDEVT(dev)	mk_kdev(XFS_DEV_MAJOR(dev),XFS_DEV_MINOR(dev))
+
+
+/* Produce a kernel stack trace */
+
 static inline void xfs_stack_trace(void)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)
 	dump_stack();
-#else
-# if defined(CONFIG_X86) || defined(CONFIG_X86_64)
-	show_stack(0);
-# endif
-#endif
 }
 
+
 /* Move the kernel do_div definition off to one side */
 
 #if defined __i386__
diff -urN linux-2.4.24-pre1/fs/xfs/linux/xfs_lrw.c linux-2.4.24-pre2/fs/xfs/linux/xfs_lrw.c
--- linux-2.4.24-pre1/fs/xfs/linux/xfs_lrw.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/linux/xfs_lrw.c	2003-12-22 11:34:36.000000000 -0800
@@ -321,16 +321,12 @@
 		}
 	}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
 	if (unlikely(ioflags & IO_ISDIRECT)) {
 		ret = do_generic_direct_read(file, buf, size, offset);
 		UPDATE_ATIME(file->f_dentry->d_inode);
 	} else {
 		ret = generic_file_read(file, buf, size, offset);
 	}
-#else
-	ret = generic_file_read(file, buf, size, offset);
-#endif
 
 	if (!(ioflags & IO_ISLOCKED))
 		xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -713,7 +709,6 @@
 	}
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
 	if ((ssize_t) size < 0) {
 		ret = -EINVAL;
 		goto error;
@@ -735,13 +730,6 @@
 					io, buf, size, *offset, ioflags);
 		ret = do_generic_file_write(file, buf, size, offset);
 	}
-#else
-retry:
-	if (ioflags & IO_ISDIRECT) {
-		xfs_inval_cached_pages(vp, io, *offset, 1, 1);
-	}
- 	ret = generic_file_write_nolock(file, buf, size, offset);
-#endif
 
 	if (unlikely(ioflags & IO_INVIS)) {
 		/* generic_file_write updates the mtime/ctime but we need
@@ -770,9 +758,7 @@
 		goto retry;
 	}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
 error:
-#endif
 	if (ret <= 0) {
 		if (iolock)
 			xfs_rwunlock(bdp, locktype);
diff -urN linux-2.4.24-pre1/fs/xfs/linux/xfs_super.c linux-2.4.24-pre2/fs/xfs/linux/xfs_super.c
--- linux-2.4.24-pre1/fs/xfs/linux/xfs_super.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/linux/xfs_super.c	2003-12-22 11:34:36.000000000 -0800
@@ -116,13 +116,7 @@
 	 */
 
 #if BITS_PER_LONG == 32
-# if defined(CONFIG_LBD)
-	ASSERT(sizeof(sector_t) == 8);
-	pagefactor = PAGE_CACHE_SIZE;
-	bitshift = BITS_PER_LONG;
-# else
 	pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
-# endif
 #endif
 
 	return (((__uint64_t)pagefactor) << bitshift) - 1;
diff -urN linux-2.4.24-pre1/fs/xfs/linux/xfs_sysctl.c linux-2.4.24-pre2/fs/xfs/linux/xfs_sysctl.c
--- linux-2.4.24-pre1/fs/xfs/linux/xfs_sysctl.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/linux/xfs_sysctl.c	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -41,7 +41,6 @@
 
 /* Custom proc handlers */
 
-#ifdef HAVE_REFCACHE
 STATIC int
 xfs_refcache_resize_proc_handler(
 	ctl_table	*ctl,
@@ -66,7 +65,6 @@
 
 	return ret;
 }
-#endif
 
 #ifdef CONFIG_PROC_FS
 STATIC int
@@ -96,8 +94,6 @@
 #endif /* CONFIG_PROC_FS */
 
 STATIC ctl_table xfs_table[] = {
-
-#ifdef HAVE_REFCACHE
 	{XFS_REFCACHE_SIZE, "refcache_size", &xfs_params.refcache_size.val,
 	sizeof(int), 0644, NULL, &xfs_refcache_resize_proc_handler,
 	&sysctl_intvec, NULL, 
@@ -108,7 +104,6 @@
 	sizeof(int), 0644, NULL, &proc_dointvec_minmax,
 	&sysctl_intvec, NULL, 
 	&xfs_params.refcache_purge.min, &xfs_params.refcache_size.val},
-#endif
 
 	{XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown.val,
 	sizeof(int), 0644, NULL, &proc_dointvec_minmax,
diff -urN linux-2.4.24-pre1/fs/xfs/pagebuf/page_buf.c linux-2.4.24-pre2/fs/xfs/pagebuf/page_buf.c
--- linux-2.4.24-pre1/fs/xfs/pagebuf/page_buf.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/pagebuf/page_buf.c	2003-12-22 11:34:36.000000000 -0800
@@ -417,9 +417,6 @@
 			page_cache_release(page);
 		}
 	}
-
-	if (pb->pb_pages != pb->pb_page_array)
-		kfree(pb->pb_pages);
 }
 
 /*
@@ -458,20 +455,17 @@
 		if (pb->pb_flags & _PBF_MEM_ALLOCATED) {
 			if (pb->pb_pages) {
 				/* release the pages in the address list */
-				if (pb->pb_pages[0] &&
-				    PageSlab(pb->pb_pages[0])) {
-					/*
-					 * This came from the slab
-					 * allocator free it as such
-					 */
+				if ((pb->pb_pages[0]) &&
+				    (pb->pb_flags & _PBF_MEM_SLAB)) {
 					kfree(pb->pb_addr);
 				} else {
 					_pagebuf_freepages(pb);
 				}
-
+				if (pb->pb_pages != pb->pb_page_array)
+					kfree(pb->pb_pages);
 				pb->pb_pages = NULL;
 			}
-			pb->pb_flags &= ~_PBF_MEM_ALLOCATED;
+			pb->pb_flags &= ~(_PBF_MEM_ALLOCATED|_PBF_MEM_SLAB);
 		}
 	}
 
@@ -847,7 +841,8 @@
 				_PBF_LOCKABLE | \
 				_PBF_ALL_PAGES_MAPPED | \
 				_PBF_ADDR_ALLOCATED | \
-				_PBF_MEM_ALLOCATED;
+				_PBF_MEM_ALLOCATED | \
+				_PBF_MEM_SLAB;
 	PB_TRACE(pb, "got_lock", 0);
 	PB_STATS_INC(pb_get_locked);
 	return (pb);
@@ -927,6 +922,7 @@
 			PB_STATS_INC(pb_get_read);
 			pagebuf_iostart(pb, flags);
 		} else if (flags & PBF_ASYNC) {
+			PB_TRACE(pb, "get_read_async", (unsigned long)flags);
 			/*
 			 * Read ahead call which is already satisfied,
 			 * drop the buffer
@@ -936,12 +932,13 @@
 			pagebuf_rele(pb);
 			return NULL;
 		} else {
+			PB_TRACE(pb, "get_read_done", (unsigned long)flags);
 			/* We do not want read in the flags */
 			pb->pb_flags &= ~PBF_READ;
 		}
+	} else {
+		PB_TRACE(pb, "get_write", (unsigned long)flags);
 	}
-
-	PB_TRACE(pb, "get_done", (unsigned long)flags);
 	return (pb);
 }
 
@@ -1067,8 +1064,8 @@
 	page_buf_t		*pb;
 	size_t			tlen = 0;
 
-	if (len > 0x20000)
-		return(NULL);
+	if (unlikely(len > 0x20000))
+		return NULL;
 
 	pb = pagebuf_allocate(flags);
 	if (!pb)
@@ -1095,7 +1092,7 @@
 		return NULL;
 	}
 	/* otherwise pagebuf_free just ignores it */
-	pb->pb_flags |= _PBF_MEM_ALLOCATED;
+	pb->pb_flags |= (_PBF_MEM_ALLOCATED | _PBF_MEM_SLAB);
 	PB_CLEAR_OWNER(pb);
 	up(&pb->pb_sema);	/* Return unlocked pagebuf */
 
diff -urN linux-2.4.24-pre1/fs/xfs/pagebuf/page_buf.h linux-2.4.24-pre2/fs/xfs/pagebuf/page_buf.h
--- linux-2.4.24-pre1/fs/xfs/pagebuf/page_buf.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/pagebuf/page_buf.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -93,12 +93,14 @@
 	_PBF_PRIVATE_BH = (1 << 17), /* do not use public buffer heads	   */
 	_PBF_ALL_PAGES_MAPPED = (1 << 18), /* all pages in range mapped	   */
 	_PBF_ADDR_ALLOCATED = (1 << 19), /* pb_addr space was allocated	   */
-	_PBF_MEM_ALLOCATED = (1 << 20), /* pb_mem+underlying pages alloc'd */
+	_PBF_MEM_ALLOCATED = (1 << 20), /* underlying pages are allocated  */
+	_PBF_MEM_SLAB = (1 << 21), /* underlying pages are slab allocated  */
 
-	PBF_FORCEIO = (1 << 21),
-	PBF_FLUSH = (1 << 22),	/* flush disk write cache		   */
-	PBF_READ_AHEAD = (1 << 23),
-	PBF_RUN_QUEUES = (1 << 24), /* run block device task queue	   */
+	PBF_FORCEIO = (1 << 22), /* ignore any cache state		   */
+	PBF_FLUSH = (1 << 23),	/* flush disk write cache		   */
+	PBF_READ_AHEAD = (1 << 24), /* asynchronous read-ahead		   */
+	PBF_RUN_QUEUES = (1 << 25), /* run block device task queue	   */
+	PBF_DIRECTIO = (1 << 26), /* used for a direct IO mapping	   */
 
 } page_buf_flags_t;
 
@@ -338,6 +340,7 @@
 # define pagebuf_trace(pb, id, ptr, ra)	do { } while (0)
 #endif
 
+#define pagebuf_target_name(target)	bdevname((target)->pbr_kdev)
 
 /*
  * Kernel version compatibility macros
diff -urN linux-2.4.24-pre1/fs/xfs/quota/xfs_dquot.c linux-2.4.24-pre2/fs/xfs/quota/xfs_dquot.c
--- linux-2.4.24-pre1/fs/xfs/quota/xfs_dquot.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/quota/xfs_dquot.c	2003-12-22 11:34:36.000000000 -0800
@@ -1508,7 +1508,7 @@
 	 */
 	ASSERT(XFS_DQ_IS_ON_FREELIST(dqp));
 
-	dqp->q_mount = NULL;;
+	dqp->q_mount = NULL;
 	dqp->q_hash = NULL;
 	dqp->dq_flags = XFS_DQ_INACTIVE;
 	memset(&dqp->q_core, 0, sizeof(dqp->q_core));
diff -urN linux-2.4.24-pre1/fs/xfs/support/uuid.c linux-2.4.24-pre2/fs/xfs/support/uuid.c
--- linux-2.4.24-pre1/fs/xfs/support/uuid.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/support/uuid.c	2003-12-22 11:34:36.000000000 -0800
@@ -30,9 +30,7 @@
  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  */
 
-#include <linux/types.h>
-#include <xfs_types.h>
-#include <xfs_arch.h>
+#include <xfs.h>
 #include "time.h"
 #include "uuid.h"
 #include "kmem.h"
diff -urN linux-2.4.24-pre1/fs/xfs/xfs.h linux-2.4.24-pre2/fs/xfs/xfs.h
--- linux-2.4.24-pre1/fs/xfs/xfs.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs.h	2003-12-22 11:34:36.000000000 -0800
@@ -32,25 +32,6 @@
 #ifndef __XFS_H__
 #define __XFS_H__
 
-#include <linux/types.h>
-#include <linux/config.h>
-#include <xfs_types.h>
-
-#include <xfs_arch.h>
-
-#include <support/kmem.h>
-#include <support/mrlock.h>
-#include <support/qsort.h>
-#include <support/spin.h>
-#include <support/sv.h>
-#include <support/ktrace.h>
-#include <support/mutex.h>
-#include <support/sema.h>
-#include <support/debug.h>
-#include <support/move.h>
-#include <support/uuid.h>
-#include <support/time.h>
-
 #include <linux/xfs_linux.h>
 
 #include <xfs_fs.h> 
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_acl.h linux-2.4.24-pre2/fs/xfs/xfs_acl.h
--- linux-2.4.24-pre1/fs/xfs/xfs_acl.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_acl.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -102,6 +102,8 @@
 #define xfs_acl_vset(v,p,sz,t)	(-EOPNOTSUPP)
 #define xfs_acl_vget(v,p,sz,t)	(-EOPNOTSUPP)
 #define xfs_acl_vremove(v,t)	(-EOPNOTSUPP)
+#define xfs_acl_vhasacl_access(v)	(0)
+#define xfs_acl_vhasacl_default(v)	(0)
 #define _ACL_DECL(a)		((void)0)
 #define _ACL_ALLOC(a)		(1)	/* successfully allocate nothing */
 #define _ACL_FREE(a)		((void)0)
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_attr.c linux-2.4.24-pre2/fs/xfs/xfs_attr.c
--- linux-2.4.24-pre1/fs/xfs/xfs_attr.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_attr.c	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -63,6 +63,7 @@
 #include "xfs_quota.h"
 #include "xfs_rw.h"
 #include "xfs_trans_space.h"
+#include "xfs_acl.h"
 
 /*
  * xfs_attr.c
@@ -2357,3 +2358,307 @@
 					 (void *)a14, (void *)a15);
 }
 #endif	/* XFS_ATTR_TRACE */
+
+
+/*========================================================================
+ * System (pseudo) namespace attribute interface routines.
+ *========================================================================*/
+
+STATIC int
+posix_acl_access_set(
+	vnode_t	*vp, char *name, void *data, size_t size, int xflags)
+{
+	return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
+}
+
+STATIC int
+posix_acl_access_remove(
+	struct vnode *vp, char *name, int xflags)
+{
+	return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
+}
+
+STATIC int
+posix_acl_access_get(
+	vnode_t *vp, char *name, void *data, size_t size, int xflags)
+{
+	return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
+}
+
+STATIC int
+posix_acl_access_exists(
+	vnode_t *vp)
+{
+	return xfs_acl_vhasacl_access(vp);
+}
+
+STATIC int
+posix_acl_default_set(
+	vnode_t	*vp, char *name, void *data, size_t size, int xflags)
+{
+	return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
+}
+
+STATIC int
+posix_acl_default_get(
+	vnode_t *vp, char *name, void *data, size_t size, int xflags)
+{
+	return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
+}
+
+STATIC int
+posix_acl_default_remove(
+	struct vnode *vp, char *name, int xflags)
+{
+	return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
+}
+
+STATIC int
+posix_acl_default_exists(
+	vnode_t *vp)
+{
+	return xfs_acl_vhasacl_default(vp);
+}
+
+struct attrnames posix_acl_access = {
+	.attr_name	= "posix_acl_access",
+	.attr_namelen	= sizeof("posix_acl_access") - 1,
+	.attr_get	= posix_acl_access_get,
+	.attr_set	= posix_acl_access_set,
+	.attr_remove	= posix_acl_access_remove,
+	.attr_exists	= posix_acl_access_exists,
+};
+
+struct attrnames posix_acl_default = {
+	.attr_name	= "posix_acl_default",
+	.attr_namelen	= sizeof("posix_acl_default") - 1,
+	.attr_get	= posix_acl_default_get,
+	.attr_set	= posix_acl_default_set,
+	.attr_remove	= posix_acl_default_remove,
+	.attr_exists	= posix_acl_default_exists,
+};
+
+struct attrnames *attr_system_names[] =
+	{ &posix_acl_access, &posix_acl_default };
+
+
+/*========================================================================
+ * Namespace-prefix-style attribute name interface routines.
+ *========================================================================*/
+
+STATIC int
+attr_generic_set(
+	struct vnode *vp, char *name, void *data, size_t size, int xflags)
+{
+	int 	error;
+
+	VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error);
+	return -error;
+}
+
+STATIC int
+attr_generic_get(
+	struct vnode *vp, char *name, void *data, size_t size, int xflags)
+{
+	int	error, asize = size;
+
+	VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error);
+	if (!error)
+		return asize;
+	return -error;
+}
+
+STATIC int
+attr_generic_remove(
+	struct vnode *vp, char *name, int xflags)
+{
+	int	error;
+
+	VOP_ATTR_REMOVE(vp, name, xflags, NULL, error);
+	return -error;
+}
+
+STATIC int
+attr_generic_listadd(
+	attrnames_t		*prefix,
+	attrnames_t		*namesp,
+	void			*data,
+	size_t			size,
+	ssize_t			*result)
+{
+	char			*p = data + *result;
+
+	*result += prefix->attr_namelen;
+	*result += namesp->attr_namelen + 1;
+	if (!size)
+		return 0;
+	if (*result > size)
+		return -ERANGE;
+	strcpy(p, prefix->attr_name);
+	p += prefix->attr_namelen;
+	strcpy(p, namesp->attr_name);
+	p += namesp->attr_namelen + 1;
+	return 0;
+}
+
+STATIC int
+attr_system_list(
+	struct vnode		*vp,
+	void			*data,
+	size_t			size,
+	ssize_t			*result)
+{
+	attrnames_t		*namesp;
+	int			i, error = 0;
+
+	for (i = 0; i < ATTR_SYSCOUNT; i++) {
+		namesp = attr_system_names[i];
+		if (!namesp->attr_exists || !namesp->attr_exists(vp))
+			continue;
+		error = attr_generic_listadd(&attr_system, namesp,
+						data, size, result);
+		if (error)
+			break;
+	}
+	return error;
+}
+
+int
+attr_generic_list(
+	struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result)
+{
+	attrlist_cursor_kern_t	cursor = { 0 };
+	int			error;
+
+	VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error);
+	if (error > 0)
+		return -error;
+	*result = -error;
+	return attr_system_list(vp, data, size, result);
+}
+
+attrnames_t *
+attr_lookup_namespace(
+	char			*name,
+	struct attrnames	**names,
+	int			nnames)
+{
+	int			i;
+
+	for (i = 0; i < nnames; i++)
+		if (!strncmp(name, names[i]->attr_name, names[i]->attr_namelen))
+			return names[i];
+	return NULL;
+}
+
+/*
+ * Some checks to prevent people abusing EAs to get over quota:
+ * - Don't allow modifying user EAs on devices/symlinks;
+ * - Don't allow modifying user EAs if sticky bit set;
+ */
+STATIC int
+attr_user_capable(
+	struct vnode	*vp,
+	cred_t		*cred)
+{
+	struct inode	*inode = LINVFS_GET_IP(vp);
+
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
+	if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) &&
+	    !capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
+	    (current_fsuid(cred) != inode->i_uid) && !capable(CAP_FOWNER))
+		return -EPERM;
+	return 0;
+}
+
+STATIC int
+attr_trusted_capable(
+	struct vnode	*vp,
+	cred_t		*cred)
+{
+	struct inode	*inode = LINVFS_GET_IP(vp);
+
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	return 0;
+}
+
+STATIC int
+attr_system_set(
+	struct vnode *vp, char *name, void *data, size_t size, int xflags)
+{
+	attrnames_t	*namesp;
+	int		error;
+
+	if (xflags & ATTR_CREATE)
+		return -EINVAL;
+
+	namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
+	if (!namesp)
+		return -EOPNOTSUPP;
+	error = namesp->attr_set(vp, name, data, size, xflags);
+	if (!error)
+		error = vn_revalidate(vp);
+	return error;
+}
+
+STATIC int
+attr_system_get(
+	struct vnode *vp, char *name, void *data, size_t size, int xflags)
+{
+	attrnames_t	*namesp;
+
+	namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
+	if (!namesp)
+		return -EOPNOTSUPP;
+	return namesp->attr_get(vp, name, data, size, xflags);
+}
+
+STATIC int
+attr_system_remove(
+	struct vnode *vp, char *name, int xflags)
+{
+	attrnames_t	*namesp;
+
+	namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
+	if (!namesp)
+		return -EOPNOTSUPP;
+	return namesp->attr_remove(vp, name, xflags);
+}
+
+struct attrnames attr_system = {
+	.attr_name	= "system.",
+	.attr_namelen	= sizeof("system.") - 1,
+	.attr_flag	= ATTR_SYSTEM,
+	.attr_get	= attr_system_get,
+	.attr_set	= attr_system_set,
+	.attr_remove	= attr_system_remove,
+	.attr_capable	= (attrcapable_t)fs_noerr,
+};
+
+struct attrnames attr_trusted = {
+	.attr_name	= "trusted.",
+	.attr_namelen	= sizeof("trusted.") - 1,
+	.attr_flag	= ATTR_ROOT,
+	.attr_get	= attr_generic_get,
+	.attr_set	= attr_generic_set,
+	.attr_remove	= attr_generic_remove,
+	.attr_capable	= attr_trusted_capable,
+};
+
+struct attrnames attr_user = {
+	.attr_name	= "user.",
+	.attr_namelen	= sizeof("user.") - 1,
+	.attr_get	= attr_generic_get,
+	.attr_set	= attr_generic_set,
+	.attr_remove	= attr_generic_remove,
+	.attr_capable	= attr_user_capable,
+};
+
+struct attrnames *attr_namespaces[] =
+	{ &attr_system, &attr_trusted, &attr_user };
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_attr.h linux-2.4.24-pre2/fs/xfs/xfs_attr.h
--- linux-2.4.24-pre1/fs/xfs/xfs_attr.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_attr.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000, 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -49,9 +49,46 @@
  * External interfaces
  *========================================================================*/
 
-#define ATTR_ROOT	0x0002	/* use attrs in root namespace, not user */
+struct cred;
+struct vnode;
+
+typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int);
+typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int);
+typedef int (*attrremove_t)(struct vnode *, char *, int);
+typedef int (*attrexists_t)(struct vnode *);
+typedef int (*attrcapable_t)(struct vnode *, struct cred *);
+
+typedef struct attrnames {
+	char *		attr_name;
+	unsigned int	attr_namelen;
+	unsigned int	attr_flag;
+	attrget_t	attr_get;
+	attrset_t	attr_set;
+	attrremove_t	attr_remove;
+	attrexists_t	attr_exists;
+	attrcapable_t	attr_capable;
+} attrnames_t;
+
+#define ATTR_NAMECOUNT	3
+extern struct attrnames attr_user;
+extern struct attrnames attr_system;
+extern struct attrnames attr_trusted;
+extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
+
+#define ATTR_SYSCOUNT	2
+extern struct attrnames posix_acl_access;
+extern struct attrnames posix_acl_default;
+extern struct attrnames *attr_system_names[ATTR_SYSCOUNT];
+
+extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
+extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *);
+
+#define ATTR_DONTFOLLOW	0x0001	/* -- unused, from IRIX -- */
+#define ATTR_ROOT	0x0002	/* use attrs in root (trusted) namespace */
+#define ATTR_TRUST	0x0004	/* -- unused, from IRIX -- */
 #define ATTR_CREATE	0x0010	/* pure create: fail if attr already exists */
 #define ATTR_REPLACE	0x0020	/* pure set: fail if attr does not exist */
+#define ATTR_SYSTEM	0x0100	/* use attrs in system (pseudo) namespace */
 #define ATTR_KERNOTIME	0x1000	/* [kernel] don't update inode timestamps */
 #define ATTR_KERNOVAL	0x2000	/* [kernel] get attr size only, not value */
 #define ATTR_KERNAMELS	0x4000	/* [kernel] list attr names (simple list) */
@@ -126,11 +163,8 @@
  * Function prototypes for the kernel.
  *========================================================================*/
 
-struct cred;
-struct vnode;
 struct xfs_inode;
 struct attrlist_cursor_kern;
-struct xfs_ext_attr;
 struct xfs_da_args;
 
 /*
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_attr_leaf.c linux-2.4.24-pre2/fs/xfs/xfs_attr_leaf.c
--- linux-2.4.24-pre1/fs/xfs/xfs_attr_leaf.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_attr_leaf.c	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -444,8 +444,10 @@
 							< context->bufsize) {
 		for (i = 0, sfe = &sf->list[0];
 				i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
-			int ns = (sfe->flags & XFS_ATTR_ROOT)?
-						ROOT_NAMES : USER_NAMES;
+			attrnames_t	*namesp;
+
+			namesp = (sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
+				  &attr_user;
 			if (((context->flags & ATTR_ROOT) != 0) !=
 			    ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
 			    !(context->flags & ATTR_KERNFULLS)) {
@@ -454,11 +456,11 @@
 			}
 			if (context->flags & ATTR_KERNOVAL) {
 				ASSERT(context->flags & ATTR_KERNAMELS);
-				context->count += xfs_namespaces[ns].namelen +
+				context->count += namesp->attr_namelen +
 					INT_GET(sfe->namelen, ARCH_CONVERT) + 1;
 			}
 			else {
-				if (xfs_attr_put_listent(context, ns,
+				if (xfs_attr_put_listent(context, namesp,
 						   (char *)sfe->nameval,
 						   (int)sfe->namelen,
 						   (int)INT_GET(sfe->valuelen,
@@ -544,18 +546,22 @@
 	 * Loop putting entries into the user buffer.
 	 */
 	for ( ; i < nsbuf; i++, sbp++) {
-		int ns = (sbp->flags & XFS_ATTR_ROOT)? ROOT_NAMES:USER_NAMES;
+		attrnames_t	*namesp;
+
+		namesp = (sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
+			  &attr_user;
+
 		if (cursor->hashval != INT_GET(sbp->hash, ARCH_CONVERT)) {
 			cursor->hashval = INT_GET(sbp->hash, ARCH_CONVERT);
 			cursor->offset = 0;
 		}
 		if (context->flags & ATTR_KERNOVAL) {
 			ASSERT(context->flags & ATTR_KERNAMELS);
-			context->count += xfs_namespaces[ns].namelen
-					+ sbp->namelen + 1;
+			context->count += namesp->attr_namelen +
+						sbp->namelen + 1;
 		}
 		else {
-			if (xfs_attr_put_listent(context, ns,
+			if (xfs_attr_put_listent(context, namesp,
 					sbp->name, sbp->namelen,
 					INT_GET(sbp->valuelen, ARCH_CONVERT)))
 				break;
@@ -2270,7 +2276,7 @@
 	retval = 0;
 	for (  ; (i < INT_GET(leaf->hdr.count, ARCH_CONVERT))
 	     && (retval == 0); entry++, i++) {
-		int ns = (entry->flags & XFS_ATTR_ROOT)? ROOT_NAMES:USER_NAMES;
+		attrnames_t	*namesp;
 
 		if (INT_GET(entry->hashval, ARCH_CONVERT) != cursor->hashval) {
 			cursor->hashval = INT_GET(entry->hashval, ARCH_CONVERT);
@@ -2284,14 +2290,17 @@
 		    !(context->flags & ATTR_KERNFULLS))
 			continue;		/* skip non-matching entries */
 
+		namesp = (entry->flags & XFS_ATTR_ROOT) ? &attr_trusted :
+			  &attr_user;
+
 		if (entry->flags & XFS_ATTR_LOCAL) {
 			name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
 			if (context->flags & ATTR_KERNOVAL) {
 				ASSERT(context->flags & ATTR_KERNAMELS);
-				context->count += xfs_namespaces[ns].namelen
-						+ (int)name_loc->namelen + 1;
+				context->count += namesp->attr_namelen +
+						(int)name_loc->namelen + 1;
 			} else {
-				retval = xfs_attr_put_listent(context, ns,
+				retval = xfs_attr_put_listent(context, namesp,
 					(char *)name_loc->nameval,
 					(int)name_loc->namelen,
 					(int)INT_GET(name_loc->valuelen,
@@ -2301,10 +2310,10 @@
 			name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
 			if (context->flags & ATTR_KERNOVAL) {
 				ASSERT(context->flags & ATTR_KERNAMELS);
-				context->count += xfs_namespaces[ns].namelen
-						+ (int)name_rmt->namelen + 1;
+				context->count += namesp->attr_namelen +
+						(int)name_rmt->namelen + 1;
 			} else {
-				retval = xfs_attr_put_listent(context, ns,
+				retval = xfs_attr_put_listent(context, namesp,
 					(char *)name_rmt->name,
 					(int)name_rmt->namelen,
 					(int)INT_GET(name_rmt->valuelen,
@@ -2333,7 +2342,7 @@
 /*ARGSUSED*/
 int
 xfs_attr_put_listent(xfs_attr_list_context_t *context,
-		     int ns, char *name, int namelen, int valuelen)
+		     attrnames_t *namesp, char *name, int namelen, int valuelen)
 {
 	attrlist_ent_t *aep;
 	int arraytop;
@@ -2341,23 +2350,21 @@
 	ASSERT(!(context->flags & ATTR_KERNOVAL));
 	if (context->flags & ATTR_KERNAMELS) {
 		char *offset;
-		xattr_namespace_t *nsp;
 
 		ASSERT(context->count >= 0);
 
-		nsp = &xfs_namespaces[ns];
-		arraytop = context->count + nsp->namelen + namelen+1;
+		arraytop = context->count + namesp->attr_namelen + namelen + 1;
 		if (arraytop > context->firstu) {
 			context->count = -1;	/* insufficient space */
 			return(1);
 		}
 		offset = (char *)context->alist + context->count;
-		strncpy(offset, nsp->name, nsp->namelen);	/* namespace */
-		offset += nsp->namelen;
+		strncpy(offset, namesp->attr_name, namesp->attr_namelen);
+		offset += namesp->attr_namelen;
 		strncpy(offset, name, namelen);			/* real name */
 		offset += namelen;
 		*offset = '\0';
-		context->count += nsp->namelen + namelen + 1;
+		context->count += namesp->attr_namelen + namelen + 1;
 		return(0);
 	}
 
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_attr_leaf.h linux-2.4.24-pre2/fs/xfs/xfs_attr_leaf.h
--- linux-2.4.24-pre1/fs/xfs/xfs_attr_leaf.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_attr_leaf.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000, 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -44,6 +44,7 @@
 
 struct attrlist;
 struct attrlist_cursor_kern;
+struct attrnames;
 struct xfs_dabuf;
 struct xfs_da_args;
 struct xfs_da_state;
@@ -128,7 +129,7 @@
  * on the system call, they are "or"ed together for various operations.
  */
 #define	XFS_ATTR_LOCAL_BIT	0	/* attr is stored locally */
-#define	XFS_ATTR_ROOT_BIT	1	/* limit access to attr to userid 0 */
+#define	XFS_ATTR_ROOT_BIT	1	/* limit access to trusted attrs */
 #define	XFS_ATTR_INCOMPLETE_BIT	7	/* attr in middle of create/delete */
 #define XFS_ATTR_LOCAL		(1 << XFS_ATTR_LOCAL_BIT)
 #define XFS_ATTR_ROOT		(1 << XFS_ATTR_ROOT_BIT)
@@ -299,7 +300,8 @@
 					int *local);
 int	xfs_attr_leaf_entsize(struct xfs_attr_leafblock *leaf, int index);
 int	xfs_attr_put_listent(struct xfs_attr_list_context *context,
-			     int ns, char *name, int namelen, int valuelen);
+			     struct attrnames *, char *name, int namelen,
+			     int valuelen);
 int	xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp);
 
 #endif	/* __XFS_ATTR_LEAF_H__ */
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_buf.h linux-2.4.24-pre2/fs/xfs/xfs_buf.h
--- linux-2.4.24-pre1/fs/xfs/xfs_buf.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_buf.h	2003-12-22 11:34:36.000000000 -0800
@@ -181,7 +181,7 @@
 #define XFS_BUF_SET_VTYPE(bp, type)
 #define XFS_BUF_SET_REF(bp, ref)
 
-#define XFS_BUF_ISPINNED(bp)   pagebuf_ispin(bp)
+#define XFS_BUF_ISPINNED(bp)	pagebuf_ispin(bp)
 
 #define XFS_BUF_VALUSEMA(bp)	pagebuf_lock_value(bp)
 #define XFS_BUF_CPSEMA(bp)	(pagebuf_cond_lock(bp) == 0)
@@ -191,16 +191,10 @@
 
 /* setup the buffer target from a buftarg structure */
 #define XFS_BUF_SET_TARGET(bp, target)	\
-	(bp)->pb_target = (target)
-
+		(bp)->pb_target = (target)
 #define XFS_BUF_TARGET(bp)	((bp)->pb_target)
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#define XFS_BUFTARG_NAME(target)    bdevname((target)->pbr_kdev)
-#else
-#define XFS_BUFTARG_NAME(target) \
-	({ char __b[BDEVNAME_SIZE]; bdevname((target)->pbr_bdev, __b); __b; })
-#endif
+#define XFS_BUFTARG_NAME(target)	\
+		pagebuf_target_name(target)
 
 #define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
 #define XFS_BUF_SET_VTYPE(bp, type)
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_log.c linux-2.4.24-pre2/fs/xfs/xfs_log.c
--- linux-2.4.24-pre1/fs/xfs/xfs_log.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_log.c	2003-12-22 11:34:36.000000000 -0800
@@ -1056,7 +1056,7 @@
 			if (xfs_physmem <= btoc(128*1024*1024)) { 
 				log->l_iclog_bufs = XLOG_MIN_ICLOGS; 
 			} else if (xfs_physmem <= btoc(400*1024*1024)) { 
-				log->l_iclog_bufs = XLOG_MED_ICLOGS;; 
+				log->l_iclog_bufs = XLOG_MED_ICLOGS; 
 			} else {
 				/* 256K with 32K bufs */
 				log->l_iclog_bufs = XLOG_MAX_ICLOGS;
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_rename.c linux-2.4.24-pre2/fs/xfs/xfs_rename.c
--- linux-2.4.24-pre1/fs/xfs/xfs_rename.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_rename.c	2003-12-22 11:34:36.000000000 -0800
@@ -485,7 +485,7 @@
 		error = xfs_droplink(tp, target_ip);
 		if (error) {
 			rename_which_error_return = __LINE__;
-			goto abort_return;;
+			goto abort_return;
 		}
 		target_ip_dropped = 1;
 
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_trans.c linux-2.4.24-pre2/fs/xfs/xfs_trans.c
--- linux-2.4.24-pre1/fs/xfs/xfs_trans.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_trans.c	2003-12-22 11:34:36.000000000 -0800
@@ -142,9 +142,9 @@
 	uint		type)
 {
 	xfs_trans_t	*tp;
+
 	ASSERT(xfs_trans_zone != NULL);
 	tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP);
-	tp->t_dqinfo = NULL;
 
 	/*
 	 * Initialize the transaction structure.
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_types.h linux-2.4.24-pre2/fs/xfs/xfs_types.h
--- linux-2.4.24-pre1/fs/xfs/xfs_types.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_types.h	2003-12-22 11:34:36.000000000 -0800
@@ -75,24 +75,6 @@
 #error BITS_PER_LONG must be 32 or 64
 #endif
 
-/*
- * Some types are conditional depending on the target system.
- * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits.
- * XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well
- * as requiring XFS_BIG_BLKNOS to be set.
- */
-#if defined(CONFIG_LBD) || (defined(HAVE_SECTOR_T) && (BITS_PER_LONG == 64))
-# define XFS_BIG_BLKNOS	1
-# if BITS_PER_LONG == 64
-#  define XFS_BIG_INUMS	1
-# else
-#  define XFS_BIG_INUMS	0
-# endif
-#else
-# define XFS_BIG_BLKNOS	0
-# define XFS_BIG_INUMS	0
-#endif
-
 #endif	/* __KERNEL__ */
 
 typedef __uint32_t	xfs_agblock_t;	/* blockno in alloc. group */
@@ -197,20 +179,4 @@
 	XFS_BTNUM_MAX
 } xfs_btnum_t;
 
-
-/*
- * Juggle IRIX device numbers - still used in ondisk structures
- */
-#define XFS_DEV_BITSMAJOR	14
-#define XFS_DEV_BITSMINOR	18
-#define XFS_DEV_MAXMAJ		0x1ff
-#define XFS_DEV_MAXMIN		0x3ffff
-#define XFS_DEV_MAJOR(dev)	((int)(((unsigned)(dev)>>XFS_DEV_BITSMINOR) \
-				    & XFS_DEV_MAXMAJ))
-#define XFS_DEV_MINOR(dev)	((int)((dev)&XFS_DEV_MAXMIN))
-#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<<XFS_DEV_BITSMINOR) \
-				    | (minor&XFS_DEV_MAXMIN)))
-
-#define XFS_DEV_TO_KDEVT(dev)	mk_kdev(XFS_DEV_MAJOR(dev),XFS_DEV_MINOR(dev))
-
 #endif	/* __XFS_TYPES_H__ */
diff -urN linux-2.4.24-pre1/fs/xfs/xfs_vfsops.c linux-2.4.24-pre2/fs/xfs/xfs_vfsops.c
--- linux-2.4.24-pre1/fs/xfs/xfs_vfsops.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfs_vfsops.c	2003-12-22 11:34:36.000000000 -0800
@@ -772,8 +772,9 @@
 #if XFS_BIG_INUMS
 		if (!mp->m_inoadd)
 #endif
-			statp->f_files =
-			    min_t(sector_t, statp->f_files, mp->m_maxicount);
+			statp->f_files = min_t(typeof(statp->f_files),
+						statp->f_files,
+						mp->m_maxicount);
 	statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
 	XFS_SB_UNLOCK(mp, s);
 
@@ -1782,10 +1783,14 @@
 		char	*str;
 	} xfs_info[] = {
 		/* the few simple ones we can get from the mount struct */
+		{ XFS_MOUNT_WSYNC,		"," MNTOPT_WSYNC },
+		{ XFS_MOUNT_INO64,		"," MNTOPT_INO64 },
 		{ XFS_MOUNT_NOALIGN,		"," MNTOPT_NOALIGN },
+		{ XFS_MOUNT_NOUUID,		"," MNTOPT_NOUUID },
 		{ XFS_MOUNT_NORECOVERY,		"," MNTOPT_NORECOVERY },
 		{ XFS_MOUNT_OSYNCISOSYNC,	"," MNTOPT_OSYNCISOSYNC },
-		{ XFS_MOUNT_NOUUID,		"," MNTOPT_NOUUID },
+		{ XFS_MOUNT_NOLOGFLUSH,		"," MNTOPT_NOLOGFLUSH },
+		{ XFS_MOUNT_IDELETE,		"," MNTOPT_NOIKEEP },
 		{ 0, NULL }
 	};
 	struct proc_xfs_info	*xfs_infop;
@@ -1821,6 +1826,9 @@
 		seq_printf(m, "," MNTOPT_SWIDTH "=%d",
 				(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
 
+	if (!(mp->m_flags & XFS_MOUNT_32BITINOOPT))
+		seq_printf(m, "," MNTOPT_64BITINODE);
+	
 	return 0;
 }
 
diff -urN linux-2.4.24-pre1/fs/xfs/xfsidbg.c linux-2.4.24-pre2/fs/xfs/xfsidbg.c
--- linux-2.4.24-pre1/fs/xfs/xfsidbg.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/fs/xfs/xfsidbg.c	2003-12-22 11:34:36.000000000 -0800
@@ -3177,13 +3177,13 @@
 	static char *attr_arg_flags[] = {
 		"DONTFOLLOW",	/* 0x0001 */
 		"ROOT",		/* 0x0002 */
-		"?",		/* 0x0004 */
-		"REPLACE",	/* 0x0008 */
+		"TRUSTED",	/* 0x0004 */
+		"?",		/* 0x0008 */
 		"CREATE",	/* 0x0010 */
-		"?",		/* 0x0020 */
+		"REPLACE",	/* 0x0020 */
 		"?",		/* 0x0040 */
 		"?",		/* 0x0080 */
-		"?",		/* 0x0100 */
+		"SYSTEM",	/* 0x0100 */
 		"?",		/* 0x0200 */
 		"?",		/* 0x0400 */
 		"?",		/* 0x0800 */
diff -urN linux-2.4.24-pre1/include/acpi/acconfig.h linux-2.4.24-pre2/include/acpi/acconfig.h
--- linux-2.4.24-pre1/include/acpi/acconfig.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.24-pre2/include/acpi/acconfig.h	2003-12-22 11:34:36.000000000 -0800
@@ -64,7 +64,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20031002
+#define ACPI_CA_VERSION                 0x20031203
 
 /* Maximum objects in the various object caches */
 
diff -urN linux-2.4.24-pre1/include/acpi/acevents.h linux-2.4.24-pre2/include/acpi/acevents.h
--- linux-2.4.24-pre1/include/acpi/acevents.h	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.24-pre2/include/acpi/acevents.h	2003-12-22 11:34:36.000000000 -0800
@@ -182,6 +182,17 @@
 	union acpi_operand_object      *region_obj,
 	u8                              acpi_ns_is_locked);
 
+acpi_status
+acpi_ev_execute_reg_method (
+	union acpi_operand_object      *region_obj,
+	u32                             function);
+
+acpi_status
+acpi_ev_reg_run (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
 
 /*
  * Evregini - Region initialization and setup
diff -urN linux-2.4.24-pre1/include/acpi/acglobal.h linux-2.4.24-pre2/include/acpi/acglobal.h
--- linux-2.4.24-pre1/include/acpi/acglobal.h	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.24-pre2/include/acpi/acglobal.h	2003-12-22 11:34:36.000000000 -0800
@@ -106,6 +106,9 @@
 ACPI_EXTERN u8                                  acpi_gbl_integer_bit_width;
 ACPI_EXTERN u8                                  acpi_gbl_integer_byte_width;
 ACPI_EXTERN u8                                  acpi_gbl_integer_nybble_width;
+
+/* Keep local copies of these FADT-based registers */
+
 ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1a_enable;
 ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1b_enable;
 
diff -urN linux-2.4.24-pre1/include/acpi/acmacros.h linux-2.4.24-pre2/include/acpi/acmacros.h
--- linux-2.4.24-pre1/include/acpi/acmacros.h	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.24-pre2/include/acpi/acmacros.h	2003-12-22 11:34:36.000000000 -0800
@@ -48,7 +48,6 @@
 /*
  * Data manipulation macros
  */
-
 #define ACPI_LOWORD(l)                  ((u16)(u32)(l))
 #define ACPI_HIWORD(l)                  ((u16)((((u32)(l)) >> 16) & 0xFFFF))
 #define ACPI_LOBYTE(l)                  ((u8)(u16)(l))
@@ -94,10 +93,18 @@
 #endif
 #endif
 
- /*
-  * Extract a byte of data using a pointer.  Any more than a byte and we
-  * get into potential aligment issues -- see the STORE macros below
-  */
+/*
+ * printf() format helpers
+ */
+
+/* Split 64-bit integer into two 32-bit values. use with %8,8_x%8.8X */
+
+#define ACPI_FORMAT_UINT64(i)           ACPI_HIDWORD(i),ACPI_LODWORD(i)
+
+/*
+ * Extract a byte of data using a pointer.  Any more than a byte and we
+ * get into potential aligment issues -- see the STORE macros below
+ */
 #define ACPI_GET8(addr)                 (*(u8*)(addr))
 
 /* Pointer arithmetic */
@@ -129,7 +136,6 @@
  * If the hardware supports the transfer of unaligned data, just do the store.
  * Otherwise, we have to move one byte at a time.
  */
-
 #ifdef ACPI_BIG_ENDIAN
 /*
  * Macros for big-endian machines
@@ -299,7 +305,6 @@
 /*
  * Fast power-of-two math macros for non-optimized compilers
  */
-
 #define _ACPI_DIV(value,power_of2)      ((u32) ((value) >> (power_of2)))
 #define _ACPI_MUL(value,power_of2)      ((u32) ((value) << (power_of2)))
 #define _ACPI_MOD(value,divisor)        ((u32) ((value) & ((divisor) -1)))
@@ -443,7 +448,6 @@
 /*
  * Reporting macros that are never compiled out
  */
-
 #define ACPI_PARAM_LIST(pl)                 pl
 
 /*
@@ -451,7 +455,6 @@
  * _THIS_MODULE gets compiled out when ACPI_DEBUG_OUTPUT isn't defined, only
  * use it in debug mode.
  */
-
 #ifdef ACPI_DEBUG_OUTPUT
 
 #define ACPI_REPORT_INFO(fp)                {acpi_ut_report_info(_THIS_MODULE,__LINE__,_COMPONENT); \
@@ -490,7 +493,6 @@
 /*
  * Debug macros that are conditionally compiled
  */
-
 #ifdef ACPI_DEBUG_OUTPUT
 
 #define ACPI_MODULE_NAME(name)               static char ACPI_UNUSED_VAR *_THIS_MODULE = name;
@@ -500,7 +502,6 @@
  * The first parameter should be the procedure name as a quoted string.  This is declared
  * as a local string ("_proc_name) so that it can be also used by the function exit macros below.
  */
-
 #define ACPI_FUNCTION_NAME(a)               struct acpi_debug_print_info _dbg; \
 												_dbg.component_id = _COMPONENT; \
 												_dbg.proc_name   = a; \
@@ -562,7 +563,6 @@
 /*
  * Generate INT3 on ACPI_ERROR (Debug only!)
  */
-
 #define ACPI_ERROR_BREAK
 #ifdef  ACPI_ERROR_BREAK
 #define ACPI_BREAK_ON_ERROR(lvl)        if ((lvl)&ACPI_ERROR) \
@@ -577,7 +577,6 @@
  *    1) Debug print for the current component is enabled
  *    2) Debug error level or trace level for the print statement is enabled
  */
-
 #define ACPI_DEBUG_PRINT(pl)            acpi_ut_debug_print ACPI_PARAM_LIST(pl)
 #define ACPI_DEBUG_PRINT_RAW(pl)        acpi_ut_debug_print_raw ACPI_PARAM_LIST(pl)
 
@@ -587,7 +586,6 @@
  * This is the non-debug case -- make everything go away,
  * leaving no executable debug code!
  */
-
 #define ACPI_MODULE_NAME(name)
 #define _THIS_MODULE ""
 
@@ -662,7 +660,6 @@
 /*
  * Memory allocation tracking (DEBUG ONLY)
  */
-
 #ifndef ACPI_DBG_TRACK_ALLOCATIONS
 
 /* Memory allocation */
diff -urN linux-2.4.24-pre1/include/acpi/acobject.h linux-2.4.24-pre2/include/acpi/acobject.h
--- linux-2.4.24-pre1/include/acpi/acobject.h	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.24-pre2/include/acpi/acobject.h	2003-12-22 11:34:36.000000000 -0800
@@ -114,7 +114,7 @@
 #define ACPI_COMMON_NOTIFY_INFO \
 	union acpi_operand_object               *system_notify;     /* Handler for system notifies */\
 	union acpi_operand_object               *device_notify;     /* Handler for driver notifies */\
-	union acpi_operand_object               *address_space;     /* Handler for Address space */
+	union acpi_operand_object               *handler;           /* Handler for Address space */
 
 
 /******************************************************************************
@@ -214,7 +214,7 @@
 	ACPI_OBJECT_COMMON_HEADER
 
 	u8                                      space_id;
-	union acpi_operand_object               *address_space;     /* Handler for region access */
+	union acpi_operand_object               *handler;           /* Handler for region access */
 	struct acpi_namespace_node              *node;              /* containing object */
 	union acpi_operand_object               *next;
 	u32                                     length;
@@ -464,21 +464,22 @@
 
 /* Object descriptor types */
 
-#define ACPI_DESC_TYPE_CACHED           0x11        /* Used only when object is cached */
-#define ACPI_DESC_TYPE_STATE            0x20
-#define ACPI_DESC_TYPE_STATE_UPDATE     0x21
-#define ACPI_DESC_TYPE_STATE_PACKAGE    0x22
-#define ACPI_DESC_TYPE_STATE_CONTROL    0x23
-#define ACPI_DESC_TYPE_STATE_RPSCOPE    0x24
-#define ACPI_DESC_TYPE_STATE_PSCOPE     0x25
-#define ACPI_DESC_TYPE_STATE_WSCOPE     0x26
-#define ACPI_DESC_TYPE_STATE_RESULT     0x27
-#define ACPI_DESC_TYPE_STATE_NOTIFY     0x28
-#define ACPI_DESC_TYPE_STATE_THREAD     0x29
-#define ACPI_DESC_TYPE_WALK             0x44
-#define ACPI_DESC_TYPE_PARSER           0x66
-#define ACPI_DESC_TYPE_OPERAND          0x88
-#define ACPI_DESC_TYPE_NAMED            0xAA
+#define ACPI_DESC_TYPE_CACHED           0x01        /* Used only when object is cached */
+#define ACPI_DESC_TYPE_STATE            0x02
+#define ACPI_DESC_TYPE_STATE_UPDATE     0x03
+#define ACPI_DESC_TYPE_STATE_PACKAGE    0x04
+#define ACPI_DESC_TYPE_STATE_CONTROL    0x05
+#define ACPI_DESC_TYPE_STATE_RPSCOPE    0x06
+#define ACPI_DESC_TYPE_STATE_PSCOPE     0x07
+#define ACPI_DESC_TYPE_STATE_WSCOPE     0x08
+#define ACPI_DESC_TYPE_STATE_RESULT     0x09
+#define ACPI_DESC_TYPE_STATE_NOTIFY     0x0A
+#define ACPI_DESC_TYPE_STATE_THREAD     0x0B
+#define ACPI_DESC_TYPE_WALK             0x0C
+#define ACPI_DESC_TYPE_PARSER           0x0D
+#define ACPI_DESC_TYPE_OPERAND          0x0E
+#define ACPI_DESC_TYPE_NAMED            0x0F
+#define ACPI_DESC_TYPE_MAX              0x0F
 
 
 union acpi_descriptor
diff -urN linux-2.4.24-pre1/include/acpi/acpi_drivers.h linux-2.4.24-pre2/include/acpi/acpi_drivers.h
--- linux-2.4.24-pre1/include/acpi/acpi_drivers.h	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.24-pre2/include/acpi/acpi_drivers.h	2003-12-22 11:34:36.000000000 -0800
@@ -162,7 +162,6 @@
 
 int acpi_pci_root_init (void);
 void acpi_pci_root_exit (void);
-void acpi_pci_get_translations (struct acpi_pci_id* id, u64* mem_tra, u64* io_tra);
 
 /* ACPI PCI Interrupt Link (pci_link.c) */
 
diff -urN linux-2.4.24-pre1/include/acpi/acutils.h linux-2.4.24-pre2/include/acpi/acutils.h
--- linux-2.4.24-pre1/include/acpi/acutils.h	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.24-pre2/include/acpi/acutils.h	2003-12-22 11:34:36.000000000 -0800
@@ -125,6 +125,14 @@
 	acpi_object_type                type);
 
 char *
+acpi_ut_get_node_name (
+	void                            *object);
+
+char *
+acpi_ut_get_descriptor_name (
+	void                            *object);
+
+char *
 acpi_ut_get_object_type_name (
 	union acpi_operand_object       *obj_desc);
 
diff -urN linux-2.4.24-pre1/include/asm-i386/edd.h linux-2.4.24-pre2/include/asm-i386/edd.h
--- linux-2.4.24-pre1/include/asm-i386/edd.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-i386/edd.h	2003-12-22 11:34:36.000000000 -0800
@@ -43,7 +43,7 @@
 
 #define READ_SECTORS 0x02
 #define MBR_SIG_OFFSET 0x1B8
-#define DISK80_SIG_BUFFER 0x228
+#define DISK80_SIG_BUFFER 0x2cc
 
 #ifndef __ASSEMBLY__
 
diff -urN linux-2.4.24-pre1/include/asm-mips/bootinfo.h linux-2.4.24-pre2/include/asm-mips/bootinfo.h
--- linux-2.4.24-pre1/include/asm-mips/bootinfo.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/bootinfo.h	2003-12-22 11:34:36.000000000 -0800
@@ -36,6 +36,7 @@
 #define MACH_GROUP_NEC_VR41XX  19 /* NEC Vr41xx based boards/gadgets        */
 #define MACH_GROUP_HP_LJ       20 /* Hewlett Packard LaserJet               */
 #define MACH_GROUP_LASAT       21
+#define MACH_GROUP_TITAN       22 /* PMC-Sierra Titan 			    */
 
 /*
  * Valid machtype values for group unknown (low order halfword of mips_machtype)
@@ -175,9 +176,6 @@
 #define MACH_DB1000		3       /* Au1000-based eval board */
 #define MACH_DB1100		4       /* Au1100-based eval board */
 #define MACH_DB1500		5       /* Au1500-based eval board */
-#define MACH_XXS1500		6       /* Au1500-based eval board */
-#define MACH_MTX1		7	/* 4G MTX-1 Au1500-based board */
-#define MACH_CSB250		8	/* Cogent Au1500 */
 
 /*
  * Valid machtype for group NEC_VR41XX
@@ -191,6 +189,11 @@
 #define MACH_TANBAC_TB0226	6	/* TANBAC TB0226 (MBASE) */
 #define MACH_TANBAC_TB0229	7	/* TANBAC TB0229 (VR4131DIMM) */
 
+/*
+ * Valid machtype for group TITAN
+ */
+#define	MACH_TITAN_YOSEMITE	1 	/* PMC-Sierra Yosemite */
+
 #define CL_SIZE			(256)
 
 const char *get_system_type(void);
diff -urN linux-2.4.24-pre1/include/asm-mips/cpu.h linux-2.4.24-pre2/include/asm-mips/cpu.h
--- linux-2.4.24-pre1/include/asm-mips/cpu.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/cpu.h	2003-12-22 11:34:36.000000000 -0800
@@ -208,5 +208,6 @@
 #define MIPS_CPU_NOFPUEX	0x00004000 /* no FPU exception */
 #define MIPS_CPU_LLSC		0x00008000 /* CPU has ll/sc instructions */
 #define MIPS_CPU_SUBSET_CACHES	0x00010000 /* P-cache subset enforced */
+#define MIPS_CPU_PREFETCH	0x00020000 /* CPU has usable prefetch */
 
 #endif /* _ASM_CPU_H */
diff -urN linux-2.4.24-pre1/include/asm-mips/page.h linux-2.4.24-pre2/include/asm-mips/page.h
--- linux-2.4.24-pre1/include/asm-mips/page.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/page.h	2003-12-22 11:34:36.000000000 -0800
@@ -41,11 +41,8 @@
 
 #define PAGE_BUG(page) do {  BUG(); } while (0)
 
-extern void (*_clear_page)(void * page);
-extern void (*_copy_page)(void * to, void * from);
-
-#define clear_page(page)	_clear_page(page)
-#define copy_page(to, from)	_copy_page(to, from)
+extern void clear_page(void * page);
+extern void copy_page(void * to, void * from);
 
 extern unsigned long shm_align_mask;
 
diff -urN linux-2.4.24-pre1/include/asm-mips/prefetch.h linux-2.4.24-pre2/include/asm-mips/prefetch.h
--- linux-2.4.24-pre1/include/asm-mips/prefetch.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/prefetch.h	2003-12-22 11:34:36.000000000 -0800
@@ -0,0 +1,43 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#ifndef __ASM_PREFETCH_H
+#define __ASM_PREFETCH_H
+
+/*
+ * R5000 and RM5200 implements pref and prefx instructions but they're nops, so
+ * rather than wasting time we pretend these processors don't support
+ * prefetching at all.
+ *
+ * R5432 implements Load, Store, LoadStreamed, StoreStreamed, LoadRetained,
+ * StoreRetained and WriteBackInvalidate but not Pref_PrepareForStore.
+ *
+ * Hell (and the book on my shelf I can't open ...) know what the R8000 does.
+ *
+ * RM7000 version 1.0 interprets all hints as Pref_Load; version 2.0 implements
+ * Pref_PrepareForStore also.
+ *
+ * RM9000 is MIPS IV but implements prefetching like MIPS32/MIPS64;
+ * it's Pref_WriteBackInvalidate is a nop.
+ *
+ * VR7701 only implements the Load prefetch.
+ *
+ * Finally MIPS32 and MIPS64 implement all of the following hints.
+ */
+
+#define Pref_Load			0
+#define Pref_Store			1
+						/* 2 and 3 are reserved */
+#define Pref_LoadStreamed		4
+#define Pref_StoreStreamed		5
+#define Pref_LoadRetained		6
+#define Pref_StoreRetained		7
+						/* 8 ... 24 are reserved */
+#define Pref_WriteBackInvalidate	25
+#define Pref_PrepareForStore		30
+
+#endif /* __ASM_PREFETCH_H */
diff -urN linux-2.4.24-pre1/include/asm-mips/processor.h linux-2.4.24-pre2/include/asm-mips/processor.h
--- linux-2.4.24-pre1/include/asm-mips/processor.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/processor.h	2003-12-22 11:34:36.000000000 -0800
@@ -86,6 +86,7 @@
 #define cpu_has_divec		(cpu_data[0].options & MIPS_CPU_DIVEC)
 #define cpu_has_vce		(cpu_data[0].options & MIPS_CPU_VCE)
 #define cpu_has_cache_cdex	(cpu_data[0].options & MIPS_CPU_CACHE_CDEX)
+#define cpu_has_prefetch	(cpu_data[0].options & MIPS_CPU_PREFETCH)
 #define cpu_has_mcheck		(cpu_data[0].options & MIPS_CPU_MCHECK)
 #define cpu_has_ejtag		(cpu_data[0].options & MIPS_CPU_EJTAG)
 #define cpu_has_nofpuex		(cpu_data[0].options & MIPS_CPU_NOFPUEX)
@@ -94,8 +95,13 @@
 #define cpu_has_dc_aliases	(cpu_data[0].dcache.flags & MIPS_CACHE_ALIASES)
 #define cpu_has_ic_fills_f_dc	(cpu_data[0].dcache.flags & MIPS_CACHE_IC_F_DC)
 #define cpu_has_64bits		(cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
+#define cpu_has_64bit_addresses	0
 #define cpu_has_subset_pcaches	(cpu_data[0].options & MIPS_CPU_SUBSET_CACHES)
 
+#define cpu_dcache_line_size()	current_cpu_data.dcache.linesz
+#define cpu_icache_line_size()	current_cpu_data.icache.linesz
+#define cpu_scache_line_size()	current_cpu_data.scache.linesz
+
 extern struct cpuinfo_mips cpu_data[];
 #define current_cpu_data cpu_data[smp_processor_id()]
 
diff -urN linux-2.4.24-pre1/include/asm-mips/serial.h linux-2.4.24-pre2/include/asm-mips/serial.h
--- linux-2.4.24-pre1/include/asm-mips/serial.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/serial.h	2003-12-22 11:34:36.000000000 -0800
@@ -6,6 +6,9 @@
  * Copyright (C) 1999 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
+#ifndef _ASM_SERIAL_H
+#define _ASM_SERIAL_H
+
 #include <linux/config.h>
 #include <asm/jazz.h>
 
@@ -338,34 +341,93 @@
 #define MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS
 #endif
 
+#ifdef CONFIG_TITAN_SERIAL
+/* 16552 20 MHz crystal */
+#define TITAN_SERIAL_BASE_BAUD	( 20000000 / 16 )
+#define	TITAN_SERIAL_IRQ	XXX
+#define	TITAN_SERIAL_BASE	0xffffffff
+
+#define	_TITAN_SERIAL_INIT(int, base)					\
+	{ baud_base: TITAN_SERIAL_BASE_BAUD, irq: int,			\
+	  flags: STD_COM_FLAGS,	iomem_base: (u8 *) base,		\
+	  iomem_reg_shift: 2, io_type: SERIAL_IO_MEM			\
+	}
+
+#define TITAN_SERIAL_PORT_DEFNS						\
+	_TITAN_SERIAL_INIT(TITAN_SERIAL_IRQ, TITAN_SERIAL_BASE)
+#else
+#define TITAN_SERIAL_PORT_DEFNS
+#endif
+
+#ifdef CONFIG_SGI_IP27
+
+/*
+ * Note about serial ports and consoles:
+ * For console output, everyone uses the IOC3 UARTA (offset 0x178)
+ * connected to the master node (look in ip27_setup_console() and
+ * ip27prom_console_write()).
+ *
+ * For serial (/dev/ttyS0 etc), we can not have hardcoded serial port
+ * addresses on a partitioned machine. Since we currently use the ioc3
+ * serial ports, we use dynamic serial port discovery that the serial.c
+ * driver uses for pci/pnp ports (there is an entry for the SGI ioc3
+ * boards in pci_boards[]). Unfortunately, UARTA's pio address is greater
+ * than UARTB's, although UARTA on o200s has traditionally been known as
+ * port 0. So, we just use one serial port from each ioc3 (since the
+ * serial driver adds addresses to get to higher ports).
+ *
+ * The first one to do a register_console becomes the preferred console
+ * (if there is no kernel command line console= directive). /dev/console
+ * (ie 5, 1) is then "aliased" into the device number returned by the
+ * "device" routine referred to in this console structure
+ * (ip27prom_console_dev).
+ *
+ * Also look in ip27-pci.c:pci_fixuop_ioc3() for some comments on working
+ * around ioc3 oddities in this respect.
+ *
+ * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
+ * (IOC3_BAUD = (22000000 / (3*16)))
+ *
+ * At the moment this is only a skeleton definition as we register all serials
+ * at runtime.
+ */
+
+#define IP27_SERIAL_PORT_DEFNS
+#else
+#define IP27_SERIAL_PORT_DEFNS
+#endif /* CONFIG_SGI_IP27 */
+
 #ifdef CONFIG_DDB5477
 #include <asm/ddb5xxx/ddb5477.h>
-#define DDB5477_SERIAL_PORT_DEFNS                                       \
-        { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART0, 		\
-	  .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04200, 	\
+#define DDB5477_SERIAL_PORT_DEFNS					 \
+	{  .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART0,		\
+	  .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04200,	\
 	  .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM},		\
-        { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART1, 		\
-	  .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04240, 	\
+	{  .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART1,		\
+	  .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04240,	\
 	  .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM},
 #else
 #define DDB5477_SERIAL_PORT_DEFNS
 #endif
 
 #define SERIAL_PORT_DFNS			\
-	IVR_SERIAL_PORT_DEFNS           	\
-	ITE_SERIAL_PORT_DEFNS           	\
 	ATLAS_SERIAL_PORT_DEFNS			\
-	SEAD_SERIAL_PORT_DEFNS			\
+	AU1000_SERIAL_PORT_DEFNS		\
 	COBALT_SERIAL_PORT_DEFNS		\
+	DDB5477_SERIAL_PORT_DEFNS		\
 	EV96100_SERIAL_PORT_DEFNS		\
-	JAZZ_SERIAL_PORT_DEFNS			\
-	STD_SERIAL_PORT_DEFNS			\
 	EXTRA_SERIAL_PORT_DEFNS			\
 	HUB6_SERIAL_PORT_DFNS			\
+	ITE_SERIAL_PORT_DEFNS           	\
+	IVR_SERIAL_PORT_DEFNS           	\
+	JAZZ_SERIAL_PORT_DEFNS			\
 	MOMENCO_OCELOT_SERIAL_PORT_DEFNS	\
 	MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS	\
 	MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS	\
 	MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS	\
-	AU1000_SERIAL_PORT_DEFNS		\
-	TXX927_SERIAL_PORT_DEFNS        	\
-	DDB5477_SERIAL_PORT_DEFNS
+	SEAD_SERIAL_PORT_DEFNS			\
+	STD_SERIAL_PORT_DEFNS			\
+	TITAN_SERIAL_PORT_DEFNS			\
+	TXX927_SERIAL_PORT_DEFNS
+
+#endif /* _ASM_SERIAL_H */
diff -urN linux-2.4.24-pre1/include/asm-mips/sgi/ioc.h linux-2.4.24-pre2/include/asm-mips/sgi/ioc.h
--- linux-2.4.24-pre1/include/asm-mips/sgi/ioc.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-mips/sgi/ioc.h	2003-12-22 11:34:36.000000000 -0800
@@ -14,48 +14,13 @@
 #define _SGI_IOC_H
 
 #include <linux/types.h>
+#include <asm/sgi/pi1.h>
 
 /* 
  * All registers are 8-bit wide alligned on 32-bit boundary. Bad things
  * happen if you try word access them. You have been warned.
  */
 
-struct sgioc_pport_regs {
-	u8 _data[3];
-	volatile u8 data;
-	u8 _ctrl[3];
-	volatile u8 ctrl;
-#define SGIOC_PCTRL_STROBE	0x01
-#define SGIOC_PCTRL_AFD		0x02
-#define SGIOC_PCTRL_INIT	0x04
-#define SGIOC_PCTRL_SLIN	0x08
-#define SGIOC_PCTRL_DIRECTION	0x20
-#define SGIOC_PCTRL_SEL		0x40
-	u8 _status[3];
-	volatile u8 status;
-#define SGIOC_PSTAT_DEVID	0x03
-#define SGIOC_PSTAT_NOINK	0x04
-#define SGIOC_PSTAT_ERROR	0x08
-#define SGIOC_PSTAT_ONLINE	0x10
-#define SGIOC_PSTAT_PE		0x20
-#define SGIOC_PSTAT_ACK		0x40
-#define SGIOC_PSTAT_BUSY	0x80
-	u8 _dmactrl[3];
-	volatile u8 dmactrl;
-	u8 _intrstat[3];
-	volatile u8 intrstat;
-	u8 _intrmask[3];
-	volatile u8 intrmask;
-	u8 _timer1[3];
-	volatile u8 timer1;
-	u8 _timer2[3];
-	volatile u8 timer2;
-	u8 _timer3[3];
-	volatile u8 timer3;
-	u8 _timer4[3];
-	volatile u8 timer4;
-};
-
 struct sgioc_uart_regs {
 	u8 _ctrl1[3];
 	volatile u8 ctrl1;
@@ -153,7 +118,7 @@
 extern u8 sgi_ioc_reset, sgi_ioc_write;
 
 struct sgioc_regs {
-	struct sgioc_pport_regs pport;
+	struct pi1_regs pport;
 	u32 _unused0[2];
 	struct sgioc_uart_regs serport;
 	struct sgioc_keyb_regs kbdmouse;
diff -urN linux-2.4.24-pre1/include/asm-mips/sgi/pi1.h linux-2.4.24-pre2/include/asm-mips/sgi/pi1.h
--- linux-2.4.24-pre1/include/asm-mips/sgi/pi1.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/sgi/pi1.h	2003-12-22 11:34:36.000000000 -0800
@@ -0,0 +1,71 @@
+/*
+ * pi1.h: Definitions for SGI PI1 parallel port
+ */
+
+#ifndef _SGI_PI1_H
+#define _SGI_PI1_H
+
+struct pi1_regs {
+	u8 _data[3];
+	volatile u8 data;
+	u8 _ctrl[3];
+	volatile u8 ctrl;
+#define PI1_CTRL_STROBE_N	0x01
+#define PI1_CTRL_AFD_N		0x02
+#define PI1_CTRL_INIT_N		0x04
+#define PI1_CTRL_SLIN_N		0x08
+#define PI1_CTRL_IRQ_ENA	0x10
+#define PI1_CTRL_DIR		0x20
+#define PI1_CTRL_SEL		0x40
+	u8 _status[3];
+	volatile u8 status;
+#define PI1_STAT_DEVID		0x03	/* bits 0-1 */
+#define PI1_STAT_NOINK		0x04	/* SGI MODE only */
+#define PI1_STAT_ERROR		0x08
+#define PI1_STAT_ONLINE		0x10
+#define PI1_STAT_PE		0x20
+#define PI1_STAT_ACK		0x40
+#define PI1_STAT_BUSY		0x80
+	u8 _dmactrl[3];
+	volatile u8 dmactrl;
+#define PI1_DMACTRL_FIFO_EMPTY	0x01    /* fifo empty R/O */
+#define PI1_DMACTRL_ABORT	0x02    /* reset DMA and internal fifo W/O */
+#define PI1_DMACTRL_STDMODE	0x00    /* bits 2-3 */
+#define PI1_DMACTRL_SGIMODE	0x04    /* bits 2-3 */
+#define PI1_DMACTRL_RICOHMODE	0x08    /* bits 2-3 */
+#define PI1_DMACTRL_HPMODE	0x0c    /* bits 2-3 */
+#define PI1_DMACTRL_BLKMODE	0x10    /* block mode */
+#define PI1_DMACTRL_FIFO_CLEAR	0x20    /* clear fifo W/O */
+#define PI1_DMACTRL_READ	0x40    /* read */
+#define PI1_DMACTRL_RUN		0x80    /* pedal to the metal */
+	u8 _intstat[3];
+	volatile u8 intstat;
+#define PI1_INTSTAT_ACK		0x04
+#define PI1_INTSTAT_FEMPTY	0x08
+#define PI1_INTSTAT_NOINK	0x10
+#define PI1_INTSTAT_ONLINE	0x20
+#define PI1_INTSTAT_ERR		0x40
+#define PI1_INTSTAT_PE		0x80
+	u8 _intmask[3];
+	volatile u8 intmask;		/* enabled low, reset high*/
+#define PI1_INTMASK_ACK		0x04
+#define PI1_INTMASK_FIFO_EMPTY	0x08
+#define PI1_INTMASK_NOINK	0x10
+#define PI1_INTMASK_ONLINE	0x20
+#define PI1_INTMASK_ERR		0x40
+#define PI1_INTMASK_PE		0x80
+	u8 _timer1[3];
+	volatile u8 timer1;
+#define PI1_TIME1		0x27
+	u8 _timer2[3];
+	volatile u8 timer2;
+#define PI1_TIME2		0x13
+	u8 _timer3[3];
+	volatile u8 timer3;
+#define PI1_TIME3		0x10
+	u8 _timer4[3];
+	volatile u8 timer4;
+#define PI1_TIME4		0x00
+};
+
+#endif
diff -urN linux-2.4.24-pre1/include/asm-mips/system.h linux-2.4.24-pre2/include/asm-mips/system.h
--- linux-2.4.24-pre1/include/asm-mips/system.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/system.h	2003-12-22 11:34:36.000000000 -0800
@@ -228,8 +228,8 @@
 
 #define wmb()		fast_wmb()
 #define rmb()		fast_rmb()
-#define mb()		wbflush();
-#define iob()		wbflush();
+#define mb()		wbflush()
+#define iob()		wbflush()
 
 #else /* !CONFIG_CPU_HAS_WB */
 
diff -urN linux-2.4.24-pre1/include/asm-mips/titan_dep.h linux-2.4.24-pre2/include/asm-mips/titan_dep.h
--- linux-2.4.24-pre1/include/asm-mips/titan_dep.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/titan_dep.h	2003-12-22 11:34:36.000000000 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Board specific definititions for the PMC-Sierra Yosemite
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __TITAN_DEP_H__
+#define __TITAN_DEP_H__
+
+#include <asm/addrspace.h>              /* for KSEG1ADDR() */
+#include <asm/byteorder.h>              /* for cpu_to_le32() */
+
+/* Turn on serial */
+#define	CONFIG_TITAN_SERIAL
+
+/* PCI */
+#define	TITAN_PCI_BASE			0xbb000000
+
+#define TITAN_WRITE(ofs, data)  \
+        *(volatile u32 *)(TITAN_PCI_BASE+(ofs)) = cpu_to_le32(data)
+#define TITAN_READ(ofs, data)   \
+        *(data) = le32_to_cpu(*(volatile u32 *)(TITAN_PCI_BASE+(ofs)))
+#define TITAN_READ_DATA(ofs)    \
+        le32_to_cpu(*(volatile u32 *)(TITAN_PCI_BASE+(ofs)))
+
+#define TITAN_WRITE_16(ofs, data)  \
+        *(volatile u16 *)(TITAN_PCI_BASE+(ofs)) = cpu_to_le16(data)
+#define TITAN_READ_16(ofs, data)   \
+        *(data) = le16_to_cpu(*(volatile u16 *)(TITAN_PCI_BASE+(ofs)))
+
+#define TITAN_WRITE_8(ofs, data)  \
+        *(volatile u8 *)(TITAN_PCI_BASE+(ofs)) = data
+#define TITAN_READ_8(ofs, data)   \
+        *(data) = *(volatile u8 *)(TITAN_PCI_BASE+(ofs))
+
+/*
+ * PCI specific defines
+ */
+#define	TITAN_PCI_0_CONFIG_ADDRESS	0x780
+#define	TITAN_PCI_0_CONFIG_DATA		0x784
+
+/*
+ * HT specific defines
+ */
+#define RM9000x2_HTLINK_REG     0xbb000644
+#define RM9000x2_BASE_ADDR      0xbb000000
+#define RM9000x2_OCD_HTCFGA     0x06f8
+#define RM9000x2_OCD_HTCFGD     0x06fc
+
+/*
+ * Hypertransport specific macros
+ */
+#define RM9K_WRITE(ofs, data)   *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs) = data
+#define RM9K_WRITE_8(ofs, data) *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs) = data
+#define RM9K_WRITE_16(ofs, data) *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs) = data
+
+#define RM9K_READ(ofs, val)     *(val) = *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs)
+#define RM9K_READ_8(ofs, val)   *(val) = *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs)
+#define RM9K_READ_16(ofs, val)  *(val) = *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs)
+
+#endif 
+
diff -urN linux-2.4.24-pre1/include/asm-mips/vr41xx/vr41xx.h linux-2.4.24-pre2/include/asm-mips/vr41xx/vr41xx.h
--- linux-2.4.24-pre1/include/asm-mips/vr41xx/vr41xx.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips/vr41xx/vr41xx.h	2003-12-22 11:34:36.000000000 -0800
@@ -7,6 +7,7 @@
  * Copyright (C) 2001, 2002 Paul Mundt
  * Copyright (C) 2002 MontaVista Software, Inc.
  * Copyright (C) 2002 TimeSys Corp.
+ * Copyright (C) 2003 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -45,6 +46,8 @@
  * Bus Control Uint
  */
 extern void vr41xx_bcu_init(void);
+extern unsigned long vr41xx_get_vtclock_frequency(void);
+extern unsigned long vr41xx_get_tclock_frequency(void);
 
 /*
  * Clock Mask Unit
@@ -77,59 +80,79 @@
 #define MIPS_CPU_IRQ(x)		(MIPS_CPU_IRQ_BASE + (x))
 #define MIPS_SOFTINT0_IRQ	MIPS_CPU_IRQ(0)
 #define MIPS_SOFTINT1_IRQ	MIPS_CPU_IRQ(1)
-#define ICU_CASCADE_IRQ		MIPS_CPU_IRQ(2)
-#define RTC_LONG1_IRQ		MIPS_CPU_IRQ(3)
-#define RTC_LONG2_IRQ		MIPS_CPU_IRQ(4)
-/* RFU */
-#define BATTERY_IRQ		MIPS_CPU_IRQ(6)
+#define INT0_CASCADE_IRQ	MIPS_CPU_IRQ(2)
+#define INT1_CASCADE_IRQ	MIPS_CPU_IRQ(3)
+#define INT2_CASCADE_IRQ	MIPS_CPU_IRQ(4)
+#define INT3_CASCADE_IRQ	MIPS_CPU_IRQ(5)
+#define INT4_CASCADE_IRQ	MIPS_CPU_IRQ(6)
 #define MIPS_COUNTER_IRQ	MIPS_CPU_IRQ(7)
 
 /* SYINT1 Interrupt Numbers */
 #define SYSINT1_IRQ_BASE	8
 #define SYSINT1_IRQ(x)		(SYSINT1_IRQ_BASE + (x))
-/* RFU */
+#define BATTRY_IRQ		SYSINT1_IRQ(0)
 #define POWER_IRQ		SYSINT1_IRQ(1)
+#define RTCLONG1_IRQ		SYSINT1_IRQ(2)
+#define ELAPSEDTIME_IRQ		SYSINT1_IRQ(3)
 /* RFU */
+#define PIU_IRQ			SYSINT1_IRQ(5)
+#define AIU_IRQ			SYSINT1_IRQ(6)
+#define KIU_IRQ			SYSINT1_IRQ(7)
 #define GIUINT_CASCADE_IRQ	SYSINT1_IRQ(8)
 #define SIU_IRQ			SYSINT1_IRQ(9)
-/* RFU */
+#define BUSERR_IRQ		SYSINT1_IRQ(10)
 #define SOFTINT_IRQ		SYSINT1_IRQ(11)
 #define CLKRUN_IRQ		SYSINT1_IRQ(12)
-#define SYSINT1_IRQ_LAST	CLKRUN_IRQ
+#define DOZEPIU_IRQ		SYSINT1_IRQ(13)
+#define SYSINT1_IRQ_LAST	DOZEPIU_IRQ
 
 /* SYSINT2 Interrupt Numbers */
 #define SYSINT2_IRQ_BASE	24
 #define SYSINT2_IRQ(x)		(SYSINT2_IRQ_BASE + (x))
-/* RFU */
+#define RTCLONG2_IRQ		SYSINT2_IRQ(0)
 #define LED_IRQ			SYSINT2_IRQ(1)
-/* RFU */
-#define VTCLOCK_IRQ		SYSINT2_IRQ(3)
+#define HSP_IRQ			SYSINT2_IRQ(2)
+#define TCLOCK_IRQ		SYSINT2_IRQ(3)
 #define FIR_IRQ			SYSINT2_IRQ(4)
+#define CEU_IRQ			SYSINT2_IRQ(4)	/* same number as FIR_IRQ */
 #define DSIU_IRQ		SYSINT2_IRQ(5)
 #define PCI_IRQ			SYSINT2_IRQ(6)
 #define SCU_IRQ			SYSINT2_IRQ(7)
 #define CSI_IRQ			SYSINT2_IRQ(8)
 #define BCU_IRQ			SYSINT2_IRQ(9)
-#define SYSINT2_IRQ_LAST	BCU_IRQ
+#define ETHERNET_IRQ		SYSINT2_IRQ(10)
+#define SYSINT2_IRQ_LAST	ETHERNET_IRQ
 
 /* GIU Interrupt Numbers */
 #define GIU_IRQ_BASE		40
 #define GIU_IRQ(x)		(GIU_IRQ_BASE + (x))	/* IRQ 40-71 */
 #define GIU_IRQ_LAST		GIU_IRQ(31)
+#define GIU_IRQ_TO_PIN(x)	((x) - GIU_IRQ_BASE)	/* Pin 0-31 */
 
 extern void (*board_irq_init)(void);
+extern int vr41xx_set_intassign(unsigned int irq, unsigned char intassign);
 extern int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq));
 
 /*
- * Gegeral-Purpose I/O Unit
+ * RTC
  */
-extern void vr41xx_enable_giuint(int pin);
-extern void vr41xx_disable_giuint(int pin);
-extern void vr41xx_clear_giuint(int pin);
+extern void vr41xx_set_rtclong1_cycle(uint32_t cycles);
+extern uint32_t vr41xx_read_rtclong1_counter(void);
 
+extern void vr41xx_set_rtclong2_cycle(uint32_t cycles);
+extern uint32_t vr41xx_read_rtclong2_counter(void);
+
+extern void vr41xx_set_tclock_cycle(uint32_t cycles);
+extern uint32_t vr41xx_read_tclock_counter(void);
+
+/*
+ * General-Purpose I/O Unit
+ */
 enum {
 	TRIGGER_LEVEL,
-	TRIGGER_EDGE
+	TRIGGER_EDGE,
+	TRIGGER_EDGE_FALLING,
+	TRIGGER_EDGE_RISING
 };
 
 enum {
diff -urN linux-2.4.24-pre1/include/asm-mips/vr41xx/vrc4173.h linux-2.4.24-pre2/include/asm-mips/vr41xx/vrc4173.h
--- linux-2.4.24-pre1/include/asm-mips/vr41xx/vrc4173.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-mips/vr41xx/vrc4173.h	2003-12-22 11:34:36.000000000 -0800
@@ -72,6 +72,19 @@
 /*
  * Clock Mask Unit
  */
+#define VRC4173_PIU_CLOCK		0x0001
+#define VRC4173_KIU_CLOCK		0x0002
+#define VRC4173_AIU_CLOCK		0x0004
+#define VRC4173_PS2CH1_CLOCK		0x0008
+#define VRC4173_PS2CH2_CLOCK		0x0010
+#define VRC4173_USBU_PCI_CLOCK		0x0020
+#define VRC4173_CARDU1_PCI_CLOCK	0x0040
+#define VRC4173_CARDU2_PCI_CLOCK	0x0080
+#define VRC4173_AC97U_PCI_CLOCK		0x0100
+#define VRC4173_USBU_48MHz_CLOCK	0x0400
+#define VRC4173_EXT_48MHz_CLOCK		0x0800
+#define VRC4173_48MHz_CLOCK		0x1000
+
 extern void vrc4173_clock_supply(u16 mask);
 extern void vrc4173_clock_mask(u16 mask);
 
diff -urN linux-2.4.24-pre1/include/asm-mips64/bootinfo.h linux-2.4.24-pre2/include/asm-mips64/bootinfo.h
--- linux-2.4.24-pre1/include/asm-mips64/bootinfo.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips64/bootinfo.h	2003-12-22 11:34:36.000000000 -0800
@@ -36,6 +36,7 @@
 #define MACH_GROUP_NEC_VR41XX  19 /* NEC Vr41xx based boards/gadgets        */
 #define MACH_GROUP_HP_LJ       20 /* Hewlett Packard LaserJet               */
 #define MACH_GROUP_LASAT       21
+#define MACH_GROUP_TITAN       22 /* PMC-Sierra Titan 			    */
 
 /*
  * Valid machtype values for group unknown (low order halfword of mips_machtype)
@@ -188,6 +189,11 @@
 #define MACH_TANBAC_TB0226	6	/* TANBAC TB0226 (MBASE) */
 #define MACH_TANBAC_TB0229	7	/* TANBAC TB0229 (VR4131DIMM) */
 
+/*
+ * Valid machtype for group TITAN
+ */
+#define	MACH_TITAN_YOSEMITE	1 	/* PMC-Sierra Yosemite */
+
 #define CL_SIZE			(256)
 
 const char *get_system_type(void);
diff -urN linux-2.4.24-pre1/include/asm-mips64/cpu.h linux-2.4.24-pre2/include/asm-mips64/cpu.h
--- linux-2.4.24-pre1/include/asm-mips64/cpu.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips64/cpu.h	2003-12-22 11:34:36.000000000 -0800
@@ -208,5 +208,6 @@
 #define MIPS_CPU_NOFPUEX	0x00000000 /* no FPU exception; never set */
 #define MIPS_CPU_LLSC		0x00008000 /* CPU has ll/sc instructions */
 #define MIPS_CPU_SUBSET_CACHES	0x00010000 /* P-cache subset enforced */
+#define MIPS_CPU_PREFETCH	0x00020000 /* CPU has usable prefetch */
 
 #endif /* _ASM_CPU_H */
diff -urN linux-2.4.24-pre1/include/asm-mips64/page.h linux-2.4.24-pre2/include/asm-mips64/page.h
--- linux-2.4.24-pre1/include/asm-mips64/page.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips64/page.h	2003-12-22 11:34:36.000000000 -0800
@@ -40,11 +40,8 @@
 
 #define PAGE_BUG(page) do {  BUG(); } while (0)
 
-extern void (*_clear_page)(void * page);
-extern void (*_copy_page)(void * to, void * from);
-
-#define clear_page(page)	_clear_page(page)
-#define copy_page(to, from)	_copy_page(to, from)
+extern void clear_page(void * page);
+extern void copy_page(void * to, void * from);
 
 extern unsigned long shm_align_mask;
 
diff -urN linux-2.4.24-pre1/include/asm-mips64/prefetch.h linux-2.4.24-pre2/include/asm-mips64/prefetch.h
--- linux-2.4.24-pre1/include/asm-mips64/prefetch.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips64/prefetch.h	2003-12-22 11:34:36.000000000 -0800
@@ -0,0 +1,43 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#ifndef __ASM_PREFETCH_H
+#define __ASM_PREFETCH_H
+
+/*
+ * R5000 and RM5200 implements pref and prefx instructions but they're nops, so
+ * rather than wasting time we pretend these processors don't support
+ * prefetching at all.
+ *
+ * R5432 implements Load, Store, LoadStreamed, StoreStreamed, LoadRetained,
+ * StoreRetained and WriteBackInvalidate but not Pref_PrepareForStore.
+ *
+ * Hell (and the book on my shelf I can't open ...) know what the R8000 does.
+ *
+ * RM7000 version 1.0 interprets all hints as Pref_Load; version 2.0 implements
+ * Pref_PrepareForStore also.
+ *
+ * RM9000 is MIPS IV but implements prefetching like MIPS32/MIPS64;
+ * it's Pref_WriteBackInvalidate is a nop.
+ *
+ * VR7701 only implements the Load prefetch.
+ *
+ * Finally MIPS32 and MIPS64 implement all of the following hints.
+ */
+
+#define Pref_Load			0
+#define Pref_Store			1
+						/* 2 and 3 are reserved */
+#define Pref_LoadStreamed		4
+#define Pref_StoreStreamed		5
+#define Pref_LoadRetained		6
+#define Pref_StoreRetained		7
+						/* 8 ... 24 are reserved */
+#define Pref_WriteBackInvalidate	25
+#define Pref_PrepareForStore		30
+
+#endif /* __ASM_PREFETCH_H */
diff -urN linux-2.4.24-pre1/include/asm-mips64/processor.h linux-2.4.24-pre2/include/asm-mips64/processor.h
--- linux-2.4.24-pre1/include/asm-mips64/processor.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips64/processor.h	2003-12-22 11:34:36.000000000 -0800
@@ -118,6 +118,7 @@
 #define cpu_has_divec		(cpu_data[0].options & MIPS_CPU_DIVEC)
 #define cpu_has_vce		(cpu_data[0].options & MIPS_CPU_VCE)
 #define cpu_has_cache_cdex	(cpu_data[0].options & MIPS_CPU_CACHE_CDEX)
+#define cpu_has_prefetch	(cpu_data[0].options & MIPS_CPU_PREFETCH)
 #define cpu_has_mcheck		(cpu_data[0].options & MIPS_CPU_MCHECK)
 #define cpu_has_ejtag		(cpu_data[0].options & MIPS_CPU_EJTAG)
 #define cpu_has_nofpuex		(cpu_data[0].options & MIPS_CPU_NOFPUEX)
@@ -126,8 +127,13 @@
 #define cpu_has_dc_aliases	(cpu_data[0].dcache.flags & MIPS_CACHE_ALIASES)
 #define cpu_has_ic_fills_f_dc	(cpu_data[0].dcache.flags & MIPS_CACHE_IC_F_DC)
 #define cpu_has_64bits		1
+#define cpu_has_64bit_addresses	1
 #define cpu_has_subset_pcaches	(cpu_data[0].options & MIPS_CPU_SUBSET_CACHES)
 
+#define cpu_dcache_line_size()	current_cpu_data.dcache.linesz
+#define cpu_icache_line_size()	current_cpu_data.icache.linesz
+#define cpu_scache_line_size()	current_cpu_data.scache.linesz
+
 extern struct cpuinfo_mips cpu_data[];
 #define current_cpu_data cpu_data[smp_processor_id()]
 
diff -urN linux-2.4.24-pre1/include/asm-mips64/serial.h linux-2.4.24-pre2/include/asm-mips64/serial.h
--- linux-2.4.24-pre1/include/asm-mips64/serial.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips64/serial.h	2003-12-22 11:34:36.000000000 -0800
@@ -90,6 +90,24 @@
 #define MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS
 #endif
 
+#ifdef CONFIG_TITAN_SERIAL
+/* 16552 20 MHz crystal */
+#define TITAN_SERIAL_BASE_BAUD	( 20000000 / 16 )
+#define	TITAN_SERIAL_IRQ	XXX
+#define	TITAN_SERIAL_BASE	0xffffffff
+
+#define	_TITAN_SERIAL_INIT(int, base)					\
+	{ baud_base: TITAN_SERIAL_BASE_BAUD, irq: int,			\
+	  flags: STD_COM_FLAGS,	iomem_base: (u8 *) base,		\
+	  iomem_reg_shift: 2, io_type: SERIAL_IO_MEM			\
+	}
+
+#define TITAN_SERIAL_PORT_DEFNS						\
+	_TITAN_SERIAL_INIT(TITAN_SERIAL_IRQ, TITAN_SERIAL_BASE)
+#else
+#define TITAN_SERIAL_PORT_DEFNS
+#endif
+
 #ifdef CONFIG_SGI_IP27
 
 /*
@@ -133,7 +151,8 @@
 	MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS		\
 	MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS		\
 	SEAD_SERIAL_PORT_DEFNS				\
-	STD_SERIAL_PORT_DEFNS
+	STD_SERIAL_PORT_DEFNS				\
+	TITAN_SERIAL_PORT_DEFNS
 
 #define RS_TABLE_SIZE	64
 
diff -urN linux-2.4.24-pre1/include/asm-mips64/sgi/ioc.h linux-2.4.24-pre2/include/asm-mips64/sgi/ioc.h
--- linux-2.4.24-pre1/include/asm-mips64/sgi/ioc.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-mips64/sgi/ioc.h	2003-12-22 11:34:36.000000000 -0800
@@ -14,48 +14,13 @@
 #define _SGI_IOC_H
 
 #include <linux/types.h>
+#include <asm/sgi/pi1.h>
 
 /* 
  * All registers are 8-bit wide alligned on 32-bit boundary. Bad things
  * happen if you try word access them. You have been warned.
  */
 
-struct sgioc_pport_regs {
-	u8 _data[3];
-	volatile u8 data;
-	u8 _ctrl[3];
-	volatile u8 ctrl;
-#define SGIOC_PCTRL_STROBE	0x01
-#define SGIOC_PCTRL_AFD		0x02
-#define SGIOC_PCTRL_INIT	0x04
-#define SGIOC_PCTRL_SLIN	0x08
-#define SGIOC_PCTRL_DIRECTION	0x20
-#define SGIOC_PCTRL_SEL		0x40
-	u8 _status[3];
-	volatile u8 status;
-#define SGIOC_PSTAT_DEVID	0x03
-#define SGIOC_PSTAT_NOINK	0x04
-#define SGIOC_PSTAT_ERROR	0x08
-#define SGIOC_PSTAT_ONLINE	0x10
-#define SGIOC_PSTAT_PE		0x20
-#define SGIOC_PSTAT_ACK		0x40
-#define SGIOC_PSTAT_BUSY	0x80
-	u8 _dmactrl[3];
-	volatile u8 dmactrl;
-	u8 _intrstat[3];
-	volatile u8 intrstat;
-	u8 _intrmask[3];
-	volatile u8 intrmask;
-	u8 _timer1[3];
-	volatile u8 timer1;
-	u8 _timer2[3];
-	volatile u8 timer2;
-	u8 _timer3[3];
-	volatile u8 timer3;
-	u8 _timer4[3];
-	volatile u8 timer4;
-};
-
 struct sgioc_uart_regs {
 	u8 _ctrl1[3];
 	volatile u8 ctrl1;
@@ -153,7 +118,7 @@
 extern u8 sgi_ioc_reset, sgi_ioc_write;
 
 struct sgioc_regs {
-	struct sgioc_pport_regs pport;
+	struct pi1_regs pport;
 	u32 _unused0[2];
 	struct sgioc_uart_regs serport;
 	struct sgioc_keyb_regs kbdmouse;
diff -urN linux-2.4.24-pre1/include/asm-mips64/sgi/pi1.h linux-2.4.24-pre2/include/asm-mips64/sgi/pi1.h
--- linux-2.4.24-pre1/include/asm-mips64/sgi/pi1.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips64/sgi/pi1.h	2003-12-22 11:34:36.000000000 -0800
@@ -0,0 +1,71 @@
+/*
+ * pi1.h: Definitions for SGI PI1 parallel port
+ */
+
+#ifndef _SGI_PI1_H
+#define _SGI_PI1_H
+
+struct pi1_regs {
+	u8 _data[3];
+	volatile u8 data;
+	u8 _ctrl[3];
+	volatile u8 ctrl;
+#define PI1_CTRL_STROBE_N	0x01
+#define PI1_CTRL_AFD_N		0x02
+#define PI1_CTRL_INIT_N		0x04
+#define PI1_CTRL_SLIN_N		0x08
+#define PI1_CTRL_IRQ_ENA	0x10
+#define PI1_CTRL_DIR		0x20
+#define PI1_CTRL_SEL		0x40
+	u8 _status[3];
+	volatile u8 status;
+#define PI1_STAT_DEVID		0x03	/* bits 0-1 */
+#define PI1_STAT_NOINK		0x04	/* SGI MODE only */
+#define PI1_STAT_ERROR		0x08
+#define PI1_STAT_ONLINE		0x10
+#define PI1_STAT_PE		0x20
+#define PI1_STAT_ACK		0x40
+#define PI1_STAT_BUSY		0x80
+	u8 _dmactrl[3];
+	volatile u8 dmactrl;
+#define PI1_DMACTRL_FIFO_EMPTY	0x01    /* fifo empty R/O */
+#define PI1_DMACTRL_ABORT	0x02    /* reset DMA and internal fifo W/O */
+#define PI1_DMACTRL_STDMODE	0x00    /* bits 2-3 */
+#define PI1_DMACTRL_SGIMODE	0x04    /* bits 2-3 */
+#define PI1_DMACTRL_RICOHMODE	0x08    /* bits 2-3 */
+#define PI1_DMACTRL_HPMODE	0x0c    /* bits 2-3 */
+#define PI1_DMACTRL_BLKMODE	0x10    /* block mode */
+#define PI1_DMACTRL_FIFO_CLEAR	0x20    /* clear fifo W/O */
+#define PI1_DMACTRL_READ	0x40    /* read */
+#define PI1_DMACTRL_RUN		0x80    /* pedal to the metal */
+	u8 _intstat[3];
+	volatile u8 intstat;
+#define PI1_INTSTAT_ACK		0x04
+#define PI1_INTSTAT_FEMPTY	0x08
+#define PI1_INTSTAT_NOINK	0x10
+#define PI1_INTSTAT_ONLINE	0x20
+#define PI1_INTSTAT_ERR		0x40
+#define PI1_INTSTAT_PE		0x80
+	u8 _intmask[3];
+	volatile u8 intmask;		/* enabled low, reset high*/
+#define PI1_INTMASK_ACK		0x04
+#define PI1_INTMASK_FIFO_EMPTY	0x08
+#define PI1_INTMASK_NOINK	0x10
+#define PI1_INTMASK_ONLINE	0x20
+#define PI1_INTMASK_ERR		0x40
+#define PI1_INTMASK_PE		0x80
+	u8 _timer1[3];
+	volatile u8 timer1;
+#define PI1_TIME1		0x27
+	u8 _timer2[3];
+	volatile u8 timer2;
+#define PI1_TIME2		0x13
+	u8 _timer3[3];
+	volatile u8 timer3;
+#define PI1_TIME3		0x10
+	u8 _timer4[3];
+	volatile u8 timer4;
+#define PI1_TIME4		0x00
+};
+
+#endif
diff -urN linux-2.4.24-pre1/include/asm-mips64/titan_dep.h linux-2.4.24-pre2/include/asm-mips64/titan_dep.h
--- linux-2.4.24-pre1/include/asm-mips64/titan_dep.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-mips64/titan_dep.h	2003-12-22 11:34:36.000000000 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Board specific definititions for the PMC-Sierra Yosemite
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __TITAN_DEP_H__
+#define __TITAN_DEP_H__
+
+#include <asm/addrspace.h>              /* for KSEG1ADDR() */
+#include <asm/byteorder.h>              /* for cpu_to_le32() */
+
+/* Turn on serial */
+#define	CONFIG_TITAN_SERIAL
+
+/* PCI */
+#define	TITAN_PCI_BASE			0xbb000000
+
+#define TITAN_WRITE(ofs, data)  \
+        *(volatile u32 *)(TITAN_PCI_BASE+(ofs)) = cpu_to_le32(data)
+#define TITAN_READ(ofs, data)   \
+        *(data) = le32_to_cpu(*(volatile u32 *)(TITAN_PCI_BASE+(ofs)))
+#define TITAN_READ_DATA(ofs)    \
+        le32_to_cpu(*(volatile u32 *)(TITAN_PCI_BASE+(ofs)))
+
+#define TITAN_WRITE_16(ofs, data)  \
+        *(volatile u16 *)(TITAN_PCI_BASE+(ofs)) = cpu_to_le16(data)
+#define TITAN_READ_16(ofs, data)   \
+        *(data) = le16_to_cpu(*(volatile u16 *)(TITAN_PCI_BASE+(ofs)))
+
+#define TITAN_WRITE_8(ofs, data)  \
+        *(volatile u8 *)(TITAN_PCI_BASE+(ofs)) = data
+#define TITAN_READ_8(ofs, data)   \
+        *(data) = *(volatile u8 *)(TITAN_PCI_BASE+(ofs))
+
+/*
+ * PCI specific defines
+ */
+#define	TITAN_PCI_0_CONFIG_ADDRESS	0x780
+#define	TITAN_PCI_0_CONFIG_DATA		0x784
+
+/*
+ * HT specific defines
+ */
+#define RM9000x2_HTLINK_REG     0xbb000644
+#define RM9000x2_BASE_ADDR      0xbb000000
+#define RM9000x2_OCD_HTCFGA     0x06f8
+#define RM9000x2_OCD_HTCFGD     0x06fc
+
+/*
+ * Hypertransport specific macros
+ */
+#define RM9K_WRITE(ofs, data)   *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs) = data
+#define RM9K_WRITE_8(ofs, data) *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs) = data
+#define RM9K_WRITE_16(ofs, data) *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs) = data
+
+#define RM9K_READ(ofs, val)     *(val) = *(volatile u_int32_t *)(RM9000x2_BASE_ADDR+ofs)
+#define RM9K_READ_8(ofs, val)   *(val) = *(volatile u8 *)(RM9000x2_BASE_ADDR+ofs)
+#define RM9K_READ_16(ofs, val)  *(val) = *(volatile u16 *)(RM9000x2_BASE_ADDR+ofs)
+
+#endif 
+
diff -urN linux-2.4.24-pre1/include/asm-ppc64/cputable.h linux-2.4.24-pre2/include/asm-ppc64/cputable.h
--- linux-2.4.24-pre1/include/asm-ppc64/cputable.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/cputable.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,5 @@
 /*
- *  include/asm-ppc/cputable.h
+ *  include/asm-ppc64/cputable.h
  *
  *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
  *
@@ -30,7 +30,7 @@
 #ifndef __ASSEMBLY__
 
 /* This structure can grow, it's real size is used by head.S code
- * via the mkdefs mecanism.
+ * via the mkdefs mechanism.
  */
 struct cpu_spec;
 
@@ -74,10 +74,20 @@
 #define FW_FEATURE_COPY		(1UL<<4)	
 #define FW_FEATURE_ASR		(1UL<<5)	
 #define FW_FEATURE_DEBUG	(1UL<<6)	
-#define FW_FEATURE_PERF		(1UL<<7)	
-#define FW_FEATURE_DUMP		(1UL<<8)	
-#define FW_FEATURE_INTERRUPT	(1UL<<9)	
-#define FW_FEATURE_MIGRATE	(1UL<<10)	
+#define FW_FEATURE_TERM		(1UL<<7)
+#define FW_FEATURE_PERF		(1UL<<8)
+#define FW_FEATURE_DUMP		(1UL<<9)
+#define FW_FEATURE_INTERRUPT	(1UL<<10)
+#define FW_FEATURE_MIGRATE	(1UL<<11)
+#define FW_FEATURE_PERFMON	(1UL<<12)
+#define FW_FEATURE_CRQ   	(1UL<<13)
+#define FW_FEATURE_VIO   	(1UL<<14)
+#define FW_FEATURE_RDMA   	(1UL<<15)
+#define FW_FEATURE_LLAN   	(1UL<<16)
+#define FW_FEATURE_BULK   	(1UL<<17)
+#define FW_FEATURE_XDABR   	(1UL<<18)
+#define FW_FEATURE_MULTITCE   	(1UL<<19)
+#define FW_FEATURE_SPLPAR   	(1UL<<20)
 
 typedef struct {
     unsigned long val;
diff -urN linux-2.4.24-pre1/include/asm-ppc64/current.h linux-2.4.24-pre2/include/asm-ppc64/current.h
--- linux-2.4.24-pre1/include/asm-ppc64/current.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/current.h	2003-12-22 11:34:36.000000000 -0800
@@ -1,5 +1,6 @@
 #ifndef _PPC64_CURRENT_H
 #define _PPC64_CURRENT_H
+#include <asm/paca.h>
 
 /*
  * This program is free software; you can redistribute it and/or
@@ -7,9 +8,11 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
- * Use r13 for current since the ppc64 ABI reserves it - Anton
+ * current is in the paca (processor data area), which is pointed
+ * to by r13.
  */
 
-register struct task_struct *current asm ("r13");
+#define get_current()   ((struct task_struct *)(get_paca()->xCurrent))
+#define current         get_current()
 
 #endif /* !(_PPC64_CURRENT_H) */
diff -urN linux-2.4.24-pre1/include/asm-ppc64/hvcall.h linux-2.4.24-pre2/include/asm-ppc64/hvcall.h
--- linux-2.4.24-pre1/include/asm-ppc64/hvcall.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/hvcall.h	2003-12-22 11:34:36.000000000 -0800
@@ -9,6 +9,14 @@
 #define H_PTEG_Full	-6	/* PTEG is full */
 #define H_Not_Found	-7	/* PTE was not found" */
 #define H_Reserved_DABR	-8	/* DABR address is reserved by the hypervisor on this processor" */
+#define H_NoMem                 -9
+#define H_Authority            -10
+#define H_Permission           -11
+#define H_Dropped              -12
+#define H_SourceParm           -13
+#define H_DestParm             -14
+#define H_RemoteParm           -15
+#define H_Resource             -16
 
 /* Flags */
 #define H_LARGE_PAGE		(1UL<<(63-16))
@@ -58,8 +66,23 @@
 #define H_IPOLL			0x70
 #define H_XIRR			0x74
 #define H_PERFMON		0x7c
+#define H_MIGRATE_DMA		0x78
+#define H_REGISTER_VPA		0xDC
+#define H_CEDE			0xE0
+#define H_CONFER		0xE4
+#define H_PROD			0xE8
+#define H_GET_PPP		0xEC
+#define H_SET_PPP		0xF0
+#define H_SET_PURR		0xF4
+#define H_PIC			0xF8
+#define H_REG_CRQ		0xFC
+#define H_FREE_CRQ		0x100
+#define H_VIO_SIGNAL		0x104
+#define H_SEND_CRQ		0x108
+#define H_COPY_RDMA		0x110
+#define H_POLL_PENDING		0x1D8
 
-#define HSC			".long 0x44000022\n"
+#define HVSC			".long 0x44000022\n"
 #define H_ENTER_r3		"li	3, 0x08\n"
 
 /* plpar_hcall() -- Generic call interface using above opcodes
@@ -84,3 +107,34 @@
  */
 long plpar_hcall_norets(unsigned long opcode, ...);
 
+/*
+ * Special hcall interface for ibmveth support.
+ * Takes 8 input parms. Returns a rc and stores the
+ * R4 return value in *out1.
+ */
+long plpar_hcall_8arg_2ret(unsigned long opcode,
+			unsigned long arg1,
+			unsigned long arg2,
+			unsigned long arg3,
+			unsigned long arg4,
+			unsigned long arg5,
+			unsigned long arg6,
+			unsigned long arg7,
+			unsigned long arg8,
+			unsigned long *out1);
+
+
+/* plpar_hcall_4out()
+ *
+ * same as plpar_hcall except with 4 output arguments.
+ *
+ */
+long plpar_hcall_4out(unsigned long opcode,
+		      unsigned long arg1,
+		      unsigned long arg2,
+		      unsigned long arg3,
+		      unsigned long arg4,
+		      unsigned long *out1,
+		      unsigned long *out2,
+		      unsigned long *out3,
+		      unsigned long *out4);
diff -urN linux-2.4.24-pre1/include/asm-ppc64/hw_irq.h linux-2.4.24-pre2/include/asm-ppc64/hw_irq.h
--- linux-2.4.24-pre1/include/asm-ppc64/hw_irq.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/hw_irq.h	2003-12-22 11:34:36.000000000 -0800
@@ -71,9 +71,21 @@
 
 #endif /* CONFIG_PPC_ISERIES */
 
-#define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);})
-#define unmask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->enable) irq_desc[irq].handler->enable(irq);})
-#define ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);})
+#define mask_irq(irq) ({ 				\
+	irq_desc_t *desc = irqdesc(irq);		\
+	if (desc->handler && desc->handler->disable)	\
+		desc->handler->disable(irq);		\
+})
+#define unmask_irq(irq) ({				\
+	irq_desc_t *desc = irqdesc(irq);		\
+	if (desc->handler && desc->handler->enable)	\
+		desc->handler->enable(irq);		\
+})
+#define ack_irq(irq) ({					\
+	irq_desc_t *desc = irqdesc(irq);		\
+	if (desc->handler && desc->handler->ack)	\
+		desc->handler->ack(irq);		\
+})
 
 /* Should we handle this via lost interrupts and IPIs or should we don't care like
  * we do now ? --BenH.
diff -urN linux-2.4.24-pre1/include/asm-ppc64/iSeries/HvCall.h linux-2.4.24-pre2/include/asm-ppc64/iSeries/HvCall.h
--- linux-2.4.24-pre1/include/asm-ppc64/iSeries/HvCall.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/iSeries/HvCall.h	2003-12-22 11:34:36.000000000 -0800
@@ -196,6 +196,12 @@
 }
 
 //=====================================================================
+static inline void              HvCall_sendLpProd(HvLpIndex lpindex)
+{
+	HvCall1( HvCallBaseSendLpProd, lpindex );
+}
+
+//=====================================================================
 static inline void		HvCall_terminateMachineSrc(void)
 {
 	HvCall0( HvCallBaseTerminateMachineSrc );
diff -urN linux-2.4.24-pre1/include/asm-ppc64/iSeries/ItLpPaca.h linux-2.4.24-pre2/include/asm-ppc64/iSeries/ItLpPaca.h
--- linux-2.4.24-pre1/include/asm-ppc64/iSeries/ItLpPaca.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/iSeries/ItLpPaca.h	2003-12-22 11:34:36.000000000 -0800
@@ -110,7 +110,10 @@
 	u64     xPDCSavedSPRG1;         // Saved SPRG1 for PMC int      x68-x6F
 	u64     xPDCSavedSRR0;          // Saved SRR0 for PMC int       x70-x77
 	volatile u32 xVirtualDecr;	// Virtual DECR for shared procsx78-x7B
-	u32	    xRsvd2_2;		// Reserved			x7C-x7F
+	u16     xSLBCount;              // # of SLBs to maintain        x7C-x7D
+	u8      xIdle;                  // Indicate OS is idle          x7E
+	u8      xRsvd2_2;               // Reserved                     x7F
+
 
 //=============================================================================
 // CACHE_LINE_3 0x0100 - 0x007F: This line is shared with other processors
diff -urN linux-2.4.24-pre1/include/asm-ppc64/irq.h linux-2.4.24-pre2/include/asm-ppc64/irq.h
--- linux-2.4.24-pre1/include/asm-ppc64/irq.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/irq.h	2003-12-22 11:34:36.000000000 -0800
@@ -15,31 +15,22 @@
 extern void disable_irq_nosync(unsigned int);
 extern void enable_irq(unsigned int);
 
-/*
- * this is the maximum number of virtual irqs we will use.
- */
-#define NR_IRQS			512
+/* Need to keep at 256 (minimum) for iSeries */
+#define NR_IRQS  256
 
-#define NUM_8259_INTERRUPTS	16
+#define MAX_IRQS (1<<24)
 
-/* Interrupt numbers are virtual in case they are sparsely
- * distributed by the hardware.
- */
-#define NR_HW_IRQS		8192
-extern unsigned short real_irq_to_virt_map[NR_HW_IRQS];
-extern unsigned short virt_irq_to_real_map[NR_IRQS];
-/* Create a mapping for a real_irq if it doesn't already exist.
- * Return the virtual irq as a convenience.
- */
-unsigned long virt_irq_create_mapping(unsigned long real_irq);
+extern unsigned int _next_irq(unsigned int irq);
 
-/* These funcs map irqs between real and virtual */
-static inline unsigned long real_irq_to_virt(unsigned long real_irq) {
-	return real_irq_to_virt_map[real_irq];
-}
-static inline unsigned long virt_irq_to_real(unsigned long virt_irq) {
-	return virt_irq_to_real_map[virt_irq];
-}
+/* Define a way to iterate across irqs fairly efficiently. */
+#define for_each_irq(i) \
+	for ((i) = 0; (i) < MAX_IRQS; (i) = _next_irq(i))
+
+
+extern void *_irqdesc(unsigned int irq);
+extern void *_real_irqdesc(unsigned int irq);
+#define irqdesc(irq) ((irq_desc_t *)_irqdesc(irq))
+#define real_irqdesc(irq) ((irq_desc_t *)_real_irqdesc(irq))
 
 /*
  * This gets called from serial.c, which is now used on
@@ -51,5 +42,34 @@
 	return irq;
 }
 
+/*
+ * Because many systems have two overlapping names spaces for
+ * interrupts (ISA and XICS for example), and the ISA interrupts
+ * have historically not been easy to renumber, we allow ISA
+ * interrupts to take values 0 - 15, and shift up the remaining
+ * interrupts by 0x10.
+ *
+ * This would be nice to remove at some point as it adds confusion
+ * and adds a nasty end case if any platform native interrupts have
+ * values within 0x10 of the end of that namespace.
+ */
+
+#define NUM_ISA_INTERRUPTS	0x10
+
+extern inline int irq_offset_up(int irq)
+{
+	return(irq + NUM_ISA_INTERRUPTS);
+}
+
+extern inline int irq_offset_down(int irq)
+{
+	return(irq - NUM_ISA_INTERRUPTS);
+}
+
+extern inline int irq_offset_value(void)
+{
+	return NUM_ISA_INTERRUPTS;
+}
+
 #endif /* _ASM_IRQ_H */
 #endif /* __KERNEL__ */
diff -urN linux-2.4.24-pre1/include/asm-ppc64/machdep.h linux-2.4.24-pre2/include/asm-ppc64/machdep.h
--- linux-2.4.24-pre1/include/asm-ppc64/machdep.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-ppc64/machdep.h	2003-12-22 11:34:36.000000000 -0800
@@ -10,6 +10,8 @@
  */
 
 #include <linux/config.h>
+#include <linux/seq_file.h>
+#include <linux/irq.h>
 
 struct pt_regs;
 struct pci_bus;	
@@ -62,6 +64,7 @@
 	unsigned int	(*irq_cannonicalize)(unsigned int irq);
 	void		(*init_IRQ)(void);
 	void		(*init_ras_IRQ)(void);
+	void		(*init_irq_desc)(irq_desc_t *desc);
 	int		(*get_irq)(struct pt_regs *);
 	
 	/* A general init function, called by ppc_init in init/main.c.
diff -urN linux-2.4.24-pre1/include/asm-ppc64/memory.h linux-2.4.24-pre2/include/asm-ppc64/memory.h
--- linux-2.4.24-pre1/include/asm-ppc64/memory.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/memory.h	2003-12-22 11:34:36.000000000 -0800
@@ -43,22 +43,28 @@
 
 /* Macros for adjusting thread priority (hardware multi-threading) */
 
-#if defined(CONFIG_PPC_ISERIES) || defined(CONFIG_HMT)
+#define HMT_very_low()     asm volatile("or 31,31,31       # very low priority")
 #define HMT_low()	asm volatile("or 1,1,1		# low priority")
+#define HMT_medium_low()   asm volatile("or 6,6,6          # medium low priority")
 #define HMT_medium()	asm volatile("or 2,2,2		# medium priority")
+#define HMT_medium_high()  asm volatile("or 5,5,5          # medium high priority")
 #define HMT_high()	asm volatile("or 3,3,3		# high priority")
 
+#define HMT_VERY_LOW            "\tor   31,31,31        # very low priority\n"
 #define HMT_LOW		"\tor	1,1,1		# low priority\n"
+#define HMT_MEDIUM_LOW          "\tor   6,6,6           # medium low priority\n"
 #define HMT_MEDIUM	"\tor	2,2,2		# medium priority\n"
+#define HMT_MEDIUM_HIGH         "\tor   5,5,5           # medium high priority\n"
 #define HMT_HIGH	"\tor	3,3,3		# high priority\n"
-#else
-#define HMT_low()	do { } while(0)
-#define HMT_medium()	do { } while(0)
-#define HMT_high()	do { } while(0)
 
-#define HMT_LOW
-#define HMT_MEDIUM
-#define HMT_HIGH
-#endif
+/*
+ * Various operational modes for SMT
+ * Off    : never run threaded
+ * On     : always run threaded
+ * Dynamic: Allow the system to switch modes as needed
+ */
+#define SMT_OFF      0
+#define SMT_ON       1
+#define SMT_DYNAMIC  2
 
 #endif
diff -urN linux-2.4.24-pre1/include/asm-ppc64/mmu.h linux-2.4.24-pre2/include/asm-ppc64/mmu.h
--- linux-2.4.24-pre1/include/asm-ppc64/mmu.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/mmu.h	2003-12-22 11:34:36.000000000 -0800
@@ -180,7 +180,7 @@
 extern HTAB htab_data;
 
 #include <linux/cache.h>
-#include <asm/spinlock.h>
+#include <linux/spinlock.h>
 typedef struct {
 	spinlock_t lock;
 } ____cacheline_aligned hash_table_lock_t;
@@ -191,6 +191,7 @@
 			unsigned long prpn, unsigned hash,
 			void * ptep, unsigned hpteflags,
 			unsigned bolted );
+unsigned long get_lock_slot(unsigned long vpn);
 
 #define PD_SHIFT (10+12)		/* Page directory */
 #define PD_MASK  0x02FF
diff -urN linux-2.4.24-pre1/include/asm-ppc64/naca.h linux-2.4.24-pre2/include/asm-ppc64/naca.h
--- linux-2.4.24-pre1/include/asm-ppc64/naca.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/naca.h	2003-12-22 11:34:36.000000000 -0800
@@ -35,7 +35,12 @@
 	u32 dCacheL1LinesPerPage;	/* L1 d-cache lines / page   0x64 */
 	u32 iCacheL1LogLineSize;	/* L1 i-cache line size Log2 0x68 */
 	u32 iCacheL1LinesPerPage;	/* L1 i-cache lines / page   0x6c */
-	u64 resv0[2];                   /* Reserved           0x70 - 0x7F */
+	u64 smt_snooze_delay;           /* Delay (in usec) before    0x70 */
+					/* entering ST mode               */
+	u8  smt_state;                  /* 0 = SMT off               0x78 */
+					/* 1 = SMT on                     */
+					/* 2 = SMT dynamic                */
+	u8  resv0[7];                   /* Reserved           0x79 - 0x7F */
 };
 
 extern struct naca_struct *naca;
diff -urN linux-2.4.24-pre1/include/asm-ppc64/paca.h linux-2.4.24-pre2/include/asm-ppc64/paca.h
--- linux-2.4.24-pre1/include/asm-ppc64/paca.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/paca.h	2003-12-22 11:34:36.000000000 -0800
@@ -45,7 +45,8 @@
 #define MAX_PACAS MAX_PROCESSORS * 2
 
 extern struct paca_struct paca[];
-#define get_paca() ((struct paca_struct *)mfspr(SPRG3))
+register struct paca_struct *local_paca asm("r13");
+#define get_paca()	local_paca
 
 /*============================================================================
  * Name_______:	paca
@@ -84,7 +85,9 @@
 	u8 xSegments[STAB_CACHE_SIZE];	/* Cache of used stab entries		0x68,0x70 */
 	u8 xProcEnabled;		/* 1=soft enabled			0x78 */
 	u8 xHrdIntCount;		/* Count of active hardware interrupts  0x79  */
-	u8 resv1[6];			/*					0x7B-0x7F */
+	u8 active;			/* Is this cpu active?			0x1a */
+	u8 available;			/* Is this cpu available?		0x1b */
+	u8 resv1[4];			/*					0x7B-0x7F */
 
 /*=====================================================================================
  * CACHE_LINE_2 0x0080 - 0x00FF
@@ -96,7 +99,9 @@
 	u64 pgtable_cache_sz;		/*					0x18 */
 	u64 next_jiffy_update_tb;	/* TB value for next jiffy update	0x20 */
 	u32 lpEvent_count;		/* lpEvents processed			0x28 */
-	u8  rsvd2[128-5*8-1*4];		/*					0x68 */
+	u8  yielded;                    /* 0 = this processor is running        0x2c */
+					/* 1 = this processor is yielded             */
+	u8  rsvd2[128-5*8-1*4-1];	/*					0x68 */
 
 /*=====================================================================================
  * CACHE_LINE_3 0x0100 - 0x017F
@@ -149,7 +154,9 @@
  * CACHE_LINE_20-30
  *=====================================================================================
  */
-	u8 rsvd6[0x500];
+	u64 slb_shadow[0x20];
+	u64 dispatch_log;
+	u8  rsvd6[0x400 - 0x8];
 
 /*=====================================================================================
  * CACHE_LINE_31 0x0F00 - 0x0F7F Exception stack
diff -urN linux-2.4.24-pre1/include/asm-ppc64/ppc32.h linux-2.4.24-pre2/include/asm-ppc64/ppc32.h
--- linux-2.4.24-pre1/include/asm-ppc64/ppc32.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/ppc32.h	2003-12-22 11:34:36.000000000 -0800
@@ -76,6 +76,13 @@
 	int f_spare[6];
 };
 
+struct ustat32 {
+	__kernel_daddr_t32      f_tfree;
+	__kernel_ino_t32        f_tinode;
+	char                    f_fname[6];
+	char                    f_fpack[6];
+};
+
 typedef union sigval32 {
 	int sival_int;
 	unsigned int sival_ptr;
diff -urN linux-2.4.24-pre1/include/asm-ppc64/processor.h linux-2.4.24-pre2/include/asm-ppc64/processor.h
--- linux-2.4.24-pre1/include/asm-ppc64/processor.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/processor.h	2003-12-22 11:34:36.000000000 -0800
@@ -492,6 +492,7 @@
 #define PLATFORM_PSERIES      0x0100
 #define PLATFORM_PSERIES_LPAR 0x0101
 #define PLATFORM_ISERIES_LPAR 0x0201
+#define PLATFORM_LPAR         0x0001
 	
 /*
  * List of interrupt controllers.
diff -urN linux-2.4.24-pre1/include/asm-ppc64/ptrace.h linux-2.4.24-pre2/include/asm-ppc64/ptrace.h
--- linux-2.4.24-pre1/include/asm-ppc64/ptrace.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/ptrace.h	2003-12-22 11:34:36.000000000 -0800
@@ -66,7 +66,11 @@
 
 #define STACK_FRAME_OVERHEAD	112	/* size of minimum stack frame */
 
-/* Size of dummy stack frame allocated when calling signal handler. */
+/*
+ * Size of dummy stack frame allocated when calling signal handler.
+ * These *MUST* be multiples of 16 since the ABI requires stack frames
+ * be quadword aligned.
+ */
 #define __SIGNAL_FRAMESIZE	128
 #define __SIGNAL_FRAMESIZE32	64
 
diff -urN linux-2.4.24-pre1/include/asm-ppc64/serial.h linux-2.4.24-pre2/include/asm-ppc64/serial.h
--- linux-2.4.24-pre1/include/asm-ppc64/serial.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/serial.h	2003-12-22 11:34:36.000000000 -0800
@@ -26,11 +26,9 @@
 
 /* Standard COM flags (except for COM4, because of the 8514 problem) */
 #ifdef CONFIG_SERIAL_DETECT_IRQ
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
-#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
 #else
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
+#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
 #ifdef CONFIG_SERIAL_MANY_PORTS
@@ -39,7 +37,7 @@
 #define BOCA_FLAGS 0
 #define HUB6_FLAGS 0
 #endif
-	
+
 /*
  * The following define the access methods for the HUB6 card. All
  * access is through two ports for all 24 possible chips. The card is
@@ -60,8 +58,8 @@
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
-	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
-	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
+	{ 0, BASE_BAUD, 0x898, 0xe, STD_COM_FLAGS },	/* ttyS2 */	\
+	{ 0, BASE_BAUD, 0x890, 0xf, STD_COM_FLAGS },	/* ttyS3 */
 
 
 #ifdef CONFIG_SERIAL_MANY_PORTS
diff -urN linux-2.4.24-pre1/include/asm-ppc64/smp.h linux-2.4.24-pre2/include/asm-ppc64/smp.h
--- linux-2.4.24-pre1/include/asm-ppc64/smp.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/smp.h	2003-12-22 11:34:36.000000000 -0800
@@ -41,6 +41,15 @@
 struct pt_regs;
 extern void smp_message_recv(int, struct pt_regs *);
 
+/*
+ * Retrieve the state of a CPU:
+ * online:    CPU is in a normal run state
+ * possible:  CPU is a candidate to be made online
+ * available: CPU is candidate for the 'possible' pool
+ */
+#define cpu_possible(cpu)       paca[cpu].active
+#define cpu_available(cpu)      paca[cpu].available
+
 #define NO_PROC_ID		0xFF            /* No processor magic marker */
 #define PROC_CHANGE_PENALTY	20
 
diff -urN linux-2.4.24-pre1/include/asm-ppc64/spinlock.h linux-2.4.24-pre2/include/asm-ppc64/spinlock.h
--- linux-2.4.24-pre1/include/asm-ppc64/spinlock.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-ppc64/spinlock.h	2003-12-22 11:34:36.000000000 -0800
@@ -6,16 +6,27 @@
  *
  * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
  * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * Type of int is used as a full 64b word is not necessary.
+ * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>, IBM
+ *   Rework to support virtual processors
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
+
+#include <asm/memory.h>
+#include <asm/hvcall.h>
+
+/*
+ * The following define is being used to select basic or shared processor
+ * locking when running on an RPA platform.  As we do more performance
+ * tuning, I would expect this selection mechanism to change.  Dave E.
+ */
+/* #define SPLPAR_LOCKS */
+
 typedef struct {
-	volatile unsigned int lock;
+	volatile unsigned long lock;
 } spinlock_t;
 
 #ifdef __KERNEL__
@@ -25,15 +36,15 @@
 
 static __inline__ int spin_trylock(spinlock_t *lock)
 {
-	unsigned int tmp;
+	unsigned long tmp;
 
 	__asm__ __volatile__(
-"1:	lwarx		%0,0,%1		# spin_trylock\n\
-	cmpwi		0,%0,0\n\
+"1:	ldarx		%0,0,%1		# spin_trylock\n\
+	cmpdi		0,%0,0\n\
 	li		%0,0\n\
 	bne-		2f\n\
 	li		%0,1\n\
-	stwcx.		%0,0,%1\n\
+	stdcx.		13,0,%1\n\
 	bne-		1b\n\
 	isync\n\
 2:"	: "=&r"(tmp)
@@ -43,27 +54,115 @@
 	return tmp;
 }
 
+/*
+ * Spin lock states:
+ *   0        : Unlocked
+ *   Negative : Locked.  Value is paca pointer (0xc...0) of holder
+ */
+#ifdef CONFIG_PPC_ISERIES
 static __inline__ void spin_lock(spinlock_t *lock)
 {
-	unsigned int tmp;
+	unsigned long tmp, tmp2;
 
 	__asm__ __volatile__(
 	"b		2f		# spin_lock\n\
-1:	or		1,1,1		# spin at low priority\n\
-	lwzx		%0,0,%1\n\
-	cmpwi		0,%0,0\n\
+1:"
+	HMT_LOW
+"       ldx		%0,0,%2         # load the lock value\n\
+	cmpdi		0,%0,0          # if not locked, try to acquire\n\
+	beq-		2f\n\
+	lwz             5,0x280(%0)     # load yield counter\n\
+	andi.           %1,5,1          # if even then spin\n\
+	beq             1b\n\
+	lwsync                          # if odd, give up cycles\n\
+	ldx             %1,0,%2         # reverify the lock holder\n\
+	cmpd            %0,%1\n\
+	bne             1b              # new holder so restart\n\
+	li              3,0x25          # yield hcall 0x8-12 \n\
+	rotrdi          3,3,1           #   put the bits in the right spot\n\
+	lhz             4,0x18(%0)      # processor number\n\
+	sldi            4,4,32          #   move into top half of word\n\
+	or              5,5,4           # r5 has yield cnt - or it in\n\
+	li              4,2             # yield to processor\n\
+	li              0,-1            # indicate an hcall\n\
+	sc                              # do the hcall \n\
+	b               1b\n\
+2: \n"
+	HMT_MEDIUM
+" 	ldarx		%0,0,%2\n\
+	cmpdi		0,%0,0\n\
+	bne-		1b\n\
+	stdcx.		13,0,%2\n\
+	bne-		2b\n\
+	isync"
+	: "=&r"(tmp), "=&r"(tmp2)
+	: "r"(&lock->lock)
+	: "r0", "r3", "r4", "r5", "ctr", "cr0", "cr1", "cr2", "cr3", "cr4",
+	  "xer", "memory");
+}
+#else
+#ifdef SPLPAR_LOCKS
+static __inline__ void spin_lock(spinlock_t *lock)
+{
+	unsigned long tmp, tmp2;
+
+	__asm__ __volatile__(
+	"b		2f		# spin_lock\n\
+1:"
+	HMT_LOW
+"       ldx		%0,0,%2         # load the lock value\n\
+	cmpdi		0,%0,0          # if not locked, try to acquire\n\
+	beq-		2f\n\
+	lwz             5,0x280(%0)     # load dispatch counter\n\
+	andi.           %1,5,1          # if even then spin\n\
+	beq             1b\n\
+	lwsync                          # if odd, give up cycles\n\
+	ldx             %1,0,%2         # reverify the lock holder\n\
+	cmpd            %0,%1\n\
+	bne             1b              # new holder so restart\n\
+	li              3,0xE4          # give up the cycles H_CONFER\n\
+	lhz             4,0x18(%0)      # processor number\n\
+					# r5 has dispatch cnt already\n"
+	HVSC
+"        b               1b\n\
+2: \n"
+	HMT_MEDIUM
+" 	ldarx		%0,0,%2\n\
+	cmpdi		0,%0,0\n\
+	bne-		1b\n\
+	stdcx.		13,0,%2\n\
+	bne-		2b\n\
+	isync"
+	: "=&r"(tmp), "=&r"(tmp2)
+	: "r"(&lock->lock)
+	: "r3", "r4", "r5", "cr0", "cr1", "ctr", "xer", "memory");
+}
+#else
+static __inline__ void spin_lock(spinlock_t *lock)
+{
+	unsigned long tmp;
+
+	__asm__ __volatile__(
+       "b		2f		# spin_lock\n\
+1:"
+	HMT_LOW
+"       ldx		%0,0,%1         # load the lock value\n\
+	cmpdi		0,%0,0          # if not locked, try to acquire\n\
 	bne+		1b\n\
-	or		2,2,2		# back to medium priority\n\
-2:	lwarx		%0,0,%1\n\
-	cmpwi		0,%0,0\n\
+2: \n"
+	HMT_MEDIUM
+" 	ldarx		%0,0,%1\n\
+	cmpdi		0,%0,0\n\
 	bne-		1b\n\
-	stwcx.		%2,0,%1\n\
+	stdcx.		13,0,%1\n\
 	bne-		2b\n\
 	isync"
 	: "=&r"(tmp)
-	: "r"(&lock->lock), "r"(1)
+	: "r"(&lock->lock)
 	: "cr0", "memory");
 }
+#endif
+#endif
 
 static __inline__ void spin_unlock(spinlock_t *lock)
 {
@@ -80,25 +179,33 @@
  * can "mix" irq-safe locks - any writer needs to get a
  * irq-safe write-lock, but readers can get non-irqsafe
  * read-locks.
+ *
+ * Write lock states:
+ *   0        : Unlocked
+ *   Positive : Reader count
+ *   Negative : Writer locked.  Value is paca pointer (0xc...0) of holder
+ *
+ * If lock is not held, try to acquire.
+ * If lock is held by a writer, yield cycles to the holder.
+ * If lock is help by reader(s), spin.
  */
 typedef struct {
-	volatile signed int lock;
+	volatile signed long lock;
 } rwlock_t;
 
 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 
 static __inline__ int read_trylock(rwlock_t *rw)
 {
-	unsigned int tmp;
+	unsigned long tmp;
 	unsigned int ret;
 
 	__asm__ __volatile__(
-"1:	lwarx		%0,0,%2		# read_trylock\n\
+"1:	ldarx		%0,0,%2		# read_trylock\n\
 	li		%1,0\n\
-	extsw		%0,%0\n\
 	addic.		%0,%0,1\n\
 	ble-		2f\n\
-	stwcx.		%0,0,%2\n\
+	stdcx.		%0,0,%2\n\
 	bne-		1b\n\
 	li		%1,1\n\
 	isync\n\
@@ -109,38 +216,118 @@
 	return ret;
 }
 
+#ifdef CONFIG_PPC_ISERIES
+static __inline__ void read_lock(rwlock_t *rw)
+{
+	unsigned long tmp, tmp2;
+
+	__asm__ __volatile__(
+	"b		2f		# read_lock\n\
+1:"
+	HMT_LOW
+"	ldx		%0,0,%2\n\
+	cmpdi		0,%0,0\n\
+	bge-		2f\n\
+	lwz             5,0x280(%0)     # load yield counter\n\
+	andi.           %1,5,1          # if even then spin\n\
+	beq             1b\n\
+	lwsync                          # if odd, give up cycles\n\
+	ldx             %1,0,%2         # reverify the lock holder\n\
+	cmpd            %0,%1\n\
+	bne             1b              # new holder so restart\n\
+	li              3,0x25          # yield hcall 0x8-12 \n\
+	rotrdi          3,3,1           #   put the bits in the right spot\n\
+	lhz             4,0x18(%0)      # processor number\n\
+	sldi            4,4,32          #   move into top half of word\n\
+	or              5,5,4           # r5 has yield cnt - or it in\n\
+	li              4,2             # yield to processor\n\
+	li              0,-1            # indicate an hcall\n\
+	sc                              # do the hcall \n\
+2: \n"
+	HMT_MEDIUM
+" 	ldarx		%0,0,%2\n\
+	addic.		%0,%0,1\n\
+	ble-		1b\n\
+	stdcx.		%0,0,%2\n\
+	bne-		2b\n\
+	isync"
+	: "=&r"(tmp), "=&r"(tmp2)
+	: "r"(&rw->lock)
+	: "r0", "r3", "r4", "r5", "ctr", "cr0", "cr1", "cr2", "cr3", "cr4",
+	  "xer", "memory");
+}
+#else
+#ifdef SPLPAR_LOCKS
+static __inline__ void read_lock(rwlock_t *rw)
+{
+	unsigned long tmp, tmp2;
+
+	__asm__ __volatile__(
+	"b		2f		# read_lock\n\
+1:"
+	HMT_LOW
+"	ldx		%0,0,%2\n\
+	cmpdi		0,%0,0\n\
+	bge-		2f\n\
+	lwz             5,0x280(%0)     # load dispatch counter\n\
+	andi.           %1,5,1          # if even then spin\n\
+	beq             1b\n\
+	lwsync                          # if odd, give up cycles\n\
+	ldx             %1,0,%2         # reverify the lock holder\n\
+	cmpd            %0,%1\n\
+	bne             1b              # new holder so restart\n\
+	li              3,0xE4          # give up the cycles H_CONFER\n\
+	lhz             4,0x18(%0)      # processor number\n\
+					# r5 has dispatch cnt already\n"
+	HVSC
+"2: \n"
+	HMT_MEDIUM
+" 	ldarx		%0,0,%2\n\
+	addic.		%0,%0,1\n\
+	ble-		1b\n\
+	stdcx.		%0,0,%2\n\
+	bne-		2b\n\
+	isync"
+	: "=&r"(tmp), "=&r"(tmp2)
+	: "r"(&rw->lock)
+	: "r3", "r4", "r5", "cr0", "cr1", "ctr", "xer", "memory");
+}
+#else
 static __inline__ void read_lock(rwlock_t *rw)
 {
-	unsigned int tmp;
+	unsigned long tmp;
 
 	__asm__ __volatile__(
 	"b		2f		# read_lock\n\
-1:	or		1,1,1		# spin at low priority\n\
-	lwax		%0,0,%1\n\
-	cmpwi		0,%0,0\n\
+1:"
+	HMT_LOW
+"	ldx		%0,0,%1\n\
+	cmpdi		0,%0,0\n\
 	blt+		1b\n\
-	or		2,2,2		# back to medium priority\n\
-2:	lwarx		%0,0,%1\n\
-	extsw		%0,%0\n\
+2: \n"
+	HMT_MEDIUM
+" 	ldarx		%0,0,%1\n\
 	addic.		%0,%0,1\n\
 	ble-		1b\n\
-	stwcx.		%0,0,%1\n\
+	stdcx.		%0,0,%1\n\
 	bne-		2b\n\
 	isync"
 	: "=&r"(tmp)
 	: "r"(&rw->lock)
 	: "cr0", "memory");
 }
+#endif
+#endif
 
 static __inline__ void read_unlock(rwlock_t *rw)
 {
-	unsigned int tmp;
+	unsigned long tmp;
 
 	__asm__ __volatile__(
-	"lwsync				# read_unlock\n\
-1:	lwarx		%0,0,%1\n\
+	"eieio				# read_unlock\n\
+1:	ldarx		%0,0,%1\n\
 	addic		%0,%0,-1\n\
-	stwcx.		%0,0,%1\n\
+	stdcx.		%0,0,%1\n\
 	bne-		1b"
 	: "=&r"(tmp)
 	: "r"(&rw->lock)
@@ -149,46 +336,131 @@
 
 static __inline__ int write_trylock(rwlock_t *rw)
 {
-	unsigned int tmp;
-	unsigned int ret;
+	unsigned long tmp;
+	unsigned long ret;
 
 	__asm__ __volatile__(
-"1:	lwarx		%0,0,%2		# write_trylock\n\
-	cmpwi		0,%0,0\n\
+"1:	ldarx		%0,0,%2		# write_trylock\n\
+	cmpdi		0,%0,0\n\
 	li		%1,0\n\
 	bne-		2f\n\
-	stwcx.		%3,0,%2\n\
+	stdcx.		13,0,%2\n\
 	bne-		1b\n\
 	li		%1,1\n\
 	isync\n\
 2:"	: "=&r"(tmp), "=&r"(ret)
-	: "r"(&rw->lock), "r"(-1)
+	: "r"(&rw->lock)
 	: "cr0", "memory");
 
 	return ret;
 }
 
+#ifdef CONFIG_PPC_ISERIES
+static __inline__ void write_lock(rwlock_t *rw)
+{
+	unsigned long tmp, tmp2;
+
+	__asm__ __volatile__(
+	"b		2f		# spin_lock\n\
+1:"
+	HMT_LOW
+"       ldx		%0,0,%2         # load the lock value\n\
+	cmpdi		0,%0,0          # if not locked(0), try to acquire\n\
+	beq-		2f\n\
+	bgt             1b              # negative(0xc..)->cycles to holder\n"
+"3:     lwz             5,0x280(%0)     # load yield counter\n\
+	andi.           %1,5,1          # if even then spin\n\
+	beq             1b\n\
+	lwsync                          # if odd, give up cycles\n\
+	ldx             %1,0,%2         # reverify the lock holder\n\
+	cmpd            %0,%1\n\
+	bne             1b              # new holder so restart\n\
+	lhz             4,0x18(%0)      # processor number\n\
+	sldi            4,4,32          #   move into top half of word\n\
+	or              5,5,4           # r5 has yield cnt - or it in\n\
+	li              3,0x25          # yield hcall 0x8-12 \n\
+	rotrdi          3,3,1           #   put the bits in the right spot\n\
+	li              4,2             # yield to processor\n\
+	li              0,-1            # indicate an hcall\n\
+	sc                              # do the hcall \n\
+2: \n"
+	HMT_MEDIUM
+" 	ldarx		%0,0,%2\n\
+	cmpdi		0,%0,0\n\
+	bne-		1b\n\
+	stdcx.		13,0,%2\n\
+	bne-		2b\n\
+	isync"
+	: "=&r"(tmp), "=&r"(tmp2)
+	: "r"(&rw->lock)
+	: "r0", "r3", "r4", "r5", "ctr", "cr0", "cr1", "cr2", "cr3", "cr4",
+	  "xer", "memory");
+}
+#else
+#ifdef SPLPAR_LOCKS
+static __inline__ void write_lock(rwlock_t *rw)
+{
+	unsigned long tmp, tmp2;
+
+	__asm__ __volatile__(
+	"b		2f		# spin_lock\n\
+1:"
+	HMT_LOW
+"       ldx		%0,0,%2         # load the lock value\n\
+	li              3,0xE4          # give up the cycles H_CONFER\n\
+	cmpdi		0,%0,0          # if not locked(0), try to acquire\n\
+	beq-		2f\n\
+	blt             3f              # negative(0xc..)->confer to holder\n\
+	b               1b\n"
+"3:      lwz             5,0x280(%0)     # load dispatch counter\n\
+	andi.           %1,5,1          # if even then spin\n\
+	beq             1b\n\
+	lwsync                          # if odd, give up cycles\n\
+	ldx             %1,0,%2         # reverify the lock holder\n\
+	cmpd            %0,%1\n\
+	bne             1b              # new holder so restart\n\
+	lhz             4,0x18(%0)      # processor number\n\
+					# r5 has dispatch cnt already\n"
+	HVSC
+"        b               1b\n\
+2: \n"
+	HMT_MEDIUM
+" 	ldarx		%0,0,%2\n\
+	cmpdi		0,%0,0\n\
+	bne-		1b\n\
+	stdcx.		13,0,%2\n\
+	bne-		2b\n\
+	isync"
+	: "=&r"(tmp), "=&r"(tmp2)
+	: "r"(&rw->lock)
+	: "r3", "r4", "r5", "cr0", "cr1", "ctr", "xer", "memory");
+}
+#else
 static __inline__ void write_lock(rwlock_t *rw)
 {
-	unsigned int tmp;
+	unsigned long tmp;
 
 	__asm__ __volatile__(
-	"b		2f		# write_lock\n\
-1:	or		1,1,1		# spin at low priority\n\
-	lwax		%0,0,%1\n\
-	cmpwi		0,%0,0\n\
+	"b		2f		# spin_lock\n\
+1:"
+	HMT_LOW
+"       ldx		%0,0,%1         # load the lock value\n\
+	cmpdi		0,%0,0          # if not locked(0), try to acquire\n\
 	bne+		1b\n\
-	or		2,2,2		# back to medium priority\n\
-2:	lwarx		%0,0,%1\n\
-	cmpwi		0,%0,0\n\
+2: \n"
+	HMT_MEDIUM
+" 	ldarx		%0,0,%1\n\
+	cmpdi		0,%0,0\n\
 	bne-		1b\n\
-	stwcx.		%2,0,%1\n\
+	stdcx.		13,0,%1\n\
 	bne-		2b\n\
 	isync"
 	: "=&r"(tmp)
-	: "r"(&rw->lock), "r"(-1)
+	: "r"(&rw->lock)
 	: "cr0", "memory");
 }
+#endif
+#endif
 
 static __inline__ void write_unlock(rwlock_t *rw)
 {
diff -urN linux-2.4.24-pre1/include/asm-ppc64/vio.h linux-2.4.24-pre2/include/asm-ppc64/vio.h
--- linux-2.4.24-pre1/include/asm-ppc64/vio.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-ppc64/vio.h	2003-12-22 11:34:36.000000000 -0800
@@ -0,0 +1,129 @@
+/*
+ * IBM PowerPC Virtual I/O Infrastructure Support.
+ *
+ * Dave Engebretsen engebret@us.ibm.com
+ *    Copyright (c) 2003 Dave Engebretsen
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _VIO_H
+#define _VIO_H
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <asm/hvcall.h>
+#include <asm/prom.h>
+#include <asm/scatterlist.h>
+/*
+ * Architecture-specific constants for drivers to
+ * extract attributes of the device using vio_get_attribute()
+*/
+#define VETH_MAC_ADDR "local-mac-address"
+#define VETH_MCAST_FILTER_SIZE "ibm,mac-address-filters"
+
+/* End architecture-specific constants */
+
+#define h_vio_signal(ua, mode) \
+  plpar_hcall_norets(H_VIO_SIGNAL, ua, mode)
+
+#define VIO_IRQ_DISABLE		0UL
+#define VIO_IRQ_ENABLE		1UL
+
+struct vio_dev;
+struct vio_driver;
+struct vio_device_id;
+struct TceTable;
+
+int vio_register_driver(struct vio_driver *drv);
+int vio_unregister_driver(struct vio_driver *drv);
+const struct vio_device_id * vio_match_device(const struct vio_device_id *ids,
+						const struct vio_dev *dev);
+struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev);
+struct vio_driver * __devinit vio_find_driver(struct vio_dev* dev);
+const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length);
+int vio_get_irq(struct vio_dev *dev);
+struct TceTable * vio_build_tce_table(struct vio_dev *dev);
+int vio_enable_interrupts(struct vio_dev *dev);
+int vio_disable_interrupts(struct vio_dev *dev);
+
+dma_addr_t vio_map_single(struct vio_dev *dev, void *vaddr,
+			  size_t size, int direction);
+void vio_unmap_single(struct vio_dev *dev, dma_addr_t dma_handle,
+		      size_t size, int direction);
+int vio_map_sg(struct vio_dev *vdev, struct scatterlist *sglist,
+	       int nelems, int direction);
+void vio_unmap_sg(struct vio_dev *vdev, struct scatterlist *sglist,
+		  int nelems, int direction);
+void *vio_alloc_consistent(struct vio_dev *dev, size_t size,
+			   dma_addr_t *dma_handle);
+void vio_free_consistent(struct vio_dev *dev, size_t size, void *vaddr,
+			 dma_addr_t dma_handle);
+
+struct vio_device_id {
+	char *type;
+	char *compat;
+/* I don't think we need this
+	unsigned long driver_data;	*/ /* Data private to the driver */
+};
+
+struct vio_driver {
+	struct list_head node;
+	char *name;
+	const struct vio_device_id *id_table;	/* NULL if wants all devices */
+	int  (*probe)  (struct vio_dev *dev, const struct vio_device_id *id);	/* New device inserted */
+	void (*remove) (struct vio_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
+	unsigned long driver_data;
+};
+
+struct vio_bus;
+/*
+ * The vio_dev structure is used to describe virtual I/O devices.
+ */
+struct vio_dev {
+	struct list_head devices_list;   /* node in list of all vio devices */
+	struct device_node *archdata;    /* Open Firmware node */
+	struct vio_bus *bus;            /* bus this device is on */
+	struct vio_driver *driver;      /* owning driver */
+	void *driver_data;              /* data private to the driver */
+	unsigned long unit_address;
+
+	struct TceTable *tce_table; /* vio_map_* uses this */
+	unsigned int irq;
+	struct proc_dir_entry *procent; /* device entry in /proc/bus/vio */
+};
+
+struct vio_bus {
+	struct list_head devices;       /* list of virtual devices */
+};
+
+
+static inline int vio_module_init(struct vio_driver *drv)
+{
+	int rc = vio_register_driver (drv);
+
+	if (rc > 0)
+		return 0;
+
+	/* iff CONFIG_HOTPLUG and built into kernel, we should
+	 * leave the driver around for future hotplug events.
+	 * For the module case, a hotplug daemon of some sort
+	 * should load a module in response to an insert event. */
+#if defined(CONFIG_HOTPLUG) && !defined(MODULE)
+	if (rc == 0)
+		return 0;
+#else
+	if (rc == 0)
+		rc = -ENODEV;
+#endif
+
+	/* if we get here, we need to clean up vio driver instance
+	 * and return some sort of error */
+
+	return rc;
+}
+
+#endif /* _PHYP_H */
diff -urN linux-2.4.24-pre1/include/asm-sparc/openprom.h linux-2.4.24-pre2/include/asm-sparc/openprom.h
--- linux-2.4.24-pre1/include/asm-sparc/openprom.h	2000-06-19 17:59:39.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-sparc/openprom.h	2003-12-22 11:34:36.000000000 -0800
@@ -169,6 +169,8 @@
 	int (*v3_cpuresume)(unsigned int whichcpu);
 };
 
+extern struct linux_romvec *romvec;
+
 /* Routines for traversing the prom device tree. */
 struct linux_nodeops {
 	int (*no_nextnode)(int node);
diff -urN linux-2.4.24-pre1/include/asm-sparc/oplib.h linux-2.4.24-pre2/include/asm-sparc/oplib.h
--- linux-2.4.24-pre1/include/asm-sparc/oplib.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/asm-sparc/oplib.h	2003-12-22 11:34:36.000000000 -0800
@@ -11,9 +11,6 @@
 #include <asm/openprom.h>
 #include <linux/spinlock.h>
 
-/* The master romvec pointer... */
-extern struct linux_romvec *romvec;
-
 /* Enumeration to describe the prom major version we have detected. */
 enum prom_major_version {
 	PROM_V0,      /* Original sun4c V0 prom */
diff -urN linux-2.4.24-pre1/include/asm-sparc/system.h linux-2.4.24-pre2/include/asm-sparc/system.h
--- linux-2.4.24-pre1/include/asm-sparc/system.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.24-pre2/include/asm-sparc/system.h	2003-12-22 11:34:36.000000000 -0800
@@ -10,7 +10,6 @@
 
 #ifdef __KERNEL__
 #include <asm/page.h>
-#include <asm/oplib.h>
 #include <asm/psr.h>
 #include <asm/ptrace.h>
 #include <asm/btfixup.h>
@@ -52,9 +51,6 @@
 extern unsigned long empty_bad_page_table;
 extern unsigned long empty_zero_page;
 
-extern struct linux_romvec *romvec;
-#define halt() romvec->pv_halt()
-
 /* When a context switch happens we must flush all user windows so that
  * the windows of the current process are flushed onto its stack. This
  * way the windows are all clean for the next process and the stack
diff -urN linux-2.4.24-pre1/include/linux/i2c-id.h linux-2.4.24-pre2/include/linux/i2c-id.h
--- linux-2.4.24-pre1/include/linux/i2c-id.h	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/include/linux/i2c-id.h	2003-12-22 11:34:36.000000000 -0800
@@ -90,7 +90,7 @@
 #define I2C_DRIVERID_DRP3510	43     /* ADR decoder (Astra Radio)	*/
 #define I2C_DRIVERID_SP5055	44     /* Satellite tuner		*/
 #define I2C_DRIVERID_STV0030	45     /* Multipurpose switch		*/
-#define I2C_DRIVERID_ADV717X   48     /* video encoder                 */
+#define I2C_DRIVERID_ADV7175	48     /* ADV 7175/7176 video encoder	*/
 #define I2C_DRIVERID_MAX1617	56     /* temp sensor			*/
 #define I2C_DRIVERID_SAA7191	57     /* video decoder                 */
 #define I2C_DRIVERID_INDYCAM	58     /* SGI IndyCam			*/
@@ -213,7 +213,7 @@
 #define I2C_HW_SMBUS_AMD756	0x05
 #define I2C_HW_SMBUS_SIS5595	0x06
 #define I2C_HW_SMBUS_ALI1535	0x07
-#define I2C_HW_SMBUS_W9968CF	0x08
+#define I2C_HW_SMBUS_W9968CF	0x0d
 
 /* --- ISA pseudo-adapter						*/
 #define I2C_HW_ISA 0x00
diff -urN linux-2.4.24-pre1/include/linux/input.h linux-2.4.24-pre2/include/linux/input.h
--- linux-2.4.24-pre1/include/linux/input.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.24-pre2/include/linux/input.h	2003-12-22 11:34:36.000000000 -0800
@@ -472,7 +472,8 @@
 #define BUS_PCI			0x01
 #define BUS_ISAPNP		0x02
 #define BUS_USB			0x03
-#define BUS_HIL                 0x04
+#define BUS_HIL			0x04
+#define BUS_BLUETOOTH		0x05
 
 #define BUS_ISA			0x10
 #define BUS_I8042		0x11
diff -urN linux-2.4.24-pre1/include/linux/uinput.h linux-2.4.24-pre2/include/linux/uinput.h
--- linux-2.4.24-pre1/include/linux/uinput.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.24-pre2/include/linux/uinput.h	2003-12-22 11:34:36.000000000 -0800
@@ -0,0 +1,79 @@
+/*
+ *  User level driver support for input subsystem
+ *
+ * Heavily based on evdev.c by Vojtech Pavlik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
+ * 
+ * Changes/Revisions:
+ *	0.1	20/06/2002
+ *		- first public version
+ */
+
+#ifndef __UINPUT_H_
+#define __UINPUT_H_
+
+#ifdef __KERNEL__
+#define UINPUT_MINOR		223
+#define UINPUT_NAME		"uinput"
+#define UINPUT_BUFFER_SIZE	16
+
+/* state flags => bit index for {set|clear|test}_bit ops */
+#define UIST_CREATED		0
+
+struct uinput_device {
+	struct input_dev	*dev;
+	unsigned long		state;
+	wait_queue_head_t	waitq;
+	unsigned char		ready,
+				head,
+				tail;
+	struct input_event	buff[UINPUT_BUFFER_SIZE];
+};
+#endif	/* __KERNEL__ */
+
+/* ioctl */
+#define UINPUT_IOCTL_BASE	'U'
+#define UI_DEV_CREATE		_IO(UINPUT_IOCTL_BASE, 1)
+#define UI_DEV_DESTROY		_IO(UINPUT_IOCTL_BASE, 2)
+#define UI_SET_EVBIT		_IOW(UINPUT_IOCTL_BASE, 100, int)
+#define UI_SET_KEYBIT		_IOW(UINPUT_IOCTL_BASE, 101, int)
+#define UI_SET_RELBIT		_IOW(UINPUT_IOCTL_BASE, 102, int)
+#define UI_SET_ABSBIT		_IOW(UINPUT_IOCTL_BASE, 103, int)
+#define UI_SET_MSCBIT		_IOW(UINPUT_IOCTL_BASE, 104, int)
+#define UI_SET_LEDBIT		_IOW(UINPUT_IOCTL_BASE, 105, int)
+#define UI_SET_SNDBIT		_IOW(UINPUT_IOCTL_BASE, 106, int)
+#define UI_SET_FFBIT		_IOW(UINPUT_IOCTL_BASE, 107, int)
+
+#ifndef NBITS
+#define NBITS(x) ((((x)-1)/(sizeof(long)*8))+1)
+#endif	/* NBITS */
+
+#define UINPUT_MAX_NAME_SIZE	80
+struct uinput_user_dev {
+	char name[UINPUT_MAX_NAME_SIZE];
+	unsigned short idbus;
+	unsigned short idvendor;
+	unsigned short idproduct;
+	unsigned short idversion;
+	int ff_effects_max;
+	int absmax[ABS_MAX + 1];
+	int absmin[ABS_MAX + 1];
+	int absfuzz[ABS_MAX + 1];
+	int absflat[ABS_MAX + 1];
+};
+#endif	/* __UINPUT_H_ */
diff -urN linux-2.4.24-pre1/include/net/bluetooth/hci.h linux-2.4.24-pre2/include/net/bluetooth/hci.h
--- linux-2.4.24-pre1/include/net/bluetooth/hci.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/include/net/bluetooth/hci.h	2003-12-22 11:34:36.000000000 -0800
@@ -462,6 +462,17 @@
 } __attribute__ ((packed)) inquiry_info;
 #define INQUIRY_INFO_SIZE 14
 
+#define EVT_INQUIRY_RESULT_WITH_RSSI	0x22
+typedef struct {
+	bdaddr_t	bdaddr;
+	__u8	pscan_rep_mode;
+	__u8	pscan_period_mode;
+	__u8	dev_class[3];
+	__u16	clock_offset;
+	__u8	rssi;
+} __attribute__ ((packed)) inquiry_info_with_rssi;
+#define INQUIRY_INFO_WITH_RSSI_SIZE 14
+
 #define EVT_CONN_COMPLETE 	0x03
 typedef struct {
 	__u8	status;
diff -urN linux-2.4.24-pre1/kernel/fork.c linux-2.4.24-pre2/kernel/fork.c
--- linux-2.4.24-pre1/kernel/fork.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/kernel/fork.c	2003-12-22 11:34:36.000000000 -0800
@@ -114,8 +114,10 @@
 						last_pid = 300;
 					next_safe = PID_MAX;
 				}
-				if(unlikely(last_pid == beginpid))
+				if(unlikely(last_pid == beginpid)) {
+					next_safe = 0;
 					goto nomorepids;
+				}
 				goto repeat;
 			}
 			if(p->pid > last_pid && next_safe > p->pid)
diff -urN linux-2.4.24-pre1/mm/page_alloc.c linux-2.4.24-pre2/mm/page_alloc.c
--- linux-2.4.24-pre1/mm/page_alloc.c	2003-12-22 11:34:31.000000000 -0800
+++ linux-2.4.24-pre2/mm/page_alloc.c	2003-12-22 11:34:36.000000000 -0800
@@ -378,8 +378,8 @@
 
 	/* here we're in the low on memory slow path */
 
-	if (((current->flags & PF_MEMALLOC) && !in_interrupt()) || 
-			(current->flags & (PF_MEMALLOC | PF_MEMDIE))) {
+	if ((current->flags & PF_MEMALLOC) && 
+			(!in_interrupt() || (current->flags & PF_MEMDIE))) {
 		zone = zonelist->zones;
 		for (;;) {
 			zone_t *z = *(zone++);
diff -urN linux-2.4.24-pre1/net/bluetooth/bnep/sock.c linux-2.4.24-pre2/net/bluetooth/bnep/sock.c
--- linux-2.4.24-pre1/net/bluetooth/bnep/sock.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.24-pre2/net/bluetooth/bnep/sock.c	2003-12-22 11:34:36.000000000 -0800
@@ -55,36 +55,6 @@
 #define BT_DBG( A... )
 #endif
 
-static inline struct socket *socki_lookup(struct inode *inode)
-{
-	return &inode->u.socket_i;
-}
-
-static struct socket *sockfd_lookup(int fd, int *err)
-{
-	struct file *file;
-	struct inode *inode;
-	struct socket *sock;
-
-	if (!(file = fget(fd))) {
-		*err = -EBADF;
-		return NULL;
-	}
-
-	inode = file->f_dentry->d_inode;
-	if (!inode->i_sock || !(sock = socki_lookup(inode))) {
-		*err = -ENOTSOCK;
-		fput(file);
-		return NULL;
-	}
-
-	if (sock->file != file) {
-		printk(KERN_ERR "socki_lookup: socket file changed!\n");
-		sock->file = file;
-	}
-	return sock;
-}
- 
 static int bnep_sock_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
diff -urN linux-2.4.24-pre1/net/bluetooth/cmtp/sock.c linux-2.4.24-pre2/net/bluetooth/cmtp/sock.c
--- linux-2.4.24-pre1/net/bluetooth/cmtp/sock.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/net/bluetooth/cmtp/sock.c	2003-12-22 11:34:36.000000000 -0800
@@ -47,36 +47,6 @@
 #define BT_DBG(D...)
 #endif
 
-static inline struct socket *socki_lookup(struct inode *inode)
-{
-	return &inode->u.socket_i;
-}
-
-static struct socket *sockfd_lookup(int fd, int *err)
-{
-	struct file *file;
-	struct inode *inode;
-	struct socket *sock;
-
-	if (!(file = fget(fd))) {
-		*err = -EBADF;
-		return NULL;
-	}
-
-	inode = file->f_dentry->d_inode;
-	if (!inode->i_sock || !(sock = socki_lookup(inode))) {
-		*err = -ENOTSOCK;
-		fput(file);
-		return NULL;
-	}
-
-	if (sock->file != file) {
-		printk(KERN_ERR "socki_lookup: socket file changed!\n");
-		sock->file = file;
-	}
-	return sock;
-}
-
 static int cmtp_sock_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
diff -urN linux-2.4.24-pre1/net/bluetooth/hci_event.c linux-2.4.24-pre2/net/bluetooth/hci_event.c
--- linux-2.4.24-pre1/net/bluetooth/hci_event.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/net/bluetooth/hci_event.c	2003-12-22 11:34:36.000000000 -0800
@@ -452,6 +452,29 @@
 	hci_dev_unlock(hdev);
 }
 
+/* Inquiry Result With RSSI */
+static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	inquiry_info_with_rssi *info = (inquiry_info_with_rssi *) (skb->data + 1);
+	int num_rsp = *((__u8 *) skb->data);
+
+	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+
+	hci_dev_lock(hdev);
+	for (; num_rsp; num_rsp--) {
+		inquiry_info tmp;
+		bacpy(&tmp.bdaddr, &info->bdaddr);
+		tmp.pscan_rep_mode    = info->pscan_rep_mode;
+		tmp.pscan_period_mode = info->pscan_period_mode;
+		tmp.pscan_mode        = 0x00;
+		memcpy(tmp.dev_class, &info->dev_class, 3);
+		tmp.clock_offset      = info->clock_offset;
+		info++;
+		inquiry_cache_update(hdev, &tmp);
+	}
+	hci_dev_unlock(hdev);
+}
+
 /* Connect Request */
 static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
@@ -748,6 +771,10 @@
 		hci_inquiry_result_evt(hdev, skb);
 		break;
 
+	case EVT_INQUIRY_RESULT_WITH_RSSI:
+		hci_inquiry_result_with_rssi_evt(hdev, skb);
+		break;
+
 	case EVT_CONN_REQUEST:
 		hci_conn_request_evt(hdev, skb);
 		break;
diff -urN linux-2.4.24-pre1/net/bluetooth/hci_sock.c linux-2.4.24-pre2/net/bluetooth/hci_sock.c
--- linux-2.4.24-pre1/net/bluetooth/hci_sock.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/net/bluetooth/hci_sock.c	2003-12-22 11:34:36.000000000 -0800
@@ -66,20 +66,20 @@
 	/* Packet types */
 	0x10,
 	/* Events */
-	{ 0xd9fe, 0x0 },
+	{ 0x1000d9fe, 0x0000300c },
 	/* Commands */
 	{
 		{ 0x0 },
 		/* OGF_LINK_CTL */
-		{ 0x2a000002, 0x0, 0x0, 0x0  },
+		{ 0xbe000006, 0x00000001, 0x0000, 0x00 },
 		/* OGF_LINK_POLICY */
-		{ 0x1200, 0x0, 0x0, 0x0      },
+		{ 0x00005200, 0x00000000, 0x0000, 0x00 },
 		/* OGF_HOST_CTL */
-		{ 0x80100000, 0x202a, 0x0, 0x0 },
+		{ 0xaab00200, 0x2b402aaa, 0x0154, 0x00 },
 		/* OGF_INFO_PARAM */
-		{ 0x22a, 0x0, 0x0, 0x0       },
+		{ 0x000002be, 0x00000000, 0x0000, 0x00 },
 		/* OGF_STATUS_PARAM */
-		{ 0x2e, 0x0, 0x0, 0x0        }
+		{ 0x000000ea, 0x00000000, 0x0000, 0x00 }
 	}
 };
 
diff -urN linux-2.4.24-pre1/net/irda/irnet/irnet.h linux-2.4.24-pre2/net/irda/irnet/irnet.h
--- linux-2.4.24-pre1/net/irda/irnet/irnet.h	2003-11-28 10:26:21.000000000 -0800
+++ linux-2.4.24-pre2/net/irda/irnet/irnet.h	2003-12-22 11:34:36.000000000 -0800
@@ -322,29 +322,29 @@
  * compiler will optimise away the if() in all cases.
  */
 /* All error messages (will show up in the normal logs) */
-#define DERROR(dbg, args...) \
+#define DERROR(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-		printk(KERN_INFO "irnet: %s(): ", __FUNCTION__); printk(args);}
+		printk(KERN_INFO "irnet: %s(): " format, __FUNCTION__ , ##args);}
 
 /* Normal debug message (will show up in /var/log/debug) */
-#define DEBUG(dbg, args...) \
+#define DEBUG(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-		printk(KERN_DEBUG "irnet: %s(): ", __FUNCTION__); printk(args);}
+		printk(KERN_DEBUG "irnet: %s(): " format, __FUNCTION__ , ##args);}
 
 /* Entering a function (trace) */
-#define DENTER(dbg, args...) \
+#define DENTER(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-	printk(KERN_DEBUG "irnet: ->%s", __FUNCTION__); printk(args);}
+		printk(KERN_DEBUG "irnet: -> %s" format, __FUNCTION__ , ##args);}
 
 /* Entering and exiting a function in one go (trace) */
-#define DPASS(dbg, args...) \
+#define DPASS(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-		printk(KERN_DEBUG "irnet: <>%s", __FUNCTION__); printk(args);}
+		printk(KERN_DEBUG "irnet: <>%s" format, __FUNCTION__ , ##args);}
 
 /* Exiting a function (trace) */
-#define DEXIT(dbg, args...) \
+#define DEXIT(dbg, format, args...) \
 	{if(DEBUG_##dbg) \
-		printk(KERN_DEBUG "irnet: <-%s()", __FUNCTION__); printk(args);}
+		printk(KERN_DEBUG "irnet: <-%s()" format, __FUNCTION__ , ##args);}
 
 /* Exit a function with debug */
 #define DRETURN(ret, dbg, args...) \
diff -urN linux-2.4.24-pre1/scripts/ver_linux linux-2.4.24-pre2/scripts/ver_linux
--- linux-2.4.24-pre1/scripts/ver_linux	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.24-pre2/scripts/ver_linux	2003-12-22 11:34:36.000000000 -0800
@@ -39,6 +39,9 @@
 reiserfsck -V 2>&1 | grep reiserfsprogs | awk \
 'NR==1{print "reiserfsprogs         ", $NF}'
 
+xfs_db -V 2>&1 | grep version | awk \
+'NR==1{print "xfsprogs              ", $3}'
+
 cardmgr -V 2>&1| grep version | awk \
 'NR==1{print "pcmcia-cs             ", $3}'
 
