diff -Nru a/CREDITS b/CREDITS
--- a/CREDITS	Mon Jan 13 21:59:50 2003
+++ b/CREDITS	Mon Jan 13 21:59:50 2003
@@ -2185,9 +2185,15 @@
 
 N: Corey Minyard
 E: minyard@wf-rch.cirr.com
+E: minyard@mvista.com
+W: http://home.attbi.com/~minyard
 D: Sony CDU31A CDROM Driver
-S: 1805 Marquette
-S: Richardson, Texas 75081
+D: IPMI driver
+D: Various networking fixes long ago
+D: Original ppc_md work
+D: Shared zlib
+S: 7406 Wheat Field Rd
+S: Garland, Texas 75044
 S: USA
 
 N: Patrick Mochel
diff -Nru a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
--- a/Documentation/DMA-API.txt	Mon Jan 13 21:59:50 2003
+++ b/Documentation/DMA-API.txt	Mon Jan 13 21:59:50 2003
@@ -22,7 +22,7 @@
 
 void *
 dma_alloc_coherent(struct device *dev, size_t size,
-			     dma_addr_t *dma_handle)
+			     dma_addr_t *dma_handle, int flag)
 void *
 pci_alloc_consistent(struct pci_dev *dev, size_t size,
 			     dma_addr_t *dma_handle)
@@ -43,6 +43,12 @@
 minimum allocation length may be as big as a page, so you should
 consolidate your requests for consistent memory as much as possible.
 
+The flag parameter (dma_alloc_coherent only) allows the caller to
+specify the GFP_ flags (see kmalloc) for the allocation (the
+implementation may chose to ignore flags that affect the location of
+the returned memory, like GFP_DMA).  For pci_alloc_consistent, you
+must assume GFP_ATOMIC behaviour.
+
 void
 dma_free_coherent(struct device *dev, size_t size, void *cpu_addr
 			   dma_addr_t dma_handle)
@@ -261,7 +267,7 @@
 
 void *
 dma_alloc_noncoherent(struct device *dev, size_t size,
-			       dma_addr_t *dma_handle)
+			       dma_addr_t *dma_handle, int flag)
 
 Identical to dma_alloc_coherent() except that the platform will
 choose to return either consistent or non-consistent memory as it sees
diff -Nru a/Documentation/IPMI.txt b/Documentation/IPMI.txt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/IPMI.txt	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,352 @@
+
+                          The Linux IPMI Driver
+			  ---------------------
+			      Corey Minyard
+			  <minyard@mvista.com>
+			    <minyard@acm.org>
+
+This document describes how to use the IPMI driver for Linux.  If you
+are not familiar with IPMI itself, see the web site at
+http://www.intel.com/design/servers/ipmi/index.htm.  IPMI is a big
+subject and I can't cover it all here!
+
+Basic Design
+------------
+
+The Linux IPMI driver is designed to be very modular and flexible, you
+only need to take the pieces you need and you can use it in many
+different ways.  Because of that, it's broken into many chunks of
+code.  These chunks are:
+
+ipmi_msghandler - This is the central piece of software for the IPMI
+system.  It handles all messages, message timing, and responses.  The
+IPMI users tie into this, and the IPMI physical interfaces (called
+System Management Interfaces, or SMIs) also tie in here.  This
+provides the kernelland interface for IPMI, but does not provide an
+interface for use by application processes.
+
+ipmi_devintf - This provides a userland IOCTL interface for the IPMI
+driver, each open file for this device ties in to the message handler
+as an IPMI user.
+
+ipmi_kcs_drv - A driver for the KCS SMI.  Most system have a KCS
+interface for IPMI.
+
+
+Much documentation for the interface is in the include files.  The
+IPMI include files are:
+
+ipmi.h - Contains the user interface and IOCTL interface for IPMI.
+
+ipmi_smi.h - Contains the interface for SMI drivers to use.
+
+ipmi_msgdefs.h - General definitions for base IPMI messaging.
+
+
+Addressing
+----------
+
+The IPMI addressing works much like IP addresses, you have an overlay
+to handle the different address types.  The overlay is:
+
+  struct ipmi_addr
+  {
+	int   addr_type;
+	short channel;
+	char  data[IPMI_MAX_ADDR_SIZE];
+  };
+
+The addr_type determines what the address really is.  The driver
+currently understands two different types of addresses.
+
+"System Interface" addresses are defined as:
+
+  struct ipmi_system_interface_addr
+  {
+	int   addr_type;
+	short channel;
+  };
+
+and the type is IPMI_SYSTEM_INTERFACE_ADDR_TYPE.  This is used for talking
+straight to the BMC on the current card.  The channel must be
+IPMI_BMC_CHANNEL.
+
+Messages that are destined to go out on the IPMB bus use the
+IPMI_IPMB_ADDR_TYPE address type.  The format is
+
+  struct ipmi_ipmb_addr
+  {
+	int           addr_type;
+	short         channel;
+	unsigned char slave_addr;
+	unsigned char lun;
+  };
+
+The "channel" here is generally zero, but some devices support more
+than one channel, it corresponds to the channel as defined in the IPMI
+spec.
+
+
+Messages
+--------
+
+Messages are defined as:
+
+struct ipmi_msg
+{
+	unsigned char netfn;
+	unsigned char lun;
+	unsigned char cmd;
+	unsigned char *data;
+	int           data_len;
+};
+
+The driver takes care of adding/stripping the header information.  The
+data portion is just the data to be send (do NOT put addressing info
+here) or the response.  Note that the completion code of a response is
+the first item in "data", it is not stripped out because that is how
+all the messages are defined in the spec (and thus makes counting the
+offsets a little easier :-).
+
+When using the IOCTL interface from userland, you must provide a block
+of data for "data", fill it, and set data_len to the length of the
+block of data, even when receiving messages.  Otherwise the driver
+will have no place to put the message.
+
+Messages coming up from the message handler in kernelland will come in
+as:
+
+  struct ipmi_recv_msg
+  {
+	struct list_head link;
+
+	/* The type of message as defined in the "Receive Types"
+           defines above. */
+	int         recv_type;
+
+	ipmi_user_t      *user;
+	struct ipmi_addr addr;
+	long             msgid;
+	struct ipmi_msg  msg;
+
+	/* Call this when done with the message.  It will presumably free
+	   the message and do any other necessary cleanup. */
+	void (*done)(struct ipmi_recv_msg *msg);
+
+	/* Place-holder for the data, don't make any assumptions about
+	   the size or existence of this, since it may change. */
+	unsigned char   msg_data[IPMI_MAX_MSG_LENGTH];
+  };
+
+You should look at the receive type and handle the message
+appropriately.
+
+
+The Upper Layer Interface (Message Handler)
+-------------------------------------------
+
+The upper layer of the interface provides the users with a consistent
+view of the IPMI interfaces.  It allows multiple SMI interfaces to be
+addressed (because some boards actually have multiple BMCs on them)
+and the user should not have to care what type of SMI is below them.
+
+
+Creating the User
+
+To user the message handler, you must first create a user using
+ipmi_create_user.  The interface number specifies which SMI you want
+to connect to, and you must supply callback functions to be called
+when data comes in.  The callback function can run at interrupt level,
+so be careful using the callbacks.  This also allows to you pass in a
+piece of data, the handler_data, that will be passed back to you on
+all calls.
+
+Once you are done, call ipmi_destroy_user() to get rid of the user.
+
+From userland, opening the device automatically creates a user, and
+closing the device automatically destroys the user.
+
+
+Messaging
+
+To send a message from kernel-land, the ipmi_request() call does
+pretty much all message handling.  Most of the parameter are
+self-explanatory.  However, it takes a "msgid" parameter.  This is NOT
+the sequence number of messages.  It is simply a long value that is
+passed back when the response for the message is returned.  You may
+use it for anything you like.
+
+Responses come back in the function pointed to by the ipmi_recv_hndl
+field of the "handler" that you passed in to ipmi_create_user().
+Remember again, these may be running at interrupt level.  Remember to
+look at the receive type, too.
+
+From userland, you fill out an ipmi_req_t structure and use the
+IPMICTL_SEND_COMMAND ioctl.  For incoming stuff, you can use select()
+or poll() to wait for messages to come in.  However, you cannot use
+read() to get them, you must call the IPMICTL_RECEIVE_MSG with the
+ipmi_recv_t structure to actually get the message.  Remember that you
+must supply a pointer to a block of data in the msg.data field, and
+you must fill in the msg.data_len field with the size of the data.
+This gives the receiver a place to actually put the message.
+
+If the message cannot fit into the data you provide, you will get an
+EMSGSIZE error and the driver will leave the data in the receive
+queue.  If you want to get it and have it truncate the message, us
+the IPMICTL_RECEIVE_MSG_TRUNC ioctl.
+
+When you send a command (which is defined by the lowest-order bit of
+the netfn per the IPMI spec) on the IPMB bus, the driver will
+automatically assign the sequence number to the command and save the
+command.  If the response is not receive in the IPMI-specified 5
+seconds, it will generate a response automatically saying the command
+timed out.  If an unsolicited response comes in (if it was after 5
+seconds, for instance), that response will be ignored.
+
+In kernelland, after you receive a message and are done with it, you
+MUST call ipmi_free_recv_msg() on it, or you will leak messages.  Note
+that you should NEVER mess with the "done" field of a message, that is
+required to properly clean up the message.
+
+Note that when sending, there is an ipmi_request_supply_msgs() call
+that lets you supply the smi and receive message.  This is useful for
+pieces of code that need to work even if the system is out of buffers
+(the watchdog timer uses this, for instance).  You supply your own
+buffer and own free routines.  This is not recommended for normal use,
+though, since it is tricky to manage your own buffers.
+
+
+Events and Incoming Commands
+
+The driver takes care of polling for IPMI events and receiving
+commands (commands are messages that are not responses, they are
+commands that other things on the IPMB bus have sent you).  To receive
+these, you must register for them, they will not automatically be sent
+to you.
+
+To receive events, you must call ipmi_set_gets_events() and set the
+"val" to non-zero.  Any events that have been received by the driver
+since startup will immediately be delivered to the first user that
+registers for events.  After that, if multiple users are registered
+for events, they will all receive all events that come in.
+
+For receiving commands, you have to individually register commands you
+want to receive.  Call ipmi_register_for_cmd() and supply the netfn
+and command name for each command you want to receive.  Only one user
+may be registered for each netfn/cmd, but different users may register
+for different commands.
+
+From userland, equivalent IOCTLs are provided to do these functions.
+
+
+The Lower Layer (SMI) Interface
+-------------------------------
+
+As mentioned before, multiple SMI interfaces may be registered to the
+message handler, each of these is assigned an interface number when
+they register with the message handler.  They are generally assigned
+in the order they register, although if an SMI unregisters and then
+another one registers, all bets are off.
+
+The ipmi_smi.h defines the interface for SMIs, see that for more
+details.
+
+
+The KCS Driver
+--------------
+
+The KCS driver allows up to 4 KCS interfaces to be configured in the
+system.  By default, the driver will register one KCS interface at the
+spec-specified I/O port 0xca2 without interrupts.  You can change this
+at module load time (for a module) with:
+
+  insmod ipmi_kcs_drv.o kcs_ports=<port1>,<port2>... kcs_addrs=<addr1>,<addr2>
+       kcs_irqs=<irq1>,<irq2>... kcs_trydefaults=[0|1]
+
+The KCS driver supports two types of interfaces, ports (for I/O port
+based KCS interfaces) and memory addresses (for KCS interfaces in
+memory).  The driver will support both of them simultaneously, setting
+the port to zero (or just not specifying it) will allow the memory
+address to be used.  The port will override the memory address if it
+is specified and non-zero.  kcs_trydefaults sets whether the standard
+IPMI interface at 0xca2 and any interfaces specified by ACPE are
+tried.  By default, the driver tries it, set this value to zero to
+turn this off.
+
+When compiled into the kernel, the addresses can be specified on the
+kernel command line as:
+
+  ipmi_kcs=<bmc1>:<irq1>,<bmc2>:<irq2>....,[nodefault]
+
+The <bmcx> values is either "p<port>" or "m<addr>" for port or memory
+addresses.  So for instance, a KCS interface at port 0xca2 using
+interrupt 9 and a memory interface at address 0xf9827341 with no
+interrupt would be specified "ipmi_kcs=p0xca2:9,m0xf9827341".
+If you specify zero for in irq or don't specify it, the driver will
+run polled unless the software can detect the interrupt to use in the
+ACPI tables.
+
+By default, the driver will attempt to detect a KCS device at the
+spec-specified 0xca2 address and any address specified by ACPI.  If
+you want to turn this off, use the "nodefault" option.
+
+If you have high-res timers compiled into the kernel, the driver will
+use them to provide much better performance.  Note that if you do not
+have high-res timers enabled in the kernel and you don't have
+interrupts enabled, the driver will run VERY slowly.  Don't blame me,
+the KCS interface sucks.
+
+
+Other Pieces
+------------
+
+Watchdog
+
+A watchdog timer is provided that implements the Linux-standard
+watchdog timer interface.  It has three module parameters that can be
+used to control it:
+
+  insmod ipmi_watchdog timeout=<t> pretimeout=<t> action=<action type>
+      preaction=<preaction type> preop=<preop type>
+
+The timeout is the number of seconds to the action, and the pretimeout
+is the amount of seconds before the reset that the pre-timeout panic will
+occur (if pretimeout is zero, then pretimeout will not be enabled).
+
+The action may be "reset", "power_cycle", or "power_off", and
+specifies what to do when the timer times out, and defaults to
+"reset".
+
+The preaction may be "pre_smi" for an indication through the SMI
+interface, "pre_int" for an indication through the SMI with an
+interrupts, and "pre_nmi" for a NMI on a preaction.  This is how
+the driver is informed of the pretimeout.
+
+The preop may be set to "preop_none" for no operation on a pretimeout,
+"preop_panic" to set the preoperation to panic, or "preop_give_data"
+to provide data to read from the watchdog device when the pretimeout
+occurs.  A "pre_nmi" setting CANNOT be used with "preop_give_data"
+because you can't do data operations from an NMI.
+
+When preop is set to "preop_give_data", one byte comes ready to read
+on the device when the pretimeout occurs.  Select and fasync work on
+the device, as well.
+
+When compiled into the kernel, the kernel command line is available
+for configuring the watchdog:
+
+  ipmi_wdog=<timeout>[,<pretimeout>[,<option>[,<options>....]]]
+
+The options are the actions and preaction above (if an option
+controlling the same thing is specified twice, the last is taken).  An
+options "start_now" is also there, if included, the watchdog will
+start running immediately when all the drivers are ready, it doesn't
+have to have a user hooked up to start it.
+
+The watchdog will panic and start a 120 second reset timeout if it
+gets a pre-action.  During a panic or a reboot, the watchdog will
+start a 120 timer if it is running to make sure the reboot occurs.
+
+Note that if you use the NMI preaction for the watchdog, you MUST
+NOT use nmi watchdog mode 1.  If you use the NMI watchdog, you
+must use mode 2.
diff -Nru a/Documentation/usb/proc_usb_info.txt b/Documentation/usb/proc_usb_info.txt
--- a/Documentation/usb/proc_usb_info.txt	Mon Jan 13 21:59:49 2003
+++ b/Documentation/usb/proc_usb_info.txt	Mon Jan 13 21:59:49 2003
@@ -23,7 +23,7 @@
 	  to interact with USB devices.
 
 	  There are a number of mount options supported by usbfs.
-	  Consult the source code (linux/drivers/usb/inode.c) for
+	  Consult the source code (linux/drivers/usb/core/inode.c) for
 	  information about those options.
 
 **NOTE**: The filesystem has been renamed from "usbdevfs" to
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Mon Jan 13 21:59:49 2003
+++ b/Makefile	Mon Jan 13 21:59:49 2003
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 57
+SUBLEVEL = 58
 EXTRAVERSION =
 
 # *DOCUMENTATION*
diff -Nru a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
--- a/arch/alpha/kernel/module.c	Mon Jan 13 21:59:49 2003
+++ b/arch/alpha/kernel/module.c	Mon Jan 13 21:59:49 2003
@@ -190,15 +190,10 @@
 		/* This is where to make the change.  */
 		location = base + rela[i].r_offset;
 
-		/* This is the symbol it is referring to.  */
+		/* This is the symbol it is referring to.  Note that all
+		   unresolved symbols have been resolved.  */
 		sym = symtab + r_sym;
-		value = sym->st_value;
-		if (!value) {
-			printk(KERN_ERR "module %s: Unknown symbol %s\n",
-			       me->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
-		value += rela[i].r_addend;
+		value = sym->st_value + rela[i].r_addend;
 
 		switch (r_type) {
 		case R_ALPHA_NONE:
diff -Nru a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
--- a/arch/arm/kernel/module.c	Mon Jan 13 21:59:49 2003
+++ b/arch/arm/kernel/module.c	Mon Jan 13 21:59:49 2003
@@ -98,11 +98,6 @@
 		}
 
 		sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
-		if (!sym->st_value) {
-			printk(KERN_WARNING "%s: unknown symbol %s\n",
-				module->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
 
 		if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) {
 			printk(KERN_ERR "%s: out of bounds relocation, "
diff -Nru a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
--- a/arch/arm/mach-integrator/cpu.c	Mon Jan 13 21:59:50 2003
+++ b/arch/arm/mach-integrator/cpu.c	Mon Jan 13 21:59:50 2003
@@ -166,6 +166,7 @@
 	.verify		= integrator_verify_speed,
 	.setpolicy	= integrator_set_policy,
 	.policy		= &integrator_policy,
+	.name		= "integrator",
 };
 #endif
 
diff -Nru a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
--- a/arch/arm/mach-sa1100/cpu-sa1100.c	Mon Jan 13 21:59:49 2003
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c	Mon Jan 13 21:59:49 2003
@@ -214,6 +214,7 @@
 	.verify		= sa11x0_verify_speed,
 	.setpolicy	= sa1100_setspeed,
 	.policy		= &sa1100_policy,
+	.name		= "sa1100",
 };
 
 static int __init sa1100_dram_init(void)
diff -Nru a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
--- a/arch/arm/mach-sa1100/cpu-sa1110.c	Mon Jan 13 21:59:49 2003
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c	Mon Jan 13 21:59:49 2003
@@ -309,6 +309,7 @@
 	.verify		 = sa11x0_verify_speed,
 	.setpolicy	 = sa1110_setspeed,
 	.policy		 = &sa1110_policy,
+	.name		= "sa1110",
 };
 
 static int __init sa1110_clk_init(void)
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Mon Jan 13 21:59:49 2003
+++ b/arch/i386/Kconfig	Mon Jan 13 21:59:49 2003
@@ -75,6 +75,14 @@
 
 	  If you don't have one of these computers, you should say N here.
 
+config X86_BIGSMP
+	bool "Support for other sub-arch SMP systems with more than 8 CPUs"
+	help
+	  This option is needed for the systems that have more than 8 CPUs
+	  and if the system is not of any sub-arch type above.
+
+	  If you don't have such a system, you should say N here.
+
 # Visual Workstation support is utterly broken.
 # If you want to see it working mail an VW540 to hch@infradead.org 8)
 #config X86_VISWS
@@ -949,15 +957,27 @@
 
 	  If in doubt, say N.
 
+config CPU_FREQ_PROC_INTF
+	bool "/proc/cpufreq interface (DEPRECATED)"
+	depends on CPU_FREQ && PROC_FS
+	help
+	  This enables the /proc/cpufreq interface for controlling
+	  CPUFreq. Please note that it is recommended to use the sysfs
+	  interface instead (which is built automatically). 
+	  
+	  For details, take a look at linux/Documentation/cpufreq. 
+	  
+	  If in doubt, say N.
+
 config CPU_FREQ_24_API
 	bool "/proc/sys/cpu/ interface (2.4. / OLD)"
 	depends on CPU_FREQ
 	help
 	  This enables the /proc/sys/cpu/ sysctl interface for controlling
 	  CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. 2.5
-	  uses /proc/cpufreq instead. Please note that some drivers do not 
-	  work well with the 2.4. /proc/sys/cpu sysctl interface, so if in
-	  doubt, say N here.
+	  uses a sysfs interface instead. Please note that some drivers do 
+	  not work well with the 2.4. /proc/sys/cpu sysctl interface,
+	  so if in doubt, say N here.
 
 	  For details, take a look at linux/Documentation/cpufreq. 
 
@@ -1034,6 +1054,18 @@
 	  For details, take a look at linux/Documentation/cpufreq. 
 
 	  If in doubt, say N.
+
+config X86_GX_SUSPMOD
+	tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
+	depends on CPU_FREQ
+	help
+	 This add the CPUFreq driver for NatSemi Geode processors which
+	 support suspend modulation.
+
+	 For details, take a look at linux/Documentation/cpufreq.
+
+	 If in doubt, say N.
+
 
 endmenu
 
diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile	Mon Jan 13 21:59:49 2003
+++ b/arch/i386/Makefile	Mon Jan 13 21:59:49 2003
@@ -65,6 +65,10 @@
 mflags-$(CONFIG_X86_NUMAQ)	:= -Iinclude/asm-i386/mach-numaq
 mcore-$(CONFIG_X86_NUMAQ)	:= mach-default
 
+# BIGSMP subarch support
+mflags-$(CONFIG_X86_BIGSMP)	:= -Iinclude/asm-i386/mach-bigsmp
+mcore-$(CONFIG_X86_BIGSMP)	:= mach-default
+
 # default subarch .h files
 mflags-y += -Iinclude/asm-i386/mach-default
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile
--- a/arch/i386/kernel/cpu/cpufreq/Makefile	Mon Jan 13 21:59:49 2003
+++ b/arch/i386/kernel/cpu/cpufreq/Makefile	Mon Jan 13 21:59:49 2003
@@ -4,3 +4,4 @@
 obj-$(CONFIG_X86_P4_CLOCKMOD)	+= p4-clockmod.o
 obj-$(CONFIG_ELAN_CPUFREQ)	+= elanfreq.o
 obj-$(CONFIG_X86_LONGRUN)	+= longrun.o  
+obj-$(CONFIG_X86_GX_SUSPMOD)    += gx-suspmod.o
diff -Nru a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c
--- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c	Mon Jan 13 21:59:49 2003
+++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c	Mon Jan 13 21:59:49 2003
@@ -260,6 +260,9 @@
 
 	driver->verify        = &elanfreq_verify;
 	driver->setpolicy     = &elanfreq_setpolicy;
+	driver->init = NULL;
+	driver->exit = NULL;
+	strncpy(driver->name, "elanfreq", CPUFREQ_NAME_LEN);
 
 	driver->policy[0].cpu    = 0;
 	ret = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &elanfreq_table[0]);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,514 @@
+/*
+ *	Cyrix MediaGX and NatSemi Geode Suspend Modulation
+ *	(C) 2002 Zwane Mwaikambo <zwane@commfireservices.com>
+ *	(C) 2002 Hiroshi Miura   <miura@da-cha.org>
+ *	All Rights Reserved
+ *
+ *	This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      version 2 as published by the Free Software Foundation 
+ *
+ *      The author(s) of this software shall not be held liable for damages
+ *      of any nature resulting due to the use of this software. This
+ *      software is provided AS-IS with no warranties.
+ *	
+ * Theoritical note:
+ *
+ *	(see Geode(tm) CS5530 manual (rev.4.1) page.56)
+ *
+ *	CPU frequency control on NatSemi Geode GX1/GXLV processor and CS55x0
+ *	are based on Suspend Moduration.
+ *
+ *	Suspend Modulation works by asserting and de-asserting the SUSP# pin
+ *	to CPU(GX1/GXLV) for configurable durations. When asserting SUSP#
+ *	the CPU enters an idle state. GX1 stops its core clock when SUSP# is 
+ *	asserted then power consumption is reduced.
+ *
+ *	Suspend Modulation's OFF/ON duration are configurable 
+ *	with 'Suspend Modulation OFF Count Register'
+ *	and 'Suspend Modulation ON Count Register'.
+ *	These registers are 8bit counters that represent the number of 
+ *	32us intervals which the SUSP# pin is asserted/de-asserted to the 
+ *	processor.
+ *
+ *	These counters define a ratio which is the effective frequency 
+ * 	of operation of the system.
+ *
+ *			       On Count
+ *	F_eff = Fgx * ----------------------
+ *	                On Count + Off Count
+ *
+ *	0 <= On Count, Off Count <= 255
+ *
+ *	From these limits, we can get register values 
+ *
+ *	on_duration + off_duration <= MAX_DURATION
+ *	off_duration = on_duration * (stock_freq - freq) / freq
+ *
+ *      on_duration  =  (freq * DURATION) / stock_freq 
+ *      off_duration = DURATION - on_duration 
+ *
+ *
+ *---------------------------------------------------------------------------
+ *
+ * ChangeLog:
+ *	Dec. 11, 2002 	Hiroshi Miura <miura@da-cha.org>
+ *		- rewrite for Cyrix MediaGX Cx5510/5520 and 
+ *		  NatSemi Geode Cs5530(A).
+ *
+ *	Jul. ??, 2002  Zwane Mwaikambo <zwane@commfireservices.com>
+ *		- cs5530_mod patch for 2.4.19-rc1.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * Todo
+ *	Test on machines with 5510, 5530, 5530A
+ */
+
+/************************************************************************
+ *			Suspend Modulation - Definitions		*
+ ************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h> 
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/cpufreq.h>
+#include <linux/pci.h>
+#include <asm/processor.h> 
+#include <asm/errno.h>
+
+/* PCI config registers, all at F0 */
+#define PCI_PMER1              0x80    /* power management enable register 1 */
+#define PCI_PMER2              0x81    /* power management enable register 2 */
+#define PCI_PMER3              0x82    /* power management enable register 3 */
+#define PCI_IRQTC              0x8c    /* irq speedup timer counter register:typical 2 to 4ms */
+#define PCI_VIDTC              0x8d    /* video speedup timer counter register: typical 50 to 100ms */
+#define PCI_MODOFF             0x94    /* suspend modulation OFF counter register, 1 = 32us */
+#define PCI_MODON              0x95    /* suspend modulation ON counter register */
+#define PCI_SUSCFG             0x96    /* suspend configuration register */
+
+/* PMER1 bits */
+#define GPM                    (1<<0)  /* global power management */
+#define GIT                    (1<<1)  /* globally enable PM device idle timers */
+#define GTR                    (1<<2)  /* globally enable IO traps */
+#define IRQ_SPDUP              (1<<3)  /* disable clock throttle during interrupt handling */
+#define VID_SPDUP              (1<<4)  /* disable clock throttle during vga video handling */
+
+/* SUSCFG bits */
+#define SUSMOD                 (1<<0)  /* enable/disable suspend modulation */
+/* the belows support only with cs5530 (after rev.1.2)/cs5530A */ 
+#define SMISPDUP               (1<<1)  /* select how SMI re-enable suspend modulation: */
+                                       /* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */
+#define SUSCFG                 (1<<2)  /* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */
+/* the belows support only with cs5530A */ 
+#define PWRSVE_ISA             (1<<3)  /* stop ISA clock  */
+#define PWRSVE                 (1<<4)  /* active idle */
+
+struct gxfreq_params {
+	u8 on_duration;
+	u8 off_duration;
+	u8 pci_suscfg;
+	u8 pci_pmer1;
+	u8 pci_pmer2;
+	u8 pci_rev;
+	struct pci_dev *cs55x0;
+};
+
+static struct cpufreq_driver *gx_driver;
+static struct gxfreq_params *gx_params;
+static int stock_freq;
+
+/* PCI bus clock - defaults to 30.000 if cpu_khz is not available */
+static int pci_busclk = 0;
+MODULE_PARM(pci_busclk, "i");
+
+/* maximum duration for which the cpu may be suspended
+ * (32us * MAX_DURATION). If no parameter is given, this defaults
+ * to 255. 
+ * Note that this leads to a maximum of 8 ms(!) where the CPU clock
+ * is suspended -- processing power is just 0.39% of what it used to be,
+ * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */
+static int max_duration = 255;
+MODULE_PARM(max_duration, "i");
+
+/* For the default policy, we want at least some processing power
+ * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV)
+ */
+#define POLICY_MIN_DIV 20
+
+
+/* DEBUG
+ *   Define it if you want verbose debug output
+ */
+
+#define SUSPMOD_DEBUG 1
+
+#ifdef SUSPMOD_DEBUG
+#define dprintk(msg...) printk(KERN_DEBUG "cpufreq:" msg)
+#else
+#define dprintk(msg...) do { } while(0);
+#endif
+
+/**
+ *      we can detect a core multipiler from dir0_lsb 
+ *      from GX1 datasheet p.56, 
+ *	   MULT[3:0]:
+ *	   0000 = SYSCLK multiplied by 4 (test only)
+ *	   0001 = SYSCLK multiplied by 10
+ *	   0010 = SYSCLK multiplied by 4
+ *	   0011 = SYSCLK multiplied by 6
+ *	   0100 = SYSCLK multiplied by 9
+ *	   0101 = SYSCLK multiplied by 5
+ *	   0110 = SYSCLK multiplied by 7
+ *	   0111 = SYSCLK multiplied by 8
+ *              of 33.3MHz
+ **/
+static int gx_freq_mult[16] = {
+		4, 10, 4, 6, 9, 5, 7, 8,
+		0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+/****************************************************************
+ * 	Low Level chipset interface				*
+ ****************************************************************/
+static struct pci_device_id gx_chipset_tbl[] __initdata = {
+        { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID },
+        { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID },
+        { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID },
+        { 0, },
+};
+
+/**
+ *     gx_detect_chipset:
+ *
+ **/
+static __init struct pci_dev *gx_detect_chipset(void)
+{
+	struct pci_dev *gx_pci;
+
+	/* check if CPU is a MediaGX or a Geode. */
+        if ((current_cpu_data.x86_vendor != X86_VENDOR_NSC) && 
+	    (current_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
+		printk(KERN_INFO "gx-suspmod: error: no MediaGX/Geode processor found!\n");
+		return NULL;		
+	}
+
+	/* detect which companion chip is used */
+	pci_for_each_dev(gx_pci) {
+		if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) {
+			return gx_pci;
+		}
+	}
+
+	dprintk(KERN_INFO "gx-suspmod: error: no supported chipset found!\n");
+	return NULL;
+}
+
+/**
+ *      gx_get_cpuspeed:
+ *
+ * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs.
+ */
+static int gx_get_cpuspeed(void)
+{
+	if ((gx_params->pci_suscfg & SUSMOD) == 0) 
+		return stock_freq;
+
+	return (stock_freq * gx_params->on_duration) 
+		/ (gx_params->on_duration + gx_params->off_duration);
+}
+
+/**
+ *      gx_validate_speed:
+ *      determine current cpu speed
+ *       
+**/
+
+static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration)
+{
+	unsigned int i;
+	u8 tmp_on, tmp_off;
+	int old_tmp_freq = stock_freq;
+	int tmp_freq;
+
+	*on_duration=1;
+	*off_duration=0;
+
+	for (i=max_duration; i>0; i--) {
+		tmp_on = ((khz * i) / stock_freq) & 0xff; 
+		tmp_off = i - tmp_on;
+		tmp_freq = (stock_freq * tmp_on) / i;
+		/* if this relation is closer to khz, use this. If it's equal,
+		 * prefer it, too - lower latency */
+		if (abs(tmp_freq - khz) <= abs(old_tmp_freq - khz)) {
+			*on_duration = tmp_on;
+			*off_duration = tmp_off;
+			old_tmp_freq = tmp_freq;
+		}
+	}
+
+	return old_tmp_freq;
+}
+
+
+/**
+ * 	gx_set_cpuspeed:
+ *		set cpu speed in khz.
+ **/
+
+static void gx_set_cpuspeed(unsigned int khz)
+{
+        u8 suscfg, pmer1;
+	unsigned int new_khz;
+	unsigned long flags;
+	struct cpufreq_freqs freqs;
+
+
+	freqs.cpu = 0;
+	freqs.old = gx_get_cpuspeed();
+
+	new_khz = gx_validate_speed(khz, &gx_params->on_duration, &gx_params->off_duration);
+
+	freqs.new = new_khz;
+
+	if (new_khz == stock_freq) {  /* if new khz == 100% of CPU speed, it is special case */
+		local_irq_save(flags);
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+		pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, (gx_params->pci_suscfg & ~(SUSMOD)));
+		pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &(gx_params->pci_suscfg));
+		local_irq_restore(flags);
+		dprintk("suspend modulation disabled: cpu runs 100 percent speed.\n");
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+		return;
+	}
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	local_irq_save(flags);
+	switch (gx_params->cs55x0->device) {
+	case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
+		pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP;
+		/* FIXME: need to test other values -- Zwane,Miura */
+		pci_write_config_byte(gx_params->cs55x0, PCI_IRQTC, 4); /* typical 2 to 4ms */
+		pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */
+		pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1);
+
+		if (gx_params->pci_rev < 0x10) {   /* CS5530(rev 1.2, 1.3) */
+			suscfg = gx_params->pci_suscfg | SUSMOD;
+		} else {                           /* CS5530A,B.. */
+			suscfg = gx_params->pci_suscfg | SUSMOD | PWRSVE;
+		}
+		break;
+	case PCI_DEVICE_ID_CYRIX_5520:
+	case PCI_DEVICE_ID_CYRIX_5510:
+		suscfg = gx_params->pci_suscfg | SUSMOD;
+		break;
+	default:
+		local_irq_restore(flags);
+		dprintk("fatal: try to set unknown chipset.\n");
+		return;
+	}
+
+	pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration);
+	pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration);
+
+        pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg);
+        pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg);
+
+        local_irq_restore(flags);
+
+	gx_params->pci_suscfg = suscfg;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+        dprintk("suspend modulation w/ duration of ON:%d us, OFF:%d us\n",
+                gx_params->on_duration * 32, gx_params->off_duration * 32);
+	dprintk("suspend modulation w/ clock speed: %d kHz.\n", freqs.new); 
+}
+
+/****************************************************************
+ *             High level functions                             *
+ ****************************************************************/
+
+/*
+ *	cpufreq_gx_verify: test if frequency range is valid 
+ *
+ *	This function checks if a given frequency range in kHz is valid 
+ *      for the hardware supported by the driver. 
+ */
+
+static int cpufreq_gx_verify(struct cpufreq_policy *policy)
+{
+	unsigned int tmp_freq = 0;
+	u8 tmp1, tmp2;
+
+        if (!gx_driver || !stock_freq || !policy)
+                return -EINVAL;
+
+	policy->cpu = 0;
+	cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq);
+
+	/* it needs to be assured that at least one supported frequency is
+	 * within policy->min and policy->max. If it is not, policy->max
+	 * needs to be increased until one freuqency is supported.
+	 * policy->min may not be decreased, though. This way we guarantee a 
+	 * specific processing capacity.
+	 */
+	tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2);
+	if (tmp_freq < policy->min) 
+		tmp_freq += stock_freq / max_duration;
+	policy->min = tmp_freq;
+	if (policy->min > policy->max) 
+		policy->max = tmp_freq;
+	tmp_freq = gx_validate_speed(policy->max, &tmp1, &tmp2);
+	if (tmp_freq > policy->max)
+		tmp_freq -= stock_freq / max_duration;
+	policy->max = tmp_freq;
+	if (policy->max < policy->min)
+		policy->max = policy->min;
+	cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq);
+	
+	return 0;
+}
+
+/*
+ *      cpufreq_gx_setpolicy:  
+ *
+ */
+static int cpufreq_gx_setpolicy(struct cpufreq_policy *policy)
+{
+
+        if (!gx_driver || !stock_freq || !policy)
+                return -EINVAL;
+
+	policy->cpu = 0;
+
+	if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
+		/* here we need to make sure that we don't set the
+		 * frequency below policy->min (see comment in
+		 * cpufreq_gx_verify() - guarantee of processing 
+		 * capacity.
+		 */
+		u8 tmp1, tmp2;
+		unsigned int tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2);
+		while (tmp_freq < policy->min) {
+			tmp_freq += stock_freq / max_duration;
+			tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
+		}
+		gx_set_cpuspeed(tmp_freq);
+	} else {
+		gx_set_cpuspeed(policy->max);
+	}
+	return 0;
+}
+
+/* 
+ * cpufreq_gx_init:
+ *   MediaGX/Geode GX initilize cpufreq driver
+ */
+
+static int __init cpufreq_gx_init(void)
+{
+	int maxfreq,ret,curfreq;
+ 	struct cpufreq_driver *driver;
+	struct gxfreq_params *params;
+	struct pci_dev *gx_pci;
+	u32 class_rev;
+
+	/* Test if we have the right hardware */
+	if ((gx_pci = gx_detect_chipset()) == NULL) 
+		return -ENODEV;
+
+	/* check whether module parameters are sane */
+	if (max_duration > 0xff)
+		max_duration = 0xff;
+
+	dprintk("geode suspend modulation available.\n");
+
+	driver = kmalloc(sizeof(struct cpufreq_driver) + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
+	if (driver == NULL) 
+		return -ENOMEM;
+	params = kmalloc(sizeof(struct gxfreq_params), GFP_KERNEL);
+	if (params == NULL) {
+		kfree(driver);
+		return -ENOMEM;
+	}
+
+	driver->policy = (struct cpufreq_policy *)(driver + 1);
+	params->cs55x0 = gx_pci;
+
+	/* keep cs55x0 configurations */
+	pci_read_config_byte(params->cs55x0, PCI_SUSCFG, &(params->pci_suscfg));
+	pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1));
+	pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2));
+	pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration));
+	pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration));
+        pci_read_config_dword(params->cs55x0, PCI_CLASS_REVISION, &class_rev);
+	params->pci_rev = class_rev && 0xff;
+
+	gx_params = params;
+
+	/* determine maximum frequency */
+	if (pci_busclk) {
+		maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
+	} else if (cpu_khz) {
+		maxfreq = cpu_khz;
+	} else {
+		maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
+	}
+	stock_freq = maxfreq;
+	curfreq = gx_get_cpuspeed();
+
+	dprintk("cpu max frequency is %d.\n", maxfreq);
+	dprintk("cpu current frequency is %dkHz.\n",curfreq);
+
+	/* setup basic struct for cpufreq API */
+#ifdef CONFIG_CPU_FREQ_24_API
+	driver->cpu_cur_freq[0] = curfreq;
+#endif
+	driver->policy[0].cpu = 0;
+
+	if (max_duration < POLICY_MIN_DIV)
+		driver->policy[0].min = maxfreq / max_duration;
+	else
+		driver->policy[0].min = maxfreq / POLICY_MIN_DIV;
+	driver->policy[0].max = maxfreq;
+	driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
+	driver->policy[0].cpuinfo.min_freq = maxfreq / max_duration;
+	driver->policy[0].cpuinfo.max_freq = maxfreq;
+	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	driver->verify = &cpufreq_gx_verify;
+	driver->setpolicy = &cpufreq_gx_setpolicy;
+
+	gx_driver = driver;
+
+	if ((ret = cpufreq_register(driver))) { 
+		kfree(driver);
+		kfree(params);
+		return ret;                   /* register error! */
+	}
+
+	return 0;
+}
+
+static void __exit cpufreq_gx_exit(void)
+{
+	if (gx_driver) {
+		/* disable throttling */
+		gx_set_cpuspeed(stock_freq);
+		cpufreq_unregister();
+		kfree(gx_driver);
+		kfree(gx_params);
+	}
+}
+
+MODULE_AUTHOR ("Hiroshi Miura <miura@da-cha.org>");
+MODULE_DESCRIPTION ("Cpufreq driver for Cyrix MediaGX and NatSemi Geode");
+MODULE_LICENSE ("GPL");
+
+module_init(cpufreq_gx_init);
+module_exit(cpufreq_gx_exit);
+
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c	Mon Jan 13 21:59:49 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c	Mon Jan 13 21:59:49 2003
@@ -771,6 +771,9 @@
 
 	driver->verify    = &longhaul_verify;
 	driver->setpolicy = &longhaul_setpolicy;
+	driver->init = NULL;
+	driver->exit = NULL;
+	strncpy(driver->name, "longhaul", CPUFREQ_NAME_LEN);
 
 	driver->policy[0].cpu = 0;
 	driver->policy[0].min = (unsigned int) lowest_speed;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c
--- a/arch/i386/kernel/cpu/cpufreq/longrun.c	Mon Jan 13 21:59:50 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longrun.c	Mon Jan 13 21:59:50 2003
@@ -251,6 +251,9 @@
 	driver->policy[0].cpuinfo.min_freq = longrun_low_freq;
 	driver->policy[0].cpuinfo.max_freq = longrun_high_freq;
 	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	driver->init = NULL;
+	driver->exit = NULL;
+	strncpy(driver->name, "longrun", CPUFREQ_NAME_LEN);
 
 	longrun_get_policy(&driver->policy[0]);
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Mon Jan 13 21:59:51 2003
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Mon Jan 13 21:59:51 2003
@@ -240,6 +240,9 @@
 
 	driver->verify        = &cpufreq_p4_verify;
 	driver->setpolicy     = &cpufreq_p4_setpolicy;
+	driver->init = NULL;
+	driver->exit = NULL;
+	strncpy(driver->name, "p4-clockmod", CPUFREQ_NAME_LEN);
 
 	for (i=0;i<NR_CPUS;i++) {
 		driver->policy[i].cpu    = i;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Mon Jan 13 21:59:49 2003
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Mon Jan 13 21:59:49 2003
@@ -184,6 +184,9 @@
 
 	driver->verify        = &powernow_k6_verify;
 	driver->setpolicy     = &powernow_k6_setpolicy;
+	driver->init = NULL;
+	driver->exit = NULL;
+	strncpy(driver->name, "powernow-k6", CPUFREQ_NAME_LEN);
 
 	/* cpuinfo and default policy values */
 	driver->policy[0].cpu    = 0;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep.c b/arch/i386/kernel/cpu/cpufreq/speedstep.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep.c	Mon Jan 13 21:59:48 2003
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep.c	Mon Jan 13 21:59:48 2003
@@ -690,6 +690,9 @@
 
 	driver->verify      = &speedstep_verify;
 	driver->setpolicy   = &speedstep_setpolicy;
+	driver->init = NULL;
+	driver->exit = NULL;
+	strncpy(driver->name, "speedstep", CPUFREQ_NAME_LEN);
 
 	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 
diff -Nru a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c
--- a/arch/i386/kernel/module.c	Mon Jan 13 21:59:50 2003
+++ b/arch/i386/kernel/module.c	Mon Jan 13 21:59:50 2003
@@ -70,14 +70,10 @@
 		/* This is where to make the change */
 		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
 			+ rel[i].r_offset;
-		/* This is the symbol it is referring to */
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
 		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
 			+ ELF32_R_SYM(rel[i].r_info);
-		if (!sym->st_value) {
-			printk(KERN_WARNING "%s: Unknown symbol %s\n",
-			       me->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
 
 		switch (ELF32_R_TYPE(rel[i].r_info)) {
 		case R_386_32:
diff -Nru a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c
--- a/arch/i386/kernel/pci-dma.c	Mon Jan 13 21:59:49 2003
+++ b/arch/i386/kernel/pci-dma.c	Mon Jan 13 21:59:49 2003
@@ -14,10 +14,11 @@
 #include <asm/io.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
-			   dma_addr_t *dma_handle)
+			   dma_addr_t *dma_handle, int gfp)
 {
 	void *ret;
-	int gfp = GFP_ATOMIC;
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
 
 	if (dev == NULL || (*dev->dma_mask < 0xffffffff))
 		gfp |= GFP_DMA;
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c	Mon Jan 13 21:59:50 2003
+++ b/arch/i386/kernel/time.c	Mon Jan 13 21:59:50 2003
@@ -78,7 +78,8 @@
 spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
 EXPORT_SYMBOL(i8253_lock);
 
-struct timer_opts* timer;
+extern struct timer_opts timer_none;
+struct timer_opts* timer = &timer_none;
 
 /*
  * This version of gettimeofday has microsecond resolution
diff -Nru a/arch/i386/kernel/timers/Makefile b/arch/i386/kernel/timers/Makefile
--- a/arch/i386/kernel/timers/Makefile	Mon Jan 13 21:59:48 2003
+++ b/arch/i386/kernel/timers/Makefile	Mon Jan 13 21:59:48 2003
@@ -2,6 +2,6 @@
 # Makefile for x86 timers
 #
 
-obj-y := timer.o timer_tsc.o timer_pit.o
+obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o
 
 obj-$(CONFIG_X86_CYCLONE)	+= timer_cyclone.o
diff -Nru a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c
--- a/arch/i386/kernel/timers/timer_cyclone.c	Mon Jan 13 21:59:50 2003
+++ b/arch/i386/kernel/timers/timer_cyclone.c	Mon Jan 13 21:59:50 2003
@@ -150,7 +150,6 @@
 }
 
 
-#if 0 /* XXX future work */
 static void delay_cyclone(unsigned long loops)
 {
 	unsigned long bclock, now;
@@ -162,12 +161,12 @@
 		now = cyclone_timer[0];
 	} while ((now-bclock) < loops);
 }
-#endif
 /************************************************************/
 
 /* cyclone timer_opts struct */
 struct timer_opts timer_cyclone = {
 	.init = init_cyclone, 
 	.mark_offset = mark_offset_cyclone, 
-	.get_offset = get_offset_cyclone
+	.get_offset = get_offset_cyclone,
+	.delay = delay_cyclone,
 };
diff -Nru a/arch/i386/kernel/timers/timer_none.c b/arch/i386/kernel/timers/timer_none.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/timers/timer_none.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,37 @@
+#include <asm/timer.h>
+
+static int init_none(void)
+{
+	return 0;
+}
+
+static void mark_offset_none(void)
+{
+	/* nothing needed */
+}
+
+static unsigned long get_offset_none(void)
+{
+	return 0;
+}
+
+static void delay_none(unsigned long loops)
+{
+	int d0;
+	__asm__ __volatile__(
+		"\tjmp 1f\n"
+		".align 16\n"
+		"1:\tjmp 2f\n"
+		".align 16\n"
+		"2:\tdecl %0\n\tjns 2b"
+		:"=&a" (d0)
+		:"0" (loops));
+}
+
+/* tsc timer_opts struct */
+struct timer_opts timer_none = {
+	.init =		init_none, 
+	.mark_offset =	mark_offset_none, 
+	.get_offset =	get_offset_none,
+	.delay = delay_none,
+};
diff -Nru a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c
--- a/arch/i386/kernel/timers/timer_pit.c	Mon Jan 13 21:59:51 2003
+++ b/arch/i386/kernel/timers/timer_pit.c	Mon Jan 13 21:59:51 2003
@@ -27,6 +27,19 @@
 	/* nothing needed */
 }
 
+static void delay_pit(unsigned long loops)
+{
+	int d0;
+	__asm__ __volatile__(
+		"\tjmp 1f\n"
+		".align 16\n"
+		"1:\tjmp 2f\n"
+		".align 16\n"
+		"2:\tdecl %0\n\tjns 2b"
+		:"=&a" (d0)
+		:"0" (loops));
+}
+
 
 /* This function must be called with interrupts disabled 
  * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
@@ -129,4 +142,5 @@
 	.init =		init_pit, 
 	.mark_offset =	mark_offset_pit, 
 	.get_offset =	get_offset_pit,
+	.delay = delay_pit,
 };
diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
--- a/arch/i386/kernel/timers/timer_tsc.c	Mon Jan 13 21:59:50 2003
+++ b/arch/i386/kernel/timers/timer_tsc.c	Mon Jan 13 21:59:50 2003
@@ -16,7 +16,6 @@
 
 int tsc_disable __initdata = 0;
 
-extern int x86_udelay_tsc;
 extern spinlock_t i8253_lock;
 
 static int use_tsc;
@@ -107,6 +106,17 @@
 	delay_at_last_interrupt = (count + LATCH/2) / LATCH;
 }
 
+static void delay_tsc(unsigned long loops)
+{
+	unsigned long bclock, now;
+	
+	rdtscl(bclock);
+	do
+	{
+		rep_nop();
+		rdtscl(now);
+	} while ((now-bclock) < loops);
+}
 
 /* ------ Calibrate the TSC ------- 
  * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
@@ -272,8 +282,6 @@
 			 *	We could be more selective here I suspect
 			 *	and just enable this for the next intel chips ?
 			 */
-			x86_udelay_tsc = 1;
-
 			/* report CPU clock rate in Hz.
 			 * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
 			 * clock/second. Our precision is about 100 ppm.
@@ -310,4 +318,5 @@
 	.init =		init_tsc,
 	.mark_offset =	mark_offset_tsc, 
 	.get_offset =	get_offset_tsc,
+	.delay = delay_tsc,
 };
diff -Nru a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c
--- a/arch/i386/lib/delay.c	Mon Jan 13 21:59:51 2003
+++ b/arch/i386/lib/delay.c	Mon Jan 13 21:59:51 2003
@@ -15,54 +15,17 @@
 #include <linux/delay.h>
 #include <asm/processor.h>
 #include <asm/delay.h>
+#include <asm/timer.h>
 
 #ifdef CONFIG_SMP
 #include <asm/smp.h>
 #endif
 
-int x86_udelay_tsc = 0;		/* Delay via TSC */
-
-	
-/*
- *	Do a udelay using the TSC for any CPU that happens
- *	to have one that we trust.
- */
-
-static void __rdtsc_delay(unsigned long loops)
-{
-	unsigned long bclock, now;
-	
-	rdtscl(bclock);
-	do
-	{
-		rep_nop();
-		rdtscl(now);
-	} while ((now-bclock) < loops);
-}
-
-/*
- *	Non TSC based delay loop for 386, 486, MediaGX
- */
- 
-static void __loop_delay(unsigned long loops)
-{
-	int d0;
-	__asm__ __volatile__(
-		"\tjmp 1f\n"
-		".align 16\n"
-		"1:\tjmp 2f\n"
-		".align 16\n"
-		"2:\tdecl %0\n\tjns 2b"
-		:"=&a" (d0)
-		:"0" (loops));
-}
+extern struct timer_opts* timer;
 
 void __delay(unsigned long loops)
 {
-	if (x86_udelay_tsc)
-		__rdtsc_delay(loops);
-	else
-		__loop_delay(loops);
+	timer->delay(loops);
 }
 
 inline void __const_udelay(unsigned long xloops)
diff -Nru a/arch/m68knommu/kernel/comempci.c b/arch/m68knommu/kernel/comempci.c
--- a/arch/m68knommu/kernel/comempci.c	Mon Jan 13 21:59:50 2003
+++ b/arch/m68knommu/kernel/comempci.c	Mon Jan 13 21:59:50 2003
@@ -338,254 +338,6 @@
 
 /*****************************************************************************/
 
-int pcibios_present(void)
-{
-	return(pci_bus_is_present);
-}
-
-/*****************************************************************************/
-
-int pcibios_read_config_dword(unsigned char bus, unsigned char dev,
-	unsigned char offset, unsigned int *val)
-{
-	volatile unsigned long	*rp;
-	unsigned long		idsel, fnsel;
-
-#ifdef DEBUGPCI
-	printk("pcibios_read_config_dword(bus=%x,dev=%x,offset=%x,val=%x)\n",
-		 bus, dev, offset, val);
-#endif
-
-	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
-		*val = 0xffffffff;
-		return(PCIBIOS_SUCCESSFUL);
-	}
-
-	rp = (volatile unsigned long *) COMEM_BASE;
-	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
-	fnsel = (dev & 0x7) << 8;
-
-	rp[LREG(COMEM_DAHBASE)] = idsel;
-	*val = rp[LREG(COMEM_PCIBUS + (offset & 0xfc) + fnsel)];
-
-#if 1
-	/* If we get back what we wrote, then nothing there */
-	/* This is pretty dodgy, but, hey, what else do we do?? */
-	if (!offset && (*val == ((idsel & 0xfffff000) | (offset & 0x00000fff))))
-		*val = 0xffffffff;
-#endif
-
-	return(PCIBIOS_SUCCESSFUL);
-}
-
-/*****************************************************************************/
-
-int pcibios_read_config_word(unsigned char bus, unsigned char dev,
-	unsigned char offset, unsigned short *val)
-{
-	volatile unsigned long	*rp;
-	volatile unsigned short	*bp;
-	unsigned long		idsel, fnsel;
-	unsigned char		swapoffset;
-
-#ifdef DEBUGPCI
-	printk("pcibios_read_config_word(bus=%x,dev=%x,offset=%x)\n",
-		bus, dev, offset);
-#endif
-
-	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
-		*val = 0xffff;
-		return(PCIBIOS_SUCCESSFUL);
-	}
-
-	rp = (volatile unsigned long *) COMEM_BASE;
-	bp = (volatile unsigned short *) COMEM_BASE;
-	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
-	fnsel = (dev & 0x7) << 8;
-	swapoffset = (offset & 0xfc) + (~offset & 0x02);
-
-	rp[LREG(COMEM_DAHBASE)] = idsel;
-	*val = bp[WREG(COMEM_PCIBUS + swapoffset + fnsel)];
-
-	return(PCIBIOS_SUCCESSFUL);
-}
-
-/*****************************************************************************/
-
-int pcibios_read_config_byte(unsigned char bus, unsigned char dev,
-	unsigned char offset, unsigned char *val)
-{
-	volatile unsigned long	*rp;
-	volatile unsigned char	*bp;
-	unsigned long		idsel, fnsel;
-	unsigned char		swapoffset;
-
-#ifdef DEBUGPCI
-	printk("pcibios_read_config_byte(bus=%x,dev=%x,offset=%x)\n",
-		bus, dev, offset);
-#endif
-
-	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0)) {
-		*val = 0xff;
-		return(PCIBIOS_SUCCESSFUL);
-	}
-
-	rp = (volatile unsigned long *) COMEM_BASE;
-	bp = (volatile unsigned char *) COMEM_BASE;
-	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
-	fnsel = (dev & 0x7) << 8;
-	swapoffset = (offset & 0xfc) + (~offset & 0x03);
-
-	rp[LREG(COMEM_DAHBASE)] = idsel;
-	*val = bp[(COMEM_PCIBUS + swapoffset + fnsel)];
-
-	return(PCIBIOS_SUCCESSFUL);
-}
-
-/*****************************************************************************/
-
-int pcibios_write_config_dword(unsigned char bus, unsigned char dev,
-	unsigned char offset, unsigned int val)
-{
-	volatile unsigned long	*rp;
-	unsigned long		idsel, fnsel;
-
-#ifdef DEBUGPCI
-	printk("pcibios_write_config_dword(bus=%x,dev=%x,offset=%x,val=%x)\n",
-		 bus, dev, offset, val);
-#endif
-
-	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
-		return(PCIBIOS_SUCCESSFUL);
-
-	rp = (volatile unsigned long *) COMEM_BASE;
-	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
-	fnsel = (dev & 0x7) << 8;
-
-	rp[LREG(COMEM_DAHBASE)] = idsel;
-	rp[LREG(COMEM_PCIBUS + (offset & 0xfc) + fnsel)] = val;
-	return(PCIBIOS_SUCCESSFUL);
-}
-
-/*****************************************************************************/
-
-int pcibios_write_config_word(unsigned char bus, unsigned char dev,
-	unsigned char offset, unsigned short val)
-{
-
-	volatile unsigned long	*rp;
-	volatile unsigned short	*bp;
-	unsigned long		idsel, fnsel;
-	unsigned char		swapoffset;
-
-#ifdef DEBUGPCI
-	printk("pcibios_write_config_word(bus=%x,dev=%x,offset=%x,val=%x)\n",
-		 bus, dev, offset, val);
-#endif
-
-	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
-		return(PCIBIOS_SUCCESSFUL);
-
-	rp = (volatile unsigned long *) COMEM_BASE;
-	bp = (volatile unsigned short *) COMEM_BASE;
-	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
-	fnsel = (dev & 0x7) << 8;
-	swapoffset = (offset & 0xfc) + (~offset & 0x02);
-
-	rp[LREG(COMEM_DAHBASE)] = idsel;
-	bp[WREG(COMEM_PCIBUS + swapoffset + fnsel)] = val;
-	return(PCIBIOS_SUCCESSFUL);
-}
-
-/*****************************************************************************/
-
-int pcibios_write_config_byte(unsigned char bus, unsigned char dev,
-	unsigned char offset, unsigned char val)
-{
-	volatile unsigned long	*rp;
-	volatile unsigned char	*bp;
-	unsigned long		idsel, fnsel;
-	unsigned char		swapoffset;
-
-#ifdef DEBUGPCI
-	printk("pcibios_write_config_byte(bus=%x,dev=%x,offset=%x,val=%x)\n",
-		 bus, dev, offset, val);
-#endif
-
-	if (bus || ((pci_slotmask & (0x1 << PCI_SLOT(dev))) == 0))
-		return(PCIBIOS_SUCCESSFUL);
-
-	rp = (volatile unsigned long *) COMEM_BASE;
-	bp = (volatile unsigned char *) COMEM_BASE;
-	idsel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << ((dev >> 3) + 16));
-	fnsel = (dev & 0x7) << 8;
-	swapoffset = (offset & 0xfc) + (~offset & 0x03);
-
-	rp[LREG(COMEM_DAHBASE)] = idsel;
-	bp[(COMEM_PCIBUS + swapoffset + fnsel)] = val;
-	return(PCIBIOS_SUCCESSFUL);
-}
-
-/*****************************************************************************/
-
-int pcibios_find_device(unsigned short vendor, unsigned short devid,
-	unsigned short index, unsigned char *bus, unsigned char *dev)
-{
-	unsigned int	vendev, val;
-	unsigned char	devnr;
-
-#ifdef DEBUGPCI
-	printk("pcibios_find_device(vendor=%04x,devid=%04x,index=%d)\n",
-		vendor, devid, index);
-#endif
-
-	if (vendor == 0xffff)
-		return(PCIBIOS_BAD_VENDOR_ID);
-
-	vendev = (devid << 16) | vendor;
-	for (devnr = 0; (devnr < 32); devnr++) {
-		pcibios_read_config_dword(0, devnr, PCI_VENDOR_ID, &val);
-		if (vendev == val) {
-			if (index-- == 0) {
-				*bus = 0;
-				*dev = devnr;
-				return(PCIBIOS_SUCCESSFUL);
-			}
-		}
-	}
-
-	return(PCIBIOS_DEVICE_NOT_FOUND);
-}
-
-/*****************************************************************************/
-
-int pcibios_find_class(unsigned int class, unsigned short index,
-	unsigned char *bus, unsigned char *dev)
-{
-	unsigned int	val;
-	unsigned char	devnr;
-
-#ifdef DEBUGPCI
-	printk("pcibios_find_class(class=%04x,index=%d)\n", class, index);
-#endif
-
-	/* FIXME: this ignores multi-function devices... */
-	for (devnr = 0; (devnr < 128); devnr += 8) {
-		pcibios_read_config_dword(0, devnr, PCI_CLASS_REVISION, &val);
-		if ((val >> 8) == class) {
-			if (index-- == 0) {
-				*bus = 0;
-				*dev = devnr;
-				return(PCIBIOS_SUCCESSFUL);
-			}
-		}
-	}
-
-	return(PCIBIOS_DEVICE_NOT_FOUND);
-}
-
-/*****************************************************************************/
-
 /*
  *	Local routines to interrcept the standard I/O and vector handling
  *	code. Don't include this 'till now - initialization code above needs
diff -Nru a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/m68knommu/kernel/entry.S	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,140 @@
+/*
+ *  linux/arch/m68knommu/kernel/entry.S
+ *
+ *  Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *
+ * Based on:
+ *
+ *  linux/arch/m68k/kernel/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ * ColdFire support by Greg Ungerer (gerg@snapgear.com)
+ * 5307 fixes by David W. Miller
+ * linux 2.4 support David McCullough <davidm@snapgear.com>
+ */
+
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/asm-offsets.h>
+#include <asm/entry.h>
+
+.text
+
+.globl buserr
+.globl trap
+.globl ret_from_exception
+.globl ret_from_signal
+.globl sys_fork
+.globl sys_clone
+.globl sys_vfork
+
+ENTRY(buserr)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument */
+	jsr	buserr_c
+	addql	#4,%sp
+	jra	ret_from_exception
+
+ENTRY(trap)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument */
+	jsr	trap_c
+	addql	#4,%sp
+	jra	ret_from_exception
+
+#ifdef TRAP_DBG_INTERRUPT
+
+.globl dbginterrupt
+ENTRY(dbginterrupt)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(LORIG_D0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument */
+	jsr	dbginterrupt_c
+	addql	#4,%sp
+	jra	ret_from_exception
+#endif
+
+ENTRY(reschedule)
+	/* save top of frame */
+	pea	%sp@
+	jbsr	set_esp0
+	addql	#4,%sp
+	pea	ret_from_exception
+	jmp	schedule
+
+ENTRY(ret_from_fork)
+	jra	ret_from_exception
+
+ENTRY(sys_fork)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_fork
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_vfork)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_vfork
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_clone)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	m68k_clone
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_sigsuspend
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_rt_sigsuspend
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	do_sigreturn
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigreturn)
+	SAVE_SWITCH_STACK
+	jbsr	do_rt_sigreturn
+	RESTORE_SWITCH_STACK
+	rts
+
diff -Nru a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
--- a/arch/m68knommu/kernel/setup.c	Mon Jan 13 21:59:50 2003
+++ b/arch/m68knommu/kernel/setup.c	Mon Jan 13 21:59:50 2003
@@ -343,10 +343,10 @@
 }
 
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	show_cpuinfo,
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= show_cpuinfo,
 };
 
 void arch_gettod(int *year, int *mon, int *day, int *hour,
diff -Nru a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
--- a/arch/m68knommu/kernel/signal.c	Mon Jan 13 21:59:50 2003
+++ b/arch/m68knommu/kernel/signal.c	Mon Jan 13 21:59:50 2003
@@ -857,7 +857,7 @@
 			case SIGQUIT: case SIGILL: case SIGTRAP:
 			case SIGIOT: case SIGFPE: case SIGSEGV:
 			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
-				if (do_coredump(signr, regs))
+				if (do_coredump(signr, exit_code, regs))
 					exit_code |= 0x80;
 				/* FALLTHRU */
 
diff -Nru a/arch/m68knommu/platform/5206/ARNEWSH/ram.ld b/arch/m68knommu/platform/5206/ARNEWSH/ram.ld
--- a/arch/m68knommu/platform/5206/ARNEWSH/ram.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x10000, LENGTH = 0x200000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4) ;
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld b/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld
--- a/arch/m68knommu/platform/5206e/MOTOROLA/ram.ld	Mon Jan 13 21:59:50 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit/text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4) ;
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5206e/eLITE/ram.ld b/arch/m68knommu/platform/5206e/eLITE/ram.ld
--- a/arch/m68knommu/platform/5206e/eLITE/ram.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x30020000, LENGTH = 0xe0000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text 0x30020000 : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4) ;
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5249/MOTOROLA/ram.ld b/arch/m68knommu/platform/5249/MOTOROLA/ram.ld
--- a/arch/m68knommu/platform/5249/MOTOROLA/ram.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,81 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x20000, LENGTH = 0x3e0000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-        	*(.modinfo)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		. = ALIGN(4);
-		_sdata = . ;
-		__data_start = . ;
-		*(.data)
-		*(.data.exit)
-		. = ALIGN(8192) ;
-		*(.data.init_task)
-		. = ALIGN(8192) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		. = ALIGN(4096);
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4);
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		. = ALIGN(4);
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5272/MOTOROLA/ram.ld b/arch/m68knommu/platform/5272/MOTOROLA/ram.ld
--- a/arch/m68knommu/platform/5272/MOTOROLA/ram.ld	Mon Jan 13 21:59:51 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,81 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x20000, LENGTH = 0x3e0000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-        	*(.modinfo)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		. = ALIGN(4);
-		_sdata = . ;
-		__data_start = . ;
-		*(.data)
-		*(.data.exit)
-		. = ALIGN(8192) ;
-		*(.data.init_task)
-		. = ALIGN(8192) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		. = ALIGN(4096);
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4);
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		. = ALIGN(4);
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5272/NETtel/ram.ld b/arch/m68knommu/platform/5272/NETtel/ram.ld
--- a/arch/m68knommu/platform/5272/NETtel/ram.ld	Mon Jan 13 21:59:48 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,81 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x400, LENGTH = 0x400000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-		*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		*(.modinfo)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		. = ALIGN(4);
-		_sdata = . ;
-		__data_start = . ;
-		*(.data)
-		*(.data.exit)
-		. = ALIGN(8192) ;
-		*(.data.init_task)
-		. = ALIGN(8192) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		. = ALIGN(4096);
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4);
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		. = ALIGN(4);
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5307/ARNEWSH/ram.ld b/arch/m68knommu/platform/5307/ARNEWSH/ram.ld
--- a/arch/m68knommu/platform/5307/ARNEWSH/ram.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4) ;
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld b/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld
--- a/arch/m68knommu/platform/5307/CLEOPATRA/ram.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x400, LENGTH = 0x1000000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = . ;
-		. = ALIGN(4);
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5307/MOTOROLA/ram.ld b/arch/m68knommu/platform/5307/MOTOROLA/ram.ld
--- a/arch/m68knommu/platform/5307/MOTOROLA/ram.ld	Mon Jan 13 21:59:51 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4) ;
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5307/MP3/ram.ld b/arch/m68knommu/platform/5307/MP3/ram.ld
--- a/arch/m68knommu/platform/5307/MP3/ram.ld	Mon Jan 13 21:59:51 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x400, LENGTH = 0x1000000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = . ;
-		. = ALIGN(4);
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5307/NETtel/ram.ld b/arch/m68knommu/platform/5307/NETtel/ram.ld
--- a/arch/m68knommu/platform/5307/NETtel/ram.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x400, LENGTH = 0x400000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4) ;
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld b/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld
--- a/arch/m68knommu/platform/5407/CLEOPATRA/ram.ld	Mon Jan 13 21:59:51 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x400, LENGTH = 0x800000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = . ;
-		. = ALIGN(4);
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/5407/MOTOROLA/ram.ld b/arch/m68knommu/platform/5407/MOTOROLA/ram.ld
--- a/arch/m68knommu/platform/5407/MOTOROLA/ram.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,77 +0,0 @@
-
-MEMORY {
-	ram    : ORIGIN = 0x20000, LENGTH = 0x007E0000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-
-	.text : {
-		_stext = . ;
-        	*(.text)
-		*(.exit.text)
-		*(.text.lock)
-		*(.exitcall.exit)
-		*(.rodata)
-		. = ALIGN(0x4) ;
-		*(.kstrtab)
-		. = ALIGN(16);          /* Exception table              */
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-
-		__start___ksymtab = .;  /* Kernel symbol table          */
-		*(__ksymtab)
-		__stop___ksymtab = .;
-
-	        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only */
-		*(__gpl_ksymtab)
-		__stop___gpl_ksymtab = .;
-
-		. = ALIGN(4) ;
-		_etext = . ;
-	} > ram
-
-	.data BLOCK(0x4) : {
-		_sdata = . ;
-		__data_start = . ;
-        	*(.data)
-		*(.data.exit)
-		. = ALIGN(0x2000) ;
-        	*(.data.init_task)
-		. = ALIGN(0x2000) ;
-		_edata = . ;
-	} > ram
-
-	.init BLOCK(4096) : {
-		__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-		. = ALIGN(16);
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-		__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-		__initcall_end = .;
-		. = ALIGN(4) ;
-		__init_end = .;
-	} > ram
-
-	.bss BLOCK(0x4) : {
-		_sbss = . ;
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4) ;
-		_ebss = . ;
-		_end = . ;
-	} > ram
-}
-
diff -Nru a/arch/m68knommu/platform/68328/pilot/rom.ld b/arch/m68knommu/platform/68328/pilot/rom.ld
--- a/arch/m68knommu/platform/68328/pilot/rom.ld	Mon Jan 13 21:59:51 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,105 +0,0 @@
-OUTPUT_ARCH(m68k)
-ENTRY(_start)
-MEMORY {
-	romvec : ORIGIN = 0x10c00000, LENGTH = 0x10400
-	flash  : ORIGIN = 0x10c10400, LENGTH = 0xfec00
-	eflash : ORIGIN = 0x10d00000, LENGTH = 4
-	ramvec : ORIGIN = 0x00000000, LENGTH = 0x400
-	ram    : ORIGIN = 0x10000400, LENGTH = 0x100000-0x400
-	eram   : ORIGIN = 0x10100000, LENGTH = 4
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS {
-  . = 0x10c00000 ;
-  .romvec : {
-	  _flashstart = . ;
-	  _romvec = . ;
-	} > romvec
-
-  . = 0x10c10400 ;
-  .text : {
-	  _text = .;                    /* Text and read-only data */
-	  text_start = . ;
-          *(.text)
-          *(.text.*)
-          *(.rodata)
-          *(.fixup)		
-          *(__ex_table)	
-	  . = ALIGN(4) ;
-	  _etext = . ;
-	  __data_rom_start = . ;
-	} > flash
-  
-  . = 0x10d00000 ;
-  .eflash :
-        {
-          _flashend = . ;
-        } > eflash
-	
-  . = 0 ;
-  .ramvec :
-	{
-	  __ramvec = . ;
-	} > ramvec
-	
-  /* . = 0x10000400 ; */
-  .data 0x10000400 :
-	{
-	  _sdata = . ;
-	  __data_start = . ;
-
-	  . = ALIGN(0x2000) ;
-	  *(.data.init_task)
-	  . = ALIGN(0x2000) ;
-
-      *(.data)
-      *(.data.*)	
-      *(.setup.init)		
-      *(.exitcall.exit)		
-	
-	  . = ALIGN(4096) ;
-	  __init_begin = .;
-	  *(.init.text)
-	  *(.init.data)
-	  . = ALIGN(16);
-	  __setup_start = .;
-	  *(.init.setup)
-	  __setup_end = .;
-	  __initcall_start = .;
-	  *(.initcall1.init)
-	  *(.initcall2.init)
-	  *(.initcall3.init)
-	  *(.initcall4.init)
-	  *(.initcall5.init)
-	  *(.initcall6.init)
-	  *(.initcall7.init)
-	  __initcall_end = .;
-	  . = ALIGN(4) ;
-	  __init_end = .;
-
-	  _edata = . ;
-	  edata = . ;
-	} > ram
-
-  .bss :
-    {
-	  . = ALIGN(16) ;
-	  _sbss = . ;
-	  __bss_start = . ;
-	  __data_end = . ;
-	  *(.bss)
-	  *(COMMON)
-	  . = ALIGN(16) ;
-	  end = . ;
-	  _ebss = . ;	  
-	  _end = . ;
-    } > ram
-
-  . = 0x10100000 ;
-  .eram :
-	{
-  	  __ramend = . ;
-	} > eram
-}
diff -Nru a/arch/m68knommu/platform/68360/uCquicc/ram.ld b/arch/m68knommu/platform/68360/uCquicc/ram.ld
--- a/arch/m68knommu/platform/68360/uCquicc/ram.ld	Mon Jan 13 21:59:50 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,116 +0,0 @@
-MEMORY
-{
-    romvec   : ORIGIN = 0x00000000,                 LENGTH = 1028
-    flash    : ORIGIN = 1028,                       LENGTH = 0x00080000 - 1028
-    eflash   : ORIGIN = 0x00000000 + 0x00100000,    LENGTH = 1
-    ramvec   : ORIGIN = 0x00200000,                 LENGTH = 1028
-    ram      : ORIGIN = 0x00200000 + 1028,          LENGTH = 0x00080000 - 1028
-    eram     : ORIGIN = 0x00200000 + 0x00080000,    LENGTH = 1
-    dpram    : ORIGIN = 0xffffe000,                 LENGTH = 0x00002000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS
-{
-    .dpram :
-    {
-        _dprbase = . ;
-    } > dpram
-
-    .romvec :
-    {
-        _romvec = . ;
-        __flashstart = . ;
-        *(.data.initvect)
-        . = ALIGN(4);
-    } > romvec
-
-    .text :
-    {
-        text_start = . ;
-        *(.text)
-        *(.exit.text)
-        *(.text.*)
-        *(.rodata)
-        *(.fixup)
-	*(.kstrtab)
-	__start___ksymtab = . ;
-	*(__ksymtab)
-        __stop___ksymtab = . ;
-	__start___gpl_ksymtab = . ;
-	*(__gpl_ksymtab)
-        __stop___gpl_ksymtab = . ;
-	__start___ex_table = . ;
-	*(___ex_table)
-	__stop___ex_table = . ;
-        . = ALIGN(4) ;_etext = . ;
-        __data_rom_start = ALIGN ( 4 ) ;
-    } > flash
-   
-    .eflash :
-    {
-        __flashend = . ;
-    } > eflash
-
-
-    .ramvec :
-    {
-        __ramstart = . ;
-        _ramvec = . ;
-    } > ramvec
-   
-    .data :
-    {
-        _sdata = . ;
-        __data_start = . ;
-       . = ALIGN(0x2000) ;
-       *(.data.init_task)
-       . = ALIGN(0x2000) ;
-        *(.data)
-        *(.data.*)
-        *(.setup.init)
-       *(.exitcall.exit)
-       . = ALIGN(4096) ;
-        __init_begin = .;
-        *(.init.text)
-        *(.init.data)
-        . = ALIGN(16);
-        __setup_start = .;
-        *(.init.setup)
-        __setup_end = .;
-        __initcall_start = .;
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
-        __initcall_end = .;
-        . = ALIGN(4) ;
-	__init_end = .;      
-        _edata = . ;
-        edata = .;
-    } > ram
-
-    .bss :
-    {
-        _sbss = ALIGN( 0x10 ) ;
-        __bss_start = ALIGN( 0x10 ) ;
-        __data_end = ALIGN( 0x10 ) ;
-        *(.bss)
-        *(COMMON)
-            _ebss = . ;
-        __bss_end = . ;
-        end = ALIGN( 0x10 ) ;
-        _end = ALIGN( 0x10 ) ;
-    } > ram
-
-    .eram :
-    {
-        _boot_stack = . - 4;
-        __ramend = . ;
-
-    } > eram
-}
diff -Nru a/arch/m68knommu/platform/68360/uCquicc/rom.ld b/arch/m68knommu/platform/68360/uCquicc/rom.ld
--- a/arch/m68knommu/platform/68360/uCquicc/rom.ld	Mon Jan 13 21:59:51 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,116 +0,0 @@
-MEMORY
-{
-    romvec   : ORIGIN = 0x00000000,                 LENGTH = 1028
-    flash    : ORIGIN = 1028,                       LENGTH = 0x00200000 - 1028
-    eflash   : ORIGIN = 0x00000000 + 0x00200000,    LENGTH = 1
-    ramvec   : ORIGIN = 0x00200000,                 LENGTH = 1028
-    ram      : ORIGIN = 0x00200000 + 1028,          LENGTH = 0x00200000 - 1028
-    eram     : ORIGIN = 0x00200000 + 0x00200000,    LENGTH = 1
-    dpram    : ORIGIN = 0xffffe000,                 LENGTH = 0x00002000
-}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS
-{
-    .dpram :
-    {
-        _dprbase = . ;
-    } > dpram
-
-    .romvec :
-    {
-        _romvec = . ;
-        __flashstart = . ;
-        *(.data.initvect)
-        . = ALIGN(4);
-    } > romvec
-
-    .text :
-    {
-        text_start = . ;
-        *(.text)
-        *(.exit.text)
-        *(.text.*)
-        *(.rodata)
-        *(.fixup)
-        *(.kstrtab)
-        __start___ksymtab = . ;
-        *(__ksymtab)
-        __stop___ksymtab = . ;
-        __start___gpl_ksymtab = . ;
-        *(__gpl_ksymtab)
-        __stop___gpl_ksymtab = . ;
-        __start___ex_table = . ;
-        *(___ex_table)
-        __stop___ex_table = . ;
-        . = ALIGN(4) ;_etext = . ;
-        __data_rom_start = ALIGN ( 4 ) ;
-    } > flash
-   
-    .eflash :
-    {
-        __flashend = . ;
-    } > eflash
-
-
-    .ramvec :
-    {
-        __ramstart = . ;
-        _ramvec = . ;
-    } > ramvec
-   
-    .data :
-    {
-        _sdata = . ;
-        __data_start = . ;
-       . = ALIGN(0x2000) ;
-       *(.data.init_task)
-       . = ALIGN(0x2000) ;
-        *(.data)
-        *(.data.*)
-        *(.setup.init)
-       *(.exitcall.exit)
-       . = ALIGN(4096) ;
-        __init_begin = .;
-        *(.init.text)
-        *(.init.data)
-        . = ALIGN(16);
-        __setup_start = .;
-        *(.init.setup)
-        __setup_end = .;
-        __initcall_start = .;
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
-        __initcall_end = .;
-        . = ALIGN(4) ;
-        __init_end = .;      
-        _edata = . ;
-        edata = .;
-    } > ram
-
-    .bss :
-    {
-        _sbss = ALIGN( 0x10 ) ;
-        __bss_start = ALIGN( 0x10 ) ;
-        __data_end = ALIGN( 0x10 ) ;
-        *(.bss)
-        *(COMMON)
-        _ebss = . ;
-        __bss_end = . ;
-        end = ALIGN( 0x10 ) ;
-        _end = ALIGN( 0x10 ) ;
-    } > ram
-
-    .eram :
-    {
-        _boot_stack = . - 4;
-        __ramend = . ;
-
-    } > eram
-}
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S
--- a/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S	Mon Jan 13 21:59:50 2003
+++ b/arch/m68knommu/platform/68EZ328/ucsimm/crt0_fixed.S	Mon Jan 13 21:59:50 2003
@@ -54,7 +54,7 @@
 	bne	1b
 
 	/* Copy data segment from ROM to RAM */
-	moveal	#__data_rom_start, %a0
+	moveal	#_etext, %a0
 	moveal	#_sdata, %a1
 	moveal	#_edata, %a2
 
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld b/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
--- a/arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld	Mon Jan 13 21:59:50 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,112 +0,0 @@
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS
-{
-  .romvec :
-	{
-	_flashstart = . ;
-	_romvec = . ;
-	__rom_start = . ;
-	} > romvec
-
-  .text :
-	{
-	_stext = . ;
-        	*(.text)
-        	*(.exit.text)
-	. = ALIGN(0x4) ;
-		*(.text.*)
-	. = ALIGN(0x4) ;
-		*(.exitcall.exit)
-	. = ALIGN(0x4) ;
-		*(.kstrtab)
-	. = ALIGN(16);          /* Exception table              */
-	__start___ex_table = .;
-		*(__ex_table)
-	__stop___ex_table = .;
-
-        __start___ksymtab = .;  /* Kernel symbol table          */
-		 *(__ksymtab)
-	__stop___ksymtab = .;
-
-        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only  */
-		 *(__gpl_ksymtab)
-	__stop___gpl_ksymtab = .;
-
-	. = ALIGN(0x4) ;
-	_etext = . ;
-	__data_rom_start = . ;
-        } > flash
-
-  .eflash :
-	{
-	_flashend = . ;
-	} > eflash
-
-  .ramvec :
-	{
-	__ram_start = . ;
-	__ramvec = . ;
-	} > ramvec
-
-  .data :
-	{
-	. = ALIGN(0x4) ;
-	_sdata = . ;
-	__data_start = . ;
-
-	. = ALIGN(0x4) ;
-		*(.rodata)
-	. = ALIGN(0x4) ;
-		*(.data)
-	. = ALIGN(0x4) ;
-		*(.data.*)	
-
-	. = ALIGN(0x4) ;
-	__init_begin = .;
-		*(.init.text)
-		*(.init.data)
-
-	. = ALIGN(0x4) ;
-	__setup_start = .;
-		*(.init.setup)
-	. = ALIGN(0x4) ;
-	__setup_end = .;
-
-	. = ALIGN(0x4) ;
-	__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-	__initcall_end = .;
-	. = ALIGN(0x4) ;
-
-	. = ALIGN(0x2000) ;
-		*(.data.init_task)
-	. = ALIGN(0x2000) ;
-
-	_edata = . ;
-        } > ram
-
-  .bss :
-        {
-	. = ALIGN(0x4) ;
-	_sbss = . ;
-		*(.bss)
-	. = ALIGN(0x4) ;
-		*(COMMON)
-	. = ALIGN(0x4) ;
-	_ebss = . ;
-	_end = . ;
-	} > ram
-
-  .eram :
-	{
-	__ramend = . ;
-	} > eram
-}
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld b/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld
--- a/arch/m68knommu/platform/68EZ328/ucsimm/himem.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,11 +0,0 @@
-MEMORY 
-	{
-        romvec : ORIGIN = 0x00600000, LENGTH = 0x00000400
-        flash  : ORIGIN = 0x00600400, LENGTH = 0x00200000 - 0x00010400
-        eflash : ORIGIN = 0x007f0000, LENGTH = 0
-        ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
-        ram    : ORIGIN = 0x00020000, LENGTH = 0x00600000 - 0x00020000
-        eram   : ORIGIN = 0x00600000, LENGTH = 0
-	}
-
-INCLUDE arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld b/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld
--- a/arch/m68knommu/platform/68EZ328/ucsimm/ram.ld	Mon Jan 13 21:59:50 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,114 +0,0 @@
-MEMORY 
-	{
-	romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
-	flash  : ORIGIN = 0x10c10400, LENGTH = 0x00200000 - 0x00010400
-	eflash : ORIGIN = 0x10e00000, LENGTH = 0
-	ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
-	bvec   : ORIGIN = 0x00020000, LENGTH = 0x00000400
-	ram    : ORIGIN = 0x00020400, LENGTH = 0x00800000 - 0x00020400
-	eram   : ORIGIN = 0x00800000, LENGTH = 0
-	}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS
-{
-	.fakevec :
-	{
-	} > romvec
-	.rom :
-	{
-	__rom_start = . ;
-	} > flash
-	.eflash :
-	{
-	_flashend = . ;
-	} > eflash
-	.realvec :
-	{
-	_ramvec = . ;
-	} > ramvec
-	.romvec :
-	{
-	_romvec = . ;
-	} > bvec
-        .text :
-	{
-	__ram_start = . ;
-	text_start = . ;
-        	*(.text)
-        	*(.exit.text)
-		*(.text.*)
-		*(.rodata)
-	. = ALIGN(0x4) ;
-		*(.kstrtab)
-	. = ALIGN(16);          /* Exception table              */
-	__start___ex_table = .;
-		*(__ex_table)
-	__stop___ex_table = .;
-
-        __start___ksymtab = .;  /* Kernel symbol table          */
-		 *(__ksymtab)
-	__stop___ksymtab = .;
-
-        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only  */
-		 *(__gpl_ksymtab)
-	__stop___gpl_ksymtab = .;
-
-	_etext = . ;
-	__data_rom_start = ALIGN ( 4 ) ;
-        } > ram
-        .data :
-	{
-	_sdata = . ;
-	__data_start = . ;
-
-        . = ALIGN(0x2000) ;
-        *(.data.init_task)
-        . = ALIGN(0x2000) ;
-
-        *(.data)
-        *(.data.*)      
-        *(.exitcall.exit)               
-
-        . = ALIGN(4096) ;
-        __init_begin = .;
-        *(.init.text)
-        *(.init.data)
-        . = ALIGN(16);
-        __setup_start = .;
-        *(.init.setup)
-        __setup_end = .;
-        __initcall_start = .;
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
-        __initcall_end = .;
-        . = ALIGN(4) ;
-        __init_end = .;
-
-	_edata = . ;
-	edata = ALIGN( 0x10 ) ;
-        } > ram
-        .bss :
-        {
-	_sbss = ALIGN( 0x10 ) ;
-	__bss_start = ALIGN( 0x10 ) ;
-	__data_end = ALIGN( 0x10 ) ;
-	*(.bss)
-	*(COMMON)
-	_ebss = . ;
-	__bss_end = . ;
-	end = ALIGN( 0x10 ) ;
-	_end = ALIGN( 0x10 ) ;
-	} > ram
-	.eram :
-	{
-	__ramend = . ;
-	_ramend = . ;
-	} > eram
-}
diff -Nru a/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld b/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld
--- a/arch/m68knommu/platform/68EZ328/ucsimm/rom.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,11 +0,0 @@
-MEMORY 
-	{
-        romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
-        flash  : ORIGIN = 0x10c10400, LENGTH = 0x001fec00
-        eflash : ORIGIN = 0x10d00000, LENGTH = 0
-        ramvec : ORIGIN = 0x00000000, LENGTH = 1024
-        ram    : ORIGIN = 0x00020000, LENGTH = 0x00800000 - 0x00020000
-        eram   : ORIGIN = 0x00800000, LENGTH = 0
-	}
-
-INCLUDE arch/m68knommu/platform/68EZ328/ucsimm/fixed.ld
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S b/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S
--- a/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S	Mon Jan 13 21:59:49 2003
+++ b/arch/m68knommu/platform/68VZ328/de2/crt0_fixed.S	Mon Jan 13 21:59:49 2003
@@ -86,7 +86,7 @@
 
 #ifndef CONFIG_RAMKERNEL
 	/* Copy data segment from ROM to RAM */
-	moveal	#__data_rom_start, %a0
+	moveal	#_etext, %a0
 	moveal	#_sdata, %a1
 	moveal	#_edata, %a2
 
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/fixed.ld b/arch/m68knommu/platform/68VZ328/de2/fixed.ld
--- a/arch/m68knommu/platform/68VZ328/de2/fixed.ld	Mon Jan 13 21:59:50 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,106 +0,0 @@
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS
-{
-  .romvec :
-	{
-	_flashstart = . ;
-	_romvec = . ;
-	__rom_start = . ;
-	} > romvec
-
-  .text :
-	{
-	_stext = . ;
-        	*(.text)
-	. = ALIGN(0x4) ;
-		*(.text.*)
-	. = ALIGN(0x4) ;
-		*(.exitcall.exit)
-	. = ALIGN(0x4) ;
-		*(.kstrtab)
-	. = ALIGN(16);          /* Exception table              */
-	__start___ex_table = .;
-		*(__ex_table)
-	__stop___ex_table = .;
-
-        __start___ksymtab = .;  /* Kernel symbol table          */
-		 *(__ksymtab)
-	__stop___ksymtab = .;
-
-        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only  */
-		 *(__gpl_ksymtab)
-	__stop___gpl_ksymtab = .;
-
-	. = ALIGN(0x4) ;
-	_etext = . ;
-	__data_rom_start = . ;
-        } > flash
-
-  .eflash :
-	{
-	_flashend = . ;
-	} > eflash
-
-  .ramvec :
-	{
-	__ram_start = . ;
-	__ramvec = . ;
-	} > ramvec
-
-  .data :
-	{
-	. = ALIGN(0x4) ;
-	_sdata = . ;
-	__data_start = . ;
-
-	. = ALIGN(0x4) ;
-		*(.rodata)
-	. = ALIGN(0x4) ;
-		*(.data)
-	. = ALIGN(0x4) ;
-		*(.data.*)	
-
-	. = ALIGN(0x4) ;
-	__setup_start = .;
-		*(.init.setup)
-	. = ALIGN(0x4) ;
-	__setup_end = .;
-
-	. = ALIGN(0x4) ;
-	__initcall_start = .;
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
-	__initcall_end = .;
-	. = ALIGN(0x4) ;
-
-	. = ALIGN(0x2000) ;
-		*(.data.init_task)
-	. = ALIGN(0x2000) ;
-
-	_edata = . ;
-        } > ram
-
-  .bss :
-        {
-	. = ALIGN(0x4) ;
-	_sbss = . ;
-		*(.bss)
-	. = ALIGN(0x4) ;
-		*(COMMON)
-	. = ALIGN(0x4) ;
-	_ebss = . ;
-	_end = . ;
-	} > ram
-
-  .eram :
-	{
-	__ramend = . ;
-	} > eram
-}
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/ram.ld b/arch/m68knommu/platform/68VZ328/de2/ram.ld
--- a/arch/m68knommu/platform/68VZ328/de2/ram.ld	Mon Jan 13 21:59:50 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,113 +0,0 @@
-MEMORY 
-	{
-	romvec : ORIGIN = 0x04030000, LENGTH = 1k
-	flash  : ORIGIN = 0x04030400, LENGTH = 2M - 197k
-	eflash : ORIGIN = 0x04200000, LENGTH = 0
-	ramvec : ORIGIN = 0x00000000, LENGTH = 1k
-	bvec   : ORIGIN = 0x00010000, LENGTH = 1k
-	ram    : ORIGIN = 0x00010400, LENGTH = 32M - 65k
-	eram   : ORIGIN = 0x02000000, LENGTH = 0
-	}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS
-{
-	.fakevec :
-	{
-	} > romvec
-	.rom :
-	{
-	__rom_start = . ;
-	} > flash
-	.eflash :
-	{
-	_flashend = . ;
-	} > eflash
-	.realvec :
-	{
-	__ramvec = . ;
-	} > ramvec
-	.romvec :
-	{
-	_romvec = . ;
-	} > bvec
-        .text :
-	{
-	__ram_start = . ;
-	text_start = . ;
-        	*(.text)
-		*(.text.*)
-		*(.rodata)
-	. = ALIGN(0x4) ;
-		*(.kstrtab)
-	. = ALIGN(16);          /* Exception table              */
-	__start___ex_table = .;
-		*(__ex_table)
-	__stop___ex_table = .;
-
-        __start___ksymtab = .;  /* Kernel symbol table          */
-		 *(__ksymtab)
-	__stop___ksymtab = .;
-
-        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only  */
-		 *(__gpl_ksymtab)
-	__stop___gpl_ksymtab = .;
-
-	_etext = . ;
-	__data_rom_start = ALIGN ( 4 ) ;
-        } > ram
-        .data :
-	{
-	_sdata = . ;
-	__data_start = . ;
-
-        . = ALIGN(0x2000) ;
-        *(.data.init_task)
-        . = ALIGN(0x2000) ;
-
-        *(.data)
-        *(.data.*)      
-        *(.exitcall.exit)               
-
-        . = ALIGN(4096) ;
-        __init_begin = .;
-        *(.init.text)
-        *(.init.data)
-        . = ALIGN(16);
-        __setup_start = .;
-        *(.init.setup)
-        __setup_end = .;
-        __initcall_start = .;
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
-        __initcall_end = .;
-        . = ALIGN(4) ;
-        __init_end = .;
-
-	_edata = . ;
-	edata = ALIGN( 0x10 ) ;
-        } > ram
-        .bss :
-        {
-	_sbss = ALIGN( 0x10 ) ;
-	__bss_start = ALIGN( 0x10 ) ;
-	__data_end = ALIGN( 0x10 ) ;
-	*(.bss)
-	*(COMMON)
-	_ebss = . ;
-	__bss_end = . ;
-	end = ALIGN( 0x10 ) ;
-	_end = ALIGN( 0x10 ) ;
-	} > ram
-	.eram :
-	{
-	__ramend = . ;
-	_ramend = . ;
-	} > eram
-}
diff -Nru a/arch/m68knommu/platform/68VZ328/de2/rom.ld b/arch/m68knommu/platform/68VZ328/de2/rom.ld
--- a/arch/m68knommu/platform/68VZ328/de2/rom.ld	Mon Jan 13 21:59:50 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,11 +0,0 @@
-MEMORY 
-	{
-        romvec : ORIGIN = 0x04030000, LENGTH = 1k
-        flash  : ORIGIN = 0x04030400, LENGTH = 2M - 197k
-        eflash : ORIGIN = 0x04200000, LENGTH = 0
-        ramvec : ORIGIN = 0x00000000, LENGTH = 1k
-        ram    : ORIGIN = 0x00010000, LENGTH = 32M - 64k
-        eram   : ORIGIN = 0x02000000, LENGTH = 0
-	}
-
-INCLUDE arch/m68knommu/platform/68VZ328/de2/fixed.ld
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S
--- a/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S	Mon Jan 13 21:59:48 2003
+++ b/arch/m68knommu/platform/68VZ328/ucdimm/crt0_fixed.S	Mon Jan 13 21:59:48 2003
@@ -54,7 +54,7 @@
 	bne	1b
 
 	/* Copy data segment from ROM to RAM */
-	moveal	#__data_rom_start, %a0
+	moveal	#_etext, %a0
 	moveal	#_sdata, %a1
 	moveal	#_edata, %a2
 
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld b/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld
--- a/arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,106 +0,0 @@
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS
-{
-  .romvec :
-	{
-	_flashstart = . ;
-	_romvec = . ;
-	__rom_start = . ;
-	} > romvec
-
-  .text :
-	{
-	_stext = . ;
-        	*(.text)
-	. = ALIGN(0x4) ;
-		*(.text.*)
-	. = ALIGN(0x4) ;
-		*(.exitcall.exit)
-	. = ALIGN(0x4) ;
-		*(.kstrtab)
-	. = ALIGN(16);          /* Exception table              */
-	__start___ex_table = .;
-		*(__ex_table)
-	__stop___ex_table = .;
-
-        __start___ksymtab = .;  /* Kernel symbol table          */
-		 *(__ksymtab)
-	__stop___ksymtab = .;
-
-        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only  */
-		 *(__gpl_ksymtab)
-	__stop___gpl_ksymtab = .;
-
-	. = ALIGN(0x4) ;
-	_etext = . ;
-	__data_rom_start = . ;
-        } > flash
-
-  .eflash :
-	{
-	_flashend = . ;
-	} > eflash
-
-  .ramvec :
-	{
-	__ram_start = . ;
-	__ramvec = . ;
-	} > ramvec
-
-  .data :
-	{
-	. = ALIGN(0x4) ;
-	_sdata = . ;
-	__data_start = . ;
-
-	. = ALIGN(0x4) ;
-		*(.rodata)
-	. = ALIGN(0x4) ;
-		*(.data)
-	. = ALIGN(0x4) ;
-		*(.data.*)	
-
-	. = ALIGN(0x4) ;
-	__setup_start = .;
-		*(.init.setup)
-	. = ALIGN(0x4) ;
-	__setup_end = .;
-
-	. = ALIGN(0x4) ;
-	__initcall_start = .;
-		*(.initcall1.init)
-		*(.initcall2.init)
-		*(.initcall3.init)
-		*(.initcall4.init)
-		*(.initcall5.init)
-		*(.initcall6.init)
-		*(.initcall7.init)
-	__initcall_end = .;
-	. = ALIGN(0x4) ;
-
-	. = ALIGN(0x2000) ;
-		*(.data.init_task)
-	. = ALIGN(0x2000) ;
-
-	_edata = . ;
-        } > ram
-
-  .bss :
-        {
-	. = ALIGN(0x4) ;
-	_sbss = . ;
-		*(.bss)
-	. = ALIGN(0x4) ;
-		*(COMMON)
-	. = ALIGN(0x4) ;
-	_ebss = . ;
-	_end = . ;
-	} > ram
-
-  .eram :
-	{
-	__ramend = . ;
-	} > eram
-}
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld b/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld
--- a/arch/m68knommu/platform/68VZ328/ucdimm/himem.ld	Mon Jan 13 21:59:49 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,11 +0,0 @@
-MEMORY 
-	{
-        romvec : ORIGIN = 0x00600000, LENGTH = 0x00000400
-        flash  : ORIGIN = 0x00600400, LENGTH = 0x00200000 - 0x00010400
-        eflash : ORIGIN = 0x007f0000, LENGTH = 0
-        ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
-        ram    : ORIGIN = 0x00020000, LENGTH = 0x00600000 - 0x00020000
-        eram   : ORIGIN = 0x00600000, LENGTH = 0
-	}
-
-INCLUDE arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld b/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld
--- a/arch/m68knommu/platform/68VZ328/ucdimm/ram.ld	Mon Jan 13 21:59:51 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,113 +0,0 @@
-MEMORY 
-	{
-	romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
-	flash  : ORIGIN = 0x10c10400, LENGTH = 0x00200000 - 0x00010400
-	eflash : ORIGIN = 0x10e00000, LENGTH = 0
-	ramvec : ORIGIN = 0x00000000, LENGTH = 0x00000400
-	bvec   : ORIGIN = 0x00020000, LENGTH = 0x00000400
-	ram    : ORIGIN = 0x00020400, LENGTH = 0x00800000 - 0x00020400
-	eram   : ORIGIN = 0x00800000, LENGTH = 0
-	}
-
-jiffies = jiffies_64 + 4;
-
-SECTIONS
-{
-	.fakevec :
-	{
-	} > romvec
-	.rom :
-	{
-	__rom_start = . ;
-	} > flash
-	.eflash :
-	{
-	_flashend = . ;
-	} > eflash
-	.realvec :
-	{
-	_ramvec = . ;
-	} > ramvec
-	.romvec :
-	{
-	_romvec = . ;
-	} > bvec
-        .text :
-	{
-	__ram_start = . ;
-	text_start = . ;
-        	*(.text)
-		*(.text.*)
-		*(.rodata)
-	. = ALIGN(0x4) ;
-		*(.kstrtab)
-	. = ALIGN(16);          /* Exception table              */
-	__start___ex_table = .;
-		*(__ex_table)
-	__stop___ex_table = .;
-
-        __start___ksymtab = .;  /* Kernel symbol table          */
-		 *(__ksymtab)
-	__stop___ksymtab = .;
-
-        __start___gpl_ksymtab = .;  /* Kernel symbol table: GPL-only  */
-		 *(__gpl_ksymtab)
-	__stop___gpl_ksymtab = .;
-
-	_etext = . ;
-	__data_rom_start = ALIGN ( 4 ) ;
-        } > ram
-        .data :
-	{
-	_sdata = . ;
-	__data_start = . ;
-
-        . = ALIGN(0x2000) ;
-        *(.data.init_task)
-        . = ALIGN(0x2000) ;
-
-        *(.data)
-        *(.data.*)      
-        *(.exitcall.exit)               
-
-        . = ALIGN(4096) ;
-        __init_begin = .;
-        *(.init.text)
-        *(.init.data)
-        . = ALIGN(16);
-        __setup_start = .;
-        *(.init.setup)
-        __setup_end = .;
-        __initcall_start = .;
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
-        __initcall_end = .;
-        . = ALIGN(4) ;
-        __init_end = .;
-
-	_edata = . ;
-	edata = ALIGN( 0x10 ) ;
-        } > ram
-        .bss :
-        {
-	_sbss = ALIGN( 0x10 ) ;
-	__bss_start = ALIGN( 0x10 ) ;
-	__data_end = ALIGN( 0x10 ) ;
-	*(.bss)
-	*(COMMON)
-	_ebss = . ;
-	__bss_end = . ;
-	end = ALIGN( 0x10 ) ;
-	_end = ALIGN( 0x10 ) ;
-	} > ram
-	.eram :
-	{
-	__ramend = . ;
-	_ramend = . ;
-	} > eram
-}
diff -Nru a/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld b/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld
--- a/arch/m68knommu/platform/68VZ328/ucdimm/rom.ld	Mon Jan 13 21:59:50 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,11 +0,0 @@
-MEMORY 
-	{
-        romvec : ORIGIN = 0x10c10000, LENGTH = 0x00000400
-        flash  : ORIGIN = 0x10c10400, LENGTH = 0x001fec00
-        eflash : ORIGIN = 0x10d00000, LENGTH = 0
-        ramvec : ORIGIN = 0x00000000, LENGTH = 1024
-        ram    : ORIGIN = 0x00020000, LENGTH = 0x00800000 - 0x00020000
-        eram   : ORIGIN = 0x00800000, LENGTH = 0
-	}
-
-INCLUDE arch/m68knommu/platform/68VZ328/ucdimm/fixed.ld
diff -Nru a/arch/m68knommu/vmlinux.lds.S b/arch/m68knommu/vmlinux.lds.S
--- a/arch/m68knommu/vmlinux.lds.S	Mon Jan 13 21:59:49 2003
+++ b/arch/m68knommu/vmlinux.lds.S	Mon Jan 13 21:59:49 2003
@@ -1,115 +1,315 @@
+/*
+ *	vmlinux.lds.S -- master linker script for m68knommu arch
+ *
+ *	(C) Copyright 2002, Greg Ungerer <gerg@snapgear.com>
+ *
+ *	This ends up looking compilcated, because of the number of
+ *	address variations for ram and rom/flash layouts. The real
+ *	work of the linker script is all at the end, and reasonably
+ *	strait forward.
+ */
 
 #include <linux/config.h>
 
+/*
+ *	Original Palm pilot (same for Xcopilot).
+ *	There is really only a rom target for this.
+ */
 #ifdef CONFIG_PILOT3
-#ifdef CONFIG_ROMKERNEL
-#include "platform/68328/pilot/rom.ld"
-#endif
-#ifdef CONFIG_RAMKERNEL
-#include "platform/68328/pilot/ram.ld"
-#endif
-#endif
-
-#ifdef CONFIG_UCSIMM
+#define	ROMVEC_START	0x10c00000
+#define	ROMVEC_LENGTH	0x10400
+#define	ROM_START	0x10c10400
+#define	ROM_LENGTH	0xfec00
+#define	ROM_END		0x10d00000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x10000400
+#define	RAM_LENGTH	0xffc00
+#define	RAM_END		0x10100000
+#define	DATA_ADDR	RAM_START
+#endif
+
+/*
+ *	Same setup on both the uCsimm and uCdimm.
+ */
+#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM)
 #ifdef CONFIG_RAMKERNEL
-#include "platform/68EZ328/ucsimm/ram.ld"
+#define	ROMVEC_START	0x10c10000
+#define	ROMVEC_LENGTH	0x400
+#define	ROM_START	0x10c10400
+#define	ROM_LENGTH	0x1efc00
+#define	ROM_END		0x10e00000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x00020400
+#define	RAM_LENGTH	0x7dfc00
+#define	RAM_END		0x00800000
 #endif
 #ifdef CONFIG_ROMKERNEL
-#include "platform/68EZ328/ucsimm/rom.ld"
+#define	ROMVEC_START	0x10c10000
+#define	ROMVEC_LENGTH	0x400
+#define	ROM_START	0x10c10400
+#define	ROM_LENGTH	0x1efc00
+#define	ROM_END		0x10e00000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x00020000
+#define	RAM_LENGTH	0x600000
+#define	RAM_END		0x00800000
 #endif
 #ifdef CONFIG_HIMEMKERNEL
-#include "platform/68EZ328/ucsimm/himem.ld"
+#define	ROMVEC_START	0x00600000
+#define	ROMVEC_LENGTH	0x400
+#define	ROM_START	0x00600400
+#define	ROM_LENGTH	0x1efc00
+#define	ROM_END		0x007f0000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x00020000
+#define	RAM_LENGTH	0x5e0000
+#define	RAM_END		0x00600000
 #endif
 #endif
 
-#ifdef CONFIG_UCDIMM
-#ifdef CONFIG_RAMKERNEL
-#include "platform/68VZ328/ucdimm/ram.ld"
-#endif
-#ifdef CONFIG_ROMKERNEL
-#include "platform/68VZ328/ucdimm/rom.ld"
-#endif
-#ifdef CONFIG_HIMEMKERNEL
-#include "platform/68VZ328/ucdimm/himem.ld"
-#endif
-#endif
 #ifdef CONFIG_DRAGEN2
 #ifdef CONFIG_RAMKERNEL
-#include "platform/68VZ328/de2/ram.ld"
+#define	ROMVEC_START	0x04030000
+#define	ROMVEC_LENGTH	0x400
+#define	ROM_START	0x04030400
+#define	ROM_LENGTH	0x1cec00
+#define	ROM_END		0x04200000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x00010400
+#define	RAM_LENGTH	0x1ff0000
+#define	RAM_END		0x02000000
 #endif
 #ifdef CONFIG_ROMKERNEL
-#include "platform/68VZ328/de2/rom.ld"
+#define	ROMVEC_START	0x04030000
+#define	ROMVEC_LENGTH	0x400
+#define	ROM_START	0x04030400
+#define	ROM_LENGTH	0x1cec00
+#define	ROM_END		0x04200000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x00010000
+#define	RAM_LENGTH	0x1ff0000
+#define	RAM_END		0x02000000
 #endif
 #ifdef CONFIG_HIMEMKERNEL
-#include "platform/68VZ328/de2/himem.ld"
+#define	ROMVEC_START	0x01e00000
+#define	ROMVEC_LENGTH	0x400
+#define	ROM_START	0x01e00400
+#define	ROM_LENGTH	0x1ffc00
+#define	ROM_END		0x02000000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x00010000
+#define	RAM_LENGTH	0x1df0000
+#define	RAM_END		0x01e00000
 #endif
 #endif
 
 #ifdef CONFIG_UCQUICC
-#ifdef CONFIG_RAMKERNEL
-#include "platform/68360/uCquicc/ram.ld"
-#endif
-#ifdef CONFIG_ROMKERNEL
-#include "platform/68360/uCquicc/rom.ld"
-#endif
-#endif
-
-#ifdef CONFIG_ARN5206
-#include "platform/5206/ARNEWSH/ram.ld"
+#define	ROMVEC_START	0x00000000
+#define	ROMVEC_LENGTH	0x404
+#define	ROM_START	0x00000404
+#define	ROM_LENGTH	0x1ff6fc
+#define	ROM_END		0x00200000
+#define	RAMVEC_START	0x00200000
+#define	RAMVEC_LENGTH	0x404
+#define	RAM_START	0x00200404
+#define	RAM_LENGTH	0x1ff6fc
+#define	RAM_END		0x00400000
+#endif
+
+/*
+ *	The standard Arnewsh 5206 board only has 1MiB of ram. Not normally
+ *	enough to be usefull. Assume the user has fitted something larger,
+ *	at least 4MiB in size. No point in not letting the kernel completely
+ *	link, it will be obvious if it is too big when they go to load it.
+ */
+#if defined(CONFIG_ARN5206)
+#define	RAM_START	0x10000
+#define	RAM_LENGTH	0x3f0000
+#endif
+
+/*
+ *	The Motorola 5206eLITE board only has 1MiB of static RAM.
+ */
+#if defined(CONFIG_ELITE)
+#define	RAM_START	0x30020000
+#define	RAM_END		0xe0000
+#endif
+
+/*
+ *	All the Motorola eval boards have the same basic arrangement.
+ *	The end of RAM will vary depending on how much ram is fitted,
+ *	but this isn't important here, we assume at least 4MiB.
+ */
+#if defined(CONFIG_M5206eC3) || defined(CONFIG_M5249C3) || \
+    defined(CONFIG_M5272C3) || defined(CONFIG_M5306C3) || \
+    defined(CONFIG_ARN5307) || defined(CONFIG_M5407C3)
+#define	RAM_START	0x20000
+#define	RAM_LENGTH	0x3e0000
+#endif
+
+/*
+ *	These flash boot boards use all of ram for operation. Again the
+ *	actual memory size is not important here, assume at least 4MiB.
+ *	They currently have no support for running in flash.
+ */
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+    defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
+    defined(CONFIG_CLEOPATRA)
+#define	RAM_START	0x400
+#define	RAM_LENGTH	0x3ffc00
 #endif
 
-#ifdef CONFIG_M5206eC3
-#include "platform/5206e/MOTOROLA/ram.ld"
-#endif
-#ifdef CONFIG_ELITE
-#include "platform/5206e/eLITE/ram.ld"
-#endif
-
-#ifdef CONFIG_M5249C3
-#include "platform/5249/MOTOROLA/ram.ld"
-#endif
-
-#ifdef CONFIG_M5272C3
-#include "platform/5272/MOTOROLA/ram.ld"
-#endif
-
-#ifdef CONFIG_ARN5307
-#include "platform/5307/ARNEWSH/ram.ld"
-#endif
-#ifdef CONFIG_M5307C3
-#include "platform/5307/MOTOROLA/ram.ld"
-#endif
-#ifdef CONFIG_eLIA
-#include "platform/5307/eLIA/ram.ld"
-#endif
-#ifdef CONFIG_DISKtel
-#include "platform/5307/DISKtel/ram.ld"
-#endif
-#ifdef CONFIG_SECUREEDGEMP3
-#include "platform/5307/MP3/ram.ld"
-#endif
-
-#ifdef CONFIG_M5407
-#include "platform/5407/MOTOROLA/ram.ld"
-#endif
-
-#ifdef CONFIG_CLEOPATRA
-#ifdef CONFIG_M5307
-#include "platform/5307/CLEOPATRA/ram.ld"
-#endif
-#ifdef CONFIG_M5407
-#include "platform/5407/CLEOPATRA/ram.ld"
+#ifdef CONFIG_RAMKERNEL
+#define	TEXT		ram
+#define	DATA		ram
+#define	INIT		ram
+#define	BSS		ram
 #endif
+#ifdef CONFIG_ROMKERNEL
+#define	TEXT		rom
+#define	DATA		ram
+#define	INIT		ram
+#define	BSS		ram
+#endif
+
+#ifndef DATA_ADDR
+#define	DATA_ADDR
+#endif
+
+
+OUTPUT_ARCH(m68k)
+ENTRY(_start)
+
+MEMORY {
+#ifdef RAMVEC_START
+	ramvec	: ORIGIN = RAMVEC_START, LENGTH = RAMVEC_LENGTH
+#endif
+	ram	: ORIGIN = RAM_START, LENGTH = RAM_LENGTH
+#ifdef RAM_END
+	eram	: ORIGIN = RAM_END, LENGTH = 0
+#endif
+#ifdef ROM_START
+	romvec	: ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH
+	rom	: ORIGIN = ROM_START, LENGTH = ROM_LENGTH
+	erom	: ORIGIN = ROM_END, LENGTH = 0
+#endif
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+#ifdef ROMVEC_START
+	. = ROMVEC_START ;
+	.romvec : {
+		__rom_start = . ;
+		_romvec = .;
+		*(.data.initvect)
+	} > romvec
+#endif
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+        	*(.text.lock)
+		*(.rodata)
+		*(.rodata.*)
+
+		. = ALIGN(0x4) ;
+		*(.kstrtab)
+
+		. = ALIGN(16);          /* Exception table              */
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+
+		__start___ksymtab = .;  /* Kernel symbol table          */
+		*(__ksymtab)
+		__stop___ksymtab = .;
+
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > TEXT
+
+#ifdef ROM_END
+	. = ROM_END ;
+	.erom : {
+		__rom_end = . ;
+	} > erom
+#endif
+#ifdef RAMVEC_START
+	. = RAMVEC_START ;
+	.ramvec : {
+		__ramvec = .;
+	} > ramvec
+#endif
+
+	.data DATA_ADDR : {
+		. = ALIGN(4);
+		_sdata = . ;
+		*(.data)
+		. = ALIGN(8192) ;
+		*(.data.init_task)
+		_edata = . ;
+	} > DATA
+
+	.init : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		*(.init.text)
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__start___param = .;
+		*(__param)
+		__stop___param = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		. = ALIGN(4);
+		__initramfs_start = .;
+		*(.init.ramfs)
+		__initramfs_end = .;
+		. = ALIGN(4);
+		__init_end = .;
+	} > INIT
+
+	/DISCARD/ : {
+		*(.exit.text)
+		*(.exit.data)
+		*(.exitcall.exit)
+	}
+
+	.bss : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+	} > BSS
+
+#ifdef RAM_END
+	. = RAM_END ;
+	.eram : {
+		__ramend = . ;
+		_ramend = . ;
+	} > eram
 #endif
+}
 
-#ifdef CONFIG_NETtel
-#ifdef CONFIG_M5206e
-#include "platform/5206e/NETtel/ram.ld"
-#endif
-#ifdef CONFIG_M5272
-#include "platform/5272/NETtel/ram.ld"
-#endif
-#ifdef CONFIG_M5307
-#include "platform/5307/NETtel/ram.ld"
-#endif
-#endif
diff -Nru a/arch/mips64/kernel/ioctl32.c b/arch/mips64/kernel/ioctl32.c
--- a/arch/mips64/kernel/ioctl32.c	Mon Jan 13 21:59:50 2003
+++ b/arch/mips64/kernel/ioctl32.c	Mon Jan 13 21:59:50 2003
@@ -755,8 +755,6 @@
 	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),
 
diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig
--- a/arch/parisc/Kconfig	Mon Jan 13 21:59:50 2003
+++ b/arch/parisc/Kconfig	Mon Jan 13 21:59:50 2003
@@ -107,6 +107,11 @@
 	  enable this option otherwise. The 64bit kernel is significantly bigger
 	  and slower than the 32bit one.
 
+config COMPAT
+	bool
+	depends on PARISC64
+	default y
+
 config PDC_NARROW
 	bool "32-bit firmware"
 	depends on PARISC64
@@ -336,6 +341,8 @@
 source "drivers/usb/Kconfig"
 
 source "net/bluetooth/Kconfig"
+
+source "arch/parisc/oprofile/Kconfig"
 
 menu "Kernel hacking"
 
diff -Nru a/arch/parisc/Makefile b/arch/parisc/Makefile
--- a/arch/parisc/Makefile	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/Makefile	Mon Jan 13 21:59:51 2003
@@ -18,69 +18,51 @@
 #
 
 ifdef CONFIG_PARISC64
-CROSS_COMPILE := hppa64-linux-
-UTS_MACHINE := parisc64
-LDFLAGS_BLOB := --format binary --oformat elf64-hppa-linux
-
+CROSS_COMPILE	:= hppa64-linux-
+UTS_MACHINE	:= parisc64
+LDFLAGS_BLOB	:= --format binary --oformat elf64-hppa-linux
 else
-MACHINE	:= $(subst 64,,$(shell uname -m))
-ifneq (${MACHINE},parisc)
-# cross compilation
-CROSS_COMPILE := hppa-linux-
+MACHINE := $(subst 64,,$(shell uname -m))
+ifneq ($(MACHINE),parisc)
+CROSS_COMPILE	:= hppa-linux-
 endif
-LDFLAGS_BLOB := --format binary --oformat elf32-hppa-linux
+LDFLAGS_BLOB	:= --format binary --oformat elf32-hppa-linux
 endif
 
 FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align 
 
 OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
 
-CFLAGS_PIPE := -pipe
-CFLAGS_NSR  := -fno-strength-reduce
-CFLAGS := $(CFLAGS) -D__linux__ $(CFLAGS_PIPE) $(CFLAGS_NSR)
+cflags-y	:= -D__linux__ -pipe -fno-strength-reduce
 
 # These should be on for older toolchains or SOM toolchains that don't
 # enable them by default.
-CFLAGS += -mno-space-regs -mfast-indirect-calls
+cflags-y	+= -mno-space-regs -mfast-indirect-calls
 
 # No fixed-point multiply
-CFLAGS += -mdisable-fpregs
+cflags-y	+= -mdisable-fpregs
 
 # Without this, "ld -r" results in .text sections that are too big
 # (> 0x40000) for branches to reach stubs.
-CFLAGS += -ffunction-sections
+cflags-y	+= -ffunction-sections
 
 # select which processor to optimise for
-ifdef CONFIG_PA7100
-CFLAGS += -march=1.1 -mschedule=7100
-endif
-
-ifdef CONFIG_PA7200
-CFLAGS += -march=1.1 -mschedule=7200
-endif
+cflags-$(CONFIG_PA7100)		+= -march=1.1 -mschedule=7100
+cflags-$(CONFIG_PA7200)		+= -march=1.1 -mschedule=7200
+cflags-$(CONFIG_PA7100LC)	+= -march=1.1 -mschedule=7100LC
+cflags-$(CONFIG_PA8X00)		+= -march=2.0 -mschedule=8000
+
+head-y			:= arch/parisc/kernel/head.o 
+head-$(CONFIG_PARISC64)	:= arch/parisc/kernel/head64.o
+
+CFLAGS	+= $(cflags-y)
+HEAD	:= $(head-y)
+
+core-y	+= $(addprefix arch/parisc/, kernel/pdc_cons.o kernel/process.o   \
+		mm/ kernel/ hpux/ math-emu/ kernel/init_task.o )
+libs-y	+= arch/parisc/lib/ `$(CC) -print-libgcc-file-name`
 
-ifdef CONFIG_PA7100LC
-CFLAGS += -march=1.1 -mschedule=7100LC
-endif
-
-ifdef CONFIG_PA8X00
-CFLAGS += -march=2.0 -mschedule=8000
-endif
-
-HEAD := arch/parisc/kernel/head.o 
-ifdef CONFIG_PARISC64
-HEAD := arch/parisc/kernel/head64.o
-endif
-
-core-y					+= arch/parisc/kernel/pdc_cons.o  \
-					   arch/parisc/kernel/process.o   \
-	   				   arch/parisc/mm/	          \
-					   arch/parisc/kernel/            \
-					   arch/parisc/hpux/		  \
-					   arch/parisc/math-emu/	  \
-					   arch/parisc/kernel/init_task.o
-libs-y					+= arch/parisc/lib/ \
-					   `$(CC) -print-libgcc-file-name`
+drivers-$(CONFIG_OPROFILE)		+= arch/parisc/oprofile/
 
 palo: vmlinux
 	@if [ $$(palo -f /dev/null >/dev/null 2>&1 ; echo $$?) != 2 ]; then \
@@ -101,33 +83,26 @@
 	export TOPDIR=`pwd`; \
 	unset STRIP LDFLAGS CPP CPPFLAGS AFLAGS CFLAGS CC LD; cd ../palo && make lifimage
 
-Image: palo
-
-Image-clean:
-
-ramdisk.o:
-
-zImage: palo
+# Shorthands for known targets not supported by parisc, use palo as default
+Image zImage bzImage: palo
 
-bzImage: palo
+prepare: include/asm-parisc/offsets.h
 
-compressed: zImage
-
-install: 
-
-archmrproper:
-
-archclean:
-
-prepare: include/asm-$(ARCH)/offsets.h
-
-arch/$(ARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
+arch/parisc/kernel/asm-offsets.s: include/asm include/linux/version.h \
 				   include/config/MARKER
 
-include/asm-$(ARCH)/offsets.h.tmp: arch/$(ARCH)/kernel/asm-offsets.s
-	@$(generate-asm-offsets.h) < $< > $@
-
-include/asm-$(ARCH)/offsets.h: include/asm-$(ARCH)/offsets.h.tmp
+include/asm-parisc/offsets.h: arch/parisc/kernel/asm-offsets.s
 	@echo -n '  Generating $@'
+	@$(generate-asm-offsets.h) < $< > $@.tmp
 	@$(update-if-changed)
 
+archclean:
+archmrproper:
+
+CLEAN_FILES	+= palo.conf lifimage include/asm-parisc/offsets.h \
+		include/asm-parisc/offsets.h.tmp
+
+define archhelp
+	@echo  '* vmlinux	- Uncompressed kernel image (./vmlinux)'
+	@echo  '  palo		- Bootable image (./lifimage)'
+endef
diff -Nru a/arch/parisc/defconfig b/arch/parisc/defconfig
--- a/arch/parisc/defconfig	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/defconfig	Mon Jan 13 21:59:49 2003
@@ -2,11 +2,10 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_PARISC=y
-# CONFIG_UID16 is not set
+CONFIG_MMU=y
+CONFIG_SWAP=y
+CONFIG_STACK_GROWSUP=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_GENERIC_ISA_DMA=y
-# CONFIG_PM is not set
 
 #
 # Code maturity level options
@@ -16,46 +15,44 @@
 #
 # General setup
 #
-CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+# CONFIG_LOG_BUF_SHIFT_17 is not set
+# CONFIG_LOG_BUF_SHIFT_16 is not set
+CONFIG_LOG_BUF_SHIFT_15=y
+# CONFIG_LOG_BUF_SHIFT_14 is not set
+# CONFIG_LOG_BUF_SHIFT_13 is not set
+# CONFIG_LOG_BUF_SHIFT_12 is not set
+CONFIG_LOG_BUF_SHIFT=15
 
 #
 # Loadable module support
 #
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+# CONFIG_MODULES is not set
 
 #
 # Processor type and features
 #
-CONFIG_PA7100=y
-# CONFIG_PA7200 is not set
-# CONFIG_PA7100LC is not set
-# CONFIG_PA8X00 is not set
-CONFIG_PA11=y
-# CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
-CONFIG_CHASSIS_LCD_LED=y
 
 #
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+# Bus options (PCI, PCMCIA, EISA, GSC, ISA)
 #
-CONFIG_IOMMU_CCIO=y
 CONFIG_GSC=y
+CONFIG_HPPB=y
+CONFIG_IOMMU_CCIO=y
 CONFIG_GSC_LASI=y
 CONFIG_GSC_WAX=y
 CONFIG_EISA=y
-CONFIG_ISA=y
 CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
 CONFIG_GSC_DINO=y
 CONFIG_PCI_LBA=y
 CONFIG_IOSAPIC=y
 CONFIG_IOMMU_SBA=y
 CONFIG_SUPERIO=y
-CONFIG_PCI_NAMES=y
+# CONFIG_CHASSIS_LCD_LED is not set
 
 #
 # Executable file formats
@@ -74,11 +71,7 @@
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
 CONFIG_PARPORT_GSC=y
-# CONFIG_PARPORT_SUNBPP is not set
 # CONFIG_PARPORT_OTHER is not set
 # CONFIG_PARPORT_1284 is not set
 
@@ -86,11 +79,9 @@
 # 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_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -100,23 +91,9 @@
 CONFIG_BLK_DEV_INITRD=y
 
 #
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_MD_RAID5=y
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM 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
@@ -127,12 +104,10 @@
 # SCSI support type (disk, tape, CD-ROM)
 #
 CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
 # 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
 
 #
@@ -147,13 +122,12 @@
 # SCSI low-level drivers
 #
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# 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_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -162,53 +136,59 @@
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS 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_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
 CONFIG_SCSI_LASI700=y
 CONFIG_53C700_MEM_MAPPED=y
 CONFIG_53C700_LE_ON_BE=y
-CONFIG_53C700_USE_CONSISTENT=y
 # CONFIG_SCSI_NCR53C7xx is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_ASK_ZALON is not set
-# CONFIG_ASK_NCR53C8XX is not set
-# CONFIG_ASK_SYM53C8XX is not set
 CONFIG_SCSI_ZALON=y
-CONFIG_ASK_ZALON=y
+# CONFIG_SCSI_NCR53C8XX is not set
 CONFIG_SCSI_SYM53C8XX=y
-CONFIG_ASK_SYM53C8XX=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
 CONFIG_SCSI_NCR53C8XX_SYNC=20
 # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
 # CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT 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_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID5=y
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_DM is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
 # Networking options
 #
 CONFIG_PACKET=y
@@ -217,6 +197,7 @@
 # CONFIG_NETFILTER is not set
 CONFIG_FILTER=y
 CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
@@ -230,13 +211,18 @@
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_XFRM_USER is not set
 # CONFIG_IPV6 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_LLC is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -253,8 +239,9 @@
 # CONFIG_NET_SCHED is not set
 
 #
-# Network device support
+# Network testing
 #
+# CONFIG_NET_PKTGEN is not set
 CONFIG_NETDEVICES=y
 
 #
@@ -272,25 +259,30 @@
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_LASI_82596=y
-# CONFIG_SUNLANCE is not set
 # CONFIG_HAPPYMEAL 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_AT1700 is not set
+
+#
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 is not set
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
+# CONFIG_B44 is not set
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
@@ -302,28 +294,22 @@
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_RHINE_MMIO is not set
-# CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
+CONFIG_DL2K=y
 # 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
@@ -335,12 +321,20 @@
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_AIRONET4500 is not set
+
+#
+# Wireless ISA/PCI cards support
+#
+CONFIG_AIRO=y
+# CONFIG_HERMES is not set
+CONFIG_NET_WIRELESS=y
 
 #
-# Token Ring devices
+# Token Ring devices (depends on LLC=y)
 #
-# CONFIG_TR is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -351,18 +345,6 @@
 # CONFIG_WAN is not set
 
 #
-# Tulip family network device support
-#
-CONFIG_NET_TULIP=y
-# CONFIG_DE2104X is not set
-CONFIG_TULIP=y
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-# CONFIG_DE4X5 is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_DM9102 is not set
-
-#
 # IrDA (infrared) support
 #
 # CONFIG_IRDA is not set
@@ -375,10 +357,7 @@
 #
 # Userland interfaces
 #
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
@@ -389,57 +368,28 @@
 #
 # CONFIG_GAMEPORT is not set
 CONFIG_SOUND_GAMEPORT=y
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
-# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461x is not set
 CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_I8042_REG_BASE=60
-CONFIG_I8042_KBD_IRQ=1
-CONFIG_I8042_AUX_IRQ=12
+# CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
 # CONFIG_SERIO_PARKBD is not set
-
-#
-#   HP HIL driver core support
-#
 CONFIG_HP_SDC=y
-# CONFIG_HP_SDC_RTC is not set
 CONFIG_HIL_MLC=y
-CONFIG_HP_SDC_MLC=y
 
 #
 # Input Device Drivers
 #
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_KEYBOARD_SUNKBD is not set
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_HIL_KBD is not set
-# CONFIG_INPUT_MOUSE is not set
+# CONFIG_KEYBOARD_HIL is not set
+CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_HIL_PTR is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_JOYSTICK_ANALOG is not set
-# CONFIG_JOYSTICK_A3D is not set
-# CONFIG_JOYSTICK_ADI is not set
-# CONFIG_JOYSTICK_COBRA is not set
-# CONFIG_JOYSTICK_GF2K is not set
-# CONFIG_JOYSTICK_GRIP is not set
-# CONFIG_JOYSTICK_GRIP_MP is not set
-# CONFIG_JOYSTICK_GUILLEMOT is not set
-# CONFIG_JOYSTICK_INTERACT is not set
-# CONFIG_JOYSTICK_SIDEWINDER is not set
-# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_MOUSE_HIL is not set
+CONFIG_INPUT_JOYSTICK=y
 # CONFIG_JOYSTICK_IFORCE is not set
 # CONFIG_JOYSTICK_WARRIOR is not set
 # CONFIG_JOYSTICK_MAGELLAN is not set
@@ -451,11 +401,13 @@
 # CONFIG_JOYSTICK_GAMECON is not set
 # CONFIG_JOYSTICK_TURBOGRAFX is not set
 # CONFIG_INPUT_JOYDUMP is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_INPUT_MISC is not set
+CONFIG_INPUT_MISC=y
 # CONFIG_INPUT_PCSPKR is not set
 # CONFIG_INPUT_UINPUT is not set
+CONFIG_INPUT_GSC=y
+# CONFIG_HP_SDC_RTC is not set
 
 #
 # Character devices
@@ -468,12 +420,11 @@
 #
 # Serial drivers
 #
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_CS is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
 # CONFIG_SERIAL_8250_DETECT_IRQ is not set
 # CONFIG_SERIAL_8250_MULTIPORT is not set
 # CONFIG_SERIAL_8250_RSA is not set
@@ -481,12 +432,16 @@
 #
 # Non-8250 serial port support
 #
-# CONFIG_PDC_CONSOLE is not set
+CONFIG_SERIAL_MUX=y
+CONFIG_SERIAL_MUX_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 CONFIG_PRINTER=y
 # CONFIG_LP_CONSOLE is not set
 # CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
 
 #
 # I2C support
@@ -494,6 +449,14 @@
 # CONFIG_I2C is not set
 
 #
+# I2C Hardware Sensors Mainboard support
+#
+
+#
+# I2C Hardware Sensors Chip support
+#
+
+#
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
@@ -506,7 +469,7 @@
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 CONFIG_GEN_RTC=y
-CONFIG_GEN_RTC_X=y
+# CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -528,28 +491,20 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_QFMT_V1 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_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
 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 is not set
 CONFIG_RAMFS=y
@@ -557,28 +512,21 @@
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_DEBUG 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=y
+# CONFIG_EXT2_FS_XATTR 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
 
 #
 # Network File Systems
@@ -587,32 +535,26 @@
 # CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+# CONFIG_CIFS is not set
 # 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
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_SMB_NLS is not set
 CONFIG_NLS=y
 
 #
@@ -658,23 +600,19 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
-# Console drivers
-#
-
-#
-# Frame-buffer support
+# Graphics support
 #
 CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_IMSTT is not set
 # CONFIG_FB_STI is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_ATY is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
 # CONFIG_FB_SIS is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_3DFX is not set
@@ -682,22 +620,25 @@
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_PM3 is not set
 # CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-# CONFIG_FBCON_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
 CONFIG_STI_CONSOLE=y
+CONFIG_DUMMY_CONSOLE_COLUMNS=160
+CONFIG_DUMMY_CONSOLE_ROWS=64
 CONFIG_DUMMY_CONSOLE=y
-CONFIG_FBCON=y
-CONFIG_FBCON_FONT=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_PCI_CONSOLE=y
+# CONFIG_FBCON_ADVANCED is not set
+# CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
-CONFIG_FONT_6x11=y
-CONFIG_FONT_SUN12x22=y
 
 #
-# Sound Drivers
+# Sound
 #
 CONFIG_SOUND=y
 
@@ -714,21 +655,124 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_UHCI_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_MIDI is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_XPAD is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BT is not set
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
 
 #
 # Kernel hacking
 #
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KALLSYMS is not set
 
 #
 # Security options
 #
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY is not set
+
+#
+# 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 -Nru a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
--- a/arch/parisc/hpux/fs.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/hpux/fs.c	Mon Jan 13 21:59:49 2003
@@ -131,9 +131,9 @@
 	tmp.st_gid = stat->gid;
 	tmp.st_rdev = stat->rdev;
 	tmp.st_size = stat->size;
-	tmp.st_atime = stat->atime;
-	tmp.st_mtime = stat->mtime;
-	tmp.st_ctime = stat->ctime;
+	tmp.st_atime = stat->atime.tv_sec;
+	tmp.st_mtime = stat->mtime.tv_sec;
+	tmp.st_ctime = stat->ctime.tv_sec;
 	tmp.st_blocks = stat->blocks;
 	tmp.st_blksize = stat->blksize;
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
diff -Nru a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
--- a/arch/parisc/kernel/Makefile	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/Makefile	Mon Jan 13 21:59:49 2003
@@ -2,16 +2,14 @@
 # Makefile for arch/parisc/kernel
 #
 
-ifdef CONFIG_PARISC64
-EXTRA_TARGETS := init_task.o pdc_cons.o process.o head64.o unaligned.o perf.o perf_asm.o
-else
-EXTRA_TARGETS := init_task.o pdc_cons.o process.o head.o unaligned.o
-endif
+head-y			:= head.o
+head-$(CONFIG_PARISC64)	:= head64.o
+EXTRA_TARGETS	:= init_task.o pdc_cons.o process.o unaligned.o $(head-y)
 
-AFLAGS_entry.o := -traditional
+AFLAGS_entry.o	:= -traditional
 AFLAGS_pacache.o := -traditional
 
-export-objs	:= parisc_ksyms.o 
+export-objs	:= parisc_ksyms.o
 
 obj-y	     	:= cache.o pacache.o setup.o traps.o time.o irq.o \
 		   pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
@@ -19,10 +17,11 @@
 		   signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
 		   processor.o pdc_chassis.o
 
-obj-$(CONFIG_SMP) += smp.o 
-obj-$(CONFIG_PA11) += pci-dma.o
-obj-$(CONFIG_PCI) += pci.o
-obj-$(CONFIG_PARISC64) += binfmt_elf32.o sys_parisc32.o \
-		ioctl32.o signal32.o
+obj-$(CONFIG_SMP)	+= smp.o
+obj-$(CONFIG_PROFILING)	+= profile.o
+obj-$(CONFIG_PA11)	+= pci-dma.o
+obj-$(CONFIG_PCI)	+= pci.o
+obj-$(CONFIG_MODULES)	+= module.o
+obj-$(CONFIG_PARISC64)	+= binfmt_elf32.o sys_parisc32.o ioctl32.o signal32.o
 # only supported for PCX-W/U in 64-bit mode at the moment
-obj-$(CONFIG_PARISC64) += perf.o perf_asm.o
+obj-$(CONFIG_PARISC64)	+= perf.o perf_asm.o
diff -Nru a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
--- a/arch/parisc/kernel/asm-offsets.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/asm-offsets.c	Mon Jan 13 21:59:49 2003
@@ -29,6 +29,7 @@
 
 int main(void)
 {
+	DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info));
 	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
 	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
 	DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending));
@@ -213,6 +214,7 @@
 	DEFINE(PT_SIZE, sizeof(struct pt_regs));
 	DEFINE(PT_SZ_ALGN, align(sizeof(struct pt_regs), 64));
 	BLANK();
+	DEFINE(TI_TASK, offsetof(struct thread_info, task));
 	DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
 	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
 	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
diff -Nru a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
--- a/arch/parisc/kernel/binfmt_elf32.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/binfmt_elf32.c	Mon Jan 13 21:59:49 2003
@@ -19,7 +19,7 @@
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/elfcore.h>
-#include "sys32.h"		/* struct timeval32 */
+#include <linux/compat.h>
 
 #define elf_prstatus elf_prstatus32
 struct elf_prstatus32
@@ -32,10 +32,10 @@
 	pid_t	pr_ppid;
 	pid_t	pr_pgrp;
 	pid_t	pr_sid;
-	struct timeval32 pr_utime;	/* User time */
-	struct timeval32 pr_stime;	/* System time */
-	struct timeval32 pr_cutime;	/* Cumulative user time */
-	struct timeval32 pr_cstime;	/* Cumulative system time */
+	struct compat_timeval pr_utime;		/* User time */
+	struct compat_timeval pr_stime;		/* System time */
+	struct compat_timeval pr_cutime;	/* Cumulative user time */
+	struct compat_timeval pr_cstime;	/* Cumulative system time */
 	elf_gregset_t pr_reg;	/* GP registers */
 	int pr_fpvalid;		/* True if math co-processor being used.  */
 };
@@ -88,5 +88,13 @@
 
 #define SET_PERSONALITY(ex, ibcs2) \
 	current->personality = PER_LINUX_32BIT
+
+#define jiffies_to_timeval jiffies_to_compat_timeval 
+static __inline__ void
+jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+{
+	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+	value->tv_sec = jiffies / HZ;
+}
 
 #include "../../../fs/binfmt_elf.c"
diff -Nru a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
--- a/arch/parisc/kernel/drivers.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/drivers.c	Mon Jan 13 21:59:51 2003
@@ -9,6 +9,7 @@
  * Copyright (c) 1999 The Puffin Group
  * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
  * Copyright (c) 2001 Helge Deller <deller@gmx.de>
+ * Copyright (c) 2001,2002 Ryan Bradetich 
  * 
  * The file handles registering devices and drivers, then matching them.
  * It's the closest we get to a dating agency.
@@ -23,21 +24,13 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/pdc.h>
+#include <asm/parisc-device.h>
 
 /* See comments in include/asm-parisc/pci.h */
-struct pci_dma_ops *hppa_dma_ops;
+struct hppa_dma_ops *hppa_dma_ops;
 
-static struct parisc_driver *pa_drivers;
 static struct parisc_device root;
 
-/* This lock protects the pa_drivers list _only_ since all parisc_devices
- * are registered before smp_init() is called.  If you wish to add devices
- * after that, this muct be serialised somehow.  I recommend a semaphore
- * rather than a spinlock since driver ->probe functions are allowed to
- * sleep (for example when allocating memory).
- */
-static spinlock_t pa_lock = SPIN_LOCK_UNLOCKED;
-
 #define for_each_padev(dev) \
 	for (dev = root.child; dev != NULL; dev = next_dev(dev))
 
@@ -102,43 +95,63 @@
 	request_mem_region(dev->hpa, 0x1000, driver->name);
 }
 
+static int parisc_driver_probe(struct device *dev)
+{
+	int rc;
+	struct parisc_device *pa_dev = to_parisc_device(dev);
+	struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
+
+	rc = pa_drv->probe(pa_dev);
+
+	if(!rc)
+		claim_device(pa_drv, pa_dev);
+
+	return rc;
+}
+
+static int parisc_driver_remove(struct device *dev)
+{
+	struct parisc_device *pa_dev = to_parisc_device(dev);
+
+	release_mem_region(pa_dev->hpa, 0x1000);
+
+	return 0;
+}
+	
+
 /**
  * register_parisc_driver - Register this driver if it can handle a device
  * @driver: the PA-RISC driver to try
  */
 int register_parisc_driver(struct parisc_driver *driver)
 {
-	struct parisc_device *device;
+	/* FIXME: we need this because apparently the sti
+	 * driver can be registered twice */
+	if(driver->drv.name) {
+		printk(KERN_WARNING 
+		       "BUG: skipping previously registered driver %s\n",
+		       driver->name);
+		return 1;
+	}
 
-	if (driver->next) {
+	if (!driver->probe) {
 		printk(KERN_WARNING 
-		       "BUG: Skipping previously registered driver: %s\n",
+		       "BUG: driver %s has no probe routine\n",
 		       driver->name);
 		return 1;
 	}
 
-	for_each_padev(device) {
-		if (device->driver)
-			continue;
-		if (!match_device(driver, device))
-			continue;
+	driver->drv.bus = &parisc_bus_type;
 
-		if (driver->probe(device) < 0)
-			continue;
-		claim_device(driver, device);
-	}
+	/* We install our own probe and remove routines */
+	WARN_ON(driver->drv.probe != NULL);
+	WARN_ON(driver->drv.remove != NULL);
 
-	/* Note that the list is in reverse order of registration.  This
-	 * may be significant if we ever actually support hotplug and have
-	 * multiple drivers capable of claiming the same chip.
-	 */
-
-	spin_lock(&pa_lock);
-	driver->next = pa_drivers;
-	pa_drivers = driver;
-	spin_unlock(&pa_lock);
+	driver->drv.probe = parisc_driver_probe;
+	driver->drv.remove = parisc_driver_remove;
+	driver->drv.name = driver->name;
 
-	return 0;
+	return driver_register(&driver->drv);
 }
 
 /**
@@ -169,39 +182,7 @@
  */
 int unregister_parisc_driver(struct parisc_driver *driver)
 {
-	struct parisc_device *dev;
-
-	spin_lock(&pa_lock);
-
-	if (pa_drivers == driver) {
-		/* was head of list - update head */
-		pa_drivers = driver->next;
-	} else {
-		struct parisc_driver *prev = pa_drivers;
-
-		while (prev && driver != prev->next) {
-			prev = prev->next;
-		}
-
-		if (!prev) {
-			printk(KERN_WARNING "unregister_parisc_driver: %s wasn't registered\n", driver->name);
-		} else {
-			/* Drop driver from list */
-			prev->next = driver->next;
-			driver->next = NULL;
-		}
-
-	}
-
-	spin_unlock(&pa_lock);
-
-	for_each_padev(dev) {
-		if (dev->driver != driver)
-			continue;
-		dev->driver = NULL;
-		release_mem_region(dev->hpa, 0x1000);
-	}
-
+	driver_unregister(&driver->drv);
 	return 0;
 }
 
@@ -300,7 +281,7 @@
 		path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
 	}
 
-	padev = HBA_DATA(bus->sysdata)->dev;
+	padev = HBA_DATA(bus->dev->platform_data)->dev;
 	while (padev != &root) {
 		path->bc[i--] = padev->hw_path;
 		padev = padev->parent;
@@ -423,6 +404,16 @@
 	return dev;
 }
 
+static int parisc_generic_match(struct device *dev, struct device_driver *drv)
+{
+	return  match_device(to_parisc_driver(drv), to_parisc_device(dev));
+}
+
+struct bus_type parisc_bus_type = {
+	.name = "parisc",
+	.match = parisc_generic_match,
+};
+
 /**
  * register_parisc_device - Locate a driver to manage this device.
  * @dev: The parisc device.
@@ -432,29 +423,13 @@
  */
 int register_parisc_device(struct parisc_device *dev)
 {
-	struct parisc_driver *driver;
-
 	if (!dev)
 		return 0;
 
 	if (dev->driver)
 		return 1;
-	
-	spin_lock(&pa_lock);
 
-	/* Locate a driver which agrees to manage this device.  */
-	for (driver = pa_drivers; driver; driver = driver->next) {
-		if (!match_device(driver,dev))
-			continue;
-		if (driver->probe(dev) == 0)
-			break;
-	}
-
-	if (driver != NULL) {
-		claim_device(driver, dev);
-	}
-	spin_unlock(&pa_lock);
-	return driver != NULL;
+	return 0;
 }
 
 #define BC_PORT_MASK 0x8
@@ -467,27 +442,41 @@
         ((gsc_readl(&((struct bc_module *)dev->hpa)->io_status) \
                 & BC_PORT_MASK) == BC_LOWER_PORT)
 
-#define READ_IO_IO_LOW(dev) \
-	(dev->id.hw_type == HPHW_IOA ? \
-	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low) << 16 : \
-	        __raw_readl((unsigned long)&((struct bc_module *)dev->hpa)->io_io_low))
+#define MAX_NATIVE_DEVICES 64
+#define NATIVE_DEVICE_OFFSET 0x1000
+
+#define FLEX_MASK 	(unsigned long)0xfffffffffffc0000
+#define IO_IO_LOW	offsetof(struct bc_module, io_io_low)
+#define IO_IO_HIGH	offsetof(struct bc_module, io_io_high)
+#define READ_IO_IO_LOW(dev)  (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_LOW)
+#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)__raw_readl(dev->hpa + IO_IO_HIGH)
+
+static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
+                            struct parisc_device *parent);
 
-static void walk_native_bus(unsigned long addr, struct parisc_device *parent);
 void walk_lower_bus(struct parisc_device *dev)
 {
+	unsigned long io_io_low, io_io_high;
 
 	if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
 		return;
 
-	walk_native_bus((unsigned long)(signed int)READ_IO_IO_LOW(dev), dev);
-}
+	if(dev->id.hw_type == HPHW_IOA) {
+		io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16);
+		io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET;
+	} else {
+		io_io_low = (READ_IO_IO_LOW(dev) + ~FLEX_MASK) & FLEX_MASK;
+		io_io_high = (READ_IO_IO_HIGH(dev)+ ~FLEX_MASK) & FLEX_MASK;
+	}
 
-#define MAX_NATIVE_DEVICES 64
-#define NATIVE_DEVICE_OFFSET 0x1000
+	walk_native_bus(io_io_low, io_io_high, dev);
+}
 
 /**
  * walk_native_bus -- Probe a bus for devices
- * @addr: Base address of this bus.
+ * @io_io_low: Base address of this bus.
+ * @io_io_high: Last address of this bus.
+ * @parent: The parent bus device.
  * 
  * A native bus (eg Runway or GSC) may have up to 64 devices on it,
  * spaced at intervals of 0x1000 bytes.  PDC may not inform us of these
@@ -495,28 +484,32 @@
  * devices which are not physically connected (such as extra serial &
  * keyboard ports).  This problem is not yet solved.
  */
-static void walk_native_bus(unsigned long addr, struct parisc_device *parent)
+static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
+                            struct parisc_device *parent)
 {
-	int i;
+	int i, devices_found = 0;
+	unsigned long hpa = io_io_low;
 	struct hardware_path path;
 
 	get_node_path(parent, &path);
-	for (i = 0; i < MAX_NATIVE_DEVICES; i++) {
-		unsigned long hpa = (addr + i * NATIVE_DEVICE_OFFSET);
-		struct parisc_device *dev;
-
-		/* Was the device already added by Firmware? */
-		dev = find_device_by_addr(hpa);
-		if (!dev) {
-			path.mod = i;
-			dev = alloc_pa_dev(hpa, &path);
-			if (!dev)
-				continue;
+	do {
+		for(i = 0; i < MAX_NATIVE_DEVICES; i++, hpa += NATIVE_DEVICE_OFFSET) {
+			struct parisc_device *dev;
 
-			register_parisc_device(dev);
+			/* Was the device already added by Firmware? */
+			dev = find_device_by_addr(hpa);
+			if (!dev) {
+				path.mod = i;
+				dev = alloc_pa_dev(hpa, &path);
+				if (!dev)
+					continue;
+
+				register_parisc_device(dev);
+				devices_found++;
+			}
+			walk_lower_bus(dev);
 		}
-		walk_lower_bus(dev);
-	}
+	} while(!devices_found && hpa < io_io_high);
 }
 
 #define CENTRAL_BUS_ADDR (unsigned long) 0xfffffffffff80000
@@ -529,7 +522,9 @@
  */
 void walk_central_bus(void)
 {
-	walk_native_bus(CENTRAL_BUS_ADDR, &root);
+	walk_native_bus(CENTRAL_BUS_ADDR,
+			CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET),
+			&root);
 }
 
 void fixup_child_irqs(struct parisc_device *parent, int base,
@@ -575,6 +570,61 @@
 	struct parisc_device *dev;
 	for (dev = parent->child; dev != parent->sibling; dev = next_dev(dev)) {
 		print_parisc_device(dev);
+	}
+}
+
+
+/*
+ * parisc_generic_device_register_recursive() - internal function to recursively
+ * 	register all parisc devices
+ */
+static void parisc_generic_device_register_recursive( struct parisc_device *dev )
+{
+	char tmp1[32];
+	
+	/* has this device been registered already ? */
+	if (dev->dev.dma_mask != NULL)
+		return;
+	
+	/* register all parents recursively */
+	if (dev->parent && dev->parent!=&root)
+		parisc_generic_device_register_recursive(dev->parent);
+	
+	/* set up the generic device tree for this */
+	snprintf(tmp1, sizeof(tmp1), "%d", dev->hw_path);
+	if (dev->parent && dev->parent != &root) {
+		struct parisc_device *ndev;
+		char tmp2[32];
+
+		dev->dev.parent = &dev->parent->dev;
+		for(ndev = dev->parent; ndev != &root;
+		    ndev = ndev->parent) {
+			snprintf(tmp2, sizeof(tmp2), "%d:%s",
+				 ndev->hw_path, tmp1);
+			strncpy(tmp1, tmp2, sizeof(tmp1));
+		}
+	}
+
+	dev->dev.bus = &parisc_bus_type;
+	snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "parisc%s",
+		 tmp1);
+	/* make the generic dma mask a pointer to the parisc one */
+	dev->dev.dma_mask = &dev->dma_mask;
+	pr_debug("device_register(%s)\n", dev->dev.bus_id);
+	device_register(&dev->dev);
+}
+
+/*
+ * parisc_generic_device_register() - register all parisc devices
+ */
+void parisc_generic_device_register(void)
+{
+	struct parisc_device *dev;
+	
+	bus_register(&parisc_bus_type);
+
+	for_each_padev(dev) {
+		parisc_generic_device_register_recursive( dev );
 	}
 }
 
diff -Nru a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
--- a/arch/parisc/kernel/entry.S	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/entry.S	Mon Jan 13 21:59:49 2003
@@ -38,13 +38,11 @@
 #include <asm/thread_info.h>
 
 #ifdef __LP64__
-#define FRAME_SIZE	128
 #define CMPIB           cmpib,*
 #define CMPB            cmpb,*
 
 	.level 2.0w
 #else
-#define FRAME_SIZE	64
 #define CMPIB           cmpib,
 #define CMPB            cmpb,
 
@@ -147,7 +145,7 @@
 
 	mfctl   %cr30, %r1
 	tophys  %r1,%r9
-	LDREG	0(%r9), %r1		/* thread_info -> task_struct */
+	LDREG	TI_TASK(%r9), %r1	/* thread_info -> task_struct */
 	tophys  %r1,%r9
 	ldo     TASK_REGS(%r9),%r9
 	STREG   %r30, PT_GR30(%r9)
@@ -499,9 +497,7 @@
 #endif
 
 	.import		handle_interruption,code
-	.import		handle_real_interruption,code
 	.import		do_cpu_irq_mask,code
-	.import		parisc_stopkernel,code
 
 	/*
 	 * r26 = function to be called
@@ -529,7 +525,7 @@
 	STREG	%r2, PT_GR27(%r1)	/* Store childs %dp */
 	ldd	16(%r26), %r26
 
-	STREG	%r22, PT_GR22(%r1)	/* Store childs %dp */
+	STREG	%r22, PT_GR22(%r1)	/* save r22 (arg5) */
 	copy	%r0, %r22		/* user_tid */
 #endif
 	STREG	%r26, PT_GR26(%r1)  /* Store function & argument for child */
@@ -568,7 +564,7 @@
 	nop
 #endif
 
-	LDREG	-THREAD_SZ_ALGN(%r30), %r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN(%r30), %r1
 	LDREG	TASK_PT_GR25(%r1), %r26
 #ifdef __LP64__
 	LDREG	TASK_PT_GR27(%r1), %r27
@@ -629,11 +625,7 @@
 
 	STREG	%r30, TASK_PT_KSP(%r26)
 	LDREG	TASK_PT_KSP(%r25), %r30
-#ifdef __LP64__
-	LDREG	8(%r25), %r25
-#else
-	LDREG	4(%r25), %r25
-#endif
+	LDREG	TASK_THREAD_INFO(%r25), %r25
 	bv	%r0(%r2)
 	mtctl   %r25,%cr30
 
@@ -667,7 +659,7 @@
 	.export	syscall_exit_rfi
 syscall_exit_rfi:
 	mfctl   %cr30,%r16
-	LDREG	0(%r16), %r16		/* thread_info -> task_struct */
+	LDREG	TI_TASK(%r16), %r16	/* thread_info -> task_struct */
 	ldo	TASK_REGS(%r16),%r16
 	/* Force iaoq to userspace, as the user has had access to our current
 	 * context via sigcontext. Also Filter the PSW for the same reason.
@@ -824,8 +816,6 @@
 	ldo	-16(%r30),%r29			/* Reference param save area */
 #endif
 
-#warning TAUSQ FIXME - review 2.5 signal return path changes
-
 	bl	do_signal,%r2
 	copy	%r0, %r26			/* sigset_t *oldset = NULL */
 
@@ -954,11 +944,11 @@
 	ldo		-16(%r30),%r29	/* Reference param save area */
 #endif
 
-	ldil		L%intr_restore, %r2
+	ldil		L%intr_check_sig, %r2
 	copy		%r25, %r16	/* save pt_regs */
 
 	b		handle_interruption
-	ldo		R%intr_restore(%r2), %r2
+	ldo		R%intr_check_sig(%r2), %r2
 
 
 	/*
@@ -1985,8 +1975,7 @@
 	.export sys_fork_wrapper
 	.export child_return
 sys_fork_wrapper:
-	mfctl	%cr30,%r1		/* get pt regs */
-	LDREG	0(%r1),%r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
 	ldo	TASK_REGS(%r1),%r1
 	reg_save %r1
 	mfctl	%cr27, %r3
@@ -2011,9 +2000,8 @@
 	LDREG	-RP_OFFSET-FRAME_SIZE(%r30),%r2
 wrapper_exit:
 	ldo	-FRAME_SIZE(%r30),%r30		/* get the stackframe */
-	mfctl	%cr30,%r1		/* get pt regs */
-	LDREG	0(%r1),%r1
-	ldo	TASK_REGS(%r1),%r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1),%r1	 /* get pt regs */
 
 	LDREG	PT_CR27(%r1), %r3
 	mtctl	%r3, %cr27
@@ -2031,18 +2019,16 @@
 	nop
 #endif
 
-	mfctl	%cr30,%r2
-	LDREG	0(%r2),%r2
-	LDREG	TASK_PT_GR19(%r2),%r2
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE-FRAME_SIZE(%r30), %r1
+	LDREG	TASK_PT_GR19(%r1),%r2
 	b	wrapper_exit
 	copy	%r0,%r28
 
 	
 	.export sys_clone_wrapper
 sys_clone_wrapper:
-	mfctl	%cr30,%r1		/* get pt regs */
-	LDREG	0(%r1),%r1
-	ldo	TASK_REGS(%r1),%r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
 	reg_save %r1
 	mfctl	%cr27, %r3
 	STREG	%r3, PT_CR27(%r1)
@@ -2063,9 +2049,8 @@
 
 	.export sys_vfork_wrapper
 sys_vfork_wrapper:
-	mfctl	%cr30,%r1		/* get pt regs */
-	LDREG	0(%r1),%r1
-	ldo	TASK_REGS(%r1),%r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
 	reg_save %r1
 	mfctl	%cr27, %r3
 	STREG	%r3, PT_CR27(%r1)
@@ -2087,9 +2072,8 @@
 
 	
 	.macro  execve_wrapper execve
-	mfctl	%cr30,%r1		/* get pt regs */
-	LDREG	0(%r1),%r1
-	ldo	TASK_REGS(%r1),%r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
 
 	/*
 	 * Do we need to save/restore r3-r18 here?
@@ -2137,9 +2121,8 @@
 
 	.export sys_rt_sigreturn_wrapper
 sys_rt_sigreturn_wrapper:
-	mfctl	%cr30,%r26		/* get pt regs */
-	LDREG	0(%r26),%r26
-	ldo	TASK_REGS(%r26),%r26
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
+	ldo	TASK_REGS(%r26),%r26	/* get pt regs */
 	/* Don't save regs, we are going to restore them from sigcontext. */
 	STREG	%r2, -RP_OFFSET(%r30)
 #ifdef __LP64__
@@ -2155,9 +2138,8 @@
 	LDREG	-RP_OFFSET(%r30), %r2
 
 	/* FIXME: I think we need to restore a few more things here. */
-	mfctl	%cr30,%r1		/* get pt regs */
-	LDREG	0(%r1),%r1
-	ldo	TASK_REGS(%r1),%r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1),%r1	/* get pt regs */
 	reg_restore %r1
 
 	/* If the signal was received while the process was blocked on a
@@ -2170,8 +2152,8 @@
 	.export sys_sigaltstack_wrapper
 sys_sigaltstack_wrapper:
 	/* Get the user stack pointer */
-	mfctl	%cr30,%r24
-	LDREG	0(%r24),%r24
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+	ldo	TASK_REGS(%r1),%r24	/* get pt regs */
 	LDREG	TASK_PT_GR30(%r24),%r24
 	STREG	%r2, -RP_OFFSET(%r30)
 #ifdef __LP64__
@@ -2192,8 +2174,7 @@
 	.export sys32_sigaltstack_wrapper
 sys32_sigaltstack_wrapper:
 	/* Get the user stack pointer */
-	mfctl	%cr30,%r24
-	LDREG	0(%r24),%r24
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24
 	LDREG	TASK_PT_GR30(%r24),%r24
 	STREG	%r2, -RP_OFFSET(%r30)
 	ldo	FRAME_SIZE(%r30), %r30
@@ -2208,9 +2189,8 @@
 
 	.export sys_rt_sigsuspend_wrapper
 sys_rt_sigsuspend_wrapper:
-	mfctl	%cr30,%r24		/* get pt regs */
-	LDREG	0(%r24),%r24
-	ldo	TASK_REGS(%r24),%r24
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
+	ldo	TASK_REGS(%r1),%r24
 	reg_save %r24
 
 	STREG	%r2, -RP_OFFSET(%r30)
@@ -2226,8 +2206,7 @@
 	ldo	-FRAME_SIZE(%r30), %r30
 	LDREG	-RP_OFFSET(%r30), %r2
 
-	mfctl	%cr30,%r1		/* get pt regs */
-	LDREG	0(%r1),%r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
 	ldo	TASK_REGS(%r1),%r1
 	reg_restore %r1
 
@@ -2247,7 +2226,7 @@
 	/* save return value now */
 
 	mfctl     %cr30, %r1
-	LDREG     0(%r1),%r1
+	LDREG     TI_TASK(%r1),%r1
 	STREG     %r28,TASK_PT_GR28(%r1)
 
 	/* Save other hpux returns if personality is PER_HPUX */
@@ -2297,25 +2276,17 @@
 
 	/* check for reschedule */
 
-	LDREG  TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19	/* long */
-	bb,<,n %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
+	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19	/* long */
+	bb,<,n	%r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
 
 syscall_check_sig:
-	/* These should be the same effect, but which is faster? */
-#if 1
-	mfctl   %cr30,%r1
-#else
-	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1    /* get thread info ptr */
-#endif
-	/* check for pending signals */
-	LDREG    TI_FLAGS(%r1),%r19
-	bb,<,n   %r19, 31-TIF_SIGPENDING, syscall_do_signal /* forward */
+	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19    /* get ti flags */
+	bb,<,n	%r19, 31-TIF_SIGPENDING, syscall_do_signal /* forward */
 
 syscall_restore:
-	mfctl   %cr30,%r1
-	LDREG	TI_FLAGS(%r1), %r19		/* Are we being ptraced? */
+	LDREG	TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19    /* get ti flags */
 	bb,<	%r19, 31-TIF_SYSCALL_TRACE,syscall_restore_rfi
-	LDREG	0(%r1),%r1		  	   /* delay slot! */
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1	/* delay slot! */
 	ldo	TASK_PT_FR31(%r1),%r19		   /* reload fpregs */
 	rest_fp	%r19
 
@@ -2444,7 +2415,7 @@
 	   FIXME: After this point the process structure should be
 	   consistent with all the relevant state of the process
 	   before the syscall.  We need to verify this. */
-	LDREG	0(%r1),%r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 
 	ldo	TASK_REGS(%r1), %r25		/* struct pt_regs *regs */
 	reg_save %r25
 
@@ -2453,12 +2424,10 @@
 #ifdef __LP64__
 	ldo	-16(%r30),%r29			/* Reference param save area */
 #endif
-#warning TAUSQ FIXME, this is wrong
 	bl	do_signal,%r2
 	copy	%r0, %r26			/* sigset_t *oldset = NULL */
 
-	mfctl	%cr30,%r1			/* reload task ptr */
-	LDREG	0(%r1),%r1
+	LDREG	TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
 	ldo	TASK_REGS(%r1), %r20		/* reload pt_regs */
 	reg_restore %r20
 
diff -Nru a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
--- a/arch/parisc/kernel/head.S	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/head.S	Mon Jan 13 21:59:51 2003
@@ -48,7 +48,6 @@
 	.import	$global$		/* forward declaration */
 	.import fault_vector_11,code	/* IVA parisc 1.1 32 bit */
 	.import fault_vector_20,code	/* IVA parisc 2.0 32 bit */
-	.import start_parisc,code	/* then enable VM and go here */
 
 	.export stext
 	.export _stext,data		/* Kernel want it this way! */
@@ -74,7 +73,7 @@
 	ldo             R%PA(_end)(%r4),%r4
 $bss_loop:
 	cmpb,<<,n       %r3,%r4,$bss_loop
-	stb,ma          %r0,1(%r3)
+	stw,ma          %r0,4(%r3)
 
 	/* Save away the arguments the boot loader passed in (32 bit args) */
 
@@ -277,8 +276,8 @@
 	ldo		R%PA(smp_init_current_idle_task)(%sp),%sp
 	ldw		0(%sp),%sp	/* load task address */
 	mtctl           %sp,%cr30       /* store in cr30 */
-	addil		L%TASK_SZ_ALGN,%sp	/* stack is above task */
-	ldo		R%TASK_SZ_ALGN(%r1),%sp
+	addil		L%THREAD_SZ_ALGN,%sp	/* stack is above task */
+	ldo		R%THREAD_SZ_ALGN(%r1),%sp
 
 	/* point CPU to kernel page tables */
 	ldil		L%PA(swapper_pg_dir),%r4
diff -Nru a/arch/parisc/kernel/head64.S b/arch/parisc/kernel/head64.S
--- a/arch/parisc/kernel/head64.S	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/head64.S	Mon Jan 13 21:59:49 2003
@@ -176,7 +176,9 @@
 #endif /* CONFIG_SMP */
 
 	/* Save the rfi target address */
-	std		%r11,  TASK_PT_GR11-TASK_SZ_ALGN(%sp)
+	ldo		-THREAD_SZ_ALGN(%sp), %r1
+	ldd		TI_TASK(%r1), %r1
+	std		%r11,  TASK_PT_GR11(%r1)
 
 #ifndef CONFIG_PDC_NARROW
 	/* Switch to wide mode; Superdome doesn't support narrow PDC
@@ -206,7 +208,9 @@
 
 stext_pdc_ret:
 	/* restore rfi target address*/
-	ldd		TASK_PT_GR11-TASK_SZ_ALGN(%sp), %r11
+	ldo		-THREAD_SZ_ALGN(%sp), %r1
+	ldd		TI_TASK(%r1), %r1
+	ldd		TASK_PT_GR11(%r1), %r11
 
 	/* PARANOID: clear user scratch/user space SR's */
 	mtsp	%r0,%sr0
@@ -310,7 +314,7 @@
 	load32		PA(smp_init_current_idle_task),%sp
 	ldd		0(%sp),%sp	/* load task address */
 	mtctl           %sp,%cr30       /* store in cr30 */
-	ldo             TASK_SZ_ALGN(%sp),%sp
+	ldo             THREAD_SZ_ALGN(%sp),%sp
 	tophys_r1       %sp
 
 	/* point CPU to kernel page tables */
diff -Nru a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c
--- a/arch/parisc/kernel/inventory.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/inventory.c	Mon Jan 13 21:59:49 2003
@@ -28,6 +28,7 @@
 #include <asm/pdc.h>
 #include <asm/processor.h>
 #include <asm/page.h>
+#include <asm/parisc-device.h>
 
 /*
 ** Debug options
@@ -529,7 +530,8 @@
 	 * first stop the usb controller, otherwise the machine
 	 * might crash during iommu setup
 	 */
-	pdc_suspend_usb();
+#warning We still probably need to worry about USB here, but how?
+        /* pdc_suspend_usb(); */
 
 	for (i = 0; status != PDC_BAD_PROC && status != PDC_NE_MOD; i++) {
 		struct parisc_device *dev;
@@ -587,6 +589,8 @@
 
 void __init do_device_inventory(void)
 {
+	extern void parisc_generic_device_register(void);
+
 	printk(KERN_INFO "Searching for devices...\n");
 
 	switch (pdc_type) {
@@ -606,7 +610,7 @@
 	default:
 		panic("Unknown PDC type!\n");
 	}
-
+	parisc_generic_device_register();
 	printk(KERN_INFO "Found devices:\n");
 	print_parisc_devices();
 }
diff -Nru a/arch/parisc/kernel/ioctl32.c b/arch/parisc/kernel/ioctl32.c
--- a/arch/parisc/kernel/ioctl32.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/ioctl32.c	Mon Jan 13 21:59:49 2003
@@ -11,6 +11,7 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include "sys32.h"
+#include <linux/compat.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
@@ -164,7 +165,7 @@
  
 static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-	struct timeval32 *up = (struct timeval32 *)arg;
+	struct compat_timeval *up = (struct compat_timeval *)arg;
 	struct timeval ktv;
 	mm_segment_t old_fs = get_fs();
 	int err;
@@ -206,13 +207,13 @@
                 struct  ifmap32 ifru_map;
                 char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
 		char	ifru_newname[IFNAMSIZ];
-                __kernel_caddr_t32 ifru_data;
+                compat_caddr_t ifru_data;
         } ifr_ifru;
 };
 
 struct ifconf32 {
-        int     ifc_len;                        /* size of buffer       */
-        __kernel_caddr_t32  ifcbuf;
+        int		ifc_len;		/* size of buffer       */
+        compat_caddr_t	ifcbuf;
 };
 
 static int dev_ifname32(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -575,29 +576,29 @@
 #endif /* 0 */
 
 struct fb_fix_screeninfo32 {
-	char			id[16];
-        __kernel_caddr_t32	smem_start;
-	__u32			smem_len;
-	__u32			type;
-	__u32			type_aux;
-	__u32			visual;
-	__u16			xpanstep;
-	__u16			ypanstep;
-	__u16			ywrapstep;
-	__u32			line_length;
-        __kernel_caddr_t32	mmio_start;
-	__u32			mmio_len;
-	__u32			accel;
-	__u16			reserved[3];
+	char		id[16];
+        compat_caddr_t	smem_start;
+	__u32		smem_len;
+	__u32		type;
+	__u32		type_aux;
+	__u32		visual;
+	__u16		xpanstep;
+	__u16		ypanstep;
+	__u16		ywrapstep;
+	__u32		line_length;
+        compat_caddr_t	mmio_start;
+	__u32		mmio_len;
+	__u32		accel;
+	__u16		reserved[3];
 };
 
 struct fb_cmap32 {
-	__u32			start;
-	__u32			len;
-	__kernel_caddr_t32	red;
-	__kernel_caddr_t32	green;
-	__kernel_caddr_t32	blue;
-	__kernel_caddr_t32	transp;
+	__u32		start;
+	__u32		len;
+	compat_caddr_t	red;
+	compat_caddr_t	green;
+	compat_caddr_t	blue;
+	compat_caddr_t	transp;
 };
 
 static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -752,7 +753,7 @@
 	unsigned char	rate;
 	unsigned char	spec1;
 	unsigned char	fmt_gap;
-	const __kernel_caddr_t32 name;
+	const compat_caddr_t name;
 };
 
 struct floppy_drive_params32 {
@@ -791,7 +792,7 @@
 	int		fd_ref;
 	int		fd_device;
 	int		last_checked;
-	__kernel_caddr_t32 dmabuf;
+	compat_caddr_t	dmabuf;
 	int		bufblocks;
 };
 
@@ -1053,15 +1054,15 @@
 }
 
 struct ppp_option_data32 {
-	__kernel_caddr_t32	ptr;
-	__u32			length;
-	int			transmit;
+	compat_caddr_t	ptr;
+	__u32		length;
+	int		transmit;
 };
 #define PPPIOCSCOMPRESS32	_IOW('t', 77, struct ppp_option_data32)
 
 struct ppp_idle32 {
-	__kernel_time_t32 xmit_idle;
-	__kernel_time_t32 recv_idle;
+	compat_time_t xmit_idle;
+	compat_time_t recv_idle;
 };
 #define PPPIOCGIDLE32		_IOR('t', 63, struct ppp_idle32)
 
@@ -1135,8 +1136,8 @@
 	__u32	mt_dsreg;
 	__u32	mt_gstat;
 	__u32	mt_erreg;
-	__kernel_daddr_t32	mt_fileno;
-	__kernel_daddr_t32	mt_blkno;
+	compat_daddr_t	mt_fileno;
+	compat_daddr_t	mt_blkno;
 };
 #define MTIOCGET32	_IOR('m', 2, struct mtget32)
 
@@ -1254,25 +1255,25 @@
 }
 
 struct cdrom_read32 {
-	int			cdread_lba;
-	__kernel_caddr_t32	cdread_bufaddr;
-	int			cdread_buflen;
+	int		cdread_lba;
+	compat_caddr_t	cdread_bufaddr;
+	int		cdread_buflen;
 };
 
 struct cdrom_read_audio32 {
 	union cdrom_addr	addr;
 	u_char			addr_format;
 	int			nframes;
-	__kernel_caddr_t32	buf;
+	compat_caddr_t		buf;
 };
 
 struct cdrom_generic_command32 {
-	unsigned char		cmd[CDROM_PACKET_SIZE];
-	__kernel_caddr_t32	buffer;
-	unsigned int		buflen;
-	int			stat;
-	__kernel_caddr_t32	sense;
-	__kernel_caddr_t32	reserved[3];
+	unsigned char	cmd[CDROM_PACKET_SIZE];
+	compat_caddr_t	buffer;
+	unsigned int	buflen;
+	int		stat;
+	compat_caddr_t	sense;
+	compat_caddr_t	reserved[3];
 };
 
 static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -1281,7 +1282,7 @@
 	struct cdrom_read cdread;
 	struct cdrom_read_audio cdreadaudio;
 	struct cdrom_generic_command cgc;
-	__kernel_caddr_t32 addr;
+	compat_caddr_t addr;
 	char *data = 0;
 	void *karg;
 	int err = 0;
@@ -1364,18 +1365,18 @@
 }
 
 struct loop_info32 {
-	int			lo_number;      /* ioctl r/o */
-	__kernel_dev_t32	lo_device;      /* ioctl r/o */
-	unsigned int		lo_inode;       /* ioctl r/o */
-	__kernel_dev_t32	lo_rdevice;     /* ioctl r/o */
-	int			lo_offset;
-	int			lo_encrypt_type;
-	int			lo_encrypt_key_size;    /* ioctl w/o */
-	int			lo_flags;       /* ioctl r/o */
-	char			lo_name[LO_NAME_SIZE];
-	unsigned char		lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
-	unsigned int		lo_init[2];
-	char			reserved[4];
+	int		lo_number;      /* ioctl r/o */
+	compat_dev_t	lo_device;      /* ioctl r/o */
+	unsigned int	lo_inode;       /* ioctl r/o */
+	compat_dev_t	lo_rdevice;     /* ioctl r/o */
+	int		lo_offset;
+	int		lo_encrypt_type;
+	int		lo_encrypt_key_size;    /* ioctl w/o */
+	int		lo_flags;       /* ioctl r/o */
+	char		lo_name[LO_NAME_SIZE];
+	unsigned char	lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
+	unsigned int	lo_init[2];
+	char		reserved[4];
 };
 
 static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -1576,21 +1577,21 @@
 	set_fs(old_fs);
 
 	if (err >= 0)
-		err = put_user(kuid, (__kernel_uid_t32 *)arg);
+		err = put_user(kuid, (compat_uid_t *)arg);
 
 	return err;
 }
 #endif
 
 struct atmif_sioc32 {
-        int                number;
-        int                length;
-        __kernel_caddr_t32 arg;
+        int		number;
+        int		length;
+        compat_caddr_t	arg;
 };
 
 struct atm_iobuf32 {
-	int                length;
-	__kernel_caddr_t32 buffer;
+	int		length;
+	compat_caddr_t	buffer;
 };
 
 #define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
@@ -1651,7 +1652,7 @@
 
 	iobuf.length = iobuf32.length;
 
-	if (iobuf32.buffer == (__kernel_caddr_t32) NULL || iobuf32.length == 0) {
+	if (iobuf32.buffer == (compat_caddr_t) NULL || iobuf32.length == 0) {
 		iobuf.buffer = (void*)(unsigned long)iobuf32.buffer;
 	} else {
 		iobuf.buffer = kmalloc(iobuf.length, GFP_KERNEL);
@@ -1705,7 +1706,7 @@
         sioc.number = sioc32.number;
         sioc.length = sioc32.length;
         
-	if (sioc32.arg == (__kernel_caddr_t32) NULL || sioc32.length == 0) {
+	if (sioc32.arg == (compat_caddr_t) NULL || sioc32.length == 0) {
 		sioc.arg = (void*)(unsigned long)sioc32.arg;
         } else {
                 sioc.arg = kmalloc(sioc.length, GFP_KERNEL);
@@ -1863,8 +1864,8 @@
 } lv_status_byindex_req32_t;
 
 typedef struct {
-	__kernel_dev_t32 dev;
-	u32   lv;
+	compat_dev_t	dev;
+	u32		lv;
 } lv_status_bydev_req32_t;
 
 typedef struct {
@@ -2950,11 +2951,6 @@
 COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO)
 
 COMPATIBLE_IOCTL(FBIOPAN_DISPLAY)
-COMPATIBLE_IOCTL(FBIOGET_FCURSORINFO)
-COMPATIBLE_IOCTL(FBIOGET_VCURSORINFO)
-COMPATIBLE_IOCTL(FBIOPUT_VCURSORINFO)
-COMPATIBLE_IOCTL(FBIOGET_CURSORSTATE)
-COMPATIBLE_IOCTL(FBIOPUT_CURSORSTATE)
 COMPATIBLE_IOCTL(FBIOGET_CON2FBMAP)
 COMPATIBLE_IOCTL(FBIOPUT_CON2FBMAP)
 /* Little f */
@@ -3468,9 +3464,6 @@
 COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)
 COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)
 #endif /* DRM */
-/* elevator */
-COMPATIBLE_IOCTL(BLKELVGET)
-COMPATIBLE_IOCTL(BLKELVSET)
 /* Big R */
 COMPATIBLE_IOCTL(RNDGETENTCNT)
 COMPATIBLE_IOCTL(RNDADDTOENTCNT)
@@ -3627,7 +3620,7 @@
 HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl)
 #if 0
 /* One SMB ioctl needs translations. */
-#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, __kernel_uid_t32)
+#define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t)
 HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid)
 #endif
 HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl)
diff -Nru a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/parisc/kernel/module.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,254 @@
+/*  Kernel module help for parisc.
+
+    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/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt...)
+#endif
+
+enum parisc_fsel {
+	e_fsel,
+	e_lsel,
+	e_rsel,
+	e_lrsel,
+	e_rrsel
+};
+
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+	return vmalloc(size);
+}
+
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
+/* We don't need anything special. */
+long module_core_size(const Elf_Ehdr *hdr,
+		      const Elf_Shdr *sechdrs,
+		      const char *secstrings,
+		      struct module *module)
+{
+	return module->core_size;
+}
+
+long module_init_size(const Elf_Ehdr *hdr,
+		      const Elf_Shdr *sechdrs,
+		      const char *secstrings,
+		      struct module *module)
+{
+	return module->init_size;
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+			      Elf_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *mod)
+{
+	/* parisc should not need this ... */
+	printk(KERN_ERR "module %s: %s not yet implemented.\n",
+	       mod->name, __FUNCTION__);
+	return 0;
+}
+
+
+
+int apply_relocate(Elf_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	/* parisc should not need this ... */
+	printk(KERN_ERR "module %s: RELOCATION unsupported\n",
+	       me->name);
+	return -ENOEXEC;
+}
+
+#ifndef __LP64__
+int apply_relocate_add(Elf_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	int i;
+	Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	Elf32_Word *loc;
+	Elf32_Addr value;
+
+	DEBUGP("Applying relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+		      + rel[i].r_offset;
+		/* This is the symbol it is referring to */
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+			+ ELF32_R_SYM(rel[i].r_info);
+		if (!sym->st_value) {
+			printk(KERN_WARNING "%s: Unknown symbol %s\n",
+			       me->name, strtab + sym->st_name);
+			return -ENOENT;
+		}
+
+		value = sym->st_value + rel[i].r_addend;
+
+		DEBUGP("Symbol %s loc 0x%lx value 0x%lx: ",
+			strtab + sym->st_name,
+			(uint32_t)loc, value);
+
+		switch (ELF32_R_TYPE(rel[i].r_info)) {
+		case R_PARISC_PLABEL32:
+			/* 32-bit function address */
+			DEBUGP("R_PARISC_PLABEL32\n");
+			break;
+		case R_PARISC_DIR32:
+			/* direct 32-bit ref */
+			DEBUGP("R_PARISC_DIR32\n");
+			break;
+		case R_PARISC_DIR21L:
+			/* left 21 bits of effective address */
+			DEBUGP("R_PARISC_DIR21L\n");
+			break;
+		case R_PARISC_DIR14R:
+			/* right 14 bits of effective address */
+			DEBUGP("R_PARISC_DIR14R\n");
+			break;
+		case R_PARISC_SEGREL32:
+			/* 32-bit segment relative address */
+			DEBUGP("R_PARISC_SEGREL32\n");
+			break;
+		case R_PARISC_DPREL21L:
+			/* left 21 bit of relative address */
+			DEBUGP("R_PARISC_DPREL21L\n");
+			break;
+		case R_PARISC_DPREL14R:
+			/* right 14 bit of relative address */
+			DEBUGP("R_PARISC_DPREL14R\n");
+			break;
+		case R_PARISC_PCREL17F:
+			/* 17-bit PC relative address */
+			DEBUGP("R_PARISC_PCREL17F\n");
+			break;
+		case R_PARISC_PCREL22F:
+			/* 22-bit PC relative address */
+			DEBUGP("R_PARISC_PCREL22F\n");
+			break;
+
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %Lu\n",
+			       me->name, ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+
+	return -ENOEXEC;
+}
+
+#else
+int apply_relocate_add(Elf_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	int i;
+	Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf64_Sym *sym;
+	Elf64_Word *loc;
+	Elf64_Addr value;
+
+	DEBUGP("Applying relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+		      + rel[i].r_offset;
+		/* This is the symbol it is referring to */
+		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
+			+ ELF64_R_SYM(rel[i].r_info);
+		if (!sym->st_value) {
+			printk(KERN_WARNING "%s: Unknown symbol %s\n",
+			       me->name, strtab + sym->st_name);
+			return -ENOENT;
+		}
+
+		value = sym->st_value + rel[i].r_addend;
+
+		DEBUGP("Symbol %s loc 0x%Lx value 0x%Lx: ",
+			strtab + sym->st_name,
+			(uint64_t)loc, value);
+
+		switch (ELF64_R_TYPE(rel[i].r_info)) {
+		case R_PARISC_LTOFF14R:
+			/* LT-relative; right 14 bits */
+			DEBUGP("R_PARISC_LTOFF14R\n");
+			break;
+		case R_PARISC_LTOFF21L:
+			/* LT-relative; left 21 bits */
+			DEBUGP("R_PARISC_LTOFF21L\n");
+			break;
+		case R_PARISC_PCREL22F:
+			/* PC-relative; 22 bits */
+			DEBUGP("R_PARISC_PCREL22F\n");
+			break;
+		case R_PARISC_DIR64:
+			/* 64-bit effective address */
+			DEBUGP("R_PARISC_DIR64\n");
+			*loc = value;
+			break;
+		case R_PARISC_SEGREL32:
+			/* 32-bit segment relative address */
+			DEBUGP("R_PARISC_SEGREL32\n");
+			break;
+		case R_PARISC_FPTR64:
+			/* 64-bit function address */
+			DEBUGP("R_PARISC_FPTR64\n");
+			break;
+
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %Lu\n",
+			       me->name, ELF64_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return -ENOEXEC;
+}
+#endif
+
+int module_finalize(const Elf_Ehdr *hdr,
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+	return 0;
+}
diff -Nru a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
--- a/arch/parisc/kernel/parisc_ksyms.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/parisc_ksyms.c	Mon Jan 13 21:59:51 2003
@@ -86,9 +86,9 @@
 #include <asm/io.h>
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(memcpy_toio);
-EXPORT_SYMBOL(memcpy_fromio);
-EXPORT_SYMBOL(memset_io);
+EXPORT_SYMBOL(__memcpy_toio);
+EXPORT_SYMBOL(__memcpy_fromio);
+EXPORT_SYMBOL(__memset_io);
 
 #if defined(CONFIG_PCI) || defined(CONFIG_ISA)
 EXPORT_SYMBOL(inb);
@@ -141,7 +141,6 @@
 extern void $$remI(void);
 extern void $$remU(void);
 extern void $$mulI(void);
-extern void $$mulU(void);
 extern void $$divU_3(void);
 extern void $$divU_5(void);
 extern void $$divU_6(void);
@@ -166,9 +165,6 @@
 EXPORT_SYMBOL_NOVERS($$remI);
 EXPORT_SYMBOL_NOVERS($$remU);
 EXPORT_SYMBOL_NOVERS($$mulI);
-#ifndef __LP64__
-EXPORT_SYMBOL_NOVERS($$mulU);
-#endif
 EXPORT_SYMBOL_NOVERS($$divU_3);
 EXPORT_SYMBOL_NOVERS($$divU_5);
 EXPORT_SYMBOL_NOVERS($$divU_6);
@@ -215,3 +211,10 @@
 EXPORT_SYMBOL_NOVERS($$dyncall);
 #endif
 
+#ifdef CONFIG_PROFILING
+EXPORT_SYMBOL_GPL(register_profile_notifier);
+EXPORT_SYMBOL_GPL(unregister_profile_notifier);
+#endif
+
+#include <asm/pgtable.h>
+EXPORT_SYMBOL_NOVERS(vmalloc_start);
diff -Nru a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
--- a/arch/parisc/kernel/pci-dma.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/pci-dma.c	Mon Jan 13 21:59:51 2003
@@ -71,7 +71,7 @@
 static inline void dump_resmap(void) {;}
 #endif
 
-static int pa11_dma_supported( struct pci_dev *dev, u64 mask)
+static int pa11_dma_supported( struct device *dev, u64 mask)
 {
 	return 1;
 }
@@ -349,7 +349,7 @@
 
 __initcall(pcxl_dma_init);
 
-static void * pa11_dma_alloc_consistent (struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+static void * pa11_dma_alloc_consistent (struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
 {
 	unsigned long vaddr;
 	unsigned long paddr;
@@ -358,7 +358,7 @@
 	order = get_order(size);
 	size = 1 << (order + PAGE_SHIFT);
 	vaddr = pcxl_alloc_range(size);
-	paddr = __get_free_pages(GFP_ATOMIC, order);
+	paddr = __get_free_pages(flag, order);
 	flush_kernel_dcache_range(paddr, size);
 	paddr = __pa(paddr);
 	map_uncached_pages(vaddr, size, paddr);
@@ -369,13 +369,13 @@
 ** ISA cards will certainly only support 24-bit DMA addressing.
 ** Not clear if we can, want, or need to support ISA.
 */
-	if (!hwdev || hwdev->dma_mask != 0xffffffff)
+	if (!dev || *dev->dma_mask != 0xffffffff)
 		gfp |= GFP_DMA;
 #endif
 	return (void *)vaddr;
 }
 
-static void pa11_dma_free_consistent (struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void pa11_dma_free_consistent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
 {
 	int order;
 
@@ -386,9 +386,9 @@
 	free_pages((unsigned long)__va(dma_handle), order);
 }
 
-static dma_addr_t pa11_dma_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+static dma_addr_t pa11_dma_map_single(struct device *dev, void *addr, size_t size, enum dma_data_direction direction)
 {
-	if (direction == PCI_DMA_NONE) {
+	if (direction == DMA_NONE) {
 		printk(KERN_ERR "pa11_dma_map_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0));
 		BUG();
 	}
@@ -397,14 +397,14 @@
 	return virt_to_phys(addr);
 }
 
-static void pa11_dma_unmap_single(struct pci_dev *dev, dma_addr_t dma_handle, size_t size, int direction)
+static void pa11_dma_unmap_single(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction)
 {
-	if (direction == PCI_DMA_NONE) {
+	if (direction == DMA_NONE) {
 		printk(KERN_ERR "pa11_dma_unmap_single(PCI_DMA_NONE) called by %p\n", __builtin_return_address(0));
 		BUG();
 	}
 
-	if (direction == PCI_DMA_TODEVICE)
+	if (direction == DMA_TO_DEVICE)
 	    return;
 
 	/*
@@ -417,11 +417,11 @@
 	return;
 }
 
-static int pa11_dma_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+static int pa11_dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
 {
 	int i;
 
-	if (direction == PCI_DMA_NONE)
+	if (direction == DMA_NONE)
 	    BUG();
 
 	for (i = 0; i < nents; i++, sglist++ ) {
@@ -433,14 +433,14 @@
 	return nents;
 }
 
-static void pa11_dma_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+static void pa11_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
 {
 	int i;
 
-	if (direction == PCI_DMA_NONE)
+	if (direction == DMA_NONE)
 	    BUG();
 
-	if (direction == PCI_DMA_TODEVICE)
+	if (direction == DMA_TO_DEVICE)
 	    return;
 
 	/* once we do combining we'll need to use phys_to_virt(sg_dma_address(sglist)) */
@@ -450,15 +450,15 @@
 	return;
 }
 
-static void pa11_dma_sync_single(struct pci_dev *dev, dma_addr_t dma_handle, size_t size, int direction)
+static void pa11_dma_sync_single(struct device *dev, dma_addr_t dma_handle, unsigned long offset, size_t size, enum dma_data_direction direction)
 {
-	if (direction == PCI_DMA_NONE)
+	if (direction == DMA_NONE)
 	    BUG();
 
-	flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle), size);
+	flush_kernel_dcache_range((unsigned long) phys_to_virt(dma_handle) + offset, size);
 }
 
-static void pa11_dma_sync_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+static void pa11_dma_sync_sg(struct device *dev, struct scatterlist *sglist, int nents, enum dma_data_direction direction)
 {
 	int i;
 
@@ -468,40 +468,56 @@
 		flush_kernel_dcache_range(sg_virt_addr(sglist), sglist->length);
 }
 
-struct pci_dma_ops pcxl_dma_ops = {
-	pa11_dma_supported,			/* dma_support */
-	pa11_dma_alloc_consistent,
-	pa11_dma_free_consistent,
-	pa11_dma_map_single,			/* map_single */
-	pa11_dma_unmap_single,			/* unmap_single */
-	pa11_dma_map_sg,			/* map_sg */
-	pa11_dma_unmap_sg,			/* unmap_sg */
-	pa11_dma_sync_single,			/* dma_sync_single */
-	pa11_dma_sync_sg			/* dma_sync_sg */
+struct hppa_dma_ops pcxl_dma_ops = {
+	.dma_supported =	pa11_dma_supported,
+	.alloc_consistent =	pa11_dma_alloc_consistent,
+	.alloc_noncoherent =	pa11_dma_alloc_consistent,
+	.free_consistent =	pa11_dma_free_consistent,
+	.map_single =		pa11_dma_map_single,
+	.unmap_single =		pa11_dma_unmap_single,
+	.map_sg =		pa11_dma_map_sg,
+	.unmap_sg =		pa11_dma_unmap_sg,
+	.dma_sync_single =	pa11_dma_sync_single,
+	.dma_sync_sg =		pa11_dma_sync_sg,
 };
 
-static void *fail_alloc_consistent(struct pci_dev *hwdev, size_t size,
-		dma_addr_t *dma_handle)
+static void *fail_alloc_consistent(struct device *dev, size_t size,
+				   dma_addr_t *dma_handle, int flag)
 {
 	return NULL;
 }
 
-static void fail_free_consistent(struct pci_dev *dev, size_t size,
-		void *vaddr, dma_addr_t iova)
+static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
+					  dma_addr_t *dma_handle, int flag)
+{
+	void *addr = NULL;
+
+	/* rely on kmalloc to be cacheline aligned */
+	addr = kmalloc(size, flag);
+	if(addr)
+		*dma_handle = (dma_addr_t)virt_to_phys(addr);
+
+	return addr;
+}
+
+static void pa11_dma_free_noncoherent(struct device *dev, size_t size,
+					void *vaddr, dma_addr_t iova)
 {
+	kfree(vaddr);
 	return;
 }
 
-struct pci_dma_ops pcx_dma_ops = {
-	pa11_dma_supported,			/* dma_support */
-	fail_alloc_consistent,
-	fail_free_consistent,
-	pa11_dma_map_single,			/* map_single */
-	pa11_dma_unmap_single,			/* unmap_single */
-	pa11_dma_map_sg,			/* map_sg */
-	pa11_dma_unmap_sg,			/* unmap_sg */
-	pa11_dma_sync_single,			/* dma_sync_single */
-	pa11_dma_sync_sg			/* dma_sync_sg */
+struct hppa_dma_ops pcx_dma_ops = {
+	.dma_supported =	pa11_dma_supported,
+	.alloc_consistent =	fail_alloc_consistent,
+	.alloc_noncoherent =	pa11_dma_alloc_noncoherent,
+	.free_consistent =	pa11_dma_free_noncoherent,
+	.map_single =		pa11_dma_map_single,
+	.unmap_single =		pa11_dma_unmap_single,
+	.map_sg =		pa11_dma_map_sg,
+	.unmap_sg =		pa11_dma_unmap_sg,
+	.dma_sync_single =	pa11_dma_sync_single,
+	.dma_sync_sg =		pa11_dma_sync_sg,
 };
 
 
diff -Nru a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
--- a/arch/parisc/kernel/pci.c	Mon Jan 13 21:59:48 2003
+++ b/arch/parisc/kernel/pci.c	Mon Jan 13 21:59:48 2003
@@ -238,7 +238,7 @@
 	if (res->flags & IORESOURCE_IO) {
 		barval = PCI_PORT_ADDR(res->start);
 	} else if (res->flags & IORESOURCE_MEM) {
-		barval = PCI_BUS_ADDR(HBA_DATA(dev->bus->sysdata), res->start);
+		barval = PCI_BUS_ADDR(HBA_DATA(dev->bus->dev->platform_data), res->start);
 	} else {
 		panic("pcibios_update_resource() WTF? flags not IO or MEM");
 	}
@@ -350,7 +350,7 @@
 	struct pbus_set_ranges_data *ranges
 	)
 {
-	struct pci_hba_data *hba = HBA_DATA(bus->sysdata);
+	struct pci_hba_data *hba = HBA_DATA(bus->dev->platform_data);
 
 	/*
 	** I/O space may see busnumbers here. Something
@@ -486,24 +486,6 @@
 #endif
 }
 
-
-/*
-** Mostly copied from drivers/pci/setup-bus.c:pci_assign_unassigned_resources()
-*/
-void __devinit
-pcibios_assign_unassigned_resources(struct pci_bus *bus)
-{
-	/* from drivers/pci/setup-bus.c */
-	extern void pbus_assign_resources(struct pci_bus *bus, struct pbus_set_ranges_data *ranges);
-
-	struct pbus_set_ranges_data ranges;
-
-	ranges.io_end = ranges.io_start
-				= bus->resource[0]->start + PCIBIOS_MIN_IO;
-	ranges.mem_end = ranges.mem_start
-				= bus->resource[1]->start + PCIBIOS_MIN_MEM;
-	pbus_assign_resources(bus, &ranges);
-}
 
 /*
 ** PARISC specific (unfortunately)
diff -Nru a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
--- a/arch/parisc/kernel/pdc_cons.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/pdc_cons.c	Mon Jan 13 21:59:49 2003
@@ -56,7 +56,7 @@
 #define PDC_CONSOLE_DEVICE pdc_console_device
 static kdev_t pdc_console_device (struct console *c)
 {
-        return mk_kdev(PDCCONS_MAJOR, 0);
+        return mk_kdev(MUX_MAJOR, 0);
 }
 #else
 #define PDC_CONSOLE_DEVICE NULL
diff -Nru a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
--- a/arch/parisc/kernel/perf.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/perf.c	Mon Jan 13 21:59:49 2003
@@ -43,7 +43,6 @@
  */
 
 #include <linux/config.h>
-#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/miscdevice.h>
@@ -51,6 +50,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/perf.h>
+#include <asm/parisc-device.h>
 #include <asm/processor.h>
 #include <asm/runway.h>
 #include <asm/io.h>		/* for __raw_read() */
@@ -269,8 +269,6 @@
 	perf_enabled = 1;
  	spin_unlock(&perf_lock);
 
-	MOD_INC_USE_COUNT;
-
 	return 0;
 }
 
@@ -283,8 +281,6 @@
 	perf_enabled = 0;
 	spin_unlock(&perf_lock);
 
-	MOD_DEC_USE_COUNT;
-
 	return 0;
 }
 
@@ -500,7 +496,7 @@
  */
 static int __init perf_init(void)
 {
-	int retval;
+	int ret;
 
 	/* Determine correct processor interface to use */
 	bitmask_array = perf_bitmasks;
@@ -520,11 +516,11 @@
 		return -ENODEV;
 	}
 
-	retval = misc_register(&perf_dev);
-	if (retval < 0) {
+	ret = misc_register(&perf_dev);
+	if (ret) {
 		printk(KERN_ERR "Performance monitoring counters: "
 			"cannot register misc device.\n");
-		return retval;
+		return ret;
 	}
 
 	/* Patch the images to match the system */
diff -Nru a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
--- a/arch/parisc/kernel/process.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/process.c	Mon Jan 13 21:59:51 2003
@@ -217,7 +217,7 @@
 {
 	struct task_struct *p;
 	int *user_tid = (int *)regs->gr[26];
-	p = do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, user_tid);
+	p = do_fork(clone_flags & ~CLONE_IDLETASK, usp, regs, 0, user_tid, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -225,7 +225,7 @@
 sys_vfork(struct pt_regs *regs)
 {
 	struct task_struct *p;
-	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL);
+	p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gr[30], regs, 0, NULL, NULL);
 	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
 }
 
@@ -293,6 +293,11 @@
 	}
 
 	return 0;
+}
+
+unsigned long thread_saved_pc(struct task_struct *t)
+{
+	return t->thread.regs.kpc;
 }
 
 /*
diff -Nru a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
--- a/arch/parisc/kernel/processor.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/processor.c	Mon Jan 13 21:59:51 2003
@@ -42,6 +42,7 @@
 #include <asm/page.h>
 #include <asm/pdc.h>
 #include <asm/irq.h>		/* for struct irq_region */
+#include <asm/parisc-device.h>
 
 struct system_cpuinfo_parisc boot_cpu_data;
 struct cpuinfo_parisc cpu_data[NR_CPUS];
diff -Nru a/arch/parisc/kernel/profile.c b/arch/parisc/kernel/profile.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/parisc/kernel/profile.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,43 @@
+/* arch/parisc/kernel/profile.c
+ *
+ * Almost entirely copied from ppc64 which is:
+ * (C) 2002 John Levon <levon@movementarian.org>
+ */
+
+#include <linux/profile.h>
+#include <linux/spinlock.h>
+#include <linux/notifier.h>
+#include <asm/irq.h>
+
+static struct notifier_block *profile_listeners;
+static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
+
+int register_profile_notifier(struct notifier_block *nb)
+{
+	int err;
+
+	write_lock_irq(&profile_lock);
+	err = notifier_chain_register(&profile_listeners, nb);
+	write_unlock_irq(&profile_lock);
+
+	return err;
+}
+
+int unregister_profile_notifier(struct notifier_block *nb)
+{
+	int err;
+
+	write_lock_irq(&profile_lock);
+	err = notifier_chain_unregister(&profile_listeners, nb);
+	write_unlock_irq(&profile_lock);
+
+	return err;
+}
+
+void parisc_profile_hook(struct pt_regs *regs)
+{
+	read_lock(&profile_lock);
+	notifier_call_chain(&profile_listeners, 0, regs);
+	read_unlock(&profile_lock);
+}
+
diff -Nru a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
--- a/arch/parisc/kernel/ptrace.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/ptrace.c	Mon Jan 13 21:59:49 2003
@@ -103,7 +103,7 @@
 		if (current->ptrace & PT_PTRACED)
 			goto out;
 
-		ret = security_ops->ptrace(current->parent, current);
+		ret = security_ptrace(current->parent, current);
 		if (ret) 
 			goto out;
 
diff -Nru a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
--- a/arch/parisc/kernel/setup.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/setup.c	Mon Jan 13 21:59:51 2003
@@ -136,15 +136,15 @@
 
 #ifdef CONFIG_CHASSIS_LCD_LED
 	/* initialize the LCD/LED after boot_cpu_data is available ! */
-        led_init();				/* LCD/LED initialization */
+	led_init();		/* LCD/LED initialization */
 #endif
 
 #ifdef CONFIG_PA11
 	dma_ops_init();
 #endif
 
-#ifdef CONFIG_DUMMY_CONSOLE
-        conswitchp = &dummy_con;        /* we use take_over_console() later ! */
+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;	/* we use take_over_console() later ! */
 #endif
 
 }
@@ -185,7 +185,7 @@
 	.show	= show_cpuinfo
 };
 
-static void parisc_proc_mkdir(void)
+static void __init parisc_proc_mkdir(void)
 {
 	/*
 	** Can't call proc_mkdir() until after proc_root_init() has been
@@ -236,7 +236,7 @@
 	.flags	= IORESOURCE_MEM,
 };
 
-int __init parisc_init_resources(void)
+static int __init parisc_init_resources(void)
 {
 	int result;
 
@@ -270,6 +270,7 @@
 extern void gsc_init(void);
 extern void processor_init(void);
 extern void ccio_init(void);
+extern void hppb_init(void);
 extern void dino_init(void);
 extern void iosapic_init(void);
 extern void lba_init(void);
@@ -321,6 +322,11 @@
 #ifdef CONFIG_EISA
 	eisa_init();
 #endif
+
+#if defined(CONFIG_HPPB)
+	hppb_init();
+#endif
+
 #if defined(CONFIG_GSC_DINO)
 	dino_init();
 #endif
diff -Nru a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
--- a/arch/parisc/kernel/signal.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/signal.c	Mon Jan 13 21:59:51 2003
@@ -29,6 +29,7 @@
 #include <asm/rt_sigframe.h>
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
 
 #define DEBUG_SIG 0
 
@@ -40,6 +41,10 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
+/* Use this to get at 32-bit user passed pointers. 
+ *    See sys_sparc32.c for description about these. */
+#define A(__x)	((unsigned long)(__x))
+
 int do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall);
 
 int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
@@ -308,28 +313,26 @@
 			   (unsigned long) &frame->tramp[4]);
 #else
 	/* It should *always* be cache line-aligned, but the compiler
-           sometimes screws up. */
+	sometimes screws up. */
 	asm volatile("fdc 0(%%sr3,%0)\n\t"
 		     "fdc %1(%%sr3,%0)\n\t"
 		     "sync\n\t"
 		     "fic 0(%%sr3,%0)\n\t"
 		     "fic %1(%%sr3,%0)\n\t"
 		     "sync\n\t"
-		     : : "r" (frame->tramp), "r" (L1_CACHE_BYTES));
+		      : : "r" (frame->tramp), "r" (L1_CACHE_BYTES));
 #endif
+
 	rp = (unsigned long) frame->tramp;
 
 	if (err)
 		goto give_sigsegv;
 
-#ifdef __LP64__
 /* Much more has to happen with signals than this -- but it'll at least */
 /* provide a pointer to some places which definitely need a look. */
-#define HACK unsigned int
-#else
-#define HACK unsigned long
-#endif
-	haddr = (HACK) ka->sa.sa_handler;
+#define HACK u32
+
+	haddr = (HACK)A(ka->sa.sa_handler);
 	/* ARGH!  Fucking brain damage.  You don't want to know. */
 	if (haddr & 2) {
 		HACK *plabel;
@@ -355,13 +358,13 @@
 
 	regs->gr[2]  = rp;                /* userland return pointer */
 	regs->gr[26] = sig;               /* signal number */
-	regs->gr[25] = (HACK) &frame->info; /* siginfo pointer */
-	regs->gr[24] = (HACK) &frame->uc;   /* ucontext pointer */
+	regs->gr[25] = (HACK)A(&frame->info); /* siginfo pointer */
+	regs->gr[24] = (HACK)A(&frame->uc);   /* ucontext pointer */
 	DBG(("making sigreturn frame: %#lx + %#x = %#lx\n",
 	       regs->gr[30], PARISC_RT_SIGFRAME_SIZE,
 	       regs->gr[30] + PARISC_RT_SIGFRAME_SIZE));
 	/* Raise the user stack pointer to make a proper call frame. */
-	regs->gr[30] = ((HACK) frame + PARISC_RT_SIGFRAME_SIZE);
+	regs->gr[30] = ((HACK)A(frame) + PARISC_RT_SIGFRAME_SIZE);
 
 	DBG(("SIG deliver (%s:%d): frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
 	       current->comm, current->pid, frame, regs->gr[30],
diff -Nru a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
--- a/arch/parisc/kernel/signal32.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/signal32.c	Mon Jan 13 21:59:49 2003
@@ -1,5 +1,6 @@
 /* mostly borrowed from kernel/signal.c */
 #include <linux/config.h>
+#include <linux/compat.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/unistd.h>
@@ -175,7 +176,7 @@
 typedef struct {
 	unsigned int ss_sp;
 	int ss_flags;
-	__kernel_size_t32 ss_size;
+	compat_size_t ss_size;
 } stack_t32;
 
 int 
diff -Nru a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
--- a/arch/parisc/kernel/smp.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/smp.c	Mon Jan 13 21:59:51 2003
@@ -516,7 +516,7 @@
 	 * don't care about the regs settings since
 	 * we'll never reschedule the forked task.
 	 */
-	return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
+	return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
 }
 
 
diff -Nru a/arch/parisc/kernel/sys32.h b/arch/parisc/kernel/sys32.h
--- a/arch/parisc/kernel/sys32.h	Mon Jan 13 21:59:50 2003
+++ b/arch/parisc/kernel/sys32.h	Mon Jan 13 21:59:50 2003
@@ -12,11 +12,6 @@
     set_fs (old_fs); \
 }
 
-struct timeval32 {
-	int tv_sec;
-	int tv_usec;
-};
-
 typedef __u32 __sighandler_t32;
 
 #include <linux/signal.h>
diff -Nru a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
--- a/arch/parisc/kernel/sys_parisc.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/sys_parisc.c	Mon Jan 13 21:59:51 2003
@@ -308,3 +308,32 @@
 {
 	return -ENOSYS;
 }
+
+/*
+ * Set a given TLS descriptor:
+ */
+asmlinkage int sys_set_thread_area(struct user_desc *u_info)
+{
+	return -ENOSYS;
+}
+
+
+/*
+ * Get the current Thread-Local Storage area:
+ */
+
+asmlinkage int sys_get_thread_area(struct user_desc *u_info)
+{
+	return -ENOSYS;
+}
+
+
+asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag)
+{
+	return -ENOMEM;
+}
+
+asmlinkage int sys_free_hugepages(unsigned long addr)
+{
+	return -EINVAL;
+}
diff -Nru a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
--- a/arch/parisc/kernel/sys_parisc32.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/sys_parisc32.c	Mon Jan 13 21:59:49 2003
@@ -10,13 +10,13 @@
  */
 
 #include <linux/config.h>
+#include <linux/compat.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/fs.h> 
 #include <linux/mm.h> 
 #include <linux/file.h> 
 #include <linux/signal.h>
-#include <linux/utime.h>
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/utsname.h>
@@ -33,7 +33,6 @@
 #include <linux/smb_mount.h>
 #include <linux/ncp_fs.h>
 #include <linux/quota.h>
-#include <linux/module.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/cache.h>
@@ -383,105 +382,6 @@
 	return error;
 }
 
-/* These may not work without my local types changes, but I wanted the
- * code available in case it's useful to others. -PB
- */
-
-/* from utime.h */
-struct utimbuf32 {
-	__kernel_time_t32 actime;
-	__kernel_time_t32 modtime;
-};
-
-asmlinkage long sys32_utime(char *filename, struct utimbuf32 *times)
-{
-    struct utimbuf32 times32;
-    struct utimbuf times64;
-    extern long sys_utime(char *filename, struct utimbuf *times);
-    char *fname;
-    long ret;
-
-    if (!times)
-    	return sys_utime(filename, NULL);
-
-    /* get the 32-bit struct from user space */
-    if (copy_from_user(&times32, times, sizeof times32))
-    	return -EFAULT;
-
-    /* convert it into the 64-bit one */
-    times64.actime = times32.actime;
-    times64.modtime = times32.modtime;
-
-    /* grab the file name */
-    fname = getname(filename);
-
-    KERNEL_SYSCALL(ret, sys_utime, fname, &times64);
-
-    /* free the file name */
-    putname(fname);
-
-    return ret;
-}
-
-struct tms32 {
-	__kernel_clock_t32 tms_utime;
-	__kernel_clock_t32 tms_stime;
-	__kernel_clock_t32 tms_cutime;
-	__kernel_clock_t32 tms_cstime;
-};
-                                
-asmlinkage long sys32_times(struct tms32 *tbuf)
-{
-	struct tms t;
-	long ret;
-	extern asmlinkage long sys_times(struct tms * tbuf);
-int err;
-	
-	KERNEL_SYSCALL(ret, sys_times, tbuf ? &t : NULL);
-	if (tbuf) {
-		err = put_user (t.tms_utime, &tbuf->tms_utime);
-		err |= __put_user (t.tms_stime, &tbuf->tms_stime);
-		err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
-		err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
-		if (err)
-			ret = -EFAULT;
-	}
-	return ret;
-}
-
-struct flock32 {
-	short l_type;
-	short l_whence;
-	__kernel_off_t32 l_start;
-	__kernel_off_t32 l_len;
-	__kernel_pid_t32 l_pid;
-};
-
-
-static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
-{
-	int err;
-	
-	err = get_user(kfl->l_type, &ufl->l_type);
-	err |= __get_user(kfl->l_whence, &ufl->l_whence);
-	err |= __get_user(kfl->l_start, &ufl->l_start);
-	err |= __get_user(kfl->l_len, &ufl->l_len);
-	err |= __get_user(kfl->l_pid, &ufl->l_pid);
-	return err;
-}
-
-static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
-{
-	int err;
-	
-	err = __put_user(kfl->l_type, &ufl->l_type);
-	err |= __put_user(kfl->l_whence, &ufl->l_whence);
-	err |= __put_user(kfl->l_start, &ufl->l_start);
-	err |= __put_user(kfl->l_len, &ufl->l_len);
-	err |= __put_user(kfl->l_pid, &ufl->l_pid);
-	return err;
-}
-
 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
 
 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
@@ -494,7 +394,7 @@
 			struct flock f;
 			long ret;
 			
-			if(get_flock(&f, (struct flock32 *)arg))
+			if (get_compat_flock(&f, (struct compat_flock *)arg))
 				return -EFAULT;
 			KERNEL_SYSCALL(ret, sys_fcntl, fd, cmd, (unsigned long)&f);
 			if (ret) return ret;
@@ -502,7 +402,7 @@
 			    f.l_len >= 0x7fffffffUL ||
 			    f.l_start + f.l_len >= 0x7fffffffUL)
 				return -EOVERFLOW;
-			if(put_flock(&f, (struct flock32 *)arg))
+			if (put_compat_flock(&f, (struct compat_flock *)arg))
 				return -EFAULT;
 			return 0;
 		}
@@ -585,71 +485,33 @@
 }
 #endif /* CONFIG_SYSCTL */
 
-struct timespec32 {
-	s32    tv_sec;
-	s32    tv_nsec;
-};
-                
-static int
-put_timespec32(struct timespec32 *u, struct timespec *t)
-{
-	struct timespec32 t32;
-	t32.tv_sec = t->tv_sec;
-	t32.tv_nsec = t->tv_nsec;
-	return copy_to_user(u, &t32, sizeof t32);
-}
-
-asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
-{
-	struct timespec t;
-	struct timespec32 t32;
-	int ret;
-	extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
-	
-	if (copy_from_user(&t32, rqtp, sizeof t32))
-		return -EFAULT;
-	t.tv_sec = t32.tv_sec;
-	t.tv_nsec = t32.tv_nsec;
-
-	DBG(("sys32_nanosleep({%d, %d})\n", t32.tv_sec, t32.tv_nsec));
-
-	KERNEL_SYSCALL(ret, sys_nanosleep, &t, rmtp ? &t : NULL);
-	if (rmtp && ret == -EINTR) {
-		if (put_timespec32(rmtp, &t))
-			return -EFAULT;
-	}
-	return ret;
-}
-
 asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
-	struct timespec32 *interval)
+	struct compat_timespec *interval)
 {
 	struct timespec t;
 	int ret;
 	extern asmlinkage long sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
 	
 	KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, &t);
-	if (put_timespec32(interval, &t))
+	if (put_compat_timespec(&t, interval))
 		return -EFAULT;
 	return ret;
 }
 
-typedef __kernel_time_t32 time_t32;
-
 static int
-put_timeval32(struct timeval32 *u, struct timeval *t)
+put_compat_timeval(struct compat_timeval *u, struct timeval *t)
 {
-	struct timeval32 t32;
+	struct compat_timeval t32;
 	t32.tv_sec = t->tv_sec;
 	t32.tv_usec = t->tv_usec;
 	return copy_to_user(u, &t32, sizeof t32);
 }
 
 static int
-get_timeval32(struct timeval32 *u, struct timeval *t)
+get_compat_timeval(struct compat_timeval *u, struct timeval *t)
 {
 	int err;
-	struct timeval32 t32;
+	struct compat_timeval t32;
 
 	if ((err = copy_from_user(&t32, u, sizeof t32)) == 0)
 	{
@@ -659,10 +521,10 @@
 	return err;
 }
 
-asmlinkage long sys32_time(time_t32 *tloc)
+asmlinkage long sys32_time(compat_time_t *tloc)
 {
     time_t now = get_seconds();
-    time_t32 now32 = now;
+    compat_time_t now32 = now;
 
     if (tloc)
     	if (put_user(now32, tloc))
@@ -672,14 +534,14 @@
 }
 
 asmlinkage int
-sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
+sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
     extern void do_gettimeofday(struct timeval *tv);
 
     if (tv) {
 	    struct timeval ktv;
 	    do_gettimeofday(&ktv);
-	    if (put_timeval32(tv, &ktv))
+	    if (put_compat_timeval(tv, &ktv))
 		    return -EFAULT;
     }
     if (tz) {
@@ -691,14 +553,14 @@
 }
 
 asmlinkage int
-sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
+sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
 {
     struct timeval ktv;
     struct timezone ktz;
     extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
 
     if (tv) {
-	    if (get_timeval32(tv, &ktv))
+	    if (get_compat_timeval(tv, &ktv))
 		    return -EFAULT;
     }
     if (tz) {
@@ -709,67 +571,9 @@
     return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
 }
 
-struct	itimerval32 {
-	struct	timeval32 it_interval;	/* timer interval */
-	struct	timeval32 it_value;	/* current value */
-};
-
-asmlinkage long sys32_getitimer(int which, struct itimerval32 *ov32)
-{
-	int error = -EFAULT;
-	struct itimerval get_buffer;
-	extern int do_getitimer(int which, struct itimerval *value);
-
-	if (ov32) {
-		error = do_getitimer(which, &get_buffer);
-		if (!error) {
-			struct itimerval32 gb32;
-			gb32.it_interval.tv_sec = get_buffer.it_interval.tv_sec;
-			gb32.it_interval.tv_usec = get_buffer.it_interval.tv_usec;
-			gb32.it_value.tv_sec = get_buffer.it_value.tv_sec;
-			gb32.it_value.tv_usec = get_buffer.it_value.tv_usec;
-			if (copy_to_user(ov32, &gb32, sizeof(gb32)))
-				error = -EFAULT; 
-		}
-	}
-	return error;
-}
-
-asmlinkage long sys32_setitimer(int which, struct itimerval32 *v32,
-			      struct itimerval32 *ov32)
-{
-	struct itimerval set_buffer, get_buffer;
-	struct itimerval32 sb32, gb32;
-	extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ov32);
-	int error;
-
-	if (v32) {
-		if(copy_from_user(&sb32, v32, sizeof(sb32)))
-			return -EFAULT;
-
-		set_buffer.it_interval.tv_sec = sb32.it_interval.tv_sec;
-		set_buffer.it_interval.tv_usec = sb32.it_interval.tv_usec;
-		set_buffer.it_value.tv_sec = sb32.it_value.tv_sec;
-		set_buffer.it_value.tv_usec = sb32.it_value.tv_usec;
-	} else
-		memset((char *) &set_buffer, 0, sizeof(set_buffer));
-
-	error = do_setitimer(which, &set_buffer, ov32 ? &get_buffer : 0);
-	if (error || !ov32)
-		return error;
-
-	gb32.it_interval.tv_sec = get_buffer.it_interval.tv_sec;
-	gb32.it_interval.tv_usec = get_buffer.it_interval.tv_usec;
-	gb32.it_value.tv_sec = get_buffer.it_value.tv_sec;
-	gb32.it_value.tv_usec = get_buffer.it_value.tv_usec;
-	if (copy_to_user(ov32, &gb32, sizeof(gb32)))
-		return -EFAULT; 
-	return 0;
-}
-
 struct rusage32 {
-        struct timeval32 ru_utime;
-        struct timeval32 ru_stime;
+        struct compat_timeval ru_utime;
+        struct compat_timeval ru_stime;
         int    ru_maxrss;
         int    ru_ixrss;
         int    ru_idrss;
@@ -824,7 +628,7 @@
 }
 
 asmlinkage int
-sys32_wait4(__kernel_pid_t32 pid, unsigned int * stat_addr, int options,
+sys32_wait4(compat_pid_t pid, unsigned int * stat_addr, int options,
 	    struct rusage32 * ru)
 {
 	if (!ru)
@@ -842,41 +646,13 @@
 	}
 }
 
-struct stat32 {
-	__kernel_dev_t32		st_dev;		/* dev_t is 32 bits on parisc */
-	__kernel_ino_t32		st_ino;		/* 32 bits */
-	__kernel_mode_t32	st_mode;	/* 16 bits */
-	__kernel_nlink_t32		st_nlink;	/* 16 bits */
-	unsigned short	st_reserved1;	/* old st_uid */
-	unsigned short	st_reserved2;	/* old st_gid */
-	__kernel_dev_t32		st_rdev;
-	__kernel_off_t32		st_size;
-	__kernel_time_t32	st_atime;
-	unsigned int	st_spare1;
-	__kernel_time_t32	st_mtime;
-	unsigned int	st_spare2;
-	__kernel_time_t32	st_ctime;
-	unsigned int	st_spare3;
-	int		st_blksize;
-	int		st_blocks;
-	unsigned int	__unused1;	/* ACL stuff */
-	__kernel_dev_t32		__unused2;	/* network */
-	__kernel_ino_t32		__unused3;	/* network */
-	unsigned int	__unused4;	/* cnodes */
-	unsigned short	__unused5;	/* netsite */
-	short		st_fstype;
-	__kernel_dev_t32		st_realdev;
-	unsigned short	st_basemode;
-	unsigned short	st_spareshort;
-	__kernel_uid_t32		st_uid;
-	__kernel_gid_t32		st_gid;
-	unsigned int	st_spare4[3];
-};
-
-static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf)
+int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
 {
 	int err;
 
+	if (stat->size > MAX_NON_LFS)
+		return -EOVERFLOW;
+
 	err  = put_user(stat->dev, &statbuf->st_dev);
 	err |= put_user(stat->ino, &statbuf->st_ino);
 	err |= put_user(stat->mode, &statbuf->st_mode);
@@ -884,15 +660,13 @@
 	err |= put_user(0, &statbuf->st_reserved1);
 	err |= put_user(0, &statbuf->st_reserved2);
 	err |= put_user(stat->rdev, &statbuf->st_rdev);
-	if (stat->size > MAX_NON_LFS)
-		return -EOVERFLOW;
 	err |= put_user(stat->size, &statbuf->st_size);
-	err |= put_user(stat->atime, &statbuf->st_atime);
-	err |= put_user(0, &statbuf->st_spare1);
-	err |= put_user(stat->mtime, &statbuf->st_mtime);
-	err |= put_user(0, &statbuf->st_spare2);
-	err |= put_user(stat->ctime, &statbuf->st_ctime);
-	err |= put_user(0, &statbuf->st_spare3);
+	err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
+	err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
+	err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
+	err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
+	err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
+	err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
 	err |= put_user(stat->blksize, &statbuf->st_blksize);
 	err |= put_user(stat->blocks, &statbuf->st_blocks);
 	err |= put_user(0, &statbuf->__unused1);
@@ -913,44 +687,11 @@
 	return err;
 }
 
-asmlinkage long sys32_newstat(char * filename, struct stat32 *statbuf)
-{
-	struct kstat stat;
-	int error = vfs_stat(filename, &stat);
-
-	if (!error) 
-		error = cp_new_stat32(&stat, statbuf);
-	
-	return error;
-}
-
-asmlinkage long sys32_newlstat(char * filename, struct stat32 *statbuf)
-{
-	struct kstat stat;
-	int error = vfs_lstat(filename, &stat);
-
-	if (!error)
-		error = cp_new_stat32(&stat, statbuf);
-
-	return error;
-}
-
-asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
-{
-	struct kstat stat;
-	int error = vfs_fstat(fd, &stat);
-
-	if (!error)
-		error = cp_new_stat32(&stat, statbuf);
-
-	return error;
-}
-
 struct linux32_dirent {
-	u32	d_ino;
-	__kernel_off_t32	d_off;
-	u16	d_reclen;
-	char	d_name[1];
+	u32		d_ino;
+	compat_off_t	d_off;
+	u16		d_reclen;
+	char		d_name[1];
 };
 
 struct old_linux32_dirent {
@@ -1243,380 +984,6 @@
 }
 
 
-#ifdef CONFIG_MODULES
-
-struct module_info32 {
-	u32 addr;
-	u32 size;
-	u32 flags;
-	s32 usecount;
-};
-
-/* Query various bits about modules.  */
-
-static inline long
-get_mod_name(const char *user_name, char **buf)
-{
-	unsigned long page;
-	long retval;
-
-	if ((unsigned long)user_name >= TASK_SIZE
-	    && !segment_eq(get_fs (), KERNEL_DS))
-		return -EFAULT;
-
-	page = __get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
-	retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
-	if (retval > 0) {
-		if (retval < PAGE_SIZE) {
-			*buf = (char *)page;
-			return retval;
-		}
-		retval = -ENAMETOOLONG;
-	} else if (!retval)
-		retval = -EINVAL;
-
-	free_page(page);
-	return retval;
-}
-
-static inline void
-put_mod_name(char *buf)
-{
-	free_page((unsigned long)buf);
-}
-
-static __inline__ struct module *find_module(const char *name)
-{
-	struct module *mod;
-
-	for (mod = module_list; mod ; mod = mod->next) {
-		if (mod->flags & MOD_DELETED)
-			continue;
-		if (!strcmp(mod->name, name))
-			break;
-	}
-
-	return mod;
-}
-
-static int
-qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
-{
-	struct module *mod;
-	size_t nmod, space, len;
-
-	nmod = space = 0;
-
-	for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
-		len = strlen(mod->name)+1;
-		if (len > bufsize)
-			goto calc_space_needed;
-		if (copy_to_user(buf, mod->name, len))
-			return -EFAULT;
-		buf += len;
-		bufsize -= len;
-		space += len;
-	}
-
-	if (put_user(nmod, ret))
-		return -EFAULT;
-	else
-		return 0;
-
-calc_space_needed:
-	space += len;
-	while ((mod = mod->next)->next != NULL)
-		space += strlen(mod->name)+1;
-
-	if (put_user(space, ret))
-		return -EFAULT;
-	else
-		return -ENOSPC;
-}
-
-static int
-qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
-{
-	size_t i, space, len;
-
-	if (mod->next == NULL)
-		return -EINVAL;
-	if (!MOD_CAN_QUERY(mod))
-		return put_user(0, ret);
-
-	space = 0;
-	for (i = 0; i < mod->ndeps; ++i) {
-		const char *dep_name = mod->deps[i].dep->name;
-
-		len = strlen(dep_name)+1;
-		if (len > bufsize)
-			goto calc_space_needed;
-		if (copy_to_user(buf, dep_name, len))
-			return -EFAULT;
-		buf += len;
-		bufsize -= len;
-		space += len;
-	}
-
-	return put_user(i, ret);
-
-calc_space_needed:
-	space += len;
-	while (++i < mod->ndeps)
-		space += strlen(mod->deps[i].dep->name)+1;
-
-	if (put_user(space, ret))
-		return -EFAULT;
-	else
-		return -ENOSPC;
-}
-
-static int
-qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
-{
-	size_t nrefs, space, len;
-	struct module_ref *ref;
-
-	if (mod->next == NULL)
-		return -EINVAL;
-	if (!MOD_CAN_QUERY(mod))
-		if (put_user(0, ret))
-			return -EFAULT;
-		else
-			return 0;
-
-	space = 0;
-	for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
-		const char *ref_name = ref->ref->name;
-
-		len = strlen(ref_name)+1;
-		if (len > bufsize)
-			goto calc_space_needed;
-		if (copy_to_user(buf, ref_name, len))
-			return -EFAULT;
-		buf += len;
-		bufsize -= len;
-		space += len;
-	}
-
-	if (put_user(nrefs, ret))
-		return -EFAULT;
-	else
-		return 0;
-
-calc_space_needed:
-	space += len;
-	while ((ref = ref->next_ref) != NULL)
-		space += strlen(ref->ref->name)+1;
-
-	if (put_user(space, ret))
-		return -EFAULT;
-	else
-		return -ENOSPC;
-}
-
-static inline int
-qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
-{
-	size_t i, space, len;
-	struct module_symbol *s;
-	char *strings;
-	unsigned *vals;
-
-	if (!MOD_CAN_QUERY(mod))
-		if (put_user(0, ret))
-			return -EFAULT;
-		else
-			return 0;
-
-	space = mod->nsyms * 2*sizeof(u32);
-
-	i = len = 0;
-	s = mod->syms;
-
-	if (space > bufsize)
-		goto calc_space_needed;
-
-	if (!access_ok(VERIFY_WRITE, buf, space))
-		return -EFAULT;
-
-	bufsize -= space;
-	vals = (unsigned *)buf;
-	strings = buf+space;
-
-	for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
-		len = strlen(s->name)+1;
-		if (len > bufsize)
-			goto calc_space_needed;
-
-		if (copy_to_user(strings, s->name, len)
-		    || __put_user(s->value, vals+0)
-		    || __put_user(space, vals+1))
-			return -EFAULT;
-
-		strings += len;
-		bufsize -= len;
-		space += len;
-	}
-
-	if (put_user(i, ret))
-		return -EFAULT;
-	else
-		return 0;
-
-calc_space_needed:
-	for (; i < mod->nsyms; ++i, ++s)
-		space += strlen(s->name)+1;
-
-	if (put_user(space, ret))
-		return -EFAULT;
-	else
-		return -ENOSPC;
-}
-
-static inline int
-qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
-{
-	int error = 0;
-
-	if (mod->next == NULL)
-		return -EINVAL;
-
-	if (sizeof(struct module_info32) <= bufsize) {
-		struct module_info32 info;
-		info.addr = (unsigned long)mod;
-		info.size = mod->size;
-		info.flags = mod->flags;
-		info.usecount =
-			((mod_member_present(mod, can_unload)
-			  && mod->can_unload)
-			 ? -1 : atomic_read(&mod->uc.usecount));
-
-		if (copy_to_user(buf, &info, sizeof(struct module_info32)))
-			return -EFAULT;
-	} else
-		error = -ENOSPC;
-
-	if (put_user(sizeof(struct module_info32), ret))
-		return -EFAULT;
-
-	return error;
-}
-
-asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, __kernel_size_t32 *ret)
-{
-	struct module *mod;
-	int err;
-
-	lock_kernel();
-	if (name_user == 0) {
-		/* This finds "kernel_module" which is not exported. */
-		for(mod = module_list; mod->next != NULL; mod = mod->next)
-			;
-	} else {
-		long namelen;
-		char *name;
-
-		if ((namelen = get_mod_name(name_user, &name)) < 0) {
-			err = namelen;
-			goto out;
-		}
-		err = -ENOENT;
-		if (namelen == 0) {
-			/* This finds "kernel_module" which is not exported. */
-			for(mod = module_list; mod->next != NULL; mod = mod->next)
-				;
-		} else if ((mod = find_module(name)) == NULL) {
-			put_mod_name(name);
-			goto out;
-		}
-		put_mod_name(name);
-	}
-
-	switch (which)
-	{
-	case 0:
-		err = 0;
-		break;
-	case QM_MODULES:
-		err = qm_modules(buf, bufsize, ret);
-		break;
-	case QM_DEPS:
-		err = qm_deps(mod, buf, bufsize, ret);
-		break;
-	case QM_REFS:
-		err = qm_refs(mod, buf, bufsize, ret);
-		break;
-	case QM_SYMBOLS:
-		err = qm_symbols(mod, buf, bufsize, ret);
-		break;
-	case QM_INFO:
-		err = qm_info(mod, buf, bufsize, ret);
-		break;
-	default:
-		err = -EINVAL;
-		break;
-	}
-out:
-	unlock_kernel();
-	return err;
-}
-
-struct kernel_sym32 {
-	u32 value;
-	char name[60];
-};
-		 
-extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
-
-asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
-{
-	int len, i;
-	struct kernel_sym *tbl;
-	mm_segment_t old_fs;
-	
-	len = sys_get_kernel_syms(NULL);
-	if (!table) return len;
-	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
-	if (!tbl) return -ENOMEM;
-	old_fs = get_fs();
-	set_fs (KERNEL_DS);
-	sys_get_kernel_syms(tbl);
-	set_fs (old_fs);
-	for (i = 0; i < len; i++, table++) {
-		if (put_user (tbl[i].value, &table->value) ||
-		    copy_to_user (table->name, tbl[i].name, 60))
-			break;
-	}
-	kfree (tbl);
-	return i;
-}
-
-#else /* CONFIG_MODULES */
-
-asmlinkage int
-sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
-		 size_t *ret)
-{
-	/* Let the program know about the new interface.  Not that
-	   it'll do them much good.  */
-	if (which == 0)
-		return 0;
-
-	return -ENOSYS;
-}
-
-asmlinkage int
-sys32_get_kernel_syms(struct kernel_sym *table)
-{
-	return -ENOSYS;
-}
-
-#endif  /* CONFIG_MODULES */
-
 /* readv/writev stolen from mips64 */
 struct iovec32 { unsigned int iov_base; int iov_len; };
 
@@ -1659,7 +1026,7 @@
 		__get_user(buf, &vector->iov_base);
 		tot_len += len;
 		ivp->iov_base = (void *)A(buf);
-		ivp->iov_len = (__kernel_size_t) len;
+		ivp->iov_len = (compat_size_t) len;
 		vector++;
 		ivp++;
 		i--;
@@ -1774,19 +1141,19 @@
 extern struct socket *sockfd_lookup(int fd, int *err);
 
 struct msghdr32 {
-        u32               msg_name;
-        int               msg_namelen;
-        u32               msg_iov;
-        __kernel_size_t32 msg_iovlen;
-        u32               msg_control;
-        __kernel_size_t32 msg_controllen;
-        unsigned          msg_flags;
+	u32		msg_name;
+	int		msg_namelen;
+	u32		msg_iov;
+	compat_size_t	msg_iovlen;
+	u32		msg_control;
+	compat_size_t	msg_controllen;
+	unsigned	msg_flags;
 };
 
 struct cmsghdr32 {
-        __kernel_size_t32 cmsg_len;
-        int               cmsg_level;
-        int               cmsg_type;
+	compat_size_t	cmsg_len;
+	int		cmsg_level;
+	int		cmsg_type;
 };
 
 /* Bleech... */
@@ -1918,7 +1285,7 @@
 {
 	struct cmsghdr32 *ucmsg;
 	struct cmsghdr *kcmsg, *kcmsg_base;
-	__kernel_size_t32 ucmlen;
+	compat_size_t ucmlen;
 	__kernel_size_t kcmlen, tmp;
 
 	kcmlen = 0;
@@ -2284,7 +1651,7 @@
 		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
 	if(cmsg_ptr != 0 && err >= 0) {
 		unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
-		__kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
+		compat_size_t uclen = (compat_size_t) (ucmsg_ptr - cmsg_ptr);
 		err |= __put_user(uclen, &user_msg->msg_controllen);
 	}
 	if(err >= 0)
@@ -2591,7 +1958,7 @@
 #define DIVIDE_ROUND_UP(x,y) (((x)+(y)-1)/(y))
 
 asmlinkage long
-sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, struct timeval32 *tvp)
+sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, struct compat_timeval *tvp)
 {
 	fd_set_bits fds;
 	char *bits;
@@ -2600,7 +1967,7 @@
 
 	timeout = MAX_SCHEDULE_TIMEOUT;
 	if (tvp) {
-		struct timeval32 tv32;
+		struct compat_timeval tv32;
 		time_t sec, usec;
 
 		if ((ret = copy_from_user(&tv32, tvp, sizeof tv32)))
@@ -2761,37 +2128,37 @@
 		default:
 			break;
 	}
-	return sys_fcntl(fd, cmd, arg);
+	return sys32_fcntl(fd, cmd, arg);
 }
 
 /* EXPORT/UNEXPORT */
 struct nfsctl_export32 {
-	char			ex_client[NFSCLNT_IDMAX+1];
-	char			ex_path[NFS_MAXPATHLEN+1];
-	__kernel_dev_t		ex_dev;
-	__kernel_ino_t32	ex_ino;
-	int			ex_flags;
-	__kernel_uid_t		ex_anon_uid;
-	__kernel_gid_t		ex_anon_gid;
+	char		ex_client[NFSCLNT_IDMAX+1];
+	char		ex_path[NFS_MAXPATHLEN+1];
+	__kernel_dev_t	ex_dev;
+	compat_ino_t	ex_ino;
+	int		ex_flags;
+	__kernel_uid_t	ex_anon_uid;
+	__kernel_gid_t	ex_anon_gid;
 };
 
 /* GETFH */
 struct nfsctl_fhparm32 {
-	struct sockaddr		gf_addr;
-	__kernel_dev_t		gf_dev;
-	__kernel_ino_t32	gf_ino;
-	int			gf_version;
+	struct sockaddr	gf_addr;
+	__kernel_dev_t	gf_dev;
+	compat_ino_t	gf_ino;
+	int		gf_version;
 };
 
 /* UGIDUPDATE */
 struct nfsctl_uidmap32 {
-	__kernel_caddr_t32	ug_ident;
-	__kernel_uid_t		ug_uidbase;
-	int			ug_uidlen;
-	__kernel_caddr_t32	ug_udimap;
-	__kernel_gid_t		ug_gidbase;
-	int			ug_gidlen;
-	__kernel_caddr_t32	ug_gdimap;
+	compat_caddr_t	ug_ident;
+	__kernel_uid_t	ug_uidbase;
+	int		ug_uidlen;
+	compat_caddr_t	ug_udimap;
+	__kernel_gid_t	ug_gidbase;
+	int		ug_gidlen;
+	compat_caddr_t	ug_gdimap;
 };
 
 struct nfsctl_arg32 {
@@ -2877,7 +2244,8 @@
 		break;
 
 	default:
-		BUG(); /* new cmd values to be translated... */
+		/* lockd probes for some other values (0x10000);
+		 * so don't BUG() */
 		ret = -EINVAL;
 		break;
 	}
@@ -2904,8 +2272,8 @@
     __u32 dqb_ihardlimit;
     __u32 dqb_isoftlimit;
     __u32 dqb_curinodes;
-    __kernel_time_t32 dqb_btime;
-    __kernel_time_t32 dqb_itime;
+    compat_time_t dqb_btime;
+    compat_time_t dqb_itime;
 };
                                 
 
@@ -2954,6 +2322,31 @@
 	return -EINVAL;
 }
 
+
+
+extern asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t *offset, size_t count);
+typedef long __kernel_loff_t32;		/* move this to asm/posix_types.h? */
+
+asmlinkage int sys32_sendfile64(int out_fd, int in_fd, __kernel_loff_t32 *offset, s32 count)
+{
+	mm_segment_t old_fs = get_fs();
+	int ret;
+	loff_t lof;
+	
+	if (offset && get_user(lof, offset))
+		return -EFAULT;
+		
+	set_fs(KERNEL_DS);
+	ret = sys_sendfile64(out_fd, in_fd, offset ? &lof : NULL, count);
+	set_fs(old_fs);
+	
+	if (offset && put_user(lof, offset))
+		return -EFAULT;
+		
+	return ret;
+}
+
+
 struct timex32 {
 	unsigned int modes;	/* mode selector */
 	int offset;		/* time offset (usec) */
@@ -2966,7 +2359,7 @@
 	int tolerance;		/* clock frequency tolerance (ppm)
 				 * (read only)
 				 */
-	struct timeval32 time;	/* (read only) */
+	struct compat_timeval time;	/* (read only) */
 	int tick;		/* (modified) usecs between clock ticks */
 
 	int ppsfreq;           /* pps frequency (scaled ppm) (ro) */
@@ -3101,3 +2494,11 @@
 	return sys_semctl (semid, semnum, cmd, arg);
 }
 
+extern int sys_lookup_dcookie(u64 cookie64, char *buf, size_t len);
+
+long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char *buf,
+			  size_t len)
+{
+	return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
+				  buf, len);
+}
diff -Nru a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
--- a/arch/parisc/kernel/syscall.S	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/syscall.S	Mon Jan 13 21:59:51 2003
@@ -23,12 +23,6 @@
 #endif
 	.text
 
-#ifdef __LP64__
-#define FRAME_SIZE	128
-#else
-#define FRAME_SIZE	64
-#endif
-
 	.import syscall_exit,code
 	.import syscall_exit_rfi,code
 	.export linux_gateway_page
@@ -99,9 +93,9 @@
 	 */
 
 	mtsp	%r0,%sr7			/* get kernel space into sr7 */
-	STREG	%r1,0(%r30)			/* Stick r1 (usp) here for now */
-	mfctl	%cr30,%r1			/*  get task ptr in %r1 */
-	LDREG	0(%r1),%r1
+	STREGM	%r1,FRAME_SIZE(%r30)		/* save r1 (usp) here for now */
+	mfctl	%cr30,%r1			/* get task ptr in %r1 */
+	LDREG	TI_TASK(%r1),%r1
 
 	/* Save some registers for sigcontext and potential task
 	   switch (see entry.S for the details of which ones are
@@ -110,7 +104,7 @@
 	   PSW value is stored.  This is needed for gdb and sys_ptrace. */
 	STREG	%r0,  TASK_PT_PSW(%r1)
 	STREG	%r2,  TASK_PT_GR2(%r1)		/* preserve rp */
-	LDREG	0(%r30), %r2			/* get users sp back */
+	LDREGM	-FRAME_SIZE(%r30), %r2		/* get users sp back */
 	STREG	%r2,  TASK_PT_GR30(%r1)		/* ... and save it */
 	STREG	%r19, TASK_PT_GR19(%r1)
 	STREG	%r20, TASK_PT_GR20(%r1)
@@ -204,7 +198,7 @@
 	 * in the saved PSW.
 	 */
 	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
-	LDREG	0(%r1), %r1
+	LDREG	TI_TASK(%r1), %r1
 	ssm	0,%r2
 	STREG	%r2,TASK_PT_PSW(%r1)		/* Lower 8 bits only!! */
 	mfsp	%sr0,%r2
@@ -255,7 +249,7 @@
 	ldo     R%sys_call_table(%r1), %r19
 
 	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
-	LDREG	0(%r1), %r1
+	LDREG	TI_TASK(%r1), %r1
 	LDREG   TASK_PT_GR20(%r1), %r20
 	LDREG   TASK_PT_GR26(%r1), %r26		/* Restore the users args */
 	LDREG   TASK_PT_GR25(%r1), %r25
@@ -292,14 +286,14 @@
 	
 tracesys_exit:
 	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
-	LDREG	0(%r1), %r1
+	LDREG	TI_TASK(%r1), %r1
 #ifdef __LP64__
 	ldo	-16(%r30),%r29			/* Reference param save area */
 #endif
 	bl	syscall_trace, %r2
 	STREG   %r28,TASK_PT_GR28(%r1)          /* save return value now */
 	ldo     -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1      /* get task ptr */
-	LDREG	0(%r1), %r1
+	LDREG	TI_TASK(%r1), %r1
 	LDREG   TASK_PT_GR28(%r1), %r28		/* Restore return val. */
 
 	ldil	L%syscall_exit,%r1
@@ -332,11 +326,13 @@
 #define ENTRY_DIFF(_name_) .dword sys32_##_name_
 #define ENTRY_UHOH(_name_) .dword sys32_##unimplemented
 #define ENTRY_OURS(_name_) .dword parisc_##_name_
+#define ENTRY_COMP(_name_) .dword compat_sys_##_name_
 #else
 #define ENTRY_SAME(_name_) .word sys_##_name_
 #define ENTRY_DIFF(_name_) .word sys_##_name_
 #define ENTRY_UHOH(_name_) .word sys_##_name_
 #define ENTRY_OURS(_name_) .word parisc_##_name_
+#define ENTRY_COMP(_name_) .word sys_##_name_
 #endif
 
 	.align 8
@@ -363,7 +359,7 @@
 	ENTRY_SAME(lchown)
 	ENTRY_SAME(socket)
 	/* struct stat is MAYBE identical wide and narrow ?? */
-	ENTRY_DIFF(newstat)
+	ENTRY_COMP(newstat)
 	ENTRY_DIFF(lseek)
 	ENTRY_SAME(getpid)		/* 20 */
 	/* the 'void * data' parameter may need re-packing in wide */
@@ -378,10 +374,10 @@
 	ENTRY_SAME(ptrace)
 	ENTRY_SAME(alarm)
 	/* see stat comment */
-	ENTRY_DIFF(newfstat)
+	ENTRY_COMP(newfstat)
 	ENTRY_SAME(pause)
 	/* struct utimbuf uses time_t which might vary */
-	ENTRY_DIFF(utime)		/* 30 */
+	ENTRY_COMP(utime)		/* 30 */
 	/* struct sockaddr... */
 	ENTRY_SAME(connect)
 	ENTRY_SAME(listen)
@@ -396,7 +392,7 @@
 	ENTRY_SAME(rmdir)		/* 40 */
 	ENTRY_SAME(dup)
 	ENTRY_SAME(pipe)
-	ENTRY_DIFF(times)
+	ENTRY_COMP(times)
 	/* struct sockaddr... */
 	ENTRY_SAME(getsockname)
 	/* it seems possible brk() could return a >4G pointer... */
@@ -447,7 +443,7 @@
 	ENTRY_SAME(sendto)
 	ENTRY_SAME(symlink)
 	/* see stat comment */
-	ENTRY_DIFF(newlstat)
+	ENTRY_COMP(newlstat)
 	ENTRY_SAME(readlink)	/* 85 */
 	/* suspect we'll need some work for narrow shlibs on wide kernel */
 	/* NOTE this doesn't get used when I boot 32-bit userspace */
@@ -474,8 +470,8 @@
 	ENTRY_SAME(syslog)
 	/* even though manpage says struct timeval contains longs, ours has
 	 * time_t and suseconds_t -- both of which are safe wide/narrow */
-	ENTRY_DIFF(setitimer)
-	ENTRY_DIFF(getitimer)	/* 105 */
+	ENTRY_COMP(setitimer)
+	ENTRY_COMP(getitimer)	/* 105 */
 	ENTRY_SAME(capget)
 	ENTRY_SAME(capset)
 	ENTRY_OURS(pread64)
@@ -501,13 +497,10 @@
 	ENTRY_SAME(mprotect)	/* 125 */
 	/* old_sigset_t forced to 32 bits.  Beware glibc sigset_t */
 	ENTRY_DIFF(sigprocmask)
-	ENTRY_SAME(create_module)
-	/* struct module contains longs, but insmod builds a 64 bit struct
-	 * if running under a 64 bit kernel */
+	ENTRY_SAME(ni_syscall)		/* create_module */
 	ENTRY_SAME(init_module)
 	ENTRY_SAME(delete_module)
-	/* struct kernel_sym contains a long. Linus never heard of size_t? */
-	ENTRY_DIFF(get_kernel_syms)	/* 130 */
+	ENTRY_SAME(ni_syscall)		/* 130: get_kernel_syms */
 	/* time_t inside struct dqblk */
 	ENTRY_DIFF(quotactl) /* -- FIXME, doesn't work */
 	ENTRY_SAME(getpgid)
@@ -551,13 +544,12 @@
 	 * carefully, like timeval for example (which is about the same).
 	 * Unfortunately it contains a long :-( */
 	ENTRY_DIFF(sched_rr_get_interval)
-	ENTRY_DIFF(nanosleep)
+	ENTRY_COMP(nanosleep)
 	ENTRY_SAME(mremap)
 	ENTRY_SAME(setresuid)
 	ENTRY_SAME(getresuid)	/* 165 */
 	ENTRY_DIFF(sigaltstack_wrapper)
-	/* struct passed back to user can contain long symbol values */
-	ENTRY_DIFF(query_module)
+	ENTRY_SAME(ni_syscall)		/* query_module */
 	ENTRY_SAME(poll)
 	/* structs contain pointers and an in_addr... */
 	ENTRY_DIFF(nfsservctl)
@@ -609,11 +601,31 @@
 #else
 	ENTRY_SAME(ni_syscall)
 	ENTRY_SAME(ni_syscall)
-	ENTRY_SAME(ni_syscall)
+	ENTRY_SAME(ni_syscall)		/* 205 */
 #endif
 	ENTRY_SAME(gettid)             
 	ENTRY_SAME(readahead)          
 	ENTRY_SAME(ni_syscall)		/* tkill */
+
+	ENTRY_SAME(sendfile64)
+	ENTRY_SAME(futex)		/* 210 */
+	ENTRY_SAME(sched_setaffinity)
+	ENTRY_SAME(sched_getaffinity)
+	ENTRY_SAME(set_thread_area)
+	ENTRY_SAME(get_thread_area)
+	ENTRY_SAME(io_setup)		/* 215 */
+	ENTRY_SAME(io_destroy)
+	ENTRY_SAME(io_getevents)
+	ENTRY_SAME(io_submit)
+	ENTRY_SAME(io_cancel)
+	ENTRY_SAME(alloc_hugepages)	/* 220 */
+	ENTRY_SAME(free_hugepages)
+	ENTRY_SAME(exit_group)
+	ENTRY_DIFF(lookup_dcookie)
+	ENTRY_SAME(epoll_create)
+	ENTRY_SAME(epoll_ctl)		/* 225 */
+	ENTRY_SAME(epoll_wait)
+ 	ENTRY_SAME(remap_file_pages)
 .end
 
 	/* Make sure nothing else is placed on this page */
diff -Nru a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
--- a/arch/parisc/kernel/time.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/time.c	Mon Jan 13 21:59:49 2003
@@ -46,13 +46,29 @@
 #endif
 
 static inline void
-parisc_do_profile(unsigned long pc)
+parisc_do_profile(struct pt_regs *regs)
 {
+	unsigned long pc = regs->iaoq[0];
+	extern unsigned long prof_cpu_mask;
 	extern char _stext;
 
+#ifdef CONFIG_PROFILING
+	extern void parisc_profile_hook(struct pt_regs *);
+
+	parisc_profile_hook(regs);
+#endif
+
+	if (user_mode(regs))
+		return;
+
 	if (!prof_buffer)
 		return;
 
+#if 0
+	if (!((1 << smp_processor_id()) & prof_cpu_mask))
+		return;
+#endif
+
 	pc -= (unsigned long) &_stext;
 	pc >>= prof_shift;
 	/*
@@ -67,13 +83,15 @@
 
 void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	long now = mfctl(16);
+	long now;
 	long next_tick;
 	int nticks;
 	int cpu = smp_processor_id();
 
-	/* initialize next_tick to time at last clocktick */
+	parisc_do_profile(regs);
 
+	now = mfctl(16);
+	/* initialize next_tick to time at last clocktick */
 	next_tick = cpu_data[cpu].it_value;
 
 	/* since time passes between the interrupt and the mfctl()
@@ -98,13 +116,6 @@
 #endif
 		if (cpu == 0) {
 			write_lock(&xtime_lock);
-#ifndef CONFIG_SMP
-			extern int pc_in_user_space;
-			if (!user_mode(regs))
-				parisc_do_profile(regs->iaoq[0]);
-			else
-				parisc_do_profile((unsigned long)&pc_in_user_space);
-#endif
 			do_timer(regs);
 			write_unlock(&xtime_lock);
 		}
@@ -240,3 +251,4 @@
 		xtime.tv_nsec = 0;
 	}
 }
+
diff -Nru a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
--- a/arch/parisc/kernel/traps.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/kernel/traps.c	Mon Jan 13 21:59:51 2003
@@ -25,6 +25,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/console.h>
+#include <linux/kallsyms.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -42,7 +43,7 @@
 #define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */
 			  /*  dumped to the console via printk)          */
 
-static int printbinary(char *buf, unsigned long x, int nbits)
+int printbinary(char *buf, unsigned long x, int nbits)
 {
 	unsigned long mask = 1UL << (nbits - 1);
 	while (mask != 0) {
@@ -192,6 +193,19 @@
 
 void die_if_kernel(char *str, struct pt_regs *regs, long err)
 {
+	if (user_mode(regs)) {
+		if (err == 0)
+			return; /* STFU */
+
+		printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
+			current->comm, current->pid, str, err, regs->iaoq[0]);
+#ifdef PRINT_USER_FAULTS
+		/* XXX for debugging only */
+		show_regs(regs);
+#endif
+		return;
+	}
+
 	/* Amuse the user in a SPARC fashion */
 	printk(
 "      _______________________________ \n"
@@ -202,19 +216,6 @@
 "                 (__)\\       )\\/\\\n"
 "                  U  ||----w |\n"
 "                     ||     ||\n");
-
-	if (user_mode(regs)) {
-#ifdef PRINT_USER_FAULTS
-		if (err == 0)
-			return; /* STFU */
-
-		/* XXX for debugging only */
-		printk(KERN_DEBUG "%s (pid %d): %s (code %ld)\n",
-			current->comm, current->pid, str, err);
-		show_regs(regs);
-#endif
-		return;
-	}
 	
 	/* unlock the pdc lock if necessary */
 	pdc_emergency_unlock();
diff -Nru a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
--- a/arch/parisc/kernel/unaligned.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/kernel/unaligned.c	Mon Jan 13 21:59:49 2003
@@ -1,8 +1,8 @@
-/*    $Id: unaligned.c,v 1.1 2002/07/20 16:27:06 rhirst Exp $
- *
+/*
  *    Unaligned memory access handler
  *
  *    Copyright (C) 2001 Randolph Chung <tausq@debian.org>
+ *    Significantly tweaked by LaMont Jones <lamont@debian.org>
  *
  *    This program is free software; you can redistribute it and/or modify
  *    it under the terms of the GNU General Public License as published by
@@ -33,6 +33,7 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -66,28 +67,28 @@
 #define OPCODE3_MASK	OPCODE3(0x3f,1)
 #define OPCODE4_MASK    OPCODE4(0x3f)
 
-/* skip LDB (index) */
+/* skip LDB - never unaligned (index) */
 #define OPCODE_LDH_I	OPCODE1(0x03,0,0x1)
 #define OPCODE_LDW_I	OPCODE1(0x03,0,0x2)
 #define OPCODE_LDD_I	OPCODE1(0x03,0,0x3)
 #define OPCODE_LDDA_I	OPCODE1(0x03,0,0x4)
-/* skip LDCD (index) */
+#define OPCODE_LDCD_I	OPCODE1(0x03,0,0x5)
 #define OPCODE_LDWA_I	OPCODE1(0x03,0,0x6)
-/* skip LDCW (index) */
-/* skip LDB (short) */
+#define OPCODE_LDCW_I	OPCODE1(0x03,0,0x7)
+/* skip LDB - never unaligned (short) */
 #define OPCODE_LDH_S	OPCODE1(0x03,1,0x1)
 #define OPCODE_LDW_S	OPCODE1(0x03,1,0x2)
 #define OPCODE_LDD_S	OPCODE1(0x03,1,0x3)
 #define OPCODE_LDDA_S	OPCODE1(0x03,1,0x4)
-/* skip LDCD (short) */
+#define OPCODE_LDCD_S	OPCODE1(0x03,1,0x5)
 #define OPCODE_LDWA_S	OPCODE1(0x03,1,0x6)
-/* skip LDCW (short) */
-/* skip STB */
+#define OPCODE_LDCW_S	OPCODE1(0x03,1,0x7)
+/* skip STB - never unaligned */
 #define OPCODE_STH	OPCODE1(0x03,1,0x9)
 #define OPCODE_STW	OPCODE1(0x03,1,0xa)
 #define OPCODE_STD	OPCODE1(0x03,1,0xb)
-/* skip STBY */
-/* skip STDBY */
+/* skip STBY - never unaligned */
+/* skip STDBY - never unaligned */
 #define OPCODE_STWA	OPCODE1(0x03,1,0xe)
 #define OPCODE_STDA	OPCODE1(0x03,1,0xf)
 
@@ -103,129 +104,200 @@
 
 #define OPCODE_LDH_L    OPCODE4(0x11)
 #define OPCODE_LDW_L    OPCODE4(0x12)
-#define OPCODE_LDW_L2   OPCODE4(0x13)
+#define OPCODE_LDWM     OPCODE4(0x13)
 #define OPCODE_STH_L    OPCODE4(0x19)
 #define OPCODE_STW_L    OPCODE4(0x1A)
-#define OPCODE_STW_L2   OPCODE4(0x1B)
+#define OPCODE_STWM     OPCODE4(0x1B)
 
+#define MAJOR_OP(i) (((i)>>26)&0x3f)
+#define R1(i) (((i)>>21)&0x1f)
+#define R2(i) (((i)>>16)&0x1f)
+#define R3(i) ((i)&0x1f)
+#define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0))
+#define IM5_2(i) IM((i)>>16,5)
+#define IM5_3(i) IM((i),5)
+#define IM14(i) IM((i),14)
 
+int unaligned_enabled = 1;
 
 void die_if_kernel (char *str, struct pt_regs *regs, long err);
 
-static int emulate_load(struct pt_regs *regs, int len, int toreg)
+static int emulate_ldh(struct pt_regs *regs, int toreg)
 {
 	unsigned long saddr = regs->ior;
 	unsigned long val = 0;
-	int ret = 0;
 
-	if (regs->isr != regs->sr[7])
-	{
-		printk(KERN_CRIT "isr verification failed (isr: " RFMT ", sr7: " RFMT "\n",
-			regs->isr, regs->sr[7]);
-		return 1;
-	}
+	DPRINTF("load " RFMT ":" RFMT " to r%d for 2 bytes\n", 
+		regs->isr, regs->ior, toreg);
 
-	DPRINTF("load " RFMT ":" RFMT " to r%d for %d bytes\n", 
-		regs->isr, regs->ior, toreg, len);
+	__asm__ __volatile__  (
+"	mtsp	%3, %%sr1\n"
+"	ldbs	0(%%sr1,%2), %%r20\n"
+"	ldbs	1(%%sr1,%2), %0\n"
+	"depw	%%r20, 23, 24, %0\n"
+	: "=r" (val)
+	: "0" (val), "r" (saddr), "r" (regs->isr)
+	: "r20" );
+
+	DPRINTF("val = 0x" RFMT "\n", val);
+
+	if (toreg)
+		regs->gr[toreg] = val;
+
+	return 0;
+}
+static int emulate_ldw(struct pt_regs *regs, int toreg)
+{
+	unsigned long saddr = regs->ior;
+	unsigned long val = 0;
+
+	DPRINTF("load " RFMT ":" RFMT " to r%d for 4 bytes\n", 
+		regs->isr, regs->ior, toreg);
 
 	__asm__ __volatile__  (
-"       mfsp %%sr1, %%r20\n"
-"       mtsp %6, %%sr1\n"
-"	copy %%r0, %0\n"
-"0:	ldbs,ma	1(%%sr1,%4), %%r19\n"
-"	addi -1, %5, %5\n"
-"	cmpib,>= 0, %5, 2f\n"
-"	or %%r19, %0, %0\n"
-"	b 0b\n"
-	
-#ifdef __LP64__
-	"depd,z %0, 55, 56, %0\n"
-#else
-	"depw,z %0, 23, 24, %0\n"
-#endif
-	
-"1:	ldi	10, %1\n"
-"2:     mtsp %%r20, %%sr1\n"
-"	.section __ex_table,\"a\"\n"
+"	zdep	%2,28,2,%%r19\n"		/* r19=(ofs&3)*8 */
+"	mtsp	%3, %%sr1\n"
+"	depw	%%r0,31,2,%2\n"
+"	ldw	0(%%sr1,%2),%0\n"
+"	ldw	4(%%sr1,%2),%%r20\n"
+"	subi	32,%%r19,%%r19\n"
+"	mtctl	%%r19,11\n"
+"	vshd	%0,%%r20,%0\n"
+	: "=r" (val)
+	: "0" (val), "r" (saddr), "r" (regs->isr)
+	: "r19", "r20" );
+
+	DPRINTF("val = 0x" RFMT "\n", val);
+
+	if (toreg)
+		regs->gr[toreg] = val;
+
+	return 0;
+}
 #ifdef __LP64__
-	".dword 0b, (1b-0b)\n"
-#else
-	".word 0b, (1b-0b)\n"
-#endif
-	".previous\n" 
-	: "=r" (val), "=r" (ret)
-	: "0" (val), "1" (ret), "r" (saddr), "r" (len), "r" (regs->isr)
+static int emulate_ldd(struct pt_regs *regs, int toreg)
+{
+	unsigned long saddr = regs->ior;
+	unsigned long val = 0;
+
+	DPRINTF("load " RFMT ":" RFMT " to r%d for 8 bytes\n", 
+		regs->isr, regs->ior, toreg);
+
+	__asm__ __volatile__  (
+"	depd,z	%2,60,3,%%r19\n"		/* r19=(ofs&7)*8 */
+"	mtsp	%3, %%sr1\n"
+"	depd	%%r0,63,3,%2\n"
+"	ldd	0(%%sr1,%2),%0\n"
+"	ldd	8(%%sr1,%2),%%r20\n"
+"	subi	64,%%r19,%%r19\n"
+"	mtsar	%%r19\n"
+"	shrpd	%0,%%r20,%%sar,%0\n"
+	: "=r" (val)
+	: "0" (val), "r" (saddr), "r" (regs->isr)
 	: "r19", "r20" );
 
 	DPRINTF("val = 0x" RFMT "\n", val);
 
-	regs->gr[toreg] = val;
+	if (toreg)
+		regs->gr[toreg] = val;
 
-	return ret;
+	return 0;
 }
+#endif
 
-static int emulate_store(struct pt_regs *regs, int len, int frreg)
+static int emulate_sth(struct pt_regs *regs, int frreg)
 {
-	int ret = 0;
-#ifdef __LP64__
-	unsigned long val = regs->gr[frreg] << (64 - (len << 3));
-#else
-	unsigned long val = regs->gr[frreg] << (32 - (len << 3));
-#endif
+	unsigned long val = regs->gr[frreg];
+	if (!frreg)
+		val = 0;
 
-	if (regs->isr != regs->sr[7])
-	{
-		printk(KERN_CRIT "isr verification failed (isr: " RFMT ", sr7: " RFMT "\n",
-			regs->isr, regs->sr[7]);
-		return 1;
-	}
+	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 2 bytes\n", frreg, 
+		regs->gr[frreg], regs->isr, regs->ior);
 
-	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for %d bytes\n", frreg, 
-		regs->gr[frreg], regs->isr, regs->ior, len);
+	__asm__ __volatile__ (
+"	mtsp %2, %%sr1\n"
+"	extrw,u %0, 23, 8, %%r19\n"
+"	stb %0, 1(%%sr1, %1)\n"
+"	stb %%r19, 0(%%sr1, %1)\n"
+	:
+	: "r" (val), "r" (regs->ior), "r" (regs->isr)
+	: "r19" );
+
+	return 0;
+}
+static int emulate_stw(struct pt_regs *regs, int frreg)
+{
+	unsigned long val = regs->gr[frreg];
+	if (!frreg)
+		val = 0;
+
+	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 4 bytes\n", frreg, 
+		regs->gr[frreg], regs->isr, regs->ior);
 
 
 	__asm__ __volatile__ (
-"       mfsp %%sr1, %%r20\n"		/* save sr1 */
-"       mtsp %5, %%sr1\n"
-#ifdef __LP64__
-"0:	extrd,u %2, 7, 8, %%r19\n"
-#else
-"0:	extrw,u %2, 7, 8, %%r19\n"
-#endif
-"1:	stb,ma %%r19, 1(%%sr1, %3)\n"
-"	addi -1, %4, %4\n"
-"	cmpib,>= 0, %4, 3f\n"
-	
+"	mtsp %2, %%sr1\n"
+"	zdep	%1, 28, 2, %%r19\n"
+"	dep	%%r0, 31, 2, %1\n"
+"	mtsar	%%r19\n"
+"	depwi,z	-2, %%sar, 32, %%r19\n"
+"	ldw	0(%%sr1,%1),%%r20\n"
+"	ldw	4(%%sr1,%1),%%r21\n"
+"	vshd	%%r0, %0, %%r22\n"
+"	vshd	%0, %%r0, %%r1\n"
+"	and	%%r20, %%r19, %%r20\n"
+"	andcm	%%r21, %%r19, %%r21\n"
+"	or	%%r22, %%r20, %%r20\n"
+"	or	%%r1, %%r21, %%r21\n"
+"	stw	%%r20,0(%%sr1,%1)\n"
+"	stw	%%r21,4(%%sr1,%1)\n"
+	:
+	: "r" (val), "r" (regs->ior), "r" (regs->isr)
+	: "r19", "r20", "r21", "r22", "r1" );
+
+	return 0;
+}
 #ifdef __LP64__
-	"depd,z %2, 55, 56, %2\n"
-#else
-	"depw,z %2, 23, 24, %2\n"
-#endif
+static int emulate_std(struct pt_regs *regs, int frreg)
+{
+	unsigned long val = regs->gr[frreg];
+	if (!frreg)
+		val = 0;
 
-"	b 0b\n"
-"	nop\n"
+	DPRINTF("store r%d (0x" RFMT ") to " RFMT ":" RFMT " for 8 bytes\n", frreg, 
+		regs->gr[frreg], regs->isr, regs->ior);
 
-"2:	ldi 11, %0\n"
-"3:     mtsp %%r20, %%sr1\n"
-"	.section __ex_table,\"a\"\n"
-#ifdef __LP64__
-	".dword 1b, (2b-1b)\n"
-#else
-	".word 1b, (2b-1b)\n"
-#endif
-	".previous\n" 
-	: "=r" (ret)
-	: "0" (ret), "r" (val), "r" (regs->ior), "r" (len), "r" (regs->isr)
-	: "r19", "r20" );
 
-	return ret;
-}
+	__asm__ __volatile__ (
+"	mtsp %2, %%sr1\n"
+"	depd,z	%1, 60, 3, %%r19\n"
+"	depd	%%r0, 63, 3, %1\n"
+"	mtsar	%%r19\n"
+"	depdi,z	-2, %%sar, 64, %%r19\n"
+"	ldd	0(%%sr1,%1),%%r20\n"
+"	ldd	8(%%sr1,%1),%%r21\n"
+"	shrpd	%%r0, %0, %%sar, %%r22\n"
+"	shrpd	%0, %%r0, %%sar, %%r1\n"
+"	and	%%r20, %%r19, %%r20\n"
+"	andcm	%%r21, %%r19, %%r21\n"
+"	or	%%r22, %%r20, %%r20\n"
+"	or	%%r1, %%r21, %%r21\n"
+"	std	%%r20,0(%%sr1,%1)\n"
+"	std	%%r21,8(%%sr1,%1)\n"
+	:
+	: "r" (val), "r" (regs->ior), "r" (regs->isr)
+	: "r19", "r20", "r21", "r22", "r1" );
 
+	return 0;
+}
+#endif
 
 void handle_unaligned(struct pt_regs *regs)
 {
 	unsigned long unaligned_count = 0;
 	unsigned long last_time = 0;
+	unsigned long newbase = regs->gr[R1(regs->iir)];
+	int modify = 0;
 	int ret = -1;
 	struct siginfo si;
 
@@ -242,7 +314,7 @@
 		 * exception handler 
 		 */ 
 
-		fix = search_exception_table(regs->iaoq[0]);
+		fix = search_exception_tables(regs->iaoq[0]);
 		if (fix)
 		{
 			/* lower bits of fix->skip are flags
@@ -281,83 +353,172 @@
 		}
 	}
 
+	if (!unaligned_enabled)
+		goto force_sigbus;
+
+	/* handle modification - OK, it's ugly, see the instruction manual */
+	switch (MAJOR_OP(regs->iir))
+	{
+	case 0x03:
+	case 0x09:
+	case 0x0b:
+		if (regs->iir&0x20)
+		{
+			modify = 1;
+			if (regs->iir&0x1000)		/* short loads */
+				if (regs->iir&0x200)
+					newbase += IM5_3(regs->iir);
+				else
+					newbase += IM5_2(regs->iir);
+			else if (regs->iir&0x2000)	/* scaled indexed */
+			{
+				int shift=0;
+				switch (regs->iir & OPCODE1_MASK)
+				{
+				case OPCODE_LDH_I:
+					shift= 1; break;
+				case OPCODE_LDW_I:
+					shift= 2; break;
+				case OPCODE_LDD_I:
+				case OPCODE_LDDA_I:
+					shift= 3; break;
+				}
+				newbase += regs->gr[R2(regs->iir)]<<shift;
+			} else				/* simple indexed */
+				newbase += regs->gr[R2(regs->iir)];
+		}
+		break;
+	case 0x13:
+	case 0x1b:
+		modify = 1;
+		newbase += IM14(regs->iir);
+		break;
+	case 0x14:
+	case 0x1c:
+		if (regs->iir&8)
+		{
+			modify = 1;
+			newbase += IM14(regs->iir&~0xe);
+		}
+		break;
+	case 0x16:
+	case 0x1e:
+		modify = 1;
+		newbase += IM14(regs->iir&6);
+		break;
+	case 0x17:
+	case 0x1f:
+		if (regs->iir&4)
+		{
+			modify = 1;
+			newbase += IM14(regs->iir&~4);
+		}
+		break;
+	}
+
+	if (regs->isr != regs->sr[7])
+	{
+		printk(KERN_CRIT "isr verification failed (isr: " RFMT ", sr7: " RFMT "\n",
+			regs->isr, regs->sr[7]);
+
+		/* don't kill him though, since he has appropriate access to the page, or we
+		 * would never have gotten here.
+		 */
+	}
+
 	/* TODO: make this cleaner... */
 	switch (regs->iir & OPCODE1_MASK)
 	{
 	case OPCODE_LDH_I:
 	case OPCODE_LDH_S:
-		ret = emulate_load(regs, 2, regs->iir & 0x1f);
+		ret = emulate_ldh(regs, R3(regs->iir));
 		break;
 
 	case OPCODE_LDW_I:
 	case OPCODE_LDWA_I:
 	case OPCODE_LDW_S:
 	case OPCODE_LDWA_S:
-		ret = emulate_load(regs, 4, regs->iir&0x1f);
-		break;
-
-	case OPCODE_LDD_I:
-	case OPCODE_LDDA_I:
-	case OPCODE_LDD_S:
-	case OPCODE_LDDA_S:
-		ret = emulate_load(regs, 8, regs->iir&0x1f);
+		ret = emulate_ldw(regs, R3(regs->iir));
 		break;
 
 	case OPCODE_STH:
-		ret = emulate_store(regs, 2, (regs->iir>>16)&0x1f);
+		ret = emulate_sth(regs, R2(regs->iir));
 		break;
 
 	case OPCODE_STW:
 	case OPCODE_STWA:
-		ret = emulate_store(regs, 4, (regs->iir>>16)&0x1f);
+		ret = emulate_stw(regs, R2(regs->iir));
+		break;
+
+#ifdef __LP64__
+	case OPCODE_LDD_I:
+	case OPCODE_LDDA_I:
+	case OPCODE_LDD_S:
+	case OPCODE_LDDA_S:
+		ret = emulate_ldd(regs, R3(regs->iir));
 		break;
 
 	case OPCODE_STD:
 	case OPCODE_STDA:
-		ret = emulate_store(regs, 8, (regs->iir>>16)&0x1f);
+		ret = emulate_std(regs, R2(regs->iir));
+		break;
+#endif
+
+	case OPCODE_LDCD_I:
+	case OPCODE_LDCW_I:
+	case OPCODE_LDCD_S:
+	case OPCODE_LDCW_S:
+		ret = -1;	/* "undefined", but lets kill them. */
 		break;
 	}
+#ifdef __LP64__
 	switch (regs->iir & OPCODE2_MASK)
 	{
 	case OPCODE_LDD_L:
 	case OPCODE_FLDD_L:
-		ret = emulate_load(regs, 8, (regs->iir>>16)&0x1f);
+		ret = emulate_ldd(regs, R2(regs->iir));
 		break;
 
 	case OPCODE_STD_L:
 	case OPCODE_FSTD_L:
-		ret = emulate_store(regs, 8, (regs->iir>>16)&0x1f);
+		ret = emulate_std(regs, R2(regs->iir));
 		break;
 	}
+#endif
 	switch (regs->iir & OPCODE3_MASK)
 	{
 	case OPCODE_LDW_M:
 	case OPCODE_FLDW_L:
-		ret = emulate_load(regs, 4, (regs->iir>>16)&0x1f);
+		ret = emulate_ldw(regs, R2(regs->iir));
 		break;
 
 	case OPCODE_FSTW_L:
 	case OPCODE_STW_M:
-		ret = emulate_store(regs, 4, (regs->iir>>16)&0x1f);
+		ret = emulate_stw(regs, R2(regs->iir));
 		break;
 	}
 	switch (regs->iir & OPCODE4_MASK)
 	{
 	case OPCODE_LDH_L:
-		ret = emulate_load(regs, 2, (regs->iir>>16)&0x1f);
+		ret = emulate_ldh(regs, R2(regs->iir));
 		break;
 	case OPCODE_LDW_L:
-	case OPCODE_LDW_L2:
-		ret = emulate_load(regs, 4, (regs->iir>>16)&0x1f);
+	case OPCODE_LDWM:
+		ret = emulate_ldw(regs, R2(regs->iir));
 		break;
 	case OPCODE_STH_L:
-		ret = emulate_store(regs, 2, (regs->iir>>16)&0x1f);
+		ret = emulate_sth(regs, R2(regs->iir));
 		break;
 	case OPCODE_STW_L:
-	case OPCODE_STW_L2:
-		ret = emulate_store(regs, 4, (regs->iir>>16)&0x1f);
+	case OPCODE_STWM:
+		ret = emulate_stw(regs, R2(regs->iir));
 		break;
 	}
+	/* XXX LJ - need to handle float load/store */
+
+	if (modify)
+		regs->gr[R1(regs->iir)] = newbase;
+
 
 	if (ret < 0)
 		printk(KERN_CRIT "Not-handled unaligned insn 0x%08lx\n", regs->iir);
@@ -368,7 +529,7 @@
 	{
 		printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
 		die_if_kernel("Unaligned data reference", regs, 28);
-
+force_sigbus:
 		/* couldn't handle it ... */
 		si.si_signo = SIGBUS;
 		si.si_errno = 0;
@@ -421,9 +582,9 @@
 			align_mask = 1UL;
 			break;
 		case OPCODE_LDW_L:
-		case OPCODE_LDW_L2:
+		case OPCODE_LDWM:
 		case OPCODE_STW_L:
-		case OPCODE_STW_L2:
+		case OPCODE_STWM:
 			align_mask = 3UL;
 			break;
 		}
@@ -432,3 +593,4 @@
 
 	return (int)(regs->ior & align_mask);
 }
+
diff -Nru a/arch/parisc/lib/io.c b/arch/parisc/lib/io.c
--- a/arch/parisc/lib/io.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/lib/io.c	Mon Jan 13 21:59:49 2003
@@ -14,9 +14,9 @@
  * Assumes the device can cope with 32-bit transfers.  If it can't,
  * don't use this function.
  */
-void memcpy_toio(unsigned long dest, const void *src, int count)
+void __memcpy_toio(unsigned long dest, unsigned long src, int count)
 {
-	if ((dest & 3) != ((unsigned long)src & 3))
+	if ((dest & 3) != (src & 3))
 		goto bytecopy;
 	while (dest & 3) {
 		writeb(*(char *)src, dest++);
@@ -25,7 +25,7 @@
 	}
 	while (count > 3) {
 		__raw_writel(*(u32 *)src, dest);
-		(unsigned long) src += 4;
+		src += 4;
 		dest += 4;
 		count -= 4;
 	}
@@ -49,13 +49,13 @@
 **      Minimize total number of transfers at cost of CPU cycles.
 **	TODO: only look at src alignment and adjust the stores to dest.
 */
-void memcpy_fromio(void *dest, unsigned long src, int count)
+void __memcpy_fromio(unsigned long dest, unsigned long src, int count)
 {
 	/* first compare alignment of src/dst */ 
-	if ( (((unsigned long)dest ^ src) & 1) || (count < 2) )
+	if ( ((dest ^ src) & 1) || (count < 2) )
 		goto bytecopy;
 
-	if ( (((unsigned long)dest ^ src) & 2) || (count < 4) )
+	if ( ((dest ^ src) & 2) || (count < 4) )
 		goto shortcopy;
 
 	/* Then check for misaligned start address */
@@ -101,7 +101,7 @@
  * Assumes the device can cope with 32-bit transfers.  If it can't,
  * don't use this function.
  */
-void memset_io(unsigned long dest, char fill, int count)
+void __memset_io(unsigned long dest, char fill, int count)
 {
 	u32 fill32 = (fill << 24) | (fill << 16) | (fill << 8) | fill;
 	while (dest & 3) {
diff -Nru a/arch/parisc/math-emu/driver.c b/arch/parisc/math-emu/driver.c
--- a/arch/parisc/math-emu/driver.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/math-emu/driver.c	Mon Jan 13 21:59:51 2003
@@ -86,8 +86,12 @@
 	int signalcode;
 	/* need an intermediate copy of float regs because FPU emulation
 	 * code expects an artificial last entry which contains zero
+	 *
+	 * also, the passed in fr registers contain one word that defines
+	 * the fpu type. the fpu type information is constructed 
+	 * inside the emulation code
 	 */
-	__u64 frcopy[33];
+	__u64 frcopy[36];
 
 	memcpy(frcopy, regs->fr, sizeof regs->fr);
 	frcopy[32] = 0;
diff -Nru a/arch/parisc/math-emu/fpudispatch.c b/arch/parisc/math-emu/fpudispatch.c
--- a/arch/parisc/math-emu/fpudispatch.c	Mon Jan 13 21:59:48 2003
+++ b/arch/parisc/math-emu/fpudispatch.c	Mon Jan 13 21:59:48 2003
@@ -51,6 +51,7 @@
 
 #include "float.h"
 #include "types.h"
+#include <asm/processor.h>
 /* #include <sys/debug.h> */
 /* #include <machine/sys/mdep_private.h> */
 
@@ -166,6 +167,20 @@
 
 #define VASSERT(x)
 
+static void parisc_linux_get_fpu_type(u_int fpregs[])
+{
+	/* on pa-linux the fpu type is not filled in by the
+	 * caller; it is constructed here  
+	 */ 
+	if (boot_cpu_data.cpu_type == pcxs)
+		fpregs[FPU_TYPE_FLAG_POS] = TIMEX_EXTEN_FLAG;
+	else if (boot_cpu_data.cpu_type == pcxt ||
+	         boot_cpu_data.cpu_type == pcxt_)
+		fpregs[FPU_TYPE_FLAG_POS] = ROLEX_EXTEN_FLAG;
+	else if (boot_cpu_data.cpu_type >= pcxu)
+		fpregs[FPU_TYPE_FLAG_POS] = PA2_0_FPU_FLAG;
+}
+
 /*
  * this routine will decode the excepting floating point instruction and
  * call the approiate emulation routine.
@@ -183,6 +198,8 @@
 
 	/* All FP emulation code assumes that ints are 4-bytes in length */
 	VASSERT(sizeof(int) == 4);
+
+	parisc_linux_get_fpu_type(fpregs);
 
 	fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS];  /* get fpu type flags */
 
diff -Nru a/arch/parisc/mm/extable.c b/arch/parisc/mm/extable.c
--- a/arch/parisc/mm/extable.c	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/mm/extable.c	Mon Jan 13 21:59:49 2003
@@ -5,20 +5,12 @@
  * Copyright (C) 2000 John Marvin (jsm@fc.hp.com)
  */
 
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/ptrace.h>
 #include <asm/uaccess.h>
 
-
-extern const struct exception_table_entry __start___ex_table[];
-extern const struct exception_table_entry __stop___ex_table[];
-
-static inline const struct exception_table_entry *
-search_one_table (const struct exception_table_entry *first,
-		  const struct exception_table_entry *last,
-		  unsigned long addr)
+const struct exception_table_entry *
+search_extable(const struct exception_table_entry *first,
+	       const struct exception_table_entry *last,
+	       unsigned long addr)
 {
 	/* Abort early if the search value is out of range.  */
 
@@ -43,27 +35,3 @@
         return 0;
 }
 
-const struct exception_table_entry *
-search_exception_table (unsigned long addr)
-{
-#ifndef CONFIG_MODULES
-	/* There is only the kernel to search.  */
-	return search_one_table(__start___ex_table, 
-                                __stop___ex_table - 1, 
-                                addr);
-#else
-	/* The kernel is the last "module" -- no need to treat it special. */
-	struct module *mp;
-
-	for (mp = module_list; mp ; mp = mp->next) {
-		const struct exception_table_entry *ret;
-		if (!mp->ex_table_start)
-			continue;
-		ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1,
-				       addr);
-		if (ret)
-			return ret;
-	}
-	return 0;
-#endif
-}
diff -Nru a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
--- a/arch/parisc/mm/fault.c	Mon Jan 13 21:59:51 2003
+++ b/arch/parisc/mm/fault.c	Mon Jan 13 21:59:51 2003
@@ -15,6 +15,7 @@
 #include <linux/ptrace.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 #include <asm/traps.h>
@@ -230,7 +231,7 @@
 
 	if (!user_mode(regs)) {
 
-		fix = search_exception_table(regs->iaoq[0]);
+		fix = search_exception_tables(regs->iaoq[0]);
 
 		if (fix) {
 
diff -Nru a/arch/parisc/oprofile/Kconfig b/arch/parisc/oprofile/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/parisc/oprofile/Kconfig	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+	depends on EXPERIMENTAL
+
+config PROFILING
+	bool "Profiling support (EXPERIMENTAL)"
+	help
+	  Say Y here to enable the extended profiling support mechanisms used
+	  by profilers such as OProfile.
+	  
+
+config OPROFILE
+	tristate "OProfile system profiling (EXPERIMENTAL)"
+	depends on PROFILING
+	help
+	  OProfile is a profiling system capable of profiling the
+	  whole system, include the kernel, kernel modules, libraries,
+	  and applications.
+
+	  If unsure, say N.
+
+endmenu
+
diff -Nru a/arch/parisc/oprofile/Makefile b/arch/parisc/oprofile/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/parisc/oprofile/Makefile	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,8 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+		oprof.o cpu_buffer.o buffer_sync.o \
+		event_buffer.o oprofile_files.o \
+		oprofilefs.o oprofile_stats.o )
+
+oprofile-y				:= $(DRIVER_OBJS) init.o timer_int.o
diff -Nru a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/parisc/oprofile/init.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,20 @@
+/**
+ * @file init.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/oprofile.h>
+#include <linux/init.h>
+ 
+extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
+
+int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+{
+	timer_init(ops, cpu);
+	return 0;
+}
diff -Nru a/arch/parisc/oprofile/timer_int.c b/arch/parisc/oprofile/timer_int.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/parisc/oprofile/timer_int.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,56 @@
+/**
+ * @file timer_int.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/notifier.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/oprofile.h>
+#include <asm/ptrace.h>
+ 
+static int timer_notify(struct notifier_block * self, unsigned long val, void * data)
+{
+	struct pt_regs * regs = (struct pt_regs *)data;
+	int cpu = smp_processor_id();
+ 
+	oprofile_add_sample(regs->iaoq[0], 0, cpu);
+	return 0;
+}
+ 
+ 
+static struct notifier_block timer_notifier = {
+	.notifier_call	= timer_notify,
+};
+ 
+
+static int timer_start(void)
+{
+	return register_profile_notifier(&timer_notifier);
+}
+
+
+static void timer_stop(void)
+{
+	unregister_profile_notifier(&timer_notifier);
+}
+
+
+static struct oprofile_operations timer_ops = {
+	.start	= timer_start,
+	.stop	= timer_stop
+};
+
+ 
+void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+{
+	*ops = &timer_ops;
+	*cpu = OPROFILE_CPU_TIMER;
+	printk(KERN_INFO "oprofile: using timer interrupt.\n");
+}
diff -Nru a/arch/parisc/vmlinux.lds.S b/arch/parisc/vmlinux.lds.S
--- a/arch/parisc/vmlinux.lds.S	Mon Jan 13 21:59:49 2003
+++ b/arch/parisc/vmlinux.lds.S	Mon Jan 13 21:59:49 2003
@@ -72,6 +72,9 @@
   __setup_start = .;
   .init.setup : { *(.init.setup) }
   __setup_end = .;
+  __start___param =.; 
+  __param : { *(__param) }
+  __stop___param = .;
   __initcall_start = .;
   .initcall.init : {
 	*(.initcall1.init) 
diff -Nru a/arch/ppc/kernel/module.c b/arch/ppc/kernel/module.c
--- a/arch/ppc/kernel/module.c	Mon Jan 13 21:59:49 2003
+++ b/arch/ppc/kernel/module.c	Mon Jan 13 21:59:49 2003
@@ -197,14 +197,10 @@
 		/* This is where to make the change */
 		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
 			+ rela[i].r_offset;
-		/* This is the symbol it is referring to */
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
 		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
 			+ ELF32_R_SYM(rela[i].r_info);
-		if (!sym->st_value) {
-			printk(KERN_WARNING "%s: Unknown symbol %s\n",
-			       module->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
 		/* `Everything is relative'. */
 		value = sym->st_value + rela[i].r_addend;
 
diff -Nru a/arch/ppc64/kernel/ioctl32.c b/arch/ppc64/kernel/ioctl32.c
--- a/arch/ppc64/kernel/ioctl32.c	Mon Jan 13 21:59:51 2003
+++ b/arch/ppc64/kernel/ioctl32.c	Mon Jan 13 21:59:51 2003
@@ -3613,22 +3613,10 @@
 }	
 
 /* 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);
@@ -4459,9 +4447,6 @@
 HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb),
 HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal),
 /* take care of sizeof(sizeof()) breakage */
-/* elevator */
-HANDLE_IOCTL(BLKELVGET_32, do_blkelvget),
-HANDLE_IOCTL(BLKELVSET_32, do_blkelvset),
 /* block stuff */
 HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget),
 HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset),
diff -Nru a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
--- a/arch/s390/kernel/module.c	Mon Jan 13 21:59:51 2003
+++ b/arch/s390/kernel/module.c	Mon Jan 13 21:59:51 2003
@@ -1,5 +1,5 @@
 /*
- *  arch/s390x/kernel/module.c - Kernel module help for s390x.
+ *  arch/s390/kernel/module.c - Kernel module help for s390.
  *
  *  S390 version
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
@@ -77,14 +77,10 @@
 		/* This is where to make the change */
 		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
 			+ rel[i].r_offset;
-		/* This is the symbol it is referring to */
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
 		sym = (ElfW(Sym) *)sechdrs[symindex].sh_addr
 			+ ELFW(R_SYM)(rel[i].r_info);
-		if (!sym->st_value) {
-			printk(KERN_WARNING "%s: Unknown symbol %s\n",
-			       me->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
 
 		switch (ELF_R_TYPE(rel[i].r_info)) {
 		case R_390_8:		/* Direct 8 bit.   */
diff -Nru a/arch/s390x/kernel/ioctl32.c b/arch/s390x/kernel/ioctl32.c
--- a/arch/s390x/kernel/ioctl32.c	Mon Jan 13 21:59:51 2003
+++ b/arch/s390x/kernel/ioctl32.c	Mon Jan 13 21:59:51 2003
@@ -798,9 +798,6 @@
 	IOCTL32_DEFAULT(BLKBSZGET),
 	IOCTL32_DEFAULT(BLKGETSIZE64),
 
-	IOCTL32_DEFAULT(BLKELVGET),
-	IOCTL32_DEFAULT(BLKELVSET),
-
 	IOCTL32_HANDLER(HDIO_GETGEO, hd_geometry_ioctl),
 
 	IOCTL32_DEFAULT(TCGETA),
diff -Nru a/arch/s390x/kernel/module.c b/arch/s390x/kernel/module.c
--- a/arch/s390x/kernel/module.c	Mon Jan 13 21:59:51 2003
+++ b/arch/s390x/kernel/module.c	Mon Jan 13 21:59:51 2003
@@ -78,14 +78,10 @@
 		/* This is where to make the change */
 		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
 			+ rel[i].r_offset;
-		/* This is the symbol it is referring to */
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
 		sym = (ElfW(Sym) *)sechdrs[symindex].sh_addr
 			+ ELFW(R_SYM)(rel[i].r_info);
-		if (!sym->st_value) {
-			printk(KERN_WARNING "%s: Unknown symbol %s\n",
-			       me->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
 
 		switch (ELF_R_TYPE(rel[i].r_info)) {
 		case R_390_8:		/* Direct 8 bit.   */
diff -Nru a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c
--- a/arch/sparc/kernel/module.c	Mon Jan 13 21:59:49 2003
+++ b/arch/sparc/kernel/module.c	Mon Jan 13 21:59:49 2003
@@ -75,15 +75,11 @@
 		location = (u8 *)sechdrs[sechdrs[relsec].sh_info].sh_addr
 			+ rel[i].r_offset;
 		loc32 = (u32 *) location;
-		/* This is the symbol it is referring to */
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
 		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
 			+ ELF32_R_SYM(rel[i].r_info);
-		if (!(v = sym->st_value)) {
-			printk(KERN_WARNING "%s: Unknown symbol %s\n",
-			       me->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
-		v += rel[i].r_addend;
+		v = sym->st_value + rel[i].r_addend;
 
 		switch (ELF32_R_TYPE(rel[i].r_info)) {
 		case R_SPARC_32:
diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
--- a/arch/sparc64/kernel/ioctl32.c	Mon Jan 13 21:59:51 2003
+++ b/arch/sparc64/kernel/ioctl32.c	Mon Jan 13 21:59:51 2003
@@ -4244,22 +4244,10 @@
 }	
 
 /* 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);
@@ -5203,9 +5191,6 @@
 HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
 HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
 /* take care of sizeof(sizeof()) breakage */
-/* elevator */
-HANDLE_IOCTL(BLKELVGET_32, do_blkelvget)
-HANDLE_IOCTL(BLKELVSET_32, do_blkelvset)
 /* block stuff */
 HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
 HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
diff -Nru a/arch/sparc64/kernel/module.c b/arch/sparc64/kernel/module.c
--- a/arch/sparc64/kernel/module.c	Mon Jan 13 21:59:50 2003
+++ b/arch/sparc64/kernel/module.c	Mon Jan 13 21:59:50 2003
@@ -185,15 +185,11 @@
 
 		BUG_ON(((u64)location >> (u64)32) != (u64)0);
 
-		/* This is the symbol it is referring to */
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
 		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
 			+ ELF64_R_SYM(rel[i].r_info);
-		if (!(v = sym->st_value)) {
-			printk(KERN_WARNING "%s: Unknown symbol %s\n",
-			       me->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
-		v += rel[i].r_addend;
+		v = sym->st_value + rel[i].r_addend;
 
 		switch (ELF64_R_TYPE(rel[i].r_info) & 0xff) {
 		case R_SPARC_64:
diff -Nru a/arch/v850/Makefile b/arch/v850/Makefile
--- a/arch/v850/Makefile	Mon Jan 13 21:59:51 2003
+++ b/arch/v850/Makefile	Mon Jan 13 21:59:51 2003
@@ -1,8 +1,8 @@
 #
 # arch/v850/Makefile
 #
-#  Copyright (C) 2001,02  NEC Corporation
-#  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+#  Copyright (C) 2001,02,03  NEC Corporation
+#  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
 #
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
@@ -21,6 +21,11 @@
 CFLAGS += -ffixed-r16 -mno-prolog-function
 CFLAGS += -fno-builtin
 CFLAGS += -D__linux__ -DUTS_SYSNAME=\"uClinux\"
+
+# This prevents the linker from consolidating the .gnu.linkonce.this_module
+# section into .text (which the v850 default linker script for -r does for
+# some reason)
+LDFLAGS_MODULE += --unique=.gnu.linkonce.this_module
 
 LDFLAGS_BLOB := -b binary --oformat elf32-little
 OBJCOPY_FLAGS_BLOB := -I binary -O elf32-little -B v850e
diff -Nru a/arch/v850/kernel/module.c b/arch/v850/kernel/module.c
--- a/arch/v850/kernel/module.c	Mon Jan 13 21:59:49 2003
+++ b/arch/v850/kernel/module.c	Mon Jan 13 21:59:49 2003
@@ -184,19 +184,12 @@
 		uint32_t *loc
 			= ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
 			   + rela[i].r_offset);
-		/* This is the symbol it is referring to */
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
 		Elf32_Sym *sym
 			= ((Elf32_Sym *)sechdrs[symindex].sh_addr
 			   + ELF32_R_SYM (rela[i].r_info));
-		uint32_t val = sym->st_value;
-
-		if (! val) {
-			printk (KERN_WARNING "%s: Unknown symbol %s\n",
-				mod->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
-
-		val += rela[i].r_addend;
+		uint32_t val = sym->st_value + rela[i].r_addend;
 
 		switch (ELF32_R_TYPE (rela[i].r_info)) {
 		case R_V850_32:
diff -Nru a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c
--- a/arch/x86_64/ia32/ia32_ioctl.c	Mon Jan 13 21:59:50 2003
+++ b/arch/x86_64/ia32/ia32_ioctl.c	Mon Jan 13 21:59:50 2003
@@ -3025,22 +3025,10 @@
 } 
 
 /* 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);
@@ -4427,9 +4415,6 @@
 HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
 HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
 /* take care of sizeof(sizeof()) breakage */
-/* elevator */
-HANDLE_IOCTL(BLKELVGET_32, do_blkelvget)
-HANDLE_IOCTL(BLKELVSET_32, do_blkelvset)
 /* block stuff */
 HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget)
 HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset)
diff -Nru a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c
--- a/arch/x86_64/kernel/module.c	Mon Jan 13 21:59:51 2003
+++ b/arch/x86_64/kernel/module.c	Mon Jan 13 21:59:51 2003
@@ -53,14 +53,10 @@
 		loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
 			+ rel[i].r_offset;
 
-		/* This is the symbol it is referring to */
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
 		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
 			+ ELF64_R_SYM(rel[i].r_info);
-		if (!sym->st_value) {
-			printk(KERN_WARNING "%s: Unknown symbol %s\n",
-			       me->name, strtab + sym->st_name);
-			return -ENOENT;
-		}
 
 	        DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
 		       (int)ELF64_R_TYPE(rel[i].r_info), 
diff -Nru a/drivers/acorn/scsi/fas216.c b/drivers/acorn/scsi/fas216.c
--- a/drivers/acorn/scsi/fas216.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/acorn/scsi/fas216.c	Mon Jan 13 21:59:49 2003
@@ -1,5 +1,5 @@
 /*
- *  linux/arch/arm/drivers/scsi/fas216.c
+ *  linux/drivers/acorn/scsi/fas216.c
  *
  *  Copyright (C) 1997-2000 Russell King
  *
@@ -308,11 +308,12 @@
 
 static void fas216_done(FAS216_Info *info, unsigned int result);
 
-/* Function: int fas216_clockrate(unsigned int clock)
- * Purpose : calculate correct value to be written into clock conversion
- *	     factor register.
- * Params  : clock - clock speed in MHz
- * Returns : CLKF_ value
+/** 
+ * fast216_clockrate - calculate clock conversion factor
+ * @clock: clock speed in MHz
+ * 
+ * Calculate correct value to be written into clock conversion factor 
+ * register. Returns CLKF_ value.
  */
 static int fas216_clockrate(int clock)
 {
@@ -326,10 +327,12 @@
 	return clock;
 }
 
-/* Function: unsigned short fas216_get_last_msg(FAS216_Info *info, int pos)
- * Purpose : retrieve a last message from the list, using position in fifo
- * Params  : info - interface to search
- *         : pos  - current fifo position
+/** 
+ * fas216_get_last_msg - retrive last message from the list
+ * @info: interface to search
+ * @pos: current fifo position
+ * 
+ * Retrieve a last message from the list, using position in fifo.
  */
 static inline unsigned short
 fas216_get_last_msg(FAS216_Info *info, int pos)
@@ -356,12 +359,13 @@
 	return packed_msg;
 }
 
-/* Function: int fas216_syncperiod(FAS216_Info *info, int ns)
- * Purpose : Calculate value to be loaded into the STP register
- *           for a given period in ns
- * Params  : info - state structure for interface connected to device
- *         : ns   - period in ns (between subsequent bytes)
- * Returns : Value suitable for REG_STP
+/** 
+ * fas216_syncperiod - calculate STP register value
+ * @info: state structure for interface connected to device
+ * @ns: period in ns (between subsequent bytes)
+ * 
+ * Calculate value to be loaded into the STP register for a given period 
+ * in ns. Returns a value suitable for REG_STP.
  */
 static int fas216_syncperiod(FAS216_Info *info, int ns)
 {
@@ -377,10 +381,12 @@
 	return value & 31;
 }
 
-/* Function: void fas216_set_sync(FAS216_Info *info, int target)
- * Purpose : Correctly setup FAS216 chip for specified transfer period.
- * Params  : info   - state structure for interface
- *         : target - target
+/**  
+ * fas216_set_sync - setup FAS216 chip for specified transfer period.
+ * @info: state structure for interface connected to device 
+ * @target: target
+ * 
+ * Correctly setup FAS216 chip for specified transfer period.
  * Notes   : we need to switch the chip out of FASTSCSI mode if we have
  *           a transfer period >= 200ns - otherwise the chip will violate
  *           the SCSI timings.
@@ -419,10 +425,12 @@
  * we have synchronous transfers disabled for this device.
  */
 
-/* Function: void fas216_handlesync(FAS216_Info *info, char *msg)
- * Purpose : Handle a synchronous transfer message from the target
- * Params  : info - state structure for interface
- *         : msg  - message from target
+/**
+ * fas216_handlesync - Handle a synchronous transfer message
+ * @info: state structure for interface
+ * @ms: message from target
+ * 
+ * Handle a synchronous transfer message from the target
  */
 static void fas216_handlesync(FAS216_Info *info, char *msg)
 {
@@ -530,10 +538,12 @@
 	}
 }
 
-/* Function: void fas216_handlewide(FAS216_Info *info, char *msg)
- * Purpose : Handle a wide transfer message from the target
- * Params  : info - state structure for interface
- *         : msg  - message from target
+/** 
+ * fas216_handlewide - Handle a wide transfer message 
+ * @info: state structure for interface
+ * @msg: message from target
+ * 
+ * Handle a wide transfer message from the target
  */
 static void fas216_handlewide(FAS216_Info *info, char *msg)
 {
@@ -627,10 +637,12 @@
 	}
 }
 
-/* Function: void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
- * Purpose : update data pointers after transfer suspended/paused
- * Params  : info              - interface's local pointer to update
- *           bytes_transferred - number of bytes transferred
+/** 
+ * fas216_updateptrs - update data pointers after transfer suspended/paused
+ * @info: interface's local pointer to update
+ * @bytes_transferred: number of bytes transferred
+ * 
+ * Update data pointers after transfer suspended/paused
  */
 static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred)
 {
@@ -664,11 +676,13 @@
 		SCp->ptr = NULL;
 }
 
-/* Function: void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
- * Purpose : transfer data off of/on to card using programmed IO
- * Params  : info      - interface to transfer data to/from
- *           direction - direction to transfer data (DMA_OUT/DMA_IN)
- * Notes   : this is incredibly slow
+/**
+ * fas216_pio - transfer data off of/on to card using programmed IO
+ * @info: interface to transfer data to/from
+ * @direction: direction to transfer data (DMA_OUT/DMA_IN)
+ * 
+ * Transfer data off of/on to card using programmed IO.
+ * Notes: this is incredibly slow.
  */
 static void fas216_pio(FAS216_Info *info, fasdmadir_t direction)
 {
@@ -730,11 +744,12 @@
 	info->dma.transfer_type = fasdma_none;
 }
 
-/* Function: void fas216_starttransfer(FAS216_Info *info,
- *				       fasdmadir_t direction)
- * Purpose : Start a DMA/PIO transfer off of/on to card
- * Params  : info      - interface from which device disconnected from
- *           direction - transfer direction (DMA_OUT/DMA_IN)
+/** 
+ * fas216_starttransfer - Start a DMA/PIO transfer off of/on to card
+ * @info: interface from which device disconnected from
+ * @direction: transfer direction (DMA_OUT/DMA_IN)
+ * 
+ * Start a DMA/PIO transfer off of/on to card
  */
 static void fas216_starttransfer(FAS216_Info *info, fasdmadir_t direction)
 {
@@ -824,9 +839,11 @@
 	}
 }
 
-/* Function: void fas216_stoptransfer(FAS216_Info *info)
- * Purpose : Stop a DMA transfer onto / off of the card
- * Params  : info      - interface from which device disconnected from
+/** 
+ * fas216_stoptransfer - Stop a DMA transfer onto / off of the card
+ * @info: interface from which device disconnected from
+ * 
+ * Stop a DMA transfer onto / off of the card
  */
 static void fas216_stoptransfer(FAS216_Info *info)
 {
@@ -856,9 +873,11 @@
 	fas216_cmd(info, CMD_FLUSHFIFO);
 }
 
-/* Function: void fas216_disconnected_intr(FAS216_Info *info)
- * Purpose : handle device disconnection
- * Params  : info - interface from which device disconnected from
+/** 
+ * fas216_disconnected_intr - handle device disconnection
+ * @info: interface from which device disconnected from
+ * 
+ * Handle device disconnection
  */
 static void fas216_disconnect_intr(FAS216_Info *info)
 {
@@ -905,9 +924,11 @@
 	}
 }
 
-/* Function: void fas216_reselected_intr(FAS216_Info *info)
- * Purpose : Start reconnection of a device
- * Params  : info - interface which was reselected
+/** 
+ * fas216_reselected_intr - start reconnection of a device
+ * @info: interface which was reselected
+ * 
+ * Start reconnection of a device
  */
 static void
 fas216_reselected_intr(FAS216_Info *info)
@@ -1018,9 +1039,11 @@
 	fas216_cmd(info, CMD_MSGACCEPTED);
 }
 
-/* Function: void fas216_finish_reconnect(FAS216_Info *info)
- * Purpose : finish reconnection sequence for device
- * Params  : info - interface which caused function done interrupt
+/** 
+ * fas216_finish_reconnect - finish reconnection sequence for device
+ * @info: interface which caused function done interrupt
+ *
+ * Finish reconnection sequence for device
  */
 static void
 fas216_finish_reconnect(FAS216_Info *info)
@@ -1258,9 +1281,11 @@
 	return -3;
 }
 
-/* Function: void fas216_message(FAS216_Info *info)
- * Purpose : handle a function done interrupt from FAS216 chip
- * Params  : info - interface which caused function done interrupt
+/**
+ * fas216_message - handle a function done interrupt from FAS216 chip
+ * @info: interface which caused function done interrupt
+ * 
+ * Handle a function done interrupt from FAS216 chip
  */
 static void fas216_message(FAS216_Info *info)
 {
@@ -1326,9 +1351,11 @@
 	return;
 }
 
-/* Function: void fas216_send_command(FAS216_Info *info)
- * Purpose : send a command to a target after all message bytes have been sent
- * Params  : info - interface which caused bus service
+/**
+ * fas216_send_command - send command after all message bytes have been sent
+ * @info: interface which caused bus service
+ * 
+ * Send a command to a target after all message bytes have been sent
  */
 static void fas216_send_command(FAS216_Info *info)
 {
@@ -1348,10 +1375,12 @@
 	info->scsi.phase = PHASE_COMMAND;
 }
 
-/* Function: void fas216_send_messageout(FAS216_Info *info, int start)
- * Purpose : handle bus service to send a message
- * Params  : info - interface which caused bus service
- * Note    : We do not allow the device to change the data direction!
+/** 
+ * fas216_send_messageout - handle bus service to send a message
+ * @info: interface which caused bus service
+ * 
+ * Handle bus service to send a message.
+ * Note: We do not allow the device to change the data direction!
  */
 static void fas216_send_messageout(FAS216_Info *info, int start)
 {
@@ -1382,11 +1411,13 @@
 	info->scsi.phase = PHASE_MSGOUT;
 }
 
-/* Function: void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
- * Purpose : handle a bus service interrupt from FAS216 chip
- * Params  : info - interface which caused bus service interrupt
- *           stat - Status register contents
- *           ssr  - SCSI Status register contents
+/** 
+ * fas216_busservice_intr - handle bus service interrupt from FAS216 chip
+ * @info: interface which caused bus service interrupt
+ * @stat: Status register contents
+ * @ssr: SCSI Status register contents
+ * 
+ * Handle a bus service interrupt from FAS216 chip
  */
 static void fas216_busservice_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
 {
@@ -1589,11 +1620,13 @@
 	fas216_done(info, DID_ERROR);
 }
 
-/* Function: void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
- * Purpose : handle a function done interrupt from FAS216 chip
- * Params  : info - interface which caused function done interrupt
- *           stat - Status register contents
- *           ssr  - SCSI Status register contents
+/**
+ * fas216_funcdone_intr - handle a function done interrupt from FAS216 chip
+ * @info: interface which caused function done interrupt
+ * @stat: Status register contents
+ * @ssr: SCSI Status register contents
+ * 
+ * Handle a function done interrupt from FAS216 chip
  */
 static void fas216_funcdone_intr(FAS216_Info *info, unsigned int stat, unsigned int ssr)
 {
@@ -1681,9 +1714,11 @@
 	wake_up(&info->eh_wait);
 }
 
-/* Function: void fas216_intr(struct Scsi_Host *instance)
- * Purpose : handle interrupts from the interface to progress a command
- * Params  : instance - interface to service
+/** 
+ * fas216_intr - handle interrupts to progress a command
+ * @instance: interface to service
+ * 
+ * Handle interrupts from the interface to progress a command
  */
 void fas216_intr(struct Scsi_Host *instance)
 {
@@ -1954,10 +1989,12 @@
 	fas216_cmd(info, CMD_SELECTATNSTOP);
 }
 
-/* Function: void fas216_kick(FAS216_Info *info)
- * Purpose : kick a command to the interface - interface should be idle
- * Params  : info - our host interface to kick
- * Notes   : Interrupts are always disabled!
+/**
+ * fas216_kick - kick a command to the interface
+ * @info: our host interface to kick
+ * 
+ * kick a command to the interface, interface should be idle.
+ * Notes: Interrupts are always disabled!
  */
 static void fas216_kick(FAS216_Info *info)
 {
@@ -2052,11 +2089,13 @@
 	wake_up(&info->eh_wait);
 }
 
-/* Function: void fas216_rq_sns_done(info, SCpnt, result)
- * Purpose : Finish processing automatic request sense command
- * Params  : info   - interface that completed
- *	     SCpnt  - command that completed
- *	     result - driver byte of result
+/**
+ * fas216_rq_sns_done - Finish processing automatic request sense command
+ * @info: interface that completed
+ * @SCpnt: command that completed
+ * @result: driver byte of result
+ * 
+ * Finish processing automatic request sense command
  */
 static void
 fas216_rq_sns_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
@@ -2083,11 +2122,13 @@
 	SCpnt->scsi_done(SCpnt);
 }
 
-/* Function: void fas216_std_done(info, SCpnt, result)
- * Purpose : Finish processing of standard command
- * Params  : info   - interface that completed
- *	     SCpnt  - command that completed
- *	     result - driver byte of result
+/**
+ * fas216_std_done - finish processing of standard command
+ * @info: interface that completed
+ * @SCpnt: command that completed
+ * @result: driver byte of result
+ * 
+ * Finish processing of standard command
  */
 static void
 fas216_std_done(FAS216_Info *info, Scsi_Cmnd *SCpnt, unsigned int result)
@@ -2188,10 +2229,12 @@
 	info->reqSCpnt = SCpnt;
 }
 
-/* Function: void fas216_done(FAS216_Info *info, unsigned int result)
- * Purpose : complete processing for current command
- * Params  : info   - interface that completed
- *	     result - driver byte of result
+/**
+ * fas216_done - complete processing for current command
+ * @info: interface that completed
+ * @result: driver byte of result
+ * 
+ * Complete processing for current command
  */
 static void fas216_done(FAS216_Info *info, unsigned int result)
 {
@@ -2251,12 +2294,14 @@
 		info->host->host_no);
 }
 
-/* Function: int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
- * Purpose : queue a command for adapter to process.
- * Params  : SCpnt - Command to queue
- *	     done  - done function to call once command is complete
- * Returns : 0 - success, else error
- * Notes   : io_request_lock is held, interrupts are disabled.
+/**
+ * fas216_queue_command - queue a command for adapter to process.
+ * @SCpnt: Command to queue
+ * @done: done function to call once command is complete
+ * 
+ * Queue a command for adapter to process.
+ * Returns: 0 in success, else error. 
+ * Notes: io_request_lock is held, interrupts are disabled.
  */
 int fas216_queue_command(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
@@ -2304,9 +2349,11 @@
 	return result;
 }
 
-/* Function: void fas216_internal_done(Scsi_Cmnd *SCpnt)
- * Purpose : trigger restart of a waiting thread in fas216_command
- * Params  : SCpnt - Command to wake
+/**
+ * fas216_internal_done - trigger restart of a waiting thread in fas216_command
+ * @SCpnt: Command to wake
+ * 
+ * Trigger restart of a waiting thread in fas216_command
  */
 static void fas216_internal_done(Scsi_Cmnd *SCpnt)
 {
@@ -2317,11 +2364,13 @@
 	info->internal_done = 1;
 }
 
-/* Function: int fas216_command(Scsi_Cmnd *SCpnt)
- * Purpose : queue a command for adapter to process.
- * Params  : SCpnt - Command to queue
- * Returns : scsi result code
- * Notes   : io_request_lock is held, interrupts are disabled.
+/**
+ * fas216_command - queue a command for adapter to process.
+ * @SCpnt:  Command to queue
+ * 
+ * Qqueue a command for adapter to process.
+ * Returns: scsi result code.
+ * Notes: io_request_lock is held, interrupts are disabled.
  */
 int fas216_command(Scsi_Cmnd *SCpnt)
 {
@@ -2394,11 +2443,12 @@
 	res_hw_abort		/* command on disconnected dev	*/
 };
 
-/*
- * Prototype: enum res_find fas216_do_abort(FAS216_Info *info, Scsi_Cmnd *SCpnt)
- * Purpose  : decide how to abort a command
- * Params   : SCpnt - command to abort
- * Returns  : abort status
+/**
+ * fas216_do_abort - decide how to abort a command
+ * @SCpnt: command to abort
+ * 
+ * Decide how to abort a command.
+ * Returns: abort status
  */
 static enum res_find fas216_find_command(FAS216_Info *info, Scsi_Cmnd *SCpnt)
 {
@@ -2459,11 +2509,13 @@
 	return res;
 }
 
-/* Function: int fas216_eh_abort(Scsi_Cmnd *SCpnt)
- * Purpose : abort this command
- * Params  : SCpnt - command to abort
- * Returns : FAILED if unable to abort
- * Notes   : io_request_lock is taken, and irqs are disabled
+/**
+ * fas216_eh_abort - abort this command
+ * @SCpnt: command to abort
+ * 
+ * Abort this command.
+ * Returns: FAILED if unable to abort
+ * Notes: io_request_lock is taken, and irqs are disabled
  */
 int fas216_eh_abort(Scsi_Cmnd *SCpnt)
 {
@@ -2513,12 +2565,14 @@
 	return result;
 }
 
-/* Function: int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
- * Purpose : Reset the device associated with this command
- * Params  : SCpnt - command specifing device to reset
- * Returns : FAILED if unable to reset
- * Notes   : We won't be re-entered, so we'll only have one device
- *           reset on the go at one time.
+/**
+ * fas216_eh_device_reset - Reset the device associated with this command
+ * @SCpnt:  command specifing device to reset
+ * 
+ * Reset the device associated with this command.
+ * Returns: FAILED if unable to reset.
+ * Notes: We won't be re-entered, so we'll only have one device
+ *        reset on the go at one time.
  */
 int fas216_eh_device_reset(Scsi_Cmnd *SCpnt)
 {
@@ -2593,11 +2647,13 @@
 	return res;
 }
 
-/* Function: int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
- * Purpose : Reset the bus associated with the command
- * Params  : SCpnt - command specifing bus to reset
- * Returns : FAILED if unable to reset
- * Notes   : Further commands are blocked.
+/**
+ * fas216_eh_bus_reset - Reset the bus associated with the command
+ * @SCpnt: command specifing bus to reset
+ * 
+ * Reset the bus associated with the command.
+ * Returns: FAILED if unable to reset.
+ * Notes: Further commands are blocked.
  */
 int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt)
 {
@@ -2670,9 +2726,11 @@
 	return info->rst_bus_status == 1 ? SUCCESS : FAILED;
 }
 
-/* Function: void fas216_init_chip(FAS216_Info *info)
- * Purpose : Initialise FAS216 state after reset
- * Params  : info - state structure for interface
+/**
+ * fas216_init_chip - Initialise FAS216 state after reset
+ * @info:  state structure for interface
+ * 
+ * Initialise FAS216 state after reset
  */
 static void fas216_init_chip(FAS216_Info *info)
 {
@@ -2686,11 +2744,13 @@
 	outb(info->scsi.cfg[0], REG_CNTL1(info));
 }
 
-/* Function: int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
- * Purpose : Reset the host associated with this command
- * Params  : SCpnt - command specifing host to reset
- * Returns : FAILED if unable to reset
- * Notes   : io_request_lock is taken, and irqs are disabled
+/**
+ * fas216_eh_host_reset - Reset the host associated with this command
+ * @SCpnt: command specifing host to reset
+ * 
+ * Reset the host associated with this command.
+ * Returns: FAILED if unable to reset.
+ * Notes: io_request_lock is taken, and irqs are disabled
  */
 int fas216_eh_host_reset(Scsi_Cmnd *SCpnt)
 {
@@ -2826,9 +2886,11 @@
 	return TYPE_NCR53C9x;
 }
 
-/* Function: void fas216_reset_state(FAS216_Info *info)
- * Purpose : Initialise driver internal state
- * Params  : info - state to initialise
+/** 
+ * fas216_reset_state - Initialise driver internal state
+ * @info: state to initialise
+ * 
+ * Initialise driver internal state
  */
 static void fas216_reset_state(FAS216_Info *info)
 {
@@ -2864,10 +2926,12 @@
 	info->origSCpnt = NULL;
 }
 
-/* Function: int fas216_init(struct Scsi_Host *instance)
- * Purpose : initialise FAS/NCR/AMD SCSI ic.
- * Params  : instance - a driver-specific filled-out structure
- * Returns : 0 on success
+/**
+ * fas216_init - initialise FAS/NCR/AMD SCSI ic.
+ * @instance: a driver-specific filled-out structure
+ * 
+ * Initialise FAS/NCR/AMD SCSI ic.
+ * Returns: 0 on success
  */
 int fas216_init(struct Scsi_Host *instance)
 {
@@ -2937,11 +3001,12 @@
 	return 0;
 }
 
-/* Function: int fas216_release(struct Scsi_Host *instance)
- * Purpose : release all resources and put everything to bed for
- *           FAS/NCR/AMD SCSI ic.
- * Params  : instance - a driver-specific filled-out structure
- * Returns : 0 on success
+/**
+ * fas216_release - release all resources for FAS/NCR/AMD SCSI ic.
+ * @instance: a driver-specific filled-out structure
+ * 
+ * release all resources and put everything to bed for FAS/NCR/AMD SCSI ic,
+ * Returns: 0 on success.
  */
 int fas216_release(struct Scsi_Host *instance)
 {
@@ -2956,13 +3021,13 @@
 	return 0;
 }
 
-/*
- * Function: int fas216_info(FAS216_Info *info, char *buffer)
- * Purpose : generate a string containing information about this
- *	     host.
- * Params  : info   - FAS216 host information
- *	     buffer - string buffer to build string
- * Returns : size of built string
+/**
+ * fas216_info - generate a string containing information about host.
+ * @info: FAS216 host information
+ * @buffer: string buffer to build string
+ * 
+ * Generate a string containing information about this host.
+ * Returns: size of built string
  */
 int fas216_info(FAS216_Info *info, char *buffer)
 {
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/acpi/processor.c	Mon Jan 13 21:59:50 2003
@@ -1823,6 +1823,9 @@
 
 	driver->verify      = &acpi_cpufreq_verify;
 	driver->setpolicy   = &acpi_cpufreq_setpolicy;
+	driver->init        = NULL;
+	driver->exit        = NULL;
+	strncpy(driver->name, "acpi-processor", CPUFREQ_NAME_LEN);
 
 	for (i=0;i<NR_CPUS;i++) {
 		driver->policy[i].cpu    = pr->id;
diff -Nru a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
--- a/drivers/atm/ambassador.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/atm/ambassador.c	Mon Jan 13 21:59:49 2003
@@ -2439,7 +2439,7 @@
 	    " IO %x, IRQ %u, MEM %p", iobase, irq, membase);
     
     // check IO region
-    if (check_region (iobase, AMB_EXTENT)) {
+    if (!request_region (iobase, AMB_EXTENT, DEV_LABEL)) {
       PRINTK (KERN_ERR, "IO range already in use!");
       return;
     }
@@ -2448,6 +2448,7 @@
     if (!dev) {
       // perhaps we should be nice: deregister all adapters and abort?
       PRINTK (KERN_ERR, "out of memory!");
+      release_region (iobase, AMB_EXTENT);
       return;
     }
     
@@ -2465,9 +2466,6 @@
 	// free_irq is at "endif"
       } else {
 	
-	// reserve IO region
-	request_region (iobase, AMB_EXTENT, DEV_LABEL);
-	
 	dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
 	if (!dev->atm_dev) {
 	  PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
@@ -2499,14 +2497,14 @@
 	  atm_dev_deregister (dev->atm_dev);
 	} /* atm_dev_register */
 	
-	release_region (iobase, AMB_EXTENT);
 	free_irq (irq, dev);
-      } /* request_region, request_irq */
+      } /* request_irq */
       
       amb_reset (dev, 0);
     } /* amb_init */
     
     kfree (dev);
+    release_region (iobase, AMB_EXTENT);
   } /* kmalloc, end-of-fn */
   
   PRINTD (DBG_FLOW, "amb_probe");
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/base/bus.c	Mon Jan 13 21:59:49 2003
@@ -43,14 +43,15 @@
 }
 
 static ssize_t
-drv_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf)
+drv_attr_store(struct kobject * kobj, struct attribute * attr, 
+	       const char * buf, size_t count)
 {
 	struct driver_attribute * drv_attr = to_drv_attr(attr);
 	struct device_driver * drv = to_driver(kobj);
 	ssize_t ret = 0;
 
 	if (drv_attr->store)
-		ret = drv_attr->store(drv,buf);
+		ret = drv_attr->store(drv,buf,count);
 	return ret;
 }
 
@@ -90,14 +91,15 @@
 }
 
 static ssize_t
-bus_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf)
+bus_attr_store(struct kobject * kobj, struct attribute * attr, 
+	       const char * buf, size_t count)
 {
 	struct bus_attribute * bus_attr = to_bus_attr(attr);
 	struct bus_type * bus = to_bus(kobj);
 	ssize_t ret = 0;
 
 	if (bus_attr->store)
-		ret = bus_attr->store(bus,buf);
+		ret = bus_attr->store(bus,buf,count);
 	return ret;
 }
 
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/base/class.c	Mon Jan 13 21:59:51 2003
@@ -26,14 +26,15 @@
 }
 
 static ssize_t
-devclass_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf)
+devclass_attr_store(struct kobject * kobj, struct attribute * attr, 
+		    const char * buf, size_t count)
 {
 	struct devclass_attribute * class_attr = to_class_attr(attr);
 	struct device_class * dc = to_class(kobj);
 	ssize_t ret = 0;
 
 	if (class_attr->store)
-		ret = class_attr->store(dc,buf);
+		ret = class_attr->store(dc,buf,count);
 	return ret;
 }
 
diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/base/core.c	Mon Jan 13 21:59:49 2003
@@ -47,14 +47,15 @@
 }
 
 static ssize_t
-dev_attr_store(struct kobject * kobj, struct attribute * attr, const char * buf)
+dev_attr_store(struct kobject * kobj, struct attribute * attr, 
+	       const char * buf, size_t count)
 {
 	struct device_attribute * dev_attr = to_dev_attr(attr);
 	struct device * dev = to_dev(kobj);
 	ssize_t ret = 0;
 
 	if (dev_attr->store)
-		ret = dev_attr->store(dev,buf);
+		ret = dev_attr->store(dev,buf,count);
 	return ret;
 }
 
diff -Nru a/drivers/base/interface.c b/drivers/base/interface.c
--- a/drivers/base/interface.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/base/interface.c	Mon Jan 13 21:59:49 2003
@@ -24,7 +24,7 @@
 }
 
 static ssize_t
-device_write_power(struct device * dev, const char * buf)
+device_write_power(struct device * dev, const char * buf, size_t count)
 {
 	char	str_command[20];
 	char	str_level[20];
@@ -80,7 +80,7 @@
 			error = 0;
 	}
  done:
-	return error < 0 ? error : strlen(buf);
+	return error < 0 ? error : count;
 }
 
 static DEVICE_ATTR(power,S_IWUSR | S_IRUGO,
diff -Nru a/drivers/base/node.c b/drivers/base/node.c
--- a/drivers/base/node.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/base/node.c	Mon Jan 13 21:59:49 2003
@@ -36,29 +36,27 @@
 static DEVICE_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
 
 #define K(x) ((x) << (PAGE_SHIFT - 10))
-static ssize_t node_read_meminfo(struct device * dev, char * buf, size_t count, loff_t off)
+static ssize_t node_read_meminfo(struct device * dev, char * buf)
 {
 	struct sys_root *node = to_root(dev);
 	int nid = node->id;
 	struct sysinfo i;
 	si_meminfo_node(&i, nid);
-	return off ? 0 : sprintf(buf, "\n"
-			"Node %d MemTotal:     %8lu kB\n"
-			"Node %d MemFree:      %8lu kB\n"
-			"Node %d MemUsed:      %8lu kB\n"
-			"Node %d HighTotal:    %8lu kB\n"
-			"Node %d HighFree:     %8lu kB\n"
-			"Node %d LowTotal:     %8lu kB\n"
-			"Node %d LowFree:      %8lu kB\n",
-			nid, K(i.totalram),
-			nid, K(i.freeram),
-			nid, K(i.totalram-i.freeram),
-			nid, K(i.totalhigh),
-			nid, K(i.freehigh),
-			nid, K(i.totalram-i.totalhigh),
-			nid, K(i.freeram-i.freehigh));
-
-	return 0;
+	return sprintf(buf, "\n"
+		       "Node %d MemTotal:     %8lu kB\n"
+		       "Node %d MemFree:      %8lu kB\n"
+		       "Node %d MemUsed:      %8lu kB\n"
+		       "Node %d HighTotal:    %8lu kB\n"
+		       "Node %d HighFree:     %8lu kB\n"
+		       "Node %d LowTotal:     %8lu kB\n"
+		       "Node %d LowFree:      %8lu kB\n",
+		       nid, K(i.totalram),
+		       nid, K(i.freeram),
+		       nid, K(i.totalram-i.freeram),
+		       nid, K(i.totalhigh),
+		       nid, K(i.freehigh),
+		       nid, K(i.totalram-i.totalhigh),
+		       nid, K(i.freeram-i.freehigh));
 }
 #undef K 
 static DEVICE_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL);
diff -Nru a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
--- a/drivers/block/deadline-iosched.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/block/deadline-iosched.c	Mon Jan 13 21:59:51 2003
@@ -17,26 +17,24 @@
 #include <linux/init.h>
 #include <linux/compiler.h>
 #include <linux/hash.h>
+#include <linux/rbtree.h>
 
 /*
- * feel free to try other values :-). read_expire value is the timeout for
- * reads, our goal is to start a request "around" the time when it expires.
- * fifo_batch is how many steps along the sorted list we will take when the
- * front fifo request expires.
+ * See Documentation/deadline-iosched.txt
  */
-static int read_expire = HZ / 2;	/* 500ms start timeout */
-static int fifo_batch = 16;
-static int seek_cost = 16;		/* seek is 16 times more expensive */
+static int read_expire = HZ / 2;  /* max time before a read is submitted. */
+static int write_expire = 5 * HZ; /* ditto for writes, these limits are SOFT! */
+static int writes_starved = 2;    /* max times reads can starve a write */
+static int fifo_batch = 16;       /* # of sequential requests treated as one
+				     by the above parameters. For throughput. */
 
-/*
- * how many times reads are allowed to starve writes
- */
-static int writes_starved = 2;
-
-static const int deadline_hash_shift = 8;
+static const int deadline_hash_shift = 10;
 #define DL_HASH_BLOCK(sec)	((sec) >> 3)
 #define DL_HASH_FN(sec)		(hash_long(DL_HASH_BLOCK((sec)), deadline_hash_shift))
 #define DL_HASH_ENTRIES		(1 << deadline_hash_shift)
+#define rq_hash_key(rq)		((rq)->sector + (rq)->nr_sectors)
+#define list_entry_hash(ptr)	list_entry((ptr), struct deadline_rq, hash)
+#define ON_HASH(drq)		(drq)->hash_valid_count
 
 #define DL_INVALIDATE_HASH(dd)				\
 	do {						\
@@ -48,31 +46,55 @@
 	/*
 	 * run time data
 	 */
-	struct list_head sort_list[2];	/* sorted listed */
-	struct list_head read_fifo;	/* fifo list */
+
+	/*
+	 * requests (deadline_rq s) are present on both sort_list and fifo_list
+	 */
+	struct rb_root sort_list[2];	
+	struct list_head fifo_list[2];
+	
+	/*
+	 * next in sort order. read, write or both are NULL
+	 */
+	struct deadline_rq *next_drq[2];
 	struct list_head *dispatch;	/* driver dispatch queue */
 	struct list_head *hash;		/* request hash */
-	sector_t last_sector;		/* last sector sent to drive */
 	unsigned long hash_valid_count;	/* barrier hash count */
-	unsigned int starved;		/* writes starved */
+	unsigned int batching;		/* number of sequential requests made */
+	sector_t last_sector;		/* head position */
+	unsigned int starved;		/* times reads have starved writes */
 
 	/*
 	 * settings that change how the i/o scheduler behaves
 	 */
-	unsigned int fifo_batch;
-	unsigned long read_expire;
-	unsigned int seek_cost;
-	unsigned int writes_starved;
+	int fifo_expire[2];
+	int fifo_batch;
+	int writes_starved;
+	int front_merges;
 };
 
 /*
  * pre-request data.
  */
 struct deadline_rq {
-	struct list_head fifo;
+	/*
+	 * rbtree index, key is the starting offset
+	 */
+	struct rb_node rb_node;
+	sector_t rb_key;
+
+	struct request *request;
+
+	/*
+	 * request hash, key is the ending offset (for back merge lookup)
+	 */
 	struct list_head hash;
 	unsigned long hash_valid_count;
-	struct request *request;
+
+	/*
+	 * expire fifo
+	 */
+	struct list_head fifo;
 	unsigned long expires;
 };
 
@@ -81,159 +103,257 @@
 #define RQ_DATA(rq)	((struct deadline_rq *) (rq)->elevator_private)
 
 /*
- * rq hash
+ * the back merge hash support functions
  */
-static inline void __deadline_del_rq_hash(struct deadline_rq *drq)
+static inline void __deadline_del_drq_hash(struct deadline_rq *drq)
 {
 	drq->hash_valid_count = 0;
 	list_del_init(&drq->hash);
 }
 
-#define ON_HASH(drq)	(drq)->hash_valid_count
-static inline void deadline_del_rq_hash(struct deadline_rq *drq)
+static inline void deadline_del_drq_hash(struct deadline_rq *drq)
 {
 	if (ON_HASH(drq))
-		__deadline_del_rq_hash(drq);
+		__deadline_del_drq_hash(drq);
 }
 
 static inline void
-deadline_add_rq_hash(struct deadline_data *dd, struct deadline_rq *drq)
+deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
 {
 	struct request *rq = drq->request;
 
 	BUG_ON(ON_HASH(drq));
 
 	drq->hash_valid_count = dd->hash_valid_count;
-	list_add(&drq->hash, &dd->hash[DL_HASH_FN(rq->sector +rq->nr_sectors)]);
+	list_add(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]);
 }
 
-#define list_entry_hash(ptr)	list_entry((ptr), struct deadline_rq, hash)
 static struct request *
-deadline_find_hash(struct deadline_data *dd, sector_t offset)
+deadline_find_drq_hash(struct deadline_data *dd, sector_t offset)
 {
 	struct list_head *hash_list = &dd->hash[DL_HASH_FN(offset)];
 	struct list_head *entry, *next = hash_list->next;
-	struct deadline_rq *drq;
-	struct request *rq = NULL;
 
 	while ((entry = next) != hash_list) {
+		struct deadline_rq *drq = list_entry_hash(entry);
+		struct request *__rq = drq->request;
+
 		next = entry->next;
 		
-		drq = list_entry_hash(entry);
+		BUG_ON(!ON_HASH(drq));
 
-		BUG_ON(!drq->hash_valid_count);
-
-		if (!rq_mergeable(drq->request)
+		if (!rq_mergeable(__rq)
 		    || drq->hash_valid_count != dd->hash_valid_count) {
-			__deadline_del_rq_hash(drq);
+			__deadline_del_drq_hash(drq);
 			continue;
 		}
 
-		if (drq->request->sector + drq->request->nr_sectors == offset) {
-			rq = drq->request;
-			break;
-		}
+		if (rq_hash_key(__rq) == offset)
+			return __rq;
 	}
 
-	return rq;
+	return NULL;
 }
 
-static sector_t deadline_get_last_sector(struct deadline_data *dd)
+/*
+ * rb tree support functions
+ */
+#define RB_NONE		(2)
+#define RB_EMPTY(root)	((root)->rb_node == NULL)
+#define ON_RB(node)	((node)->rb_color != RB_NONE)
+#define RB_CLEAR(node)	((node)->rb_color = RB_NONE)
+#define rb_entry_drq(node)	rb_entry((node), struct deadline_rq, rb_node)
+#define DRQ_RB_ROOT(dd, drq)	(&(dd)->sort_list[rq_data_dir((drq)->request)])
+#define rq_rb_key(rq)		(rq)->sector
+
+static struct deadline_rq *
+__deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
+{
+	struct rb_node **p = &DRQ_RB_ROOT(dd, drq)->rb_node;
+	struct rb_node *parent = NULL;
+	struct deadline_rq *__drq;
+
+	while (*p) {
+		parent = *p;
+		__drq = rb_entry_drq(parent);
+
+		if (drq->rb_key < __drq->rb_key)
+			p = &(*p)->rb_left;
+		else if (drq->rb_key > __drq->rb_key)
+			p = &(*p)->rb_right;
+		else
+			return __drq;
+	}
+
+	rb_link_node(&drq->rb_node, parent, p);
+	return 0;
+}
+
+static int
+deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
 {
-	sector_t last_sec = dd->last_sector;
+	struct deadline_rq *__alias;
+
+	drq->rb_key = rq_rb_key(drq->request);
+
+	__alias = __deadline_add_drq_rb(dd, drq);
+	if (!__alias) {
+		rb_insert_color(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
+		return 0;
+	}
 
 	/*
-	 * if dispatch is non-empty, disregard last_sector and check last one
+	 * this should not typically happen, but if it does simply chain
+	 * the two requests. then they will be moved to the dispatch list
+	 * at the same time
 	 */
-	if (!list_empty(dd->dispatch)) {
-		struct request *__rq = list_entry_rq(dd->dispatch->prev);
+	list_add(&drq->request->queuelist, &__alias->request->queuelist);
+	return 1;
+}
+
+static inline void
+deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
+{
+	const int data_dir = rq_data_dir(drq->request);
 
-		last_sec = __rq->sector + __rq->nr_sectors;
+	if (dd->next_drq[data_dir] == drq) {
+		struct rb_node *rbnext = rb_next(&drq->rb_node);
+
+		dd->next_drq[data_dir] = NULL;
+		if (rbnext)
+			dd->next_drq[data_dir] = rb_entry_drq(rbnext);
+	}
+
+	if (ON_RB(&drq->rb_node)) {
+		rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
+		RB_CLEAR(&drq->rb_node);
 	}
+}
 
-	return last_sec;
+static struct request *
+deadline_find_drq_rb(struct deadline_data *dd, sector_t sector, int data_dir)
+{
+	struct rb_node *n = dd->sort_list[data_dir].rb_node;
+	struct deadline_rq *drq;
+
+	while (n) {
+		drq = rb_entry_drq(n);
+
+		if (sector < drq->rb_key)
+			n = n->rb_left;
+		else if (sector > drq->rb_key)
+			n = n->rb_right;
+		else
+			return drq->request;
+	}
+
+	return NULL;
+}
+
+/*
+ * deadline_find_first_drq finds the first (lowest sector numbered) request
+ * for the specified data_dir. Used to sweep back to the start of the disk
+ * (1-way elevator) after we process the last (highest sector) request.
+ */
+static struct deadline_rq *
+deadline_find_first_drq(struct deadline_data *dd, int data_dir)
+{
+	struct rb_node *n = dd->sort_list[data_dir].rb_node;
+
+	for (;;) {
+		if (n->rb_left == NULL)
+			return rb_entry_drq(n);
+		
+		n = n->rb_left;
+	}
+}
+
+/*
+ * add drq to rbtree and fifo
+ */
+static inline void
+deadline_add_request(struct deadline_data *dd, struct deadline_rq *drq)
+{
+	const int data_dir = rq_data_dir(drq->request);
+
+	if (!deadline_add_drq_rb(dd, drq)) {
+		/*
+		 * set expire time (only used for reads) and add to fifo list
+		 */
+		drq->expires = jiffies + dd->fifo_expire[data_dir];
+		list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]);
+	}
+}
+
+/*
+ * remove rq from rbtree, fifo, and hash
+ */
+static void deadline_remove_request(request_queue_t *q, struct request *rq)
+{
+	struct deadline_rq *drq = RQ_DATA(rq);
+
+	if (drq) {
+		struct deadline_data *dd = q->elevator.elevator_data;
+
+		list_del_init(&drq->fifo);
+		deadline_del_drq_hash(drq);
+		deadline_del_drq_rb(dd, drq);
+	}
+
+	list_del_init(&rq->queuelist);
 }
 
 static int
 deadline_merge(request_queue_t *q, struct list_head **insert, struct bio *bio)
 {
 	struct deadline_data *dd = q->elevator.elevator_data;
-	const int data_dir = bio_data_dir(bio);
-	struct list_head *entry, *sort_list;
 	struct request *__rq;
-	int ret = ELEVATOR_NO_MERGE;
+	int ret;
 
 	/*
 	 * try last_merge to avoid going to hash
 	 */
 	ret = elv_try_last_merge(q, bio);
 	if (ret != ELEVATOR_NO_MERGE) {
-		*insert = q->last_merge;
-		goto out;
+		__rq = list_entry_rq(q->last_merge);
+		goto out_insert;
 	}
 
 	/*
 	 * see if the merge hash can satisfy a back merge
 	 */
-	if ((__rq = deadline_find_hash(dd, bio->bi_sector))) {
+	__rq = deadline_find_drq_hash(dd, bio->bi_sector);
+	if (__rq) {
 		BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
 
 		if (elv_rq_merge_ok(__rq, bio)) {
-			*insert = &__rq->queuelist;
 			ret = ELEVATOR_BACK_MERGE;
 			goto out;
 		}
 	}
 
 	/*
-	 * scan list from back to find insertion point.
+	 * check for front merge
 	 */
-	entry = sort_list = &dd->sort_list[data_dir];
-	while ((entry = entry->prev) != sort_list) {
-		__rq = list_entry_rq(entry);
-
-		BUG_ON(__rq->flags & REQ_STARTED);
-
-		if (!(__rq->flags & REQ_CMD))
-			continue;
-
-		/*
-		 * it's not necessary to break here, and in fact it could make
-		 * us loose a front merge. emperical evidence shows this to
-		 * be a big waste of cycles though, so quit scanning
-		 */
-		if (!*insert && bio_rq_in_between(bio, __rq, sort_list)) {
-			*insert = &__rq->queuelist;
-			break;
-		}
-
-		if (__rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER))
-			break;
+	if (dd->front_merges) {
+		sector_t rb_key = bio->bi_sector + bio_sectors(bio);
 
-		/*
-		 * checking for a front merge, hash will miss those
-		 */
-		if (__rq->sector - bio_sectors(bio) == bio->bi_sector) {
-			ret = elv_try_merge(__rq, bio);
-			if (ret != ELEVATOR_NO_MERGE) {
-				*insert = &__rq->queuelist;
-				break;
+		__rq = deadline_find_drq_rb(dd, rb_key, bio_data_dir(bio));
+		if (__rq) {
+			BUG_ON(rb_key != rq_rb_key(__rq));
+
+			if (elv_rq_merge_ok(__rq, bio)) {
+				ret = ELEVATOR_FRONT_MERGE;
+				goto out;
 			}
 		}
 	}
 
-	/*
-	 * no insertion point found, check the very front
-	 */
-	if (!*insert && !list_empty(sort_list)) {
-		__rq = list_entry_rq(sort_list->next);
-
-		if (bio->bi_sector + bio_sectors(bio) < __rq->sector &&
-		    bio->bi_sector > deadline_get_last_sector(dd))
-			*insert = sort_list;
-	}
-
+	return ELEVATOR_NO_MERGE;
 out:
+	q->last_merge = &__rq->queuelist;
+out_insert:
+	*insert = &__rq->queuelist;
 	return ret;
 }
 
@@ -242,14 +362,26 @@
 	struct deadline_data *dd = q->elevator.elevator_data;
 	struct deadline_rq *drq = RQ_DATA(req);
 
-	deadline_del_rq_hash(drq);
-	deadline_add_rq_hash(dd, drq);
+	/*
+	 * hash always needs to be repositioned, key is end sector
+	 */
+	deadline_del_drq_hash(drq);
+	deadline_add_drq_hash(dd, drq);
+
+	/*
+	 * if the merge was a front merge, we need to reposition request
+	 */
+	if (rq_rb_key(req) != drq->rb_key) {
+		deadline_del_drq_rb(dd, drq);
+		deadline_add_drq_rb(dd, drq);
+	}
 
 	q->last_merge = &req->queuelist;
 }
 
 static void
-deadline_merge_request(request_queue_t *q, struct request *req, struct request *next)
+deadline_merged_requests(request_queue_t *q, struct request *req,
+			 struct request *next)
 {
 	struct deadline_data *dd = q->elevator.elevator_data;
 	struct deadline_rq *drq = RQ_DATA(req);
@@ -258,11 +390,20 @@
 	BUG_ON(!drq);
 	BUG_ON(!dnext);
 
-	deadline_del_rq_hash(drq);
-	deadline_add_rq_hash(dd, drq);
+	/*
+	 * reposition drq (this is the merged request) in hash, and in rbtree
+	 * in case of a front merge
+	 */
+	deadline_del_drq_hash(drq);
+	deadline_add_drq_hash(dd, drq);
+
+	if (rq_rb_key(req) != drq->rb_key) {
+		deadline_del_drq_rb(dd, drq);
+		deadline_add_drq_rb(dd, drq);
+	}
 
 	/*
-	 * if dnext expires before drq, assign it's expire time to drq
+	 * if dnext expires before drq, assign its expire time to drq
 	 * and move into dnext position (dnext will be deleted) in fifo
 	 */
 	if (!list_empty(&drq->fifo) && !list_empty(&dnext->fifo)) {
@@ -271,209 +412,255 @@
 			drq->expires = dnext->expires;
 		}
 	}
+
+	/*
+	 * kill knowledge of next, this one is a goner
+	 */
+	deadline_remove_request(q, next);
 }
 
 /*
- * move request from sort list to dispatch queue. maybe remove from rq hash
- * here too?
+ * move request from sort list to dispatch queue.
  */
 static inline void
-deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq)
+deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq)
 {
-	struct deadline_rq *drq = RQ_DATA(rq);
-
-	list_move_tail(&rq->queuelist, dd->dispatch);
+	deadline_del_drq_rb(dd, drq);
 	list_del_init(&drq->fifo);
+	list_add_tail(&drq->request->queuelist, dd->dispatch);
 }
 
 /*
- * move along sort list and move entries to dispatch queue, starting from rq
+ * move an entry to dispatch queue
  */
-static void deadline_move_requests(struct deadline_data *dd, struct request *rq)
+static void
+deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq)
 {
-	struct list_head *sort_head = &dd->sort_list[rq_data_dir(rq)];
-	sector_t last_sec = deadline_get_last_sector(dd);
-	int batch_count = dd->fifo_batch;
-
-	do {
-		struct list_head *nxt = rq->queuelist.next;
-		int this_rq_cost;
-
-		/*
-		 * take it off the sort and fifo list, move
-		 * to dispatch queue
-		 */
-		deadline_move_to_dispatch(dd, rq);
-
-		/*
-		 * if this is the last entry, don't bother doing accounting
-		 */
-		if (nxt == sort_head)
-			break;
+	const int data_dir = rq_data_dir(drq->request);
+	struct rb_node *rbnext = rb_next(&drq->rb_node);
 
-		this_rq_cost = dd->seek_cost;
-		if (rq->sector == last_sec)
-			this_rq_cost = (rq->nr_sectors + 255) >> 8;
+	dd->next_drq[READ] = NULL;
+	dd->next_drq[WRITE] = NULL;
 
-		batch_count -= this_rq_cost;
-		if (batch_count <= 0)
-			break;
+	if (rbnext)
+		dd->next_drq[data_dir] = rb_entry_drq(rbnext);
+	
+	dd->last_sector = drq->request->sector + drq->request->nr_sectors;
 
-		last_sec = rq->sector + rq->nr_sectors;
-		rq = list_entry_rq(nxt);
-	} while (1);
+	/*
+	 * take it off the sort and fifo list, move
+	 * to dispatch queue
+	 */
+	deadline_move_to_dispatch(dd, drq);
 }
 
+#define list_entry_fifo(ptr)	list_entry((ptr), struct deadline_rq, fifo)
+
 /*
- * returns 0 if there are no expired reads on the fifo, 1 otherwise
+ * deadline_check_fifo returns 0 if there are no expired reads on the fifo,
+ * 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir])
  */
-#define list_entry_fifo(ptr)	list_entry((ptr), struct deadline_rq, fifo)
-static inline int deadline_check_fifo(struct deadline_data *dd)
+static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
 {
-	if (!list_empty(&dd->read_fifo)) {
-		struct deadline_rq *drq = list_entry_fifo(dd->read_fifo.next);
+	struct deadline_rq *drq = list_entry_fifo(dd->fifo_list[ddir].next);
 
-		/*
-		 * drq is expired!
-		 */
-		if (time_after(jiffies, drq->expires))
-			return 1;
-	}
+	/*
+	 * drq is expired!
+	 */
+	if (time_after(jiffies, drq->expires))
+		return 1;
 
 	return 0;
 }
 
-static struct request *deadline_next_request(request_queue_t *q)
+/*
+ * deadline_dispatch_requests selects the best request according to
+ * read/write expire, fifo_batch, etc
+ */
+static int deadline_dispatch_requests(struct deadline_data *dd)
 {
-	struct deadline_data *dd = q->elevator.elevator_data;
+	const int reads = !list_empty(&dd->fifo_list[READ]);
+	const int writes = !list_empty(&dd->fifo_list[WRITE]);
 	struct deadline_rq *drq;
-	struct list_head *nxt;
-	struct request *rq;
-	int writes;
+	int data_dir, other_dir;
 
 	/*
-	 * if still requests on the dispatch queue, just grab the first one
+	 * batches are currently reads XOR writes
 	 */
-	if (!list_empty(&q->queue_head)) {
-dispatch:
-		rq = list_entry_rq(q->queue_head.next);
-		dd->last_sector = rq->sector + rq->nr_sectors;
-		return rq;
-	}
+	drq = NULL;
+
+	if (dd->next_drq[READ])
+		drq = dd->next_drq[READ];
+
+	if (dd->next_drq[WRITE])
+		drq = dd->next_drq[WRITE];
 
-	writes = !list_empty(&dd->sort_list[WRITE]);
+	if (drq) {
+		/* we have a "next request" */
+		
+		if (dd->last_sector != drq->request->sector)
+			/* end the batch on a non sequential request */
+			dd->batching += dd->fifo_batch;
+		
+		if (dd->batching < dd->fifo_batch)
+			/* we are still entitled to batch */
+			goto dispatch_request;
+	}
 
 	/*
-	 * if we have expired entries on the fifo list, move some to dispatch
+	 * at this point we are not running a batch. select the appropriate
+	 * data direction (read / write)
 	 */
-	if (deadline_check_fifo(dd)) {
-		if (writes && (dd->starved++ >= dd->writes_starved))
-			goto dispatch_writes;
 
-		nxt = dd->read_fifo.next;
-		drq = list_entry_fifo(nxt);
-		deadline_move_requests(dd, drq->request);
-		goto dispatch;
-	}
+	if (reads) {
+		BUG_ON(RB_EMPTY(&dd->sort_list[READ]));
 
-	if (!list_empty(&dd->sort_list[READ])) {
 		if (writes && (dd->starved++ >= dd->writes_starved))
 			goto dispatch_writes;
 
-		nxt = dd->sort_list[READ].next;
-		deadline_move_requests(dd, list_entry_rq(nxt));
-		goto dispatch;
+		data_dir = READ;
+		other_dir = WRITE;
+
+		goto dispatch_find_request;
 	}
 
 	/*
-	 * either there are no reads expired or on sort list, or the reads
-	 * have starved writes for too long. dispatch some writes
+	 * there are either no reads or writes have been starved
 	 */
+
 	if (writes) {
 dispatch_writes:
-		nxt = dd->sort_list[WRITE].next;
-		deadline_move_requests(dd, list_entry_rq(nxt));
+		BUG_ON(RB_EMPTY(&dd->sort_list[WRITE]));
+
 		dd->starved = 0;
-		goto dispatch;
+
+		data_dir = WRITE;
+		other_dir = READ;
+
+		goto dispatch_find_request;
 	}
 
-	BUG_ON(!list_empty(&dd->sort_list[READ]));
-	BUG_ON(writes);
+	return 0;
+
+dispatch_find_request:
+	/*
+	 * we are not running a batch, find best request for selected data_dir
+	 */
+	if (deadline_check_fifo(dd, data_dir)) {
+		/* An expired request exists - satisfy it */
+		dd->batching = 0;
+		drq = list_entry_fifo(dd->fifo_list[data_dir].next);
+		
+	} else if (dd->next_drq[data_dir]) {
+		/*
+		 * The last req was the same dir and we have a next request in
+		 * sort order. No expired requests so continue on from here.
+		 */
+		drq = dd->next_drq[data_dir];
+	} else {
+		/*
+		 * The last req was the other direction or we have run out of
+		 * higher-sectored requests. Go back to the lowest sectored
+		 * request (1 way elevator) and start a new batch.
+		 */
+		dd->batching = 0;
+		drq = deadline_find_first_drq(dd, data_dir);
+	}
+
+dispatch_request:
+	/*
+	 * drq is the selected appropriate request.
+	 */
+	dd->batching++;
+	deadline_move_request(dd, drq);
+
+	return 1;
+}
+
+static struct request *deadline_next_request(request_queue_t *q)
+{
+	struct deadline_data *dd = q->elevator.elevator_data;
+	struct request *rq;
+
+	/*
+	 * if there are still requests on the dispatch queue, grab the first one
+	 */
+	if (!list_empty(dd->dispatch)) {
+dispatch:
+		rq = list_entry_rq(dd->dispatch->next);
+		return rq;
+	}
+
+	if (deadline_dispatch_requests(dd))
+		goto dispatch;
+
 	return NULL;
 }
 
 static void
-deadline_add_request(request_queue_t *q, struct request *rq, struct list_head *insert_here)
+deadline_insert_request(request_queue_t *q, struct request *rq,
+			struct list_head *insert_here)
 {
 	struct deadline_data *dd = q->elevator.elevator_data;
 	struct deadline_rq *drq = RQ_DATA(rq);
-	const int data_dir = rq_data_dir(rq);
 
-	/*
-	 * flush hash on barrier insert, as not to allow merges before a
-	 * barrier.
-	 */
 	if (unlikely(rq->flags & REQ_HARDBARRIER)) {
 		DL_INVALIDATE_HASH(dd);
 		q->last_merge = NULL;
 	}
 
-	/*
-	 * add to sort list
-	 */
-	if (!insert_here)
-		insert_here = dd->sort_list[data_dir].prev;
+	if (unlikely(!blk_fs_request(rq))) {
+		if (!insert_here)
+			insert_here = dd->dispatch->prev;
 
-	list_add(&rq->queuelist, insert_here);
-
-	if (unlikely(!(rq->flags & REQ_CMD)))
+		list_add(&rq->queuelist, insert_here);
 		return;
+	}
 
 	if (rq_mergeable(rq)) {
-		deadline_add_rq_hash(dd, drq);
+		deadline_add_drq_hash(dd, drq);
 
 		if (!q->last_merge)
 			q->last_merge = &rq->queuelist;
 	}
 
-	if (data_dir == READ) {
-		/*
-		 * set expire time and add to fifo list
-		 */
-		drq->expires = jiffies + dd->read_expire;
-		list_add_tail(&drq->fifo, &dd->read_fifo);
-	}
-}
-
-static void deadline_remove_request(request_queue_t *q, struct request *rq)
-{
-	struct deadline_rq *drq = RQ_DATA(rq);
-
-	if (drq) {
-		list_del_init(&drq->fifo);
-		deadline_del_rq_hash(drq);
-	}
+	deadline_add_request(dd, drq);
 }
 
 static int deadline_queue_empty(request_queue_t *q)
 {
 	struct deadline_data *dd = q->elevator.elevator_data;
 
-	if (!list_empty(&dd->sort_list[WRITE]) ||
-	    !list_empty(&dd->sort_list[READ]) ||
-	    !list_empty(&q->queue_head))
+	if (!list_empty(&dd->fifo_list[WRITE])
+	    || !list_empty(&dd->fifo_list[READ])
+	    || !list_empty(dd->dispatch))
 		return 0;
 
-	BUG_ON(!list_empty(&dd->read_fifo));
 	return 1;
 }
 
-static struct list_head *
-deadline_get_sort_head(request_queue_t *q, struct request *rq)
+static struct request *
+deadline_former_request(request_queue_t *q, struct request *rq)
 {
-	struct deadline_data *dd = q->elevator.elevator_data;
+	struct deadline_rq *drq = RQ_DATA(rq);
+	struct rb_node *rbprev = rb_prev(&drq->rb_node);
 
-	return &dd->sort_list[rq_data_dir(rq)];
+	if (rbprev)
+		return rb_entry_drq(rbprev)->request;
+
+	return NULL;
+}
+
+static struct request *
+deadline_latter_request(request_queue_t *q, struct request *rq)
+{
+	struct deadline_rq *drq = RQ_DATA(rq);
+	struct rb_node *rbnext = rb_next(&drq->rb_node);
+
+	if (rbnext)
+		return rb_entry_drq(rbnext)->request;
+
+	return NULL;
 }
 
 static void deadline_exit(request_queue_t *q, elevator_t *e)
@@ -483,18 +670,14 @@
 	struct request *rq;
 	int i;
 
-	BUG_ON(!list_empty(&dd->read_fifo));
-	BUG_ON(!list_empty(&dd->sort_list[READ]));
-	BUG_ON(!list_empty(&dd->sort_list[WRITE]));
+	BUG_ON(!list_empty(&dd->fifo_list[READ]));
+	BUG_ON(!list_empty(&dd->fifo_list[WRITE]));
 
 	for (i = READ; i <= WRITE; i++) {
 		struct request_list *rl = &q->rq[i];
-		struct list_head *entry = &rl->free;
+		struct list_head *entry;
 
-		if (list_empty(&rl->free))
-			continue;
-	
-		while ((entry = entry->next) != &rl->free) {
+		list_for_each(entry, &rl->free) {
 			rq = list_entry_rq(entry);
 
 			if ((drq = RQ_DATA(rq)) == NULL)
@@ -537,25 +720,24 @@
 	for (i = 0; i < DL_HASH_ENTRIES; i++)
 		INIT_LIST_HEAD(&dd->hash[i]);
 
-	INIT_LIST_HEAD(&dd->read_fifo);
-	INIT_LIST_HEAD(&dd->sort_list[READ]);
-	INIT_LIST_HEAD(&dd->sort_list[WRITE]);
+	INIT_LIST_HEAD(&dd->fifo_list[READ]);
+	INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
+	dd->sort_list[READ] = RB_ROOT;
+	dd->sort_list[WRITE] = RB_ROOT;
 	dd->dispatch = &q->queue_head;
-	dd->fifo_batch = fifo_batch;
-	dd->read_expire = read_expire;
-	dd->seek_cost = seek_cost;
+	dd->fifo_expire[READ] = read_expire;
+	dd->fifo_expire[WRITE] = write_expire;
 	dd->hash_valid_count = 1;
 	dd->writes_starved = writes_starved;
+	dd->front_merges = 1;
+	dd->fifo_batch = fifo_batch;
 	e->elevator_data = dd;
 
 	for (i = READ; i <= WRITE; i++) {
 		struct request_list *rl = &q->rq[i];
-		struct list_head *entry = &rl->free;
+		struct list_head *entry;
 
-		if (list_empty(&rl->free))
-			continue;
-	
-		while ((entry = entry->next) != &rl->free) {
+		list_for_each(entry, &rl->free) {
 			rq = list_entry_rq(entry);
 
 			drq = kmem_cache_alloc(drq_pool, GFP_KERNEL);
@@ -567,6 +749,7 @@
 			memset(drq, 0, sizeof(*drq));
 			INIT_LIST_HEAD(&drq->fifo);
 			INIT_LIST_HEAD(&drq->hash);
+			RB_CLEAR(&drq->rb_node);
 			drq->request = rq;
 			rq->elevator_private = drq;
 		}
@@ -578,10 +761,135 @@
 	return ret;
 }
 
+/*
+ * sysfs parts below
+ */
+struct deadline_fs_entry {
+	struct attribute attr;
+	ssize_t (*show)(struct deadline_data *, char *);
+	ssize_t (*store)(struct deadline_data *, const char *, size_t);
+};
+
+static ssize_t
+deadline_var_show(unsigned int var, char *page)
+{
+	return sprintf(page, "%d\n", var);
+}
+
+static ssize_t
+deadline_var_store(unsigned int *var, const char *page, size_t count)
+{
+	char *p = (char *) page;
+
+	*var = simple_strtoul(p, &p, 10);
+	return count;
+}
+
+#define SHOW_FUNCTION(__FUNC, __VAR)					\
+static ssize_t __FUNC(struct deadline_data *dd, char *page)		\
+{									\
+	return deadline_var_show(__VAR, (page));			\
+}
+SHOW_FUNCTION(deadline_readexpire_show, dd->fifo_expire[READ]);
+SHOW_FUNCTION(deadline_writeexpire_show, dd->fifo_expire[WRITE]);
+SHOW_FUNCTION(deadline_writesstarved_show, dd->writes_starved);
+SHOW_FUNCTION(deadline_frontmerges_show, dd->front_merges);
+SHOW_FUNCTION(deadline_fifobatch_show, dd->fifo_batch);
+#undef SHOW_FUNCTION
+
+#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX)				\
+static ssize_t __FUNC(struct deadline_data *dd, const char *page, size_t count)	\
+{									\
+	int ret = deadline_var_store(__PTR, (page), count);		\
+	if (*(__PTR) < (MIN))						\
+		*(__PTR) = (MIN);					\
+	else if (*(__PTR) > (MAX))					\
+		*(__PTR) = (MAX);					\
+	return ret;							\
+}
+STORE_FUNCTION(deadline_readexpire_store, &dd->fifo_expire[READ], 0, INT_MAX);
+STORE_FUNCTION(deadline_writeexpire_store, &dd->fifo_expire[WRITE], 0, INT_MAX);
+STORE_FUNCTION(deadline_writesstarved_store, &dd->writes_starved, INT_MIN, INT_MAX);
+STORE_FUNCTION(deadline_frontmerges_store, &dd->front_merges, 0, 1);
+STORE_FUNCTION(deadline_fifobatch_store, &dd->fifo_batch, 0, INT_MAX);
+#undef STORE_FUNCTION
+
+static struct deadline_fs_entry deadline_readexpire_entry = {
+	.attr = {.name = "read_expire", .mode = S_IRUGO | S_IWUSR },
+	.show = deadline_readexpire_show,
+	.store = deadline_readexpire_store,
+};
+static struct deadline_fs_entry deadline_writeexpire_entry = {
+	.attr = {.name = "write_expire", .mode = S_IRUGO | S_IWUSR },
+	.show = deadline_writeexpire_show,
+	.store = deadline_writeexpire_store,
+};
+static struct deadline_fs_entry deadline_writesstarved_entry = {
+	.attr = {.name = "writes_starved", .mode = S_IRUGO | S_IWUSR },
+	.show = deadline_writesstarved_show,
+	.store = deadline_writesstarved_store,
+};
+static struct deadline_fs_entry deadline_frontmerges_entry = {
+	.attr = {.name = "front_merges", .mode = S_IRUGO | S_IWUSR },
+	.show = deadline_frontmerges_show,
+	.store = deadline_frontmerges_store,
+};
+static struct deadline_fs_entry deadline_fifobatch_entry = {
+	.attr = {.name = "fifo_batch", .mode = S_IRUGO | S_IWUSR },
+	.show = deadline_fifobatch_show,
+	.store = deadline_fifobatch_store,
+};
+
+static struct attribute *default_attrs[] = {
+	&deadline_readexpire_entry.attr,
+	&deadline_writeexpire_entry.attr,
+	&deadline_writesstarved_entry.attr,
+	&deadline_frontmerges_entry.attr,
+	&deadline_fifobatch_entry.attr,
+	NULL,
+};
+
+#define to_deadline(atr) container_of((atr), struct deadline_fs_entry, attr)
+
+static ssize_t
+deadline_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+	elevator_t *e = container_of(kobj, elevator_t, kobj);
+	struct deadline_fs_entry *entry = to_deadline(attr);
+
+	if (!entry->show)
+		return 0;
+
+	return entry->show(e->elevator_data, page);
+}
+
+static ssize_t
+deadline_attr_store(struct kobject *kobj, struct attribute *attr,
+		    const char *page, size_t length)
+{
+	elevator_t *e = container_of(kobj, elevator_t, kobj);
+	struct deadline_fs_entry *entry = to_deadline(attr);
+
+	if (!entry->store)
+		return -EINVAL;
+
+	return entry->store(e->elevator_data, page, length);
+}
+
+static struct sysfs_ops deadline_sysfs_ops = {
+	.show	= deadline_attr_show,
+	.store	= deadline_attr_store,
+};
+
+struct kobj_type deadline_ktype = {
+	.sysfs_ops	= &deadline_sysfs_ops,
+	.default_attrs	= default_attrs,
+};
+
 static int __init deadline_slab_setup(void)
 {
 	drq_pool = kmem_cache_create("deadline_drq", sizeof(struct deadline_rq),
-				     0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+				     0, 0, NULL, NULL);
 
 	if (!drq_pool)
 		panic("deadline: can't init slab pool\n");
@@ -594,14 +902,17 @@
 elevator_t iosched_deadline = {
 	.elevator_merge_fn = 		deadline_merge,
 	.elevator_merged_fn =		deadline_merged_request,
-	.elevator_merge_req_fn =	deadline_merge_request,
+	.elevator_merge_req_fn =	deadline_merged_requests,
 	.elevator_next_req_fn =		deadline_next_request,
-	.elevator_add_req_fn =		deadline_add_request,
+	.elevator_add_req_fn =		deadline_insert_request,
 	.elevator_remove_req_fn =	deadline_remove_request,
 	.elevator_queue_empty_fn =	deadline_queue_empty,
-	.elevator_get_sort_head_fn =	deadline_get_sort_head,
+	.elevator_former_req_fn =	deadline_former_request,
+	.elevator_latter_req_fn =	deadline_latter_request,
 	.elevator_init_fn =		deadline_init,
 	.elevator_exit_fn =		deadline_exit,
+
+	.elevator_ktype =		&deadline_ktype,
 };
 
 EXPORT_SYMBOL(iosched_deadline);
diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c
--- a/drivers/block/elevator.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/block/elevator.c	Mon Jan 13 21:59:51 2003
@@ -194,6 +194,12 @@
 	return ELEVATOR_NO_MERGE;
 }
 
+void elevator_noop_merge_requests(request_queue_t *q, struct request *req,
+				  struct request *next)
+{
+	list_del_init(&next->queuelist);
+}
+
 void elevator_noop_add_request(request_queue_t *q, struct request *rq,
 			       struct list_head *insert_here)
 {
@@ -370,19 +376,70 @@
 	return list_empty(&q->queue_head);
 }
 
-inline struct list_head *elv_get_sort_head(request_queue_t *q,
-					   struct request *rq)
+struct request *elv_latter_request(request_queue_t *q, struct request *rq)
+{
+	struct list_head *next;
+
+	elevator_t *e = &q->elevator;
+
+	if (e->elevator_latter_req_fn)
+		return e->elevator_latter_req_fn(q, rq);
+
+	next = rq->queuelist.next;
+	if (next != &q->queue_head && next != &rq->queuelist)
+		return list_entry_rq(next);
+
+	return NULL;
+}
+
+struct request *elv_former_request(request_queue_t *q, struct request *rq)
 {
+	struct list_head *prev;
+
 	elevator_t *e = &q->elevator;
 
-	if (e->elevator_get_sort_head_fn)
-		return e->elevator_get_sort_head_fn(q, rq);
+	if (e->elevator_former_req_fn)
+		return e->elevator_latter_req_fn(q, rq);
+
+	prev = rq->queuelist.prev;
+	if (prev != &q->queue_head && prev != &rq->queuelist)
+		return list_entry_rq(prev);
+
+	return NULL;
+}
+
+int elv_register_queue(struct gendisk *disk)
+{
+	request_queue_t *q = disk->queue;
+	elevator_t *e;
+
+	if (!q)
+		return -ENXIO;
+
+	e = &q->elevator;
+
+	e->kobj.parent = kobject_get(&disk->kobj);
+	if (!e->kobj.parent)
+		return -EBUSY;
+
+	snprintf(e->kobj.name, KOBJ_NAME_LEN, "%s", "iosched");
+	e->kobj.ktype = e->elevator_ktype;
+
+	return kobject_register(&e->kobj);
+}
+
+void elv_unregister_queue(struct gendisk *disk)
+{
+	request_queue_t *q = disk->queue;
+	elevator_t *e = &q->elevator;
 
-	return &q->queue_head;
+	kobject_unregister(&e->kobj);
+	kobject_put(&disk->kobj);
 }
 
 elevator_t elevator_noop = {
 	.elevator_merge_fn		= elevator_noop_merge,
+	.elevator_merge_req_fn		= elevator_noop_merge_requests,
 	.elevator_next_req_fn		= elevator_noop_next_request,
 	.elevator_add_req_fn		= elevator_noop_add_request,
 };
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/block/genhd.c	Mon Jan 13 21:59:50 2003
@@ -112,6 +112,7 @@
 	blk_register_region(MKDEV(disk->major, disk->first_minor), disk->minors,
 			NULL, exact_match, exact_lock, disk);
 	register_disk(disk);
+	elv_register_queue(disk);
 }
 
 EXPORT_SYMBOL(add_disk);
@@ -119,6 +120,7 @@
 
 void unlink_gendisk(struct gendisk *disk)
 {
+	elv_unregister_queue(disk);
 	blk_unregister_region(MKDEV(disk->major, disk->first_minor),
 			      disk->minors);
 }
diff -Nru a/drivers/block/ioctl.c b/drivers/block/ioctl.c
--- a/drivers/block/ioctl.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/block/ioctl.c	Mon Jan 13 21:59:49 2003
@@ -128,10 +128,6 @@
 	int ret, n;
 
 	switch (cmd) {
-	case BLKELVGET:
-	case BLKELVSET:
-		/* deprecated, use the /proc/iosched interface instead */
-		return -ENOTTY;
 	case BLKRAGET:
 	case BLKFRAGET:
 		if (!arg)
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/block/ll_rw_blk.c	Mon Jan 13 21:59:49 2003
@@ -68,7 +68,7 @@
 {
 	int ret;
 
-	ret = queue_nr_requests / 4 - 1;
+	ret = queue_nr_requests / 8 - 1;
 	if (ret < 0)
 		ret = 1;
 	return ret;
@@ -81,7 +81,7 @@
 {
 	int ret;
 
-	ret = queue_nr_requests / 4 + 1;
+	ret = queue_nr_requests / 8 + 1;
 	if (ret > queue_nr_requests)
 		ret = queue_nr_requests;
 	return ret;
@@ -1159,6 +1159,8 @@
 {
 	int count = (queue_nr_requests*2);
 
+	elevator_exit(q);
+
 	count -= __blk_cleanup_queue(&q->rq[READ]);
 	count -= __blk_cleanup_queue(&q->rq[WRITE]);
 
@@ -1168,8 +1170,6 @@
 	if (blk_queue_tagged(q))
 		blk_queue_free_tags(q);
 
-	elevator_exit(q);
-
 	memset(q, 0, sizeof(*q));
 }
 
@@ -1576,22 +1576,22 @@
 /*
  * Has to be called with the request spinlock acquired
  */
-static void attempt_merge(request_queue_t *q, struct request *req,
+static int attempt_merge(request_queue_t *q, struct request *req,
 			  struct request *next)
 {
 	if (!rq_mergeable(req) || !rq_mergeable(next))
-		return;
+		return 0;
 
 	/*
 	 * not contigious
 	 */
 	if (req->sector + req->nr_sectors != next->sector)
-		return;
+		return 0;
 
 	if (rq_data_dir(req) != rq_data_dir(next)
 	    || req->rq_disk != next->rq_disk
 	    || next->waiting || next->special)
-		return;
+		return 0;
 
 	/*
 	 * If we are allowed to merge, then append bio list
@@ -1612,27 +1612,31 @@
 			req->rq_disk->in_flight--;
 		}
 
-		blkdev_dequeue_request(next);
 		__blk_put_request(q, next);
+		return 1;
 	}
+
+	return 0;
 }
 
-static inline void attempt_back_merge(request_queue_t *q, struct request *rq)
+static inline int attempt_back_merge(request_queue_t *q, struct request *rq)
 {
-	struct list_head *next = rq->queuelist.next;
-	struct list_head *sort_head = elv_get_sort_head(q, rq);
+	struct request *next = elv_latter_request(q, rq);
 
-	if (next != sort_head)
-		attempt_merge(q, rq, list_entry_rq(next));
+	if (next)
+		return attempt_merge(q, rq, next);
+
+	return 0;
 }
 
-static inline void attempt_front_merge(request_queue_t *q, struct request *rq)
+static inline int attempt_front_merge(request_queue_t *q, struct request *rq)
 {
-	struct list_head *prev = rq->queuelist.prev;
-	struct list_head *sort_head = elv_get_sort_head(q, rq);
+	struct request *prev = elv_former_request(q, rq);
 
-	if (prev != sort_head)
-		attempt_merge(q, list_entry_rq(prev), rq);
+	if (prev)
+		return attempt_merge(q, prev, rq);
+
+	return 0;
 }
 
 /**
@@ -1715,8 +1719,8 @@
 			req->biotail = bio;
 			req->nr_sectors = req->hard_nr_sectors += nr_sectors;
 			drive_stat_acct(req, nr_sectors, 0);
-			elv_merged_request(q, req);
-			attempt_back_merge(q, req);
+			if (!attempt_back_merge(q, req))
+				elv_merged_request(q, req);
 			goto out;
 
 		case ELEVATOR_FRONT_MERGE:
@@ -1742,8 +1746,8 @@
 			req->sector = req->hard_sector = sector;
 			req->nr_sectors = req->hard_nr_sectors += nr_sectors;
 			drive_stat_acct(req, nr_sectors, 0);
-			elv_merged_request(q, req);
-			attempt_front_merge(q, req);
+			if (!attempt_front_merge(q, req))
+				elv_merged_request(q, req);
 			goto out;
 
 		/*
@@ -2169,8 +2173,7 @@
 	int i;
 
 	request_cachep = kmem_cache_create("blkdev_requests",
-			sizeof(struct request), 0,
-			SLAB_HWCACHE_ALIGN, NULL, NULL);
+			sizeof(struct request), 0, 0, NULL, NULL);
 	if (!request_cachep)
 		panic("Can't create request pool slab cache\n");
 
diff -Nru a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c
--- a/drivers/block/paride/bpck6.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/block/paride/bpck6.c	Mon Jan 13 21:59:50 2003
@@ -21,7 +21,7 @@
 
 
 /* PARAMETERS */
-int verbose=0; /* set this to 1 to see debugging messages and whatnot */
+static int verbose; /* set this to 1 to see debugging messages and whatnot */
 
 #define BACKPACK_VERSION "2.0.2"
 
diff -Nru a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
--- a/drivers/block/scsi_ioctl.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/block/scsi_ioctl.c	Mon Jan 13 21:59:51 2003
@@ -40,6 +40,11 @@
 
 #define BLK_DEFAULT_TIMEOUT	(60 * HZ)
 
+/* defined in ../scsi/scsi.h  ... should it be included? */
+#ifndef SCSI_SENSE_BUFFERSIZE
+#define SCSI_SENSE_BUFFERSIZE 64
+#endif
+
 int blk_do_rq(request_queue_t *q, struct block_device *bdev, struct request *rq)
 {
 	DECLARE_COMPLETION(wait);
@@ -126,11 +131,11 @@
 		 struct sg_io_hdr *uptr)
 {
 	unsigned long uaddr, start_time;
-	int err, reading, writing, nr_sectors;
+	int reading, writing, nr_sectors;
 	struct sg_io_hdr hdr;
 	struct request *rq;
 	struct bio *bio;
-	char sense[24];
+	char sense[SCSI_SENSE_BUFFERSIZE];
 	void *buffer;
 
 	if (!access_ok(VERIFY_WRITE, uptr, sizeof(*uptr)))
@@ -265,26 +270,36 @@
 
 	start_time = jiffies;
 
-	/*
-	 * return -EIO if we didn't transfer all data, caller can look at
-	 * residual count to find out how much did succeed
+	/* ignore return value. All information is passed back to caller
+	 * (if he doesn't check that is his problem).
+	 * N.B. a non-zero SCSI status is _not_ necessarily an error.
 	 */
-	err = blk_do_rq(q, bdev, rq);
-	if (rq->data_len > 0)
-		err = -EIO;
+	blk_do_rq(q, bdev, rq);
 	
 	if (bio) {
 		bio_unmap_user(bio, reading);
 		bio_put(bio);
 	}
 
-	hdr.status = rq->errors;
+	/* write to all output members */
+	hdr.status = rq->errors;	
+	hdr.masked_status = (hdr.status >> 1) & 0x1f;
+	hdr.msg_status = 0;
+	hdr.host_status = 0;
+	hdr.driver_status = 0;
+	hdr.info = 0;
+	if (hdr.masked_status || hdr.host_status || hdr.driver_status)
+		hdr.info |= SG_INFO_CHECK;
 	hdr.resid = rq->data_len;
 	hdr.duration = (jiffies - start_time) * (1000 / HZ);
+	hdr.sb_len_wr = 0;
 
 	if (rq->sense_len && hdr.sbp) {
-		if (!copy_to_user(hdr.sbp,rq->sense, rq->sense_len))
-			hdr.sb_len_wr = rq->sense_len;
+		int len = (hdr.mx_sb_len < rq->sense_len) ? 
+				hdr.mx_sb_len : rq->sense_len;
+
+		if (!copy_to_user(hdr.sbp, rq->sense, len))
+			hdr.sb_len_wr = len;
 	}
 
 	blk_put_request(rq);
@@ -297,8 +312,9 @@
 
 		kfree(buffer);
 	}
-
-	return err;
+	/* may not have succeeded, but output values written to control
+	 * structure (struct sg_io_hdr).  */
+	return 0;
 }
 
 #define FORMAT_UNIT_TIMEOUT		(2 * 60 * 60 * HZ)
diff -Nru a/drivers/char/Kconfig b/drivers/char/Kconfig
--- a/drivers/char/Kconfig	Mon Jan 13 21:59:49 2003
+++ b/drivers/char/Kconfig	Mon Jan 13 21:59:49 2003
@@ -6,6 +6,7 @@
 
 config VT
 	bool "Virtual terminal"
+	requires INPUT=y
 	---help---
 	  If you say Y here, you will get support for terminal devices with
 	  display and keyboard devices. These are called "virtual" because you
@@ -636,6 +637,8 @@
 comment "metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/"
 	depends on QIC02_TAPE && QIC02_DYNCONF
 
+source "drivers/char/ipmi/Kconfig"
+
 source "drivers/char/watchdog/Kconfig"
 
 config DS1620
@@ -771,6 +774,7 @@
 
 config RTC
 	tristate "Enhanced Real Time Clock Support"
+	depends on !PPC32 && !PARISC && !IA64
 	---help---
 	  If you say Y here and create a character special file /dev/rtc with
 	  major number 10 and minor number 135 using mknod ("man mknod"), you
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Mon Jan 13 21:59:51 2003
+++ b/drivers/char/Makefile	Mon Jan 13 21:59:51 2003
@@ -82,6 +82,7 @@
 obj-$(CONFIG_AGP) += agp/
 obj-$(CONFIG_DRM) += drm/
 obj-$(CONFIG_PCMCIA) += pcmcia/
+obj-$(CONFIG_IPMI_HANDLER) += ipmi/
 
 
 # Files generated that shall be removed upon make clean
diff -Nru a/drivers/char/i8k.c b/drivers/char/i8k.c
--- a/drivers/char/i8k.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/char/i8k.c	Mon Jan 13 21:59:49 2003
@@ -66,8 +66,8 @@
 static char bios_version [4]  = "?";
 static char serial_number[16] = "?";
 
-int force = 0;
-int power_status = 0;
+static int force = 0;
+static int power_status = 0;
 
 MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
 MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
diff -Nru a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/ipmi/Kconfig	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,40 @@
+#
+# IPMI device configuration
+#
+
+menu "IPMI"
+config IPMI_HANDLER
+       tristate 'IPMI top-level message handler'
+       help
+         This enables the central IPMI message handler, required for IPMI
+	 to work.  Note that you must have this enabled to do any other IPMI
+	 things.  See IPMI.txt for more details.
+
+config IPMI_PANIC_EVENT
+       bool 'Generate a panic event to all BMCs on a panic'
+       depends on IPMI_HANDLER
+       help
+         When a panic occurs, this will cause the IPMI message handler to
+	 generate an IPMI event describing the panic to each interface
+	 registered with the message handler.
+
+config IPMI_DEVICE_INTERFACE
+       tristate 'Device interface for IPMI'
+       depends on IPMI_HANDLER
+       help
+         This provides an IOCTL interface to the IPMI message handler so
+	 userland processes may use IPMI.  It supports poll() and select().
+
+config IPMI_KCS
+       tristate 'IPMI KCS handler'
+       depends on IPMI_HANDLER
+       help
+         Provides a driver for a KCS-style interface to a BMC.
+
+config IPMI_WATCHDOG
+       tristate 'IPMI Watchdog Timer'
+       depends on IPMI_HANDLER
+       help
+         This enables the IPMI watchdog timer.
+
+endmenu
diff -Nru a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/ipmi/Makefile	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,15 @@
+#
+# Makefile for the ipmi drivers.
+#
+
+export-objs	:= ipmi_msghandler.o ipmi_watchdog.o
+
+ipmi_kcs_drv-objs := ipmi_kcs_sm.o ipmi_kcs_intf.o
+
+obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o
+obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
+obj-$(CONFIG_IPMI_KCS) += ipmi_kcs_drv.o
+obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
+
+ipmi_kcs_drv.o:	$(ipmi_kcs_drv-objs)
+	$(LD) -r -o $@ $(ipmi_kcs_drv-objs) 
diff -Nru a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/ipmi/ipmi_devintf.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,532 @@
+/*
+ * ipmi_devintf.c
+ *
+ * Linux device interface for the IPMI message handler.
+ *
+ * Author: MontaVista Software, Inc.
+ *         Corey Minyard <minyard@mvista.com>
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <asm/system.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/ipmi.h>
+#include <asm/semaphore.h>
+#include <linux/init.h>
+
+struct ipmi_file_private
+{
+	ipmi_user_t          user;
+	spinlock_t           recv_msg_lock;
+	struct list_head     recv_msgs;
+	struct file          *file;
+	struct fasync_struct *fasync_queue;
+	wait_queue_head_t    wait;
+	struct semaphore     recv_sem;
+};
+
+static void file_receive_handler(struct ipmi_recv_msg *msg,
+				 void                 *handler_data)
+{
+	struct ipmi_file_private *priv = handler_data;
+	int                      was_empty;
+	unsigned long            flags;
+
+	spin_lock_irqsave(&(priv->recv_msg_lock), flags);
+
+	was_empty = list_empty(&(priv->recv_msgs));
+	list_add_tail(&(msg->link), &(priv->recv_msgs));
+
+	if (was_empty) {
+		wake_up_interruptible(&priv->wait);
+		kill_fasync(&priv->fasync_queue, SIGIO, POLL_IN);
+	}
+
+	spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
+}
+
+static unsigned int ipmi_poll(struct file *file, poll_table *wait)
+{
+	struct ipmi_file_private *priv = file->private_data;
+	unsigned int             mask = 0;
+	unsigned long            flags;
+
+	spin_lock_irqsave(&priv->recv_msg_lock, flags);
+
+	poll_wait(file, &priv->wait, wait);
+
+	if (! list_empty(&(priv->recv_msgs)))
+		mask |= (POLLIN | POLLRDNORM);
+
+	spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
+
+	return mask;
+}
+
+static int ipmi_fasync(int fd, struct file *file, int on)
+{
+	struct ipmi_file_private *priv = file->private_data;
+	int                      result;
+
+	result = fasync_helper(fd, file, on, &priv->fasync_queue);
+
+	return (result);
+}
+
+static struct ipmi_user_hndl ipmi_hndlrs =
+{
+	ipmi_recv_hndl : file_receive_handler
+};
+
+static int ipmi_open(struct inode *inode, struct file *file)
+{
+	int                      if_num = minor(inode->i_rdev);
+	int                      rv;
+	struct ipmi_file_private *priv;
+
+
+	priv = kmalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->file = file;
+
+	rv = ipmi_create_user(if_num,
+			      &ipmi_hndlrs,
+			      priv,
+			      &(priv->user));
+	if (rv) {
+		kfree(priv);
+		return rv;
+	}
+
+	file->private_data = priv;
+
+	spin_lock_init(&(priv->recv_msg_lock));
+	INIT_LIST_HEAD(&(priv->recv_msgs));
+	init_waitqueue_head(&priv->wait);
+	priv->fasync_queue = NULL;
+	sema_init(&(priv->recv_sem), 1);
+
+	return 0;
+}
+
+static int ipmi_release(struct inode *inode, struct file *file)
+{
+	struct ipmi_file_private *priv = file->private_data;
+	int                      rv;
+
+	rv = ipmi_destroy_user(priv->user);
+	if (rv)
+		return rv;
+
+	ipmi_fasync (-1, file, 0);
+
+	/* FIXME - free the messages in the list. */
+	kfree(priv);
+
+	return 0;
+}
+
+static int ipmi_ioctl(struct inode  *inode,
+		      struct file   *file,
+		      unsigned int  cmd,
+		      unsigned long data)
+{
+	int                      rv = -EINVAL;
+	struct ipmi_file_private *priv = file->private_data;
+
+	switch (cmd) 
+	{
+	case IPMICTL_SEND_COMMAND:
+	{
+		struct ipmi_req    req;
+		struct ipmi_addr   addr;
+		unsigned char msgdata[IPMI_MAX_MSG_LENGTH];
+
+		if (copy_from_user(&req, (void *) data, sizeof(req))) {
+			rv = -EFAULT;
+			break;
+		}
+
+		if (req.addr_len > sizeof(struct ipmi_addr))
+		{
+			rv = -EINVAL;
+			break;
+		}
+
+		if (copy_from_user(&addr, req.addr, req.addr_len)) {
+			rv = -EFAULT;
+			break;
+		}
+
+		rv = ipmi_validate_addr(&addr, req.addr_len);
+		if (rv)
+			break;
+
+		if (req.msg.data != NULL) {
+			if (req.msg.data_len > IPMI_MAX_MSG_LENGTH) {
+				rv = -EMSGSIZE;
+				break;
+			}
+
+			if (copy_from_user(&msgdata,
+					   req.msg.data,
+					   req.msg.data_len))
+			{
+				rv = -EFAULT;
+				break;
+			}
+		} else {
+			req.msg.data_len = 0;
+		}
+
+		req.msg.data = msgdata;
+
+		rv = ipmi_request(priv->user,
+				  &addr,
+				  req.msgid,
+				  &(req.msg),
+				  0);
+		break;
+	}
+
+	case IPMICTL_RECEIVE_MSG:
+	case IPMICTL_RECEIVE_MSG_TRUNC:
+	{
+		struct ipmi_recv      rsp;
+		int              addr_len;
+		struct list_head *entry;
+		struct ipmi_recv_msg  *msg;
+		unsigned long    flags;
+		
+
+		rv = 0;
+		if (copy_from_user(&rsp, (void *) data, sizeof(rsp))) {
+			rv = -EFAULT;
+			break;
+		}
+
+		/* We claim a semaphore because we don't want two
+                   users getting something from the queue at a time.
+                   Since we have to release the spinlock before we can
+                   copy the data to the user, it's possible another
+                   user will grab something from the queue, too.  Then
+                   the messages might get out of order if something
+                   fails and the message gets put back onto the
+                   queue.  This semaphore prevents that problem. */
+		down(&(priv->recv_sem));
+
+		/* Grab the message off the list. */
+		spin_lock_irqsave(&(priv->recv_msg_lock), flags);
+		if (list_empty(&(priv->recv_msgs))) {
+			spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
+			rv = -EAGAIN;
+			goto recv_err;
+		}
+		entry = priv->recv_msgs.next;
+		msg = list_entry(entry, struct ipmi_recv_msg, link);
+		list_del(entry);
+		spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
+
+		addr_len = ipmi_addr_length(msg->addr.addr_type);
+		if (rsp.addr_len < addr_len)
+		{
+			rv = -EINVAL;
+			goto recv_putback_on_err;
+		}
+
+		if (copy_to_user(rsp.addr, &(msg->addr), addr_len)) {
+			rv = -EFAULT;
+			goto recv_putback_on_err;
+		}
+		rsp.addr_len = addr_len;
+
+		rsp.recv_type = msg->recv_type;
+		rsp.msgid = msg->msgid;
+		rsp.msg.netfn = msg->msg.netfn;
+		rsp.msg.cmd = msg->msg.cmd;
+
+		if (msg->msg.data_len > 0) {
+			if (rsp.msg.data_len < msg->msg.data_len) {
+				rv = -EMSGSIZE;
+				if (cmd == IPMICTL_RECEIVE_MSG_TRUNC) {
+					msg->msg.data_len = rsp.msg.data_len;
+				} else {
+					goto recv_putback_on_err;
+				}
+			}
+
+			if (copy_to_user(rsp.msg.data,
+					 msg->msg.data,
+					 msg->msg.data_len))
+			{
+				rv = -EFAULT;
+				goto recv_putback_on_err;
+			}
+			rsp.msg.data_len = msg->msg.data_len;
+		} else {
+			rsp.msg.data_len = 0;
+		}
+
+		if (copy_to_user((void *) data, &rsp, sizeof(rsp))) {
+			rv = -EFAULT;
+			goto recv_putback_on_err;
+		}
+
+		up(&(priv->recv_sem));
+		ipmi_free_recv_msg(msg);
+		break;
+
+	recv_putback_on_err:
+		/* If we got an error, put the message back onto
+		   the head of the queue. */
+		spin_lock_irqsave(&(priv->recv_msg_lock), flags);
+		list_add(entry, &(priv->recv_msgs));
+		spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
+		up(&(priv->recv_sem));
+		break;
+
+	recv_err:
+		up(&(priv->recv_sem));
+		break;
+	}
+
+	case IPMICTL_REGISTER_FOR_CMD:
+	{
+		struct ipmi_cmdspec val;
+
+		if (copy_from_user(&val, (void *) data, sizeof(val))) {
+			rv = -EFAULT;
+			break;
+		}
+
+		rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd);
+		break;
+	}
+
+	case IPMICTL_UNREGISTER_FOR_CMD:
+	{
+		struct ipmi_cmdspec   val;
+
+		if (copy_from_user(&val, (void *) data, sizeof(val))) {
+			rv = -EFAULT;
+			break;
+		}
+
+		rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd);
+		break;
+	}
+
+	case IPMICTL_SET_GETS_EVENTS_CMD:
+	{
+		int val;
+
+		if (copy_from_user(&val, (void *) data, sizeof(val))) {
+			rv = -EFAULT;
+			break;
+		}
+
+		rv = ipmi_set_gets_events(priv->user, val);
+		break;
+	}
+
+	case IPMICTL_SET_MY_ADDRESS_CMD:
+	{
+		unsigned int val;
+
+		if (copy_from_user(&val, (void *) data, sizeof(val))) {
+			rv = -EFAULT;
+			break;
+		}
+
+		ipmi_set_my_address(priv->user, val);
+		rv = 0;
+		break;
+	}
+
+	case IPMICTL_GET_MY_ADDRESS_CMD:
+	{
+		unsigned int val;
+
+		val = ipmi_get_my_address(priv->user);
+
+		if (copy_to_user((void *) data, &val, sizeof(val))) {
+			rv = -EFAULT;
+			break;
+		}
+		rv = 0;
+		break;
+	}
+
+	case IPMICTL_SET_MY_LUN_CMD:
+	{
+		unsigned int val;
+
+		if (copy_from_user(&val, (void *) data, sizeof(val))) {
+			rv = -EFAULT;
+			break;
+		}
+
+		ipmi_set_my_LUN(priv->user, val);
+		rv = 0;
+		break;
+	}
+
+	case IPMICTL_GET_MY_LUN_CMD:
+	{
+		unsigned int val;
+
+		val = ipmi_get_my_LUN(priv->user);
+
+		if (copy_to_user((void *) data, &val, sizeof(val))) {
+			rv = -EFAULT;
+			break;
+		}
+		rv = 0;
+		break;
+	}
+
+	}
+  
+	return rv;
+}
+
+
+static struct file_operations ipmi_fops = {
+	owner:   THIS_MODULE,
+	ioctl:   ipmi_ioctl,
+	open:    ipmi_open,
+	release: ipmi_release,
+	fasync:  ipmi_fasync,
+	poll:    ipmi_poll
+};
+
+#define DEVICE_NAME     "ipmidev"
+
+static int ipmi_major = 0;
+MODULE_PARM(ipmi_major, "i");
+
+static devfs_handle_t devfs_handle;
+
+#define MAX_DEVICES 10
+static devfs_handle_t handles[MAX_DEVICES];
+
+static void ipmi_new_smi(int if_num)
+{
+	char name[2];
+
+	if (if_num > MAX_DEVICES)
+		return;
+
+	name[0] = if_num + '0';
+	name[1] = '\0';
+
+	handles[if_num] = devfs_register(devfs_handle, name, DEVFS_FL_NONE,
+					 ipmi_major, if_num,
+					 S_IFCHR | S_IRUSR | S_IWUSR,
+					 &ipmi_fops, NULL);
+}
+
+static void ipmi_smi_gone(int if_num)
+{
+	if (if_num > MAX_DEVICES)
+		return;
+
+	devfs_unregister(handles[if_num]);
+}
+
+static struct ipmi_smi_watcher smi_watcher =
+{
+	new_smi  : ipmi_new_smi,
+	smi_gone : ipmi_smi_gone
+};
+
+static __init int init_ipmi_devintf(void)
+{
+	int rv;
+
+	if (ipmi_major < 0)
+		return -EINVAL;
+
+	rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
+	if (rv < 0) {
+		printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
+		return rv;
+	}
+
+	if (ipmi_major == 0) {
+		ipmi_major = rv;
+	}
+
+	devfs_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL);
+
+	rv = ipmi_smi_watcher_register(&smi_watcher);
+	if (rv) {
+		unregister_chrdev(ipmi_major, DEVICE_NAME);
+		printk(KERN_WARNING "ipmi: can't register smi watcher");
+		return rv;
+	}
+
+	printk(KERN_INFO "ipmi: device interface at char major %d\n",
+	       ipmi_major);
+
+	return 0;
+}
+module_init(init_ipmi_devintf);
+
+static __exit void cleanup_ipmi(void)
+{
+	ipmi_smi_watcher_unregister(&smi_watcher);
+	devfs_unregister(devfs_handle);
+	unregister_chrdev(ipmi_major, DEVICE_NAME);
+}
+module_exit(cleanup_ipmi);
+#ifndef MODULE
+static __init int ipmi_setup (char *str)
+{
+	int x;
+
+	if (get_option (&str, &x)) {
+		/* ipmi=x sets the major number to x. */
+		ipmi_major = x;
+	} else if (!strcmp(str, "off")) {
+		ipmi_major = -1;
+	}
+
+	return 1;
+}
+#endif
+
+__setup("ipmi=", ipmi_setup);
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/char/ipmi/ipmi_kcs_intf.c b/drivers/char/ipmi/ipmi_kcs_intf.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/ipmi/ipmi_kcs_intf.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,1242 @@
+/*
+ * ipmi_kcs_intf.c
+ *
+ * The interface to the IPMI driver for the KCS.
+ *
+ * Author: MontaVista Software, Inc.
+ *         Corey Minyard <minyard@mvista.com>
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * This file holds the "policy" for the interface to the KCS state
+ * machine.  It does the configuration, handles timers and interrupts,
+ * and drives the real KCS state machine.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/system.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+#ifdef CONFIG_HIGH_RES_TIMERS
+#include <linux/hrtime.h>
+#endif
+#include <linux/interrupt.h>
+#include <linux/rcupdate.h>
+#include <linux/ipmi_smi.h>
+#include <asm/io.h>
+#include "ipmi_kcs_sm.h"
+#include <linux/init.h>
+
+/* Measure times between events in the driver. */
+#undef DEBUG_TIMING
+
+#ifdef CONFIG_IPMI_KCS
+/* This forces a dependency to the config file for this option. */
+#endif
+
+enum kcs_intf_state {
+	KCS_NORMAL,
+	KCS_GETTING_FLAGS,
+	KCS_GETTING_EVENTS,
+	KCS_CLEARING_FLAGS,
+	KCS_CLEARING_FLAGS_THEN_SET_IRQ,
+	KCS_GETTING_MESSAGES,
+	KCS_ENABLE_INTERRUPTS1,
+	KCS_ENABLE_INTERRUPTS2
+	/* FIXME - add watchdog stuff. */
+};
+
+struct kcs_info
+{
+	ipmi_smi_t          intf;
+	struct kcs_data     *kcs_sm;
+	spinlock_t          kcs_lock;
+	spinlock_t          msg_lock;
+	struct list_head    xmit_msgs;
+	struct list_head    hp_xmit_msgs;
+	struct ipmi_smi_msg *curr_msg;
+	enum kcs_intf_state kcs_state;
+
+	/* Flags from the last GET_MSG_FLAGS command, used when an ATTN
+	   is set to hold the flags until we are done handling everything
+	   from the flags. */
+#define RECEIVE_MSG_AVAIL	0x01
+#define EVENT_MSG_BUFFER_FULL	0x02
+#define WDT_PRE_TIMEOUT_INT	0x08
+	unsigned char       msg_flags;
+
+	/* If set to true, this will request events the next time the
+	   state machine is idle. */
+	atomic_t            req_events;
+
+	/* If true, run the state machine to completion on every send
+	   call.  Generally used after a panic to make sure stuff goes
+	   out. */
+	int                 run_to_completion;
+
+	/* The I/O port of a KCS interface. */
+	int                 port;
+
+	/* zero if no irq; */
+	int                 irq;
+
+	/* The physical and remapped memory addresses of a KCS interface. */
+	unsigned long	    physaddr;
+	unsigned char	    *addr;
+
+	/* The timer for this kcs. */
+	struct timer_list   kcs_timer;
+
+	/* The time (in jiffies) the last timeout occurred at. */
+	unsigned long       last_timeout_jiffies;
+
+	/* Used to gracefully stop the timer without race conditions. */
+	volatile int        stop_operation;
+	volatile int        timer_stopped;
+
+	/* The driver will disable interrupts when it gets into a
+	   situation where it cannot handle messages due to lack of
+	   memory.  Once that situation clears up, it will re-enable
+	   interupts. */
+	int                 interrupt_disabled;
+};
+
+static void deliver_recv_msg(struct kcs_info *kcs_info, struct ipmi_smi_msg *msg)
+{
+	/* Deliver the message to the upper layer with the lock
+           released. */
+	spin_unlock(&(kcs_info->kcs_lock));
+	ipmi_smi_msg_received(kcs_info->intf, msg);
+	spin_lock(&(kcs_info->kcs_lock));
+}
+
+static void return_hosed_msg(struct kcs_info *kcs_info)
+{
+	struct ipmi_smi_msg *msg = kcs_info->curr_msg;
+
+	/* Make it a reponse */
+	msg->rsp[0] = msg->data[0] | 4;
+	msg->rsp[1] = msg->data[1];
+	msg->rsp[2] = 0xFF; /* Unknown error. */
+	msg->rsp_size = 3;
+			
+	kcs_info->curr_msg = NULL;
+	deliver_recv_msg(kcs_info, msg);
+}
+
+static enum kcs_result start_next_msg(struct kcs_info *kcs_info)
+{
+	int              rv;
+	struct list_head *entry = NULL;
+#ifdef DEBUG_TIMING
+	struct timeval t;
+#endif
+
+	/* No need to save flags, we aleady have interrupts off and we
+	   already hold the KCS lock. */
+	spin_lock(&(kcs_info->msg_lock));
+	
+	/* Pick the high priority queue first. */
+	if (! list_empty(&(kcs_info->hp_xmit_msgs))) {
+		entry = kcs_info->hp_xmit_msgs.next;
+	} else if (! list_empty(&(kcs_info->xmit_msgs))) {
+		entry = kcs_info->xmit_msgs.next;
+	}
+
+	if (!entry) {
+		kcs_info->curr_msg = NULL;
+		rv = KCS_SM_IDLE;
+	} else {
+		int err;
+
+		list_del(entry);
+		kcs_info->curr_msg = list_entry(entry,
+						struct ipmi_smi_msg,
+						link);
+#ifdef DEBUG_TIMING
+		do_gettimeofday(&t);
+		printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
+#endif
+		err = start_kcs_transaction(kcs_info->kcs_sm,
+					   kcs_info->curr_msg->data,
+					   kcs_info->curr_msg->data_size);
+		if (err) {
+			return_hosed_msg(kcs_info);
+		}
+
+		rv = KCS_CALL_WITHOUT_DELAY;
+	}
+	spin_unlock(&(kcs_info->msg_lock));
+
+	return rv;
+}
+
+static void start_enable_irq(struct kcs_info *kcs_info)
+{
+	unsigned char msg[2];
+
+	/* If we are enabling interrupts, we have to tell the
+	   BMC to use them. */
+	msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
+	msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
+
+	start_kcs_transaction(kcs_info->kcs_sm, msg, 2);
+	kcs_info->kcs_state = KCS_ENABLE_INTERRUPTS1;
+}
+
+static void start_clear_flags(struct kcs_info *kcs_info)
+{
+	unsigned char msg[3];
+
+	/* Make sure the watchdog pre-timeout flag is not set at startup. */
+	msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
+	msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
+	msg[2] = WDT_PRE_TIMEOUT_INT;
+
+	start_kcs_transaction(kcs_info->kcs_sm, msg, 3);
+	kcs_info->kcs_state = KCS_CLEARING_FLAGS;
+}
+
+/* When we have a situtaion where we run out of memory and cannot
+   allocate messages, we just leave them in the BMC and run the system
+   polled until we can allocate some memory.  Once we have some
+   memory, we will re-enable the interrupt. */
+static inline void disable_kcs_irq(struct kcs_info *kcs_info)
+{
+	if ((kcs_info->irq) && (!kcs_info->interrupt_disabled)) {
+		disable_irq_nosync(kcs_info->irq);
+		kcs_info->interrupt_disabled = 1;
+	}
+}
+
+static inline void enable_kcs_irq(struct kcs_info *kcs_info)
+{
+	if ((kcs_info->irq) && (kcs_info->interrupt_disabled)) {
+		enable_irq(kcs_info->irq);
+		kcs_info->interrupt_disabled = 0;
+	}
+}
+
+static void handle_flags(struct kcs_info *kcs_info)
+{
+	if (kcs_info->msg_flags & WDT_PRE_TIMEOUT_INT) {
+		/* Watchdog pre-timeout */
+		start_clear_flags(kcs_info);
+		kcs_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
+		spin_unlock(&(kcs_info->kcs_lock));
+		ipmi_smi_watchdog_pretimeout(kcs_info->intf);
+		spin_lock(&(kcs_info->kcs_lock));
+	} else if (kcs_info->msg_flags & RECEIVE_MSG_AVAIL) {
+		/* Messages available. */
+		kcs_info->curr_msg = ipmi_alloc_smi_msg();
+		if (!kcs_info->curr_msg) {
+			disable_kcs_irq(kcs_info);
+			kcs_info->kcs_state = KCS_NORMAL;
+			return;
+		}
+		enable_kcs_irq(kcs_info);
+
+		kcs_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
+		kcs_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
+		kcs_info->curr_msg->data_size = 2;
+
+		start_kcs_transaction(kcs_info->kcs_sm,
+				      kcs_info->curr_msg->data,
+				      kcs_info->curr_msg->data_size);
+		kcs_info->kcs_state = KCS_GETTING_MESSAGES;
+	} else if (kcs_info->msg_flags & EVENT_MSG_BUFFER_FULL) {
+		/* Events available. */
+		kcs_info->curr_msg = ipmi_alloc_smi_msg();
+		if (!kcs_info->curr_msg) {
+			disable_kcs_irq(kcs_info);
+			kcs_info->kcs_state = KCS_NORMAL;
+			return;
+		}
+		enable_kcs_irq(kcs_info);
+
+		kcs_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
+		kcs_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
+		kcs_info->curr_msg->data_size = 2;
+
+		start_kcs_transaction(kcs_info->kcs_sm,
+				      kcs_info->curr_msg->data,
+				      kcs_info->curr_msg->data_size);
+		kcs_info->kcs_state = KCS_GETTING_EVENTS;
+	} else {
+		kcs_info->kcs_state = KCS_NORMAL;
+	}
+}
+
+static void handle_transaction_done(struct kcs_info *kcs_info)
+{
+	struct ipmi_smi_msg *msg;
+#ifdef DEBUG_TIMING
+	struct timeval t;
+
+	do_gettimeofday(&t);
+	printk("**Done: %d.%9.9d\n", t.tv_sec, t.tv_usec);
+#endif
+	switch (kcs_info->kcs_state) {
+	case KCS_NORMAL:
+		kcs_info->curr_msg->rsp_size
+			= kcs_get_result(kcs_info->kcs_sm,
+					 kcs_info->curr_msg->rsp,
+					 IPMI_MAX_MSG_LENGTH);
+		
+		/* Do this here becase deliver_recv_msg() releases the
+		   lock, and a new message can be put in during the
+		   time the lock is released. */
+		msg = kcs_info->curr_msg;
+		kcs_info->curr_msg = NULL;
+		deliver_recv_msg(kcs_info, msg);
+		break;
+		
+	case KCS_GETTING_FLAGS:
+	{
+		unsigned char msg[4];
+		unsigned int  len;
+
+		/* We got the flags from the KCS, now handle them. */
+		len = kcs_get_result(kcs_info->kcs_sm, msg, 4);
+		if (msg[2] != 0) {
+			/* Error fetching flags, just give up for
+			   now. */
+			kcs_info->kcs_state = KCS_NORMAL;
+		} else if (len < 3) {
+			/* Hmm, no flags.  That's technically illegal, but
+			   don't use uninitialized data. */
+			kcs_info->kcs_state = KCS_NORMAL;
+		} else {
+			kcs_info->msg_flags = msg[3];
+			handle_flags(kcs_info);
+		}
+		break;
+	}
+
+	case KCS_CLEARING_FLAGS:
+	case KCS_CLEARING_FLAGS_THEN_SET_IRQ:
+	{
+		unsigned char msg[3];
+
+		/* We cleared the flags. */
+		kcs_get_result(kcs_info->kcs_sm, msg, 3);
+		if (msg[2] != 0) {
+			/* Error clearing flags */
+			printk(KERN_WARNING
+			       "ipmi_kcs: Error clearing flags: %2.2x\n",
+			       msg[2]);
+		}
+		if (kcs_info->kcs_state == KCS_CLEARING_FLAGS_THEN_SET_IRQ)
+			start_enable_irq(kcs_info);
+		else
+			kcs_info->kcs_state = KCS_NORMAL;
+		break;
+	}
+
+	case KCS_GETTING_EVENTS:
+	{
+		kcs_info->curr_msg->rsp_size
+			= kcs_get_result(kcs_info->kcs_sm,
+					 kcs_info->curr_msg->rsp,
+					 IPMI_MAX_MSG_LENGTH);
+
+		/* Do this here becase deliver_recv_msg() releases the
+		   lock, and a new message can be put in during the
+		   time the lock is released. */
+		msg = kcs_info->curr_msg;
+		kcs_info->curr_msg = NULL;
+		if (msg->rsp[2] != 0) {
+			/* Error getting event, probably done. */
+			msg->done(msg);
+
+			/* Take off the event flag. */
+			kcs_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
+		} else {
+			deliver_recv_msg(kcs_info, msg);
+		}
+		handle_flags(kcs_info);
+		break;
+	}
+
+	case KCS_GETTING_MESSAGES:
+	{
+		kcs_info->curr_msg->rsp_size
+			= kcs_get_result(kcs_info->kcs_sm,
+					 kcs_info->curr_msg->rsp,
+					 IPMI_MAX_MSG_LENGTH);
+
+		/* Do this here becase deliver_recv_msg() releases the
+		   lock, and a new message can be put in during the
+		   time the lock is released. */
+		msg = kcs_info->curr_msg;
+		kcs_info->curr_msg = NULL;
+		if (msg->rsp[2] != 0) {
+			/* Error getting event, probably done. */
+			msg->done(msg);
+
+			/* Take off the msg flag. */
+			kcs_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
+		} else {
+			deliver_recv_msg(kcs_info, msg);
+		}
+		handle_flags(kcs_info);
+		break;
+	}
+
+	case KCS_ENABLE_INTERRUPTS1:
+	{
+		unsigned char msg[4];
+
+		/* We got the flags from the KCS, now handle them. */
+		kcs_get_result(kcs_info->kcs_sm, msg, 4);
+		if (msg[2] != 0) {
+			printk(KERN_WARNING
+			       "ipmi_kcs: Could not enable interrupts"
+			       ", failed get, using polled mode.\n");
+			kcs_info->kcs_state = KCS_NORMAL;
+		} else {
+			msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
+			msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
+			msg[2] = msg[3] | 1; /* enable msg queue int */
+			start_kcs_transaction(kcs_info->kcs_sm, msg,3);
+			kcs_info->kcs_state = KCS_ENABLE_INTERRUPTS2;
+		}
+		break;
+	}
+
+	case KCS_ENABLE_INTERRUPTS2:
+	{
+		unsigned char msg[4];
+
+		/* We got the flags from the KCS, now handle them. */
+		kcs_get_result(kcs_info->kcs_sm, msg, 4);
+		if (msg[2] != 0) {
+			printk(KERN_WARNING
+			       "ipmi_kcs: Could not enable interrupts"
+			       ", failed set, using polled mode.\n");
+		}
+		kcs_info->kcs_state = KCS_NORMAL;
+		break;
+	}
+	}
+}
+
+/* Called on timeouts and events.  Timeouts should pass the elapsed
+   time, interrupts should pass in zero. */
+static enum kcs_result kcs_event_handler(struct kcs_info *kcs_info, int time)
+{
+	enum kcs_result kcs_result;
+
+ restart:
+	/* There used to be a loop here that waited a little while
+	   (around 25us) before giving up.  That turned out to be
+	   pointless, the minimum delays I was seeing were in the 300us
+	   range, which is far too long to wait in an interrupt.  So
+	   we just run until the state machine tells us something
+	   happened or it needs a delay. */
+	kcs_result = kcs_event(kcs_info->kcs_sm, time);
+	time = 0;
+	while (kcs_result == KCS_CALL_WITHOUT_DELAY)
+	{
+		kcs_result = kcs_event(kcs_info->kcs_sm, 0);
+	}
+
+	if (kcs_result == KCS_TRANSACTION_COMPLETE)
+	{
+		handle_transaction_done(kcs_info);
+		kcs_result = kcs_event(kcs_info->kcs_sm, 0);
+	}
+	else if (kcs_result == KCS_SM_HOSED)
+	{
+		if (kcs_info->curr_msg != NULL) {
+			/* If we were handling a user message, format
+                           a response to send to the upper layer to
+                           tell it about the error. */
+			return_hosed_msg(kcs_info);
+		}
+		kcs_result = kcs_event(kcs_info->kcs_sm, 0);
+		kcs_info->kcs_state = KCS_NORMAL;
+	}
+
+	/* We prefer handling attn over new messages. */
+	if (kcs_result == KCS_ATTN)
+	{
+		unsigned char msg[2];
+
+		/* Got a attn, send down a get message flags to see
+                   what's causing it.  It would be better to handle
+                   this in the upper layer, but due to the way
+                   interrupts work with the KCS, that's not really
+                   possible. */
+		msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
+		msg[1] = IPMI_GET_MSG_FLAGS_CMD;
+
+		start_kcs_transaction(kcs_info->kcs_sm, msg, 2);
+		kcs_info->kcs_state = KCS_GETTING_FLAGS;
+		goto restart;
+	}
+
+	/* If we are currently idle, try to start the next message. */
+	if (kcs_result == KCS_SM_IDLE) {
+		kcs_result = start_next_msg(kcs_info);
+		if (kcs_result != KCS_SM_IDLE)
+			goto restart;
+        }
+
+	if ((kcs_result == KCS_SM_IDLE)
+	    && (atomic_read(&kcs_info->req_events)))
+	{
+		/* We are idle and the upper layer requested that I fetch
+		   events, so do so. */
+		unsigned char msg[2];
+
+		atomic_set(&kcs_info->req_events, 0);
+		msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
+		msg[1] = IPMI_GET_MSG_FLAGS_CMD;
+
+		start_kcs_transaction(kcs_info->kcs_sm, msg, 2);
+		kcs_info->kcs_state = KCS_GETTING_FLAGS;
+		goto restart;
+	}
+
+	return kcs_result;
+}
+
+static void sender(void                *send_info,
+		   struct ipmi_smi_msg *msg,
+		   int                 priority)
+{
+	struct kcs_info *kcs_info = (struct kcs_info *) send_info;
+	enum kcs_result result;
+	unsigned long   flags;
+#ifdef DEBUG_TIMING
+	struct timeval t;
+#endif
+
+	spin_lock_irqsave(&(kcs_info->msg_lock), flags);
+#ifdef DEBUG_TIMING
+	do_gettimeofday(&t);
+	printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec);
+#endif
+
+	if (kcs_info->run_to_completion) {
+		/* If we are running to completion, then throw it in
+		   the list and run transactions until everything is
+		   clear.  Priority doesn't matter here. */
+		list_add_tail(&(msg->link), &(kcs_info->xmit_msgs));
+
+		/* We have to release the msg lock and claim the kcs
+		   lock in this case, because of race conditions. */
+		spin_unlock_irqrestore(&(kcs_info->msg_lock), flags);
+
+		spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
+		result = kcs_event_handler(kcs_info, 0);
+		while (result != KCS_SM_IDLE) {
+			udelay(500);
+			result = kcs_event_handler(kcs_info, 500);
+		}
+		spin_unlock_irqrestore(&(kcs_info->kcs_lock), flags);
+		return;
+	} else {
+		if (priority > 0) {
+			list_add_tail(&(msg->link), &(kcs_info->hp_xmit_msgs));
+		} else {
+			list_add_tail(&(msg->link), &(kcs_info->xmit_msgs));
+		}
+	}
+	spin_unlock_irqrestore(&(kcs_info->msg_lock), flags);
+
+	spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
+	if ((kcs_info->kcs_state == KCS_NORMAL)
+	    && (kcs_info->curr_msg == NULL))
+	{
+		start_next_msg(kcs_info);
+	}
+	spin_unlock_irqrestore(&(kcs_info->kcs_lock), flags);
+}
+
+static void set_run_to_completion(void *send_info, int i_run_to_completion)
+{
+	struct kcs_info *kcs_info = (struct kcs_info *) send_info;
+	enum kcs_result result;
+	unsigned long   flags;
+
+	spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
+
+	kcs_info->run_to_completion = i_run_to_completion;
+	if (i_run_to_completion) {
+		result = kcs_event_handler(kcs_info, 0);
+		while (result != KCS_SM_IDLE) {
+			udelay(500);
+			result = kcs_event_handler(kcs_info, 500);
+		}
+	}
+
+	spin_unlock_irqrestore(&(kcs_info->kcs_lock), flags);
+}
+
+static void request_events(void *send_info)
+{
+	struct kcs_info *kcs_info = (struct kcs_info *) send_info;
+
+	atomic_set(&kcs_info->req_events, 1);
+}
+
+static int new_user(void *send_info)
+{
+	if (!try_module_get(THIS_MODULE))
+		return -EBUSY;
+	return 0;
+}
+
+static void user_left(void *send_info)
+{
+	module_put(THIS_MODULE);
+}
+
+/* Call every 10 ms. */
+#define KCS_TIMEOUT_TIME_USEC	10000
+#define KCS_USEC_PER_JIFFY	(1000000/HZ)
+#define KCS_TIMEOUT_JIFFIES	(KCS_TIMEOUT_TIME_USEC/KCS_USEC_PER_JIFFY)
+#define KCS_SHORT_TIMEOUT_USEC  500 /* .5ms when the SM request a
+                                       short timeout */
+static int initialized = 0;
+
+static void kcs_timeout(unsigned long data)
+{
+	struct kcs_info *kcs_info = (struct kcs_info *) data;
+	enum kcs_result kcs_result;
+	unsigned long   flags;
+	unsigned long   jiffies_now;
+	unsigned long   time_diff;
+#ifdef DEBUG_TIMING
+	struct timeval t;
+#endif
+
+	if (kcs_info->stop_operation) {
+		kcs_info->timer_stopped = 1;
+		return;
+	}
+
+	spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
+#ifdef DEBUG_TIMING
+	do_gettimeofday(&t);
+	printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec);
+#endif
+	jiffies_now = jiffies;
+	time_diff = ((jiffies_now - kcs_info->last_timeout_jiffies)
+		     * KCS_USEC_PER_JIFFY);
+	kcs_result = kcs_event_handler(kcs_info, time_diff);
+
+	spin_unlock_irqrestore(&(kcs_info->kcs_lock), flags);
+
+	kcs_info->last_timeout_jiffies = jiffies_now;
+
+	if ((kcs_info->irq) && (! kcs_info->interrupt_disabled)) {
+		/* Running with interrupts, only do long timeouts. */
+		kcs_info->kcs_timer.expires = jiffies + KCS_TIMEOUT_JIFFIES;
+		goto do_add_timer;
+	}
+
+	/* If the state machine asks for a short delay, then shorten
+           the timer timeout. */
+#ifdef CONFIG_HIGH_RES_TIMERS
+	if (kcs_result == KCS_CALL_WITH_DELAY) {
+		kcs_info->kcs_timer.sub_expires
+			+= usec_to_arch_cycles(KCS_SHORT_TIMEOUT_USEC);
+		while (kcs_info->kcs_timer.sub_expires >= cycles_per_jiffies) {
+			kcs_info->kcs_timer.expires++;
+			kcs_info->kcs_timer.sub_expires -= cycles_per_jiffies;
+		}
+	} else {
+		kcs_info->kcs_timer.expires = jiffies + KCS_TIMEOUT_JIFFIES;
+	}
+#else
+	/* If requested, take the shortest delay possible */
+	if (kcs_result == KCS_CALL_WITH_DELAY) {
+		kcs_info->kcs_timer.expires = jiffies + 1;
+	} else {
+		kcs_info->kcs_timer.expires = jiffies + KCS_TIMEOUT_JIFFIES;
+	}
+#endif
+
+ do_add_timer:
+	add_timer(&(kcs_info->kcs_timer));
+}
+
+static void kcs_irq_handler(int irq, void *data, struct pt_regs *regs)
+{
+	struct kcs_info *kcs_info = (struct kcs_info *) data;
+	unsigned long   flags;
+#ifdef DEBUG_TIMING
+	struct timeval t;
+#endif
+
+	spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
+	if (kcs_info->stop_operation)
+		goto out;
+
+#ifdef DEBUG_TIMING
+	do_gettimeofday(&t);
+	printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec);
+#endif
+	kcs_event_handler(kcs_info, 0);
+ out:
+	spin_unlock_irqrestore(&(kcs_info->kcs_lock), flags);
+}
+
+static struct ipmi_smi_handlers handlers =
+{
+	sender:		       sender,
+	request_events:        request_events,
+	new_user:	       new_user,
+	user_left:	       user_left,
+	set_run_to_completion: set_run_to_completion
+};
+
+static unsigned char ipmi_kcs_dev_rev;
+static unsigned char ipmi_kcs_fw_rev_major;
+static unsigned char ipmi_kcs_fw_rev_minor;
+static unsigned char ipmi_version_major;
+static unsigned char ipmi_version_minor;
+
+extern int kcs_dbg;
+static int ipmi_kcs_detect_hardware(unsigned int port,
+				    unsigned char *addr,
+				    struct kcs_data *data)
+{
+	unsigned char   msg[2];
+	unsigned char   resp[IPMI_MAX_MSG_LENGTH];
+	unsigned long   resp_len;
+	enum kcs_result kcs_result;
+
+	/* It's impossible for the KCS status register to be all 1's,
+	   (assuming a properly functioning, self-initialized BMC)
+	   but that's what you get from reading a bogus address, so we
+	   test that first. */
+
+	if (port) {
+		if (inb(port+1) == 0xff) return -ENODEV; 
+	} else { 
+		if (readb(addr+1) == 0xff) return -ENODEV; 
+	}
+
+	/* Do a Get Device ID command, since it comes back with some
+	   useful info. */
+	msg[0] = IPMI_NETFN_APP_REQUEST << 2;
+	msg[1] = IPMI_GET_DEVICE_ID_CMD;
+	start_kcs_transaction(data, msg, 2);
+	
+	kcs_result = kcs_event(data, 0);
+	for (;;)
+	{
+		if (kcs_result == KCS_CALL_WITH_DELAY) {
+			udelay(100);
+			kcs_result = kcs_event(data, 100);
+		}
+		else if (kcs_result == KCS_CALL_WITHOUT_DELAY)
+		{
+			kcs_result = kcs_event(data, 0);
+		}
+		else
+			break;
+	}
+	if (kcs_result == KCS_SM_HOSED) {
+		/* We couldn't get the state machine to run, so whatever's at
+		   the port is probably not an IPMI KCS interface. */
+		return -ENODEV;
+	}
+	/* Otherwise, we got some data. */
+	resp_len = kcs_get_result(data, resp, IPMI_MAX_MSG_LENGTH);
+	if (resp_len < 6)
+		/* That's odd, it should be longer. */
+		return -EINVAL;
+	
+	if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0))
+		/* That's odd, it shouldn't be able to fail. */
+		return -EINVAL;
+	
+	ipmi_kcs_dev_rev = resp[4] & 0xf;
+	ipmi_kcs_fw_rev_major = resp[5] & 0x7f;
+	ipmi_kcs_fw_rev_minor = resp[6];
+	ipmi_version_major = resp[7] & 0xf;
+	ipmi_version_minor = resp[7] >> 4;
+
+	return 0;
+}
+
+/* There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
+   a default IO port, and 1 ACPI/SPMI address.  That sets KCS_MAX_DRIVERS */
+
+#define KCS_MAX_PARMS 4
+#define KCS_MAX_DRIVERS ((KCS_MAX_PARMS * 2) + 2)
+static struct kcs_info *kcs_infos[KCS_MAX_DRIVERS] =
+{ NULL, NULL, NULL, NULL };
+
+#define DEVICE_NAME "ipmi_kcs"
+
+#define DEFAULT_IO_PORT 0xca2
+
+static int kcs_trydefaults = 1;
+static unsigned long kcs_addrs[KCS_MAX_PARMS] = { 0, 0, 0, 0 };
+static int kcs_ports[KCS_MAX_PARMS] = { 0, 0, 0, 0 };
+static int kcs_irqs[KCS_MAX_PARMS] = { 0, 0, 0, 0 };
+
+MODULE_PARM(kcs_trydefaults, "i");
+MODULE_PARM(kcs_addrs, "1-4l");
+MODULE_PARM(kcs_irqs, "1-4i");
+MODULE_PARM(kcs_ports, "1-4i");
+
+/* Returns 0 if initialized, or negative on an error. */
+static int init_one_kcs(int kcs_port, 
+			int irq, 
+			unsigned long kcs_physaddr,
+			struct kcs_info **kcs)
+{
+	int		rv;
+	struct kcs_info *new_kcs;
+
+	/* Did anything get passed in at all?  Both == zero disables the
+	   driver. */
+
+	if (!(kcs_port || kcs_physaddr)) 
+		return -ENODEV;
+	
+	/* Only initialize a port OR a physical address on this call.
+	   Also, IRQs can go with either ports or addresses. */
+
+	if (kcs_port && kcs_physaddr)
+		return -EINVAL;
+
+	new_kcs = kmalloc(kcs_size(), GFP_KERNEL);
+	if (!new_kcs) {
+		printk(KERN_ERR "ipmi_kcs: out of memory\n");
+		return -ENOMEM;
+	}
+
+	/* So we know not to free it unless we have allocated one. */
+	new_kcs->kcs_sm = NULL;
+
+	new_kcs->addr = NULL;
+	new_kcs->physaddr = kcs_physaddr;
+	new_kcs->port = kcs_port;
+
+	if (kcs_port) {
+		if (request_region(kcs_port, 2, DEVICE_NAME) == NULL) {
+			kfree(new_kcs);
+			printk(KERN_ERR 
+			       "ipmi_kcs: can't reserve port @ 0x%4.4x\n",
+		       	       kcs_port);
+			return -EIO;
+		}
+	} else {
+		if (request_mem_region(kcs_physaddr, 2, DEVICE_NAME) == NULL) {
+			kfree(new_kcs);
+			printk(KERN_ERR 
+			       "ipmi_kcs: can't reserve memory @ 0x%lx\n",
+		       	       kcs_physaddr);
+			return -EIO;
+		}
+		if ((new_kcs->addr = ioremap(kcs_physaddr, 2)) == NULL) {
+			kfree(new_kcs);
+			printk(KERN_ERR 
+			       "ipmi_kcs: can't remap memory at 0x%lx\n",
+		       	       kcs_physaddr);
+			return -EIO;
+		}
+	}
+
+	new_kcs->kcs_sm = kmalloc(kcs_size(), GFP_KERNEL);
+	if (!new_kcs->kcs_sm) {
+		printk(KERN_ERR "ipmi_kcs: out of memory\n");
+		rv = -ENOMEM;
+		goto out_err;
+	}
+	init_kcs_data(new_kcs->kcs_sm, kcs_port, new_kcs->addr);
+	spin_lock_init(&(new_kcs->kcs_lock));
+	spin_lock_init(&(new_kcs->msg_lock));
+
+	rv = ipmi_kcs_detect_hardware(kcs_port, new_kcs->addr, new_kcs->kcs_sm);
+	if (rv) {
+		if (kcs_port) 
+			printk(KERN_ERR 
+			       "ipmi_kcs: No KCS @ port 0x%4.4x\n", 
+			       kcs_port);
+		else
+			printk(KERN_ERR 
+			       "ipmi_kcs: No KCS @ addr 0x%lx\n", 
+			       kcs_physaddr);
+		goto out_err;
+	}
+
+	if (irq != 0) {
+		rv = request_irq(irq,
+				 kcs_irq_handler,
+				 SA_INTERRUPT,
+				 DEVICE_NAME,
+				 new_kcs);
+		if (rv) {
+			printk(KERN_WARNING
+			       "ipmi_kcs: %s unable to claim interrupt %d,"
+			       " running polled\n",
+			       DEVICE_NAME, irq);
+			irq = 0;
+		}
+	}
+	new_kcs->irq = irq;
+
+	INIT_LIST_HEAD(&(new_kcs->xmit_msgs));
+	INIT_LIST_HEAD(&(new_kcs->hp_xmit_msgs));
+	new_kcs->curr_msg = NULL;
+	atomic_set(&new_kcs->req_events, 0);
+	new_kcs->run_to_completion = 0;
+
+	start_clear_flags(new_kcs);
+
+	if (irq) {
+		new_kcs->kcs_state = KCS_CLEARING_FLAGS_THEN_SET_IRQ;
+
+		printk(KERN_INFO 
+		       "ipmi_kcs: Acquiring BMC @ port=0x%x irq=%d\n",
+		       kcs_port, irq);
+
+	} else {
+		if (kcs_port)
+			printk(KERN_INFO 
+			       "ipmi_kcs: Acquiring BMC @ port=0x%x\n",
+		       	       kcs_port);
+		else
+			printk(KERN_INFO 
+			       "ipmi_kcs: Acquiring BMC @ addr=0x%lx\n",
+		       	       kcs_physaddr);
+	}
+
+	rv = ipmi_register_smi(&handlers,
+			       new_kcs,
+			       ipmi_version_major,
+			       ipmi_version_minor,
+			       &(new_kcs->intf));
+	if (rv) {
+		free_irq(irq, new_kcs);
+		printk(KERN_ERR 
+		       "ipmi_kcs: Unable to register device: error %d\n",
+		       rv);
+		goto out_err;
+	}
+
+	new_kcs->interrupt_disabled = 0;
+	new_kcs->timer_stopped = 0;
+	new_kcs->stop_operation = 0;
+
+	init_timer(&(new_kcs->kcs_timer));
+	new_kcs->kcs_timer.data = (long) new_kcs;
+	new_kcs->kcs_timer.function = kcs_timeout;
+	new_kcs->last_timeout_jiffies = jiffies;
+	new_kcs->kcs_timer.expires = jiffies + KCS_TIMEOUT_JIFFIES;
+	add_timer(&(new_kcs->kcs_timer));
+
+	*kcs = new_kcs;
+
+	return 0;
+
+ out_err:
+	if (kcs_port) 
+		release_region (kcs_port, 2);
+	if (new_kcs->addr) 
+		iounmap(new_kcs->addr);
+	if (kcs_physaddr) 
+		release_mem_region(kcs_physaddr, 2);
+	if (new_kcs->kcs_sm)
+		kfree(new_kcs->kcs_sm);
+	kfree(new_kcs);
+	return rv;
+}
+
+#ifdef CONFIG_ACPI
+
+/* Retrieve the base physical address from ACPI tables.  Originally
+   from Hewlett-Packard simple bmc.c, a GPL KCS driver. */
+
+#include <linux/acpi.h>
+
+struct SPMITable {
+	s8	Signature[4];
+	u32	Length;
+	u8	Revision;
+	u8	Checksum;
+	s8	OEMID[6];
+	s8	OEMTableID[8];
+	s8	OEMRevision[4];
+	s8	CreatorID[4];
+	s8	CreatorRevision[4];
+	s16	InterfaceType;
+	s16	SpecificationRevision;
+	u8	InterruptType;
+	u8	GPE;
+	s16	Reserved;
+	u64	GlobalSystemInterrupt;
+	u8	BaseAddress[12];
+	u8	UID[4];
+} __attribute__ ((packed));
+
+static unsigned long acpi_find_bmc(void)
+{
+	acpi_status status;
+	struct acpi_table_header *spmi;
+	static unsigned long io_base = 0;
+
+	if (io_base != 0)
+		return io_base;
+
+	status = acpi_get_firmware_table("SPMI", 1,
+			ACPI_LOGICAL_ADDRESSING, &spmi);
+
+	if (status != AE_OK) {
+		printk(KERN_ERR "ipmi_kcs: SPMI table not found.\n");
+		return 0;
+	}
+
+	memcpy(&io_base, ((struct SPMITable *)spmi)->BaseAddress,
+			sizeof(io_base));
+	
+	return io_base;
+}
+#endif
+
+static __init int init_ipmi_kcs(void)
+{
+	int		rv = 0;
+	int		pos = 0;
+	int		i = 0;
+#ifdef CONFIG_ACPI
+	unsigned long	physaddr = 0;
+#endif
+
+	if (initialized)
+		return 0;
+	initialized = 1;
+
+	/* First do the "command-line" parameters */
+
+	for (i=0; i < KCS_MAX_PARMS; i++) {
+		rv = init_one_kcs(kcs_ports[i], 
+				  kcs_irqs[i], 
+				  0, 
+				  &(kcs_infos[pos]));
+		if (rv == 0)
+			pos++;
+
+		rv = init_one_kcs(0, 
+				  kcs_irqs[i], 
+				  kcs_addrs[i], 
+				  &(kcs_infos[pos]));
+		if (rv == 0)
+			pos++;
+	}
+
+	/* Only try the defaults if enabled and resources are available
+	   (because they weren't already specified above). */
+
+	if (kcs_trydefaults) {
+#ifdef CONFIG_ACPI
+		if ((physaddr = acpi_find_bmc())) {
+			if (!check_mem_region(physaddr, 2)) {
+				rv = init_one_kcs(0, 
+						  0, 
+						  physaddr, 
+						  &(kcs_infos[pos]));
+				if (rv == 0)
+					pos++;
+			}
+		}
+#endif
+		if (!check_region(DEFAULT_IO_PORT, 2)) {
+			rv = init_one_kcs(DEFAULT_IO_PORT, 
+					  0, 
+					  0, 
+					  &(kcs_infos[pos]));
+			if (rv == 0)
+				pos++;
+		}
+	}
+
+	if (kcs_infos[0] == NULL) {
+		printk("ipmi_kcs: Unable to find any KCS interfaces\n");
+		return -ENODEV;
+	} 
+
+	return 0;
+}
+module_init(init_ipmi_kcs);
+
+#ifdef MODULE
+void __exit cleanup_one_kcs(struct kcs_info *to_clean)
+{
+	int           rv;
+	unsigned long flags;
+
+	if (! to_clean)
+		return;
+
+	/* Tell the timer and interrupt handlers that we are shutting
+	   down. */
+	spin_lock_irqsave(&(to_clean->kcs_lock), flags);
+	spin_lock(&(to_clean->msg_lock));
+
+	to_clean->stop_operation = 1;
+
+	if (to_clean->irq != 0)
+		free_irq(to_clean->irq, to_clean);
+	if (to_clean->port) {
+		printk(KERN_INFO 
+		       "ipmi_kcs: Releasing BMC @ port=0x%x\n",
+		       to_clean->port);
+		release_region (to_clean->port, 2);
+	}
+	if (to_clean->addr) {
+		printk(KERN_INFO 
+		       "ipmi_kcs: Releasing BMC @ addr=0x%lx\n",
+		       to_clean->physaddr);
+		iounmap(to_clean->addr);
+		release_mem_region(to_clean->physaddr, 2);
+	}
+
+	spin_unlock(&(to_clean->msg_lock));
+	spin_unlock_irqrestore(&(to_clean->kcs_lock), flags);
+
+	/* Wait until we know that we are out of any interrupt
+	   handlers might have been running before we freed the
+	   interrupt. */
+	synchronize_kernel();
+
+	/* Wait for the timer to stop.  This avoids problems with race
+	   conditions removing the timer here. */
+	while (!to_clean->timer_stopped) {
+		schedule_timeout(1);
+	}
+
+	rv = ipmi_unregister_smi(to_clean->intf);
+	if (rv) {
+		printk(KERN_ERR 
+		       "ipmi_kcs: Unable to unregister device: errno=%d\n",
+		       rv);
+	}
+
+	initialized = 0;
+
+	kfree(to_clean->kcs_sm);
+	kfree(to_clean);
+}
+
+static __exit void cleanup_ipmi_kcs(void)
+{
+	int i;
+
+	if (!initialized)
+		return;
+
+	for (i=0; i<KCS_MAX_DRIVERS; i++) {
+		cleanup_one_kcs(kcs_infos[i]);
+	}
+}
+module_exit(cleanup_ipmi_kcs);
+#else
+
+/* Unfortunately, cmdline::get_options() only returns integers, not
+   longs.  Since we need ulongs (64-bit physical addresses) parse the 
+   comma-separated list manually.  Arguments can be one of these forms:
+   m0xaabbccddeeff	A physical memory address without an IRQ
+   m0xaabbccddeeff:cc	A physical memory address with an IRQ
+   p0xaabb		An IO port without an IRQ
+   p0xaabb:cc		An IO port with an IRQ
+   nodefaults		Suppress trying the default IO port or ACPI address 
+
+   For example, to pass one IO port with an IRQ, one address, and 
+   suppress the use of the default IO port and ACPI address,
+   use this option string: ipmi_kcs=p0xCA2:5,m0xFF5B0022,nodefaults
+
+   Remember, ipmi_kcs_setup() is passed the string after the equal sign. */
+
+static int __init ipmi_kcs_setup(char *str)
+{
+	unsigned long val;
+	char *cur, *colon;
+	int pos;
+
+	pos = 0;
+	
+	cur = strsep(&str, ",");
+	while ((cur) && (*cur) && (pos < KCS_MAX_PARMS)) {
+		switch (*cur) {
+		case 'n':
+			if (strcmp(cur, "nodefaults") == 0)
+				kcs_trydefaults = 0;
+			else
+				printk(KERN_INFO 
+				       "ipmi_kcs: bad parameter value %s\n",
+				       cur);
+			break;
+		
+		case 'm':
+		case 'p':
+			val = simple_strtoul(cur + 1,
+					     &colon,
+					     0);
+			if (*cur == 'p')
+				kcs_ports[pos] = val;
+			else
+				kcs_addrs[pos] = val;
+			if (*colon == ':') {
+				val = simple_strtoul(colon + 1,
+						     &colon,
+						     0);
+				kcs_irqs[pos] = val;
+			}
+			pos++;
+			break;
+
+		default:
+			printk(KERN_INFO 
+			       "ipmi_kcs: bad parameter value %s\n",
+			       cur);
+		}
+		cur = strsep(&str, ",");
+	}
+
+	return 1;
+}
+__setup("ipmi_kcs=", ipmi_kcs_setup);
+#endif
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,485 @@
+/*
+ * ipmi_kcs_sm.c
+ *
+ * State machine for handling IPMI KCS interfaces.
+ *
+ * Author: MontaVista Software, Inc.
+ *         Corey Minyard <minyard@mvista.com>
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * This state machine is taken from the state machine in the IPMI spec,
+ * pretty much verbatim.  If you have questions about the states, see
+ * that document.
+ */
+
+#include <asm/io.h>
+#include <asm/string.h>		/* Gets rid of memcpy warning */
+
+#include "ipmi_kcs_sm.h"
+
+/* Set this if you want a printout of why the state machine was hosed
+   when it gets hosed. */
+#define DEBUG_HOSED_REASON
+
+/* Print the state machine state on entry every time. */
+#undef DEBUG_STATE
+
+/* The states the KCS driver may be in. */
+enum kcs_states {
+	KCS_IDLE,		/* The KCS interface is currently
+                                   doing nothing. */
+	KCS_START_OP,		/* We are starting an operation.  The
+				   data is in the output buffer, but
+				   nothing has been done to the
+				   interface yet.  This was added to
+				   the state machine in the spec to
+				   wait for the initial IBF. */
+	KCS_WAIT_WRITE_START,	/* We have written a write cmd to the
+				   interface. */
+	KCS_WAIT_WRITE,		/* We are writing bytes to the
+                                   interface. */
+	KCS_WAIT_WRITE_END,	/* We have written the write end cmd
+                                   to the interface, and still need to
+                                   write the last byte. */
+	KCS_WAIT_READ,		/* We are waiting to read data from
+				   the interface. */
+	KCS_ERROR0,		/* State to transition to the error
+				   handler, this was added to the
+				   state machine in the spec to be
+				   sure IBF was there. */
+	KCS_ERROR1,		/* First stage error handler, wait for
+                                   the interface to respond. */
+	KCS_ERROR2,		/* The abort cmd has been written,
+				   wait for the interface to
+				   respond. */
+	KCS_ERROR3,		/* We wrote some data to the
+				   interface, wait for it to switch to
+				   read mode. */
+	KCS_HOSED		/* The hardware failed to follow the
+				   state machine. */
+};
+
+#define MAX_KCS_READ_SIZE 80
+#define MAX_KCS_WRITE_SIZE 80
+
+/* Timeouts in microseconds. */
+#define IBF_RETRY_TIMEOUT 1000000
+#define OBF_RETRY_TIMEOUT 1000000
+#define MAX_ERROR_RETRIES 10
+
+#define IPMI_ERR_MSG_TRUNCATED	0xc6
+#define IPMI_ERR_UNSPECIFIED	0xff
+
+struct kcs_data
+{
+	enum kcs_states state;
+	unsigned int    port;
+	unsigned char	*addr;
+	unsigned char   write_data[MAX_KCS_WRITE_SIZE];
+	int             write_pos;
+	int             write_count;
+	int             orig_write_count;
+	unsigned char   read_data[MAX_KCS_READ_SIZE];
+	int             read_pos;
+	int	        truncated;
+
+	unsigned int  error_retries;
+	long          ibf_timeout;
+	long          obf_timeout;
+};
+
+void init_kcs_data(struct kcs_data *kcs, unsigned int port, unsigned char *addr)
+{
+	kcs->state = KCS_IDLE;
+	kcs->port = port;
+	kcs->addr = addr;
+	kcs->write_pos = 0;
+	kcs->write_count = 0;
+	kcs->orig_write_count = 0;
+	kcs->read_pos = 0;
+	kcs->error_retries = 0;
+	kcs->truncated = 0;
+	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
+	kcs->obf_timeout = OBF_RETRY_TIMEOUT;
+}
+
+/* Remember, init_one_kcs() insured port and addr can't both be set */
+
+static inline unsigned char read_status(struct kcs_data *kcs)
+{
+        if (kcs->port)
+		return inb(kcs->port + 1);
+        else
+		return readb(kcs->addr + 1);
+}
+
+static inline unsigned char read_data(struct kcs_data *kcs)
+{
+        if (kcs->port)
+		return inb(kcs->port + 0);
+        else
+		return readb(kcs->addr + 0);
+}
+
+static inline void write_cmd(struct kcs_data *kcs, unsigned char data)
+{
+        if (kcs->port)
+		outb(data, kcs->port + 1);
+        else
+		writeb(data, kcs->addr + 1);
+}
+
+static inline void write_data(struct kcs_data *kcs, unsigned char data)
+{
+        if (kcs->port)
+		outb(data, kcs->port + 0);
+        else
+		writeb(data, kcs->addr + 0);
+}
+
+/* Control codes. */
+#define KCS_GET_STATUS_ABORT	0x60
+#define KCS_WRITE_START		0x61
+#define KCS_WRITE_END		0x62
+#define KCS_READ_BYTE		0x68
+
+/* Status bits. */
+#define GET_STATUS_STATE(status) (((status) >> 6) & 0x03)
+#define KCS_IDLE_STATE	0
+#define KCS_READ_STATE	1
+#define KCS_WRITE_STATE	2
+#define KCS_ERROR_STATE	3
+#define GET_STATUS_ATN(status) ((status) & 0x04)
+#define GET_STATUS_IBF(status) ((status) & 0x02)
+#define GET_STATUS_OBF(status) ((status) & 0x01)
+
+
+static inline void write_next_byte(struct kcs_data *kcs)
+{
+	write_data(kcs, kcs->write_data[kcs->write_pos]);
+	(kcs->write_pos)++;
+	(kcs->write_count)--;
+}
+
+static inline void start_error_recovery(struct kcs_data *kcs, char *reason)
+{
+	(kcs->error_retries)++;
+	if (kcs->error_retries > MAX_ERROR_RETRIES) {
+#ifdef DEBUG_HOSED_REASON
+		printk("ipmi_kcs_sm: kcs hosed: %s\n", reason);
+#endif
+		kcs->state = KCS_HOSED;
+	} else {
+		kcs->state = KCS_ERROR0;
+	}
+}
+
+static inline void read_next_byte(struct kcs_data *kcs)
+{
+	if (kcs->read_pos >= MAX_KCS_READ_SIZE) {
+		/* Throw the data away and mark it truncated. */
+		read_data(kcs);
+		kcs->truncated = 1;
+	} else {
+		kcs->read_data[kcs->read_pos] = read_data(kcs);
+		(kcs->read_pos)++;
+	}
+	write_data(kcs, KCS_READ_BYTE);
+}
+
+static inline int check_ibf(struct kcs_data *kcs,
+			    unsigned char   status,
+			    long            time)
+{
+	if (GET_STATUS_IBF(status)) {
+		kcs->ibf_timeout -= time;
+		if (kcs->ibf_timeout < 0) {
+			start_error_recovery(kcs, "IBF not ready in time");
+			kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
+			return 1;
+		}
+		return 0;
+	}
+	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
+	return 1;
+}
+
+static inline int check_obf(struct kcs_data *kcs,
+			    unsigned char   status,
+			    long            time)
+{
+	if (! GET_STATUS_OBF(status)) {
+		kcs->obf_timeout -= time;
+		if (kcs->obf_timeout < 0) {
+		    start_error_recovery(kcs, "OBF not ready in time");
+		    return 1;
+		}
+		return 0;
+	}
+	kcs->obf_timeout = OBF_RETRY_TIMEOUT;
+	return 1;
+}
+
+static void clear_obf(struct kcs_data *kcs, unsigned char status)
+{
+	if (GET_STATUS_OBF(status))
+		read_data(kcs);
+}
+
+static void restart_kcs_transaction(struct kcs_data *kcs)
+{
+	kcs->write_count = kcs->orig_write_count;
+	kcs->write_pos = 0;
+	kcs->read_pos = 0;
+	kcs->state = KCS_WAIT_WRITE_START;
+	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
+	kcs->obf_timeout = OBF_RETRY_TIMEOUT;
+	write_cmd(kcs, KCS_WRITE_START);
+}
+
+int start_kcs_transaction(struct kcs_data *kcs, char *data, unsigned int size)
+{
+	if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
+		return -1;
+	}
+
+	if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
+		return -2;
+	}
+
+	kcs->error_retries = 0;
+	memcpy(kcs->write_data, data, size);
+	kcs->write_count = size;
+	kcs->orig_write_count = size;
+	kcs->write_pos = 0;
+	kcs->read_pos = 0;
+	kcs->state = KCS_START_OP;
+	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
+	kcs->obf_timeout = OBF_RETRY_TIMEOUT;
+	return 0;
+}
+
+int kcs_get_result(struct kcs_data *kcs, unsigned char *data, int length)
+{
+	if (length < kcs->read_pos) {
+		kcs->read_pos = length;
+		kcs->truncated = 1;
+	}
+
+	memcpy(data, kcs->read_data, kcs->read_pos);
+
+	if ((length >= 3) && (kcs->read_pos < 3)) {
+		/* Guarantee that we return at least 3 bytes, with an
+		   error in the third byte if it is too short. */
+		data[2] = IPMI_ERR_UNSPECIFIED;
+		kcs->read_pos = 3;
+	}
+	if (kcs->truncated) {
+		/* Report a truncated error.  We might overwrite
+		   another error, but that's too bad, the user needs
+		   to know it was truncated. */
+		data[2] = IPMI_ERR_MSG_TRUNCATED;
+		kcs->truncated = 0;
+	}
+
+	return kcs->read_pos;
+}
+
+/* This implements the state machine defined in the IPMI manual, see
+   that for details on how this works.  Divide that flowchart into
+   sections delimited by "Wait for IBF" and this will become clear. */
+enum kcs_result kcs_event(struct kcs_data *kcs, long time)
+{
+	unsigned char status;
+	unsigned char state;
+
+	status = read_status(kcs);
+
+#ifdef DEBUG_STATE
+	printk("  State = %d, %x\n", kcs->state, status);
+#endif
+	/* All states wait for ibf, so just do it here. */
+	if (!check_ibf(kcs, status, time))
+		return KCS_CALL_WITH_DELAY;
+
+	/* Just about everything looks at the KCS state, so grab that, too. */
+	state = GET_STATUS_STATE(status);
+
+	switch (kcs->state) {
+	case KCS_IDLE:
+		/* If there's and interrupt source, turn it off. */
+		clear_obf(kcs, status);
+
+		if (GET_STATUS_ATN(status))
+			return KCS_ATTN;
+		else
+			return KCS_SM_IDLE;
+
+	case KCS_START_OP:
+		if (state != KCS_IDLE) {
+			start_error_recovery(kcs,
+					     "State machine not idle at start");
+			break;
+		}
+
+		clear_obf(kcs, status);
+		write_cmd(kcs, KCS_WRITE_START);
+		kcs->state = KCS_WAIT_WRITE_START;
+		break;
+
+	case KCS_WAIT_WRITE_START:
+		if (state != KCS_WRITE_STATE) {
+			start_error_recovery(
+				kcs,
+				"Not in write state at write start");
+			break;
+		}
+		read_data(kcs);
+		if (kcs->write_count == 1) {
+			write_cmd(kcs, KCS_WRITE_END);
+			kcs->state = KCS_WAIT_WRITE_END;
+		} else {
+			write_next_byte(kcs);
+			kcs->state = KCS_WAIT_WRITE;
+		}
+		break;
+
+	case KCS_WAIT_WRITE:
+		if (state != KCS_WRITE_STATE) {
+			start_error_recovery(kcs,
+					     "Not in write state for write");
+			break;
+		}
+		clear_obf(kcs, status);
+		if (kcs->write_count == 1) {
+			write_cmd(kcs, KCS_WRITE_END);
+			kcs->state = KCS_WAIT_WRITE_END;
+		} else {
+			write_next_byte(kcs);
+		}
+		break;
+		
+	case KCS_WAIT_WRITE_END:
+		if (state != KCS_WRITE_STATE) {
+			start_error_recovery(kcs,
+					     "Not in write state for write end");
+			break;
+		}
+		clear_obf(kcs, status);
+		write_next_byte(kcs);
+		kcs->state = KCS_WAIT_READ;
+		break;
+
+	case KCS_WAIT_READ:
+		if ((state != KCS_READ_STATE) && (state != KCS_IDLE_STATE)) {
+			start_error_recovery(
+				kcs,
+				"Not in read or idle in read state");
+			break;
+		}
+
+		if (state == KCS_READ_STATE) {
+			if (! check_obf(kcs, status, time))
+				return KCS_CALL_WITH_DELAY;
+			read_next_byte(kcs);
+		} else {
+			/* We don't implement this exactly like the state
+			   machine in the spec.  Some broken hardware
+			   does not write the final dummy byte to the
+			   read register.  Thus obf will never go high
+			   here.  We just go straight to idle, and we
+			   handle clearing out obf in idle state if it
+			   happens to come in. */
+			clear_obf(kcs, status);
+			kcs->orig_write_count = 0;
+			kcs->state = KCS_IDLE;
+			return KCS_TRANSACTION_COMPLETE;
+		}
+		break;
+
+	case KCS_ERROR0:
+		clear_obf(kcs, status);
+		write_cmd(kcs, KCS_GET_STATUS_ABORT);
+		kcs->state = KCS_ERROR1;
+		break;
+
+	case KCS_ERROR1:
+		clear_obf(kcs, status);
+		write_data(kcs, 0);
+		kcs->state = KCS_ERROR2;
+		break;
+		
+	case KCS_ERROR2:
+		if (state != KCS_READ_STATE) {
+			start_error_recovery(kcs,
+					     "Not in read state for error2");
+			break;
+		}
+		if (! check_obf(kcs, status, time))
+			return KCS_CALL_WITH_DELAY;
+
+		clear_obf(kcs, status);
+		write_data(kcs, KCS_READ_BYTE);
+		kcs->state = KCS_ERROR3;
+		break;
+		
+	case KCS_ERROR3:
+		if (state != KCS_IDLE_STATE) {
+			start_error_recovery(kcs,
+					     "Not in idle state for error3");
+			break;
+		}
+
+		if (! check_obf(kcs, status, time))
+			return KCS_CALL_WITH_DELAY;
+
+		clear_obf(kcs, status);
+		if (kcs->orig_write_count) {
+			restart_kcs_transaction(kcs);
+		} else {
+			kcs->state = KCS_IDLE;
+			return KCS_TRANSACTION_COMPLETE;
+		}
+		break;
+			
+	case KCS_HOSED:
+		return KCS_SM_HOSED;
+	}
+
+	if (kcs->state == KCS_HOSED) {
+		init_kcs_data(kcs, kcs->port, kcs->addr);
+		return KCS_SM_HOSED;
+	}
+
+	return KCS_CALL_WITHOUT_DELAY;
+}
+
+int kcs_size(void)
+{
+	return sizeof(struct kcs_data);
+}
diff -Nru a/drivers/char/ipmi/ipmi_kcs_sm.h b/drivers/char/ipmi/ipmi_kcs_sm.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/ipmi/ipmi_kcs_sm.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,70 @@
+/*
+ * ipmi_kcs_sm.h
+ *
+ * State machine for handling IPMI KCS interfaces.
+ *
+ * Author: MontaVista Software, Inc.
+ *         Corey Minyard <minyard@mvista.com>
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+struct kcs_data;
+
+void init_kcs_data(struct kcs_data *kcs,
+		   unsigned int    port,
+		   unsigned char   *addr);
+
+/* Start a new transaction in the state machine.  This will return -2
+   if the state machine is not idle, -1 if the size is invalid (to
+   large or too small), or 0 if the transaction is successfully
+   completed. */
+int start_kcs_transaction(struct kcs_data *kcs, char *data, unsigned int size);
+
+/* Return the results after the transaction.  This will return -1 if
+   the buffer is too small, zero if no transaction is present, or the
+   actual length of the result data. */
+int kcs_get_result(struct kcs_data *kcs, unsigned char *data, int length);
+
+enum kcs_result
+{
+	KCS_CALL_WITHOUT_DELAY, /* Call the driver again immediately */
+	KCS_CALL_WITH_DELAY,	/* Delay some before calling again. */
+	KCS_TRANSACTION_COMPLETE, /* A transaction is finished. */
+	KCS_SM_IDLE,		/* The SM is in idle state. */
+	KCS_SM_HOSED,		/* The hardware violated the state machine. */
+	KCS_ATTN		/* The hardware is asserting attn and the
+				   state machine is idle. */
+};
+
+/* Call this periodically (for a polled interface) or upon receiving
+   an interrupt (for a interrupt-driven interface).  If interrupt
+   driven, you should probably poll this periodically when not in idle
+   state.  This should be called with the time that passed since the
+   last call, if it is significant.  Time is in microseconds. */
+enum kcs_result kcs_event(struct kcs_data *kcs, long time);
+
+/* Return the size of the KCS structure in bytes. */
+int kcs_size(void);
diff -Nru a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/ipmi/ipmi_msghandler.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,1973 @@
+/*
+ * ipmi_msghandler.c
+ *
+ * Incoming and outgoing message routing for an IPMI interface.
+ *
+ * Author: MontaVista Software, Inc.
+ *         Corey Minyard <minyard@mvista.com>
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <asm/system.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+#include <linux/slab.h>
+#include <linux/ipmi.h>
+#include <linux/ipmi_smi.h>
+#include <linux/notifier.h>
+#include <linux/init.h>
+
+struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
+static int ipmi_init_msghandler(void);
+
+static int initialized = 0;
+
+#define MAX_EVENTS_IN_QUEUE	25
+
+/* Don't let a message sit in a queue forever, always time it with at lest
+   the max message timer. */
+#define MAX_MSG_TIMEOUT		60000
+
+struct ipmi_user
+{
+	struct list_head link;
+
+	/* The upper layer that handles receive messages. */
+	struct ipmi_user_hndl *handler;
+	void             *handler_data;
+
+	/* The interface this user is bound to. */
+	ipmi_smi_t intf;
+
+	/* Does this interface receive IPMI events? */
+	int gets_events;
+};
+
+struct cmd_rcvr
+{
+	struct list_head link;
+
+	ipmi_user_t   user;
+	unsigned char netfn;
+	unsigned char cmd;
+};
+
+struct seq_table
+{
+	int                  inuse : 1;
+
+	unsigned long        timeout;
+	unsigned long        orig_timeout;
+	unsigned int         retries_left;
+
+	/* To verify on an incoming send message response that this is
+           the message that the response is for, we keep a sequence id
+           and increment it every time we send a message. */
+	long                 seqid;
+
+	/* This is held so we can properly respond to the message on a
+           timeout, and it is used to hold the temporary data for
+           retransmission, too. */
+	struct ipmi_recv_msg *recv_msg;
+};
+
+/* Store the information in a msgid (long) to allow us to find a
+   sequence table entry from the msgid. */
+#define STORE_SEQ_IN_MSGID(seq, seqid) (((seq&0xff)<<26) | (seqid&0x3ffffff))
+
+#define GET_SEQ_FROM_MSGID(msgid, seq, seqid) \
+	do {								\
+		seq = ((msgid >> 26) & 0x3f);				\
+		seqid = (msgid & 0x3fffff);				\
+        } while(0)
+
+#define NEXT_SEQID(seqid) (((seqid) + 1) & 0x3fffff)
+
+
+#define IPMI_IPMB_NUM_SEQ	64
+struct ipmi_smi
+{
+	/* The list of upper layers that are using me.  We read-lock
+           this when delivering messages to the upper layer to keep
+           the user from going away while we are processing the
+           message.  This means that you cannot add or delete a user
+           from the receive callback. */
+	rwlock_t                users_lock;
+	struct list_head        users;
+
+	/* The IPMI version of the BMC on the other end. */
+	unsigned char       version_major;
+	unsigned char       version_minor;
+
+	/* This is the lower-layer's sender routine. */
+	struct ipmi_smi_handlers *handlers;
+	void                     *send_info;
+
+	/* A table of sequence numbers for this interface.  We use the
+           sequence numbers for IPMB messages that go out of the
+           interface to match them up with their responses.  A routine
+           is called periodically to time the items in this list. */
+	spinlock_t       seq_lock;
+	struct seq_table seq_table[IPMI_IPMB_NUM_SEQ];
+	int curr_seq;
+
+	/* Messages that were delayed for some reason (out of memory,
+           for instance), will go in here to be processed later in a
+           periodic timer interrupt. */
+	spinlock_t       waiting_msgs_lock;
+	struct list_head waiting_msgs;
+
+	/* The list of command receivers that are registered for commands
+	   on this interface. */
+	rwlock_t	 cmd_rcvr_lock;
+	struct list_head cmd_rcvrs;
+
+	/* Events that were queues because no one was there to receive
+           them. */
+	spinlock_t       events_lock; /* For dealing with event stuff. */
+	struct list_head waiting_events;
+	unsigned int     waiting_events_count; /* How many events in queue? */
+
+	/* This will be non-null if someone registers to receive all
+	   IPMI commands (this is for interface emulation).  There
+	   may not be any things in the cmd_rcvrs list above when
+	   this is registered. */
+	ipmi_user_t all_cmd_rcvr;
+
+	/* My slave address.  This is initialized to IPMI_BMC_SLAVE_ADDR,
+	   but may be changed by the user. */
+	unsigned char my_address;
+
+	/* My LUN.  This should generally stay the SMS LUN, but just in
+	   case... */
+	unsigned char my_lun;
+};
+
+int
+ipmi_register_all_cmd_rcvr(ipmi_user_t user)
+{
+	int flags;
+	int rv = -EBUSY;
+
+	write_lock_irqsave(&(user->intf->users_lock), flags);
+	write_lock(&(user->intf->cmd_rcvr_lock));
+	if ((user->intf->all_cmd_rcvr == NULL)
+	    && (list_empty(&(user->intf->cmd_rcvrs))))
+	{
+		user->intf->all_cmd_rcvr = user;
+		rv = 0;
+	}
+	write_unlock(&(user->intf->cmd_rcvr_lock));
+	write_unlock_irqrestore(&(user->intf->users_lock), flags);
+	return rv;
+}
+
+int
+ipmi_unregister_all_cmd_rcvr(ipmi_user_t user)
+{
+	int flags;
+	int rv = -EINVAL;
+
+	write_lock_irqsave(&(user->intf->users_lock), flags);
+	write_lock(&(user->intf->cmd_rcvr_lock));
+	if (user->intf->all_cmd_rcvr == user)
+	{
+		user->intf->all_cmd_rcvr = NULL;
+		rv = 0;
+	}
+	write_unlock(&(user->intf->cmd_rcvr_lock));
+	write_unlock_irqrestore(&(user->intf->users_lock), flags);
+	return rv;
+}
+
+
+#define MAX_IPMI_INTERFACES 4
+static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES];
+
+/* Used to keep interfaces from going away while operations are
+   operating on interfaces.  Grab read if you are not modifying the
+   interfaces, write if you are. */
+static DECLARE_RWSEM(interfaces_sem);
+
+/* Directly protects the ipmi_interfaces data structure.  This is
+   claimed in the timer interrupt. */
+static spinlock_t interfaces_lock = SPIN_LOCK_UNLOCKED;
+
+/* List of watchers that want to know when smi's are added and
+   deleted. */
+static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers);
+static DECLARE_RWSEM(smi_watchers_sem);
+
+int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
+{
+	int i;
+
+	down_read(&interfaces_sem);
+	down_write(&smi_watchers_sem);
+	list_add(&(watcher->link), &smi_watchers);
+	for (i=0; i<MAX_IPMI_INTERFACES; i++) {
+		if (ipmi_interfaces[i] != NULL) {
+			watcher->new_smi(i);
+		}
+	}
+	up_write(&smi_watchers_sem);
+	up_read(&interfaces_sem);
+	return 0;
+}
+
+int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher)
+{
+	down_write(&smi_watchers_sem);
+	list_del(&(watcher->link));
+	up_write(&smi_watchers_sem);
+	return 0;
+}
+
+int
+ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
+{
+	if (addr1->addr_type != addr2->addr_type)
+		return 0;
+
+	if (addr1->channel != addr2->channel)
+		return 0;
+
+	if (addr1->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) {
+		struct ipmi_system_interface_addr *smi_addr1
+		    = (struct ipmi_system_interface_addr *) addr1;
+		struct ipmi_system_interface_addr *smi_addr2
+		    = (struct ipmi_system_interface_addr *) addr2;
+		return (smi_addr1->lun == smi_addr2->lun);
+	}
+
+	if ((addr1->addr_type == IPMI_IPMB_ADDR_TYPE)
+	    || (addr1->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
+	{
+		struct ipmi_ipmb_addr *ipmb_addr1
+		    = (struct ipmi_ipmb_addr *) addr1;
+		struct ipmi_ipmb_addr *ipmb_addr2
+		    = (struct ipmi_ipmb_addr *) addr2;
+
+		return ((ipmb_addr1->slave_addr == ipmb_addr2->slave_addr)
+			&& (ipmb_addr1->lun == ipmb_addr2->lun));
+	}
+
+	return 1;
+}
+
+int ipmi_validate_addr(struct ipmi_addr *addr, int len)
+{
+	if (len < sizeof(struct ipmi_system_interface_addr)) {
+		return -EINVAL;
+	}
+
+	if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) {
+		if (addr->channel != IPMI_BMC_CHANNEL)
+			return -EINVAL;
+		return 0;
+	}
+
+	if ((addr->channel == IPMI_BMC_CHANNEL)
+	    || (addr->channel >= IPMI_NUM_CHANNELS)
+	    || (addr->channel < 0))
+		return -EINVAL;
+
+	if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
+	    || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
+	{
+		if (len < sizeof(struct ipmi_ipmb_addr)) {
+			return -EINVAL;
+		}
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+unsigned int ipmi_addr_length(int addr_type)
+{
+	if (addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
+		return sizeof(struct ipmi_system_interface_addr);
+
+	if ((addr_type == IPMI_IPMB_ADDR_TYPE)
+	    || (addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
+	{
+		return sizeof(struct ipmi_ipmb_addr);
+	}
+
+	return 0;
+}
+
+static void deliver_response(struct ipmi_recv_msg *msg)
+{
+    msg->user->handler->ipmi_recv_hndl(msg, msg->user->handler_data);
+}
+
+/* Find the next sequence number not being used and add the given
+   message with the given timeout to the sequence table.  This must be
+   called with the interface's seq_lock held. */
+static int intf_next_seq(ipmi_smi_t           intf,
+			 struct ipmi_recv_msg *recv_msg,
+			 unsigned long        timeout,
+			 int                  retries,
+			 unsigned char        *seq,
+			 long                 *seqid)
+{
+	int          rv = 0;
+	unsigned int i;
+
+	for (i=intf->curr_seq;
+	     i!=(intf->curr_seq-1);
+	     i=(i+1)%IPMI_IPMB_NUM_SEQ)
+	{
+		if (! intf->seq_table[i].inuse)
+			break;
+	}
+
+	if (! intf->seq_table[i].inuse) {
+		intf->seq_table[i].recv_msg = recv_msg;
+
+		/* Start with the maximum timeout, when the send response
+		   comes in we will start the real timer. */
+		intf->seq_table[i].timeout = MAX_MSG_TIMEOUT;
+		intf->seq_table[i].orig_timeout = timeout;
+		intf->seq_table[i].retries_left = retries;
+		intf->seq_table[i].inuse = 1;
+		intf->seq_table[i].seqid = NEXT_SEQID(intf->seq_table[i].seqid);
+		*seq = i;
+		*seqid = intf->seq_table[i].seqid;
+		intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ;
+	} else {
+		rv = -EAGAIN;
+	}
+	
+	return rv;
+}
+
+/* Return the receive message for the given sequence number and
+   release the sequence number so it can be reused.  Some other data
+   is passed in to be sure the message matches up correctly (to help
+   guard against message coming in after their timeout and the
+   sequence number being reused). */
+static int intf_find_seq(ipmi_smi_t           intf,
+			 unsigned char        seq,
+			 short                channel,
+			 unsigned char        cmd,
+			 unsigned char        netfn,
+			 struct ipmi_addr     *addr,
+			 struct ipmi_recv_msg **recv_msg)
+{
+	int           rv = -ENODEV;
+	unsigned long flags;
+
+	if (seq >= IPMI_IPMB_NUM_SEQ)
+		return -EINVAL;
+
+	spin_lock_irqsave(&(intf->seq_lock), flags);
+	if (intf->seq_table[seq].inuse) {
+		struct ipmi_recv_msg *msg = intf->seq_table[seq].recv_msg;
+
+		if ((msg->addr.channel == channel)
+		    && (msg->msg.cmd == cmd)
+		    && (msg->msg.netfn == netfn)
+		    && (ipmi_addr_equal(addr, &(msg->addr))))
+		{
+			*recv_msg = msg;
+			intf->seq_table[seq].inuse = 0;
+			rv = 0;
+		}
+	}
+	spin_unlock_irqrestore(&(intf->seq_lock), flags);
+
+	return rv;
+}
+
+
+/* Start the timer for a specific sequence table entry. */
+static int intf_start_seq_timer(ipmi_smi_t           intf,
+				long                 msgid)
+{
+	int           rv = -ENODEV;
+	unsigned long flags;
+	unsigned char seq;
+	unsigned long seqid;
+
+
+	GET_SEQ_FROM_MSGID(msgid, seq, seqid);
+
+	spin_lock_irqsave(&(intf->seq_lock), flags);
+	/* We do this verification because the user can be deleted
+           while a message is outstanding. */
+	if ((intf->seq_table[seq].inuse)
+	    && (intf->seq_table[seq].seqid == seqid))
+	{
+		struct seq_table *ent = &(intf->seq_table[seq]);
+		ent->timeout = ent->orig_timeout;
+	}
+	spin_unlock_irqrestore(&(intf->seq_lock), flags);
+
+	return rv;
+}
+
+
+int ipmi_create_user(unsigned int          if_num,
+		     struct ipmi_user_hndl *handler,
+		     void                  *handler_data,
+		     ipmi_user_t           *user)
+{
+	unsigned long flags;
+	ipmi_user_t   new_user;
+	int           rv = 0;
+
+	/* There is no module usecount here, because it's not
+           required.  Since this can only be used by and called from
+           other modules, they will implicitly use this module, and
+           thus this can't be removed unless the other modules are
+           removed. */
+
+	if (handler == NULL)
+		return -EINVAL;
+
+	/* Make sure the driver is actually initialized, this handles
+	   problems with initialization order. */
+	if (!initialized) {
+		rv = ipmi_init_msghandler();
+		if (rv)
+			return rv;
+
+		/* The init code doesn't return an error if it was turned
+		   off, but it won't initialize.  Check that. */
+		if (!initialized)
+			return -ENODEV;
+	}
+
+	new_user = kmalloc(sizeof(*new_user), GFP_KERNEL);
+	if (! new_user)
+		return -ENOMEM;
+
+	down_read(&interfaces_sem);
+	if ((if_num > MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL)
+	{
+		rv = -EINVAL;
+		goto out_unlock;
+	}
+
+	new_user->handler = handler;
+	new_user->handler_data = handler_data;
+	new_user->intf = ipmi_interfaces[if_num];
+	new_user->gets_events = 0;
+
+	rv = new_user->intf->handlers->new_user(new_user->intf->send_info);
+	if (rv)
+		goto out_unlock;
+
+	write_lock_irqsave(&(new_user->intf->users_lock), flags);
+	list_add_tail(&(new_user->link), &(new_user->intf->users));
+	write_unlock_irqrestore(&(new_user->intf->users_lock), flags);
+
+ out_unlock:	
+	if (rv) {
+		kfree(new_user);
+	} else {
+		*user = new_user;
+	}
+
+	up_read(&interfaces_sem);
+	return rv;
+}
+
+static int ipmi_destroy_user_nolock(ipmi_user_t user)
+{
+	int              rv = -ENODEV;
+	ipmi_user_t      t_user;
+	struct list_head *entry, *entry2;
+	int              i;
+	unsigned long    flags;
+
+	/* Find the user and delete them from the list. */
+	list_for_each(entry, &(user->intf->users)) {
+		t_user = list_entry(entry, struct ipmi_user, link);
+		if (t_user == user) {
+			list_del(entry);
+			rv = 0;
+			break;
+		}
+	}
+
+	if (rv) {
+		goto out_unlock;
+	}
+
+	/* Remove the user from the interfaces sequence table. */
+	spin_lock_irqsave(&(user->intf->seq_lock), flags);
+	for (i=0; i<IPMI_IPMB_NUM_SEQ; i++) {
+		if (user->intf->seq_table[i].inuse
+		    && (user->intf->seq_table[i].recv_msg->user == user))
+		{
+			user->intf->seq_table[i].inuse = 0;
+		}
+	}
+	spin_unlock_irqrestore(&(user->intf->seq_lock), flags);
+
+	/* Remove the user from the command receiver's table. */
+	write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
+	list_for_each_safe(entry, entry2, &(user->intf->cmd_rcvrs)) {
+		struct cmd_rcvr *rcvr;
+		rcvr = list_entry(entry, struct cmd_rcvr, link);
+		if (rcvr->user == user) {
+			list_del(entry);
+			kfree(rcvr);
+		}
+	}
+	write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
+
+	kfree(user);
+
+ out_unlock:
+
+	return rv;
+}
+
+int ipmi_destroy_user(ipmi_user_t user)
+{
+	int           rv;
+	ipmi_smi_t    intf = user->intf;
+	unsigned long flags;
+
+	down_read(&interfaces_sem);
+	write_lock_irqsave(&(intf->users_lock), flags);
+	rv = ipmi_destroy_user_nolock(user);
+	if (!rv)
+		intf->handlers->user_left(intf->send_info);
+		
+	write_unlock_irqrestore(&(intf->users_lock), flags);
+	up_read(&interfaces_sem);
+	return rv;
+}
+
+void ipmi_get_version(ipmi_user_t   user,
+		      unsigned char *major,
+		      unsigned char *minor)
+{
+	*major = user->intf->version_major;
+	*minor = user->intf->version_minor;
+}
+
+void ipmi_set_my_address(ipmi_user_t   user,
+			 unsigned char address)
+{
+	user->intf->my_address = address;
+}
+
+unsigned char ipmi_get_my_address(ipmi_user_t user)
+{
+	return user->intf->my_address;
+}
+
+void ipmi_set_my_LUN(ipmi_user_t   user,
+		     unsigned char LUN)
+{
+	user->intf->my_lun = LUN & 0x3;
+}
+
+unsigned char ipmi_get_my_LUN(ipmi_user_t user)
+{
+	return user->intf->my_lun;
+}
+
+int ipmi_set_gets_events(ipmi_user_t user, int val)
+{
+	unsigned long         flags;
+	struct list_head      *e, *e2;
+	struct ipmi_recv_msg  *msg;
+
+	read_lock(&(user->intf->users_lock));
+	spin_lock_irqsave(&(user->intf->events_lock), flags);
+	user->gets_events = val;
+
+	if (val) {
+		/* Deliver any queued events. */
+		list_for_each_safe(e, e2, &(user->intf->waiting_events)) {
+			msg = list_entry(e, struct ipmi_recv_msg, link);
+			list_del(e);
+			msg->user = user;
+			deliver_response(msg);
+		}
+	}
+	
+	spin_unlock_irqrestore(&(user->intf->events_lock), flags);
+	read_unlock(&(user->intf->users_lock));
+
+	return 0;
+}
+
+int ipmi_register_for_cmd(ipmi_user_t   user,
+			  unsigned char netfn,
+			  unsigned char cmd)
+{
+	struct list_head *entry;
+	unsigned long    flags;
+	struct cmd_rcvr  *rcvr;
+	int              rv = 0;
+
+
+	rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
+	if (! rcvr)
+		return -ENOMEM;
+
+	read_lock(&(user->intf->users_lock));
+	write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
+	if (user->intf->all_cmd_rcvr != NULL) {
+		rv = -EBUSY;
+		goto out_unlock;
+	}
+
+	/* Make sure the command/netfn is not already registered. */
+	list_for_each(entry, &(user->intf->cmd_rcvrs)) {
+		struct cmd_rcvr *cmp;
+		cmp = list_entry(entry, struct cmd_rcvr, link);
+		if ((cmp->netfn == netfn) && (cmp->cmd == cmd)) {
+			rv = -EBUSY;
+			break;
+		}
+	}
+
+	if (! rv) {
+		rcvr->cmd = cmd;
+		rcvr->netfn = netfn;
+		rcvr->user = user;
+		list_add_tail(&(rcvr->link), &(user->intf->cmd_rcvrs));
+	}
+ out_unlock:
+	write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
+	read_unlock(&(user->intf->users_lock));
+
+	if (rv)
+		kfree(rcvr);
+
+	return rv;
+}
+
+int ipmi_unregister_for_cmd(ipmi_user_t   user,
+			    unsigned char netfn,
+			    unsigned char cmd)
+{
+	struct list_head *entry;
+	unsigned long    flags;
+	struct cmd_rcvr  *rcvr;
+	int              rv = -ENOENT;
+
+	read_lock(&(user->intf->users_lock));
+	write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
+	/* Make sure the command/netfn is not already registered. */
+	list_for_each(entry, &(user->intf->cmd_rcvrs)) {
+		rcvr = list_entry(entry, struct cmd_rcvr, link);
+		if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
+			rv = 0;
+			list_del(entry);
+			kfree(rcvr);
+			break;
+		}
+	}
+	write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
+	read_unlock(&(user->intf->users_lock));
+
+	return rv;
+}
+
+static unsigned char
+ipmb_checksum(unsigned char *data, int size)
+{
+	unsigned char csum = 0;
+	
+	for (; size > 0; size--, data++)
+		csum += *data;
+
+	return -csum;
+}
+
+static inline void format_ipmb_msg(struct ipmi_smi_msg   *smi_msg,
+				   struct ipmi_msg       *msg,
+				   struct ipmi_ipmb_addr *ipmb_addr,
+				   long                  msgid,
+				   unsigned char         ipmb_seq,
+				   int                   broadcast,
+				   unsigned char         source_address,
+				   unsigned char         source_lun)
+{
+	int i = broadcast;
+
+	/* Format the IPMB header data. */
+	smi_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
+	smi_msg->data[1] = IPMI_SEND_MSG_CMD;
+	smi_msg->data[2] = ipmb_addr->channel;
+	if (broadcast)
+		smi_msg->data[3] = 0;
+	smi_msg->data[i+3] = ipmb_addr->slave_addr;
+	smi_msg->data[i+4] = (msg->netfn << 2) | (ipmb_addr->lun & 0x3);
+	smi_msg->data[i+5] = ipmb_checksum(&(smi_msg->data[i+3]), 2);
+	smi_msg->data[i+6] = source_address;
+	smi_msg->data[i+7] = (ipmb_seq << 2) | source_lun;
+	smi_msg->data[i+8] = msg->cmd;
+
+	/* Now tack on the data to the message. */
+	if (msg->data_len > 0)
+		memcpy(&(smi_msg->data[i+9]), msg->data,
+		       msg->data_len);
+	smi_msg->data_size = msg->data_len + 9;
+
+	/* Now calculate the checksum and tack it on. */
+	smi_msg->data[i+smi_msg->data_size]
+		= ipmb_checksum(&(smi_msg->data[i+6]),
+				smi_msg->data_size-6);
+
+	/* Add on the checksum size and the offset from the
+	   broadcast. */
+	smi_msg->data_size += 1 + i;
+
+	smi_msg->msgid = msgid;
+}
+
+/* Separate from ipmi_request so that the user does not have to be
+   supplied in certain circumstances (mainly at panic time).  If
+   messages are supplied, they will be freed, even if an error
+   occurs. */
+static inline int i_ipmi_request(ipmi_user_t          user,
+				 ipmi_smi_t           intf,
+				 struct ipmi_addr     *addr,
+				 long                 msgid,
+				 struct ipmi_msg      *msg,
+				 void                 *supplied_smi,
+				 struct ipmi_recv_msg *supplied_recv,
+				 int                  priority,
+				 unsigned char        source_address,
+				 unsigned char        source_lun)
+{
+	int                  rv = 0;
+	struct ipmi_smi_msg  *smi_msg;
+	struct ipmi_recv_msg *recv_msg;
+	unsigned long        flags;
+
+
+	if (supplied_recv) {
+		recv_msg = supplied_recv;
+	} else {
+		recv_msg = ipmi_alloc_recv_msg();
+		if (recv_msg == NULL) {
+			return -ENOMEM;
+		}
+	}
+
+	if (supplied_smi) {
+		smi_msg = (struct ipmi_smi_msg *) supplied_smi;
+	} else {
+		smi_msg = ipmi_alloc_smi_msg();
+		if (smi_msg == NULL) {
+			ipmi_free_recv_msg(recv_msg);
+			return -ENOMEM;
+		}
+	}
+
+	if (addr->channel > IPMI_NUM_CHANNELS) {
+	    rv = -EINVAL;
+	    goto out_err;
+	}
+
+	recv_msg->user = user;
+	recv_msg->msgid = msgid;
+	/* Store the message to send in the receive message so timeout
+	   responses can get the proper response data. */
+	recv_msg->msg = *msg;
+
+	if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) {
+		struct ipmi_system_interface_addr *smi_addr;
+
+
+		smi_addr = (struct ipmi_system_interface_addr *) addr;
+		if (smi_addr->lun > 3)
+			return -EINVAL;
+
+		memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr));
+
+		if ((msg->netfn == IPMI_NETFN_APP_REQUEST)
+		    && ((msg->cmd == IPMI_SEND_MSG_CMD)
+			|| (msg->cmd == IPMI_GET_MSG_CMD)
+			|| (msg->cmd == IPMI_READ_EVENT_MSG_BUFFER_CMD)))
+		{
+			/* We don't let the user do these, since we manage
+			   the sequence numbers. */
+			rv = -EINVAL;
+			goto out_err;
+		}
+
+		if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) {
+			rv = -EMSGSIZE;
+			goto out_err;
+		}
+
+		smi_msg->data[0] = (msg->netfn << 2) | (smi_addr->lun & 0x3);
+		smi_msg->data[1] = msg->cmd;
+		smi_msg->msgid = msgid;
+		smi_msg->user_data = recv_msg;
+		if (msg->data_len > 0)
+			memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
+		smi_msg->data_size = msg->data_len + 2;
+	} else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
+		   || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
+	{
+		struct ipmi_ipmb_addr *ipmb_addr;
+		unsigned char         ipmb_seq;
+		long                  seqid;
+		int                   broadcast;
+		int                   retries;
+
+		if (addr == NULL) {
+			rv = -EINVAL;
+			goto out_err;
+		}
+
+		if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE) {
+		    /* Broadcasts add a zero at the beginning of the
+		       message, but otherwise is the same as an IPMB
+		       address. */
+		    addr->addr_type = IPMI_IPMB_ADDR_TYPE;
+		    broadcast = 1;
+		    retries = 0; /* Don't retry broadcasts. */
+		} else {
+		    broadcast = 0;
+		    retries = 4;
+		}
+
+		/* 9 for the header and 1 for the checksum, plus
+                   possibly one for the broadcast. */
+		if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) {
+			rv = -EMSGSIZE;
+			goto out_err;
+		}
+
+		ipmb_addr = (struct ipmi_ipmb_addr *) addr;
+		if (ipmb_addr->lun > 3) {
+			rv = -EINVAL;
+			goto out_err;
+		}
+
+		memcpy(&recv_msg->addr, ipmb_addr, sizeof(*ipmb_addr));
+
+		if (recv_msg->msg.netfn & 0x1) {
+			/* It's a response, so use the user's sequence
+                           from msgid. */
+			format_ipmb_msg(smi_msg, msg, ipmb_addr, msgid,
+					msgid, broadcast,
+					source_address, source_lun);
+		} else {
+			/* It's a command, so get a sequence for it. */
+
+			spin_lock_irqsave(&(intf->seq_lock), flags);
+
+			/* Create a sequence number with a 1 second
+                           timeout and 4 retries. */
+			/* FIXME - magic number for the timeout. */
+			rv = intf_next_seq(intf,
+					   recv_msg,
+					   1000,
+					   retries,
+					   &ipmb_seq,
+					   &seqid);
+			if (rv) {
+				/* We have used up all the sequence numbers,
+				   probably, so abort. */
+				spin_unlock_irqrestore(&(intf->seq_lock),
+						       flags);
+				ipmi_free_recv_msg(recv_msg);
+				ipmi_free_smi_msg(smi_msg);
+				goto out_err;
+			}
+
+			/* Store the sequence number in the message,
+                           so that when the send message response
+                           comes back we can start the timer. */
+			format_ipmb_msg(smi_msg, msg, ipmb_addr,
+					STORE_SEQ_IN_MSGID(ipmb_seq, seqid),
+					ipmb_seq, broadcast,
+					source_address, source_lun);
+
+			/* Copy the message into the recv message data, so we
+			   can retransmit it later if necessary. */
+			memcpy(recv_msg->msg_data, smi_msg->data,
+			       smi_msg->data_size);
+			recv_msg->msg.data = recv_msg->msg_data;
+			recv_msg->msg.data_len = smi_msg->data_size;
+
+			/* We don't unlock until here, because we need
+                           to copy the completed message into the
+                           recv_msg before we release the lock.
+                           Otherwise, race conditions may bite us.  I
+                           know that's pretty paranoid, but I prefer
+                           to be correct. */
+			spin_unlock_irqrestore(&(intf->seq_lock), flags);
+		}
+	} else {
+	    /* Unknown address type. */
+	    rv = -EINVAL;
+	    goto out_err;
+	}
+
+#if DEBUG_MSGING
+	{
+	    int m;
+	    for (m=0; m<smi_msg->data_size; m++)
+		printk(" %2.2x", smi_msg->data[m]);
+	    printk("\n");
+	}
+#endif
+	intf->handlers->sender(intf->send_info, smi_msg, priority);
+
+	return 0;
+
+ out_err:
+	ipmi_free_smi_msg(smi_msg);
+	ipmi_free_recv_msg(recv_msg);
+	return rv;
+}
+
+int ipmi_request(ipmi_user_t      user,
+		 struct ipmi_addr *addr,
+		 long             msgid,
+		 struct ipmi_msg  *msg,
+		 int              priority)
+{
+	return i_ipmi_request(user,
+			      user->intf,
+			      addr,
+			      msgid,
+			      msg,
+			      NULL, NULL,
+			      priority,
+			      user->intf->my_address,
+			      user->intf->my_lun);
+}
+
+int ipmi_request_supply_msgs(ipmi_user_t          user,
+			     struct ipmi_addr     *addr,
+			     long                 msgid,
+			     struct ipmi_msg      *msg,
+			     void                 *supplied_smi,
+			     struct ipmi_recv_msg *supplied_recv,
+			     int                  priority)
+{
+	return i_ipmi_request(user,
+			      user->intf,
+			      addr,
+			      msgid,
+			      msg,
+			      supplied_smi,
+			      supplied_recv,
+			      priority,
+			      user->intf->my_address,
+			      user->intf->my_lun);
+}
+
+int ipmi_request_with_source(ipmi_user_t      user,
+			     struct ipmi_addr *addr,
+			     long             msgid,
+			     struct ipmi_msg  *msg,
+			     int              priority,
+			     unsigned char    source_address,
+			     unsigned char    source_lun)
+{
+	return i_ipmi_request(user,
+			      user->intf,
+			      addr,
+			      msgid,
+			      msg,
+			      NULL, NULL,
+			      priority,
+			      source_address,
+			      source_lun);
+}
+
+int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
+		      void		       *send_info,
+		      unsigned char            version_major,
+		      unsigned char            version_minor,
+		      ipmi_smi_t               *intf)
+{
+	int              i, j;
+	int              rv;
+	ipmi_smi_t       new_intf;
+	struct list_head *entry;
+	unsigned int     flags;
+
+
+	/* Make sure the driver is actually initialized, this handles
+	   problems with initialization order. */
+	if (!initialized) {
+		rv = ipmi_init_msghandler();
+		if (rv)
+			return rv;
+		/* The init code doesn't return an error if it was turned
+		   off, but it won't initialize.  Check that. */
+		if (!initialized)
+			return -ENODEV;
+	}
+
+	new_intf = kmalloc(sizeof(*new_intf), GFP_KERNEL);
+	if (!new_intf)
+		return -ENOMEM;
+
+	rv = -ENOMEM;
+
+	down_write(&interfaces_sem);
+	for (i=0; i<MAX_IPMI_INTERFACES; i++) {
+		if (ipmi_interfaces[i] == NULL) {
+			new_intf->version_major = version_major;
+			new_intf->version_minor = version_minor;
+			new_intf->my_address = IPMI_BMC_SLAVE_ADDR;
+			new_intf->my_lun = 2;  /* the SMS LUN. */
+			rwlock_init(&(new_intf->users_lock));
+			INIT_LIST_HEAD(&(new_intf->users));
+			new_intf->handlers = handlers;
+			new_intf->send_info = send_info;
+			spin_lock_init(&(new_intf->seq_lock));
+			for (j=0; j<IPMI_IPMB_NUM_SEQ; j++) {
+				new_intf->seq_table[j].inuse = 0;
+				new_intf->seq_table[j].seqid = 0;
+			}
+			new_intf->curr_seq = 0;
+			spin_lock_init(&(new_intf->waiting_msgs_lock));
+			INIT_LIST_HEAD(&(new_intf->waiting_msgs));
+			spin_lock_init(&(new_intf->events_lock));
+			INIT_LIST_HEAD(&(new_intf->waiting_events));
+			new_intf->waiting_events_count = 0;
+			rwlock_init(&(new_intf->cmd_rcvr_lock));
+			INIT_LIST_HEAD(&(new_intf->cmd_rcvrs));
+			new_intf->all_cmd_rcvr = NULL;
+
+			spin_lock_irqsave(&interfaces_lock, flags);
+			ipmi_interfaces[i] = new_intf;
+			spin_unlock_irqrestore(&interfaces_lock, flags);
+
+			rv = 0;
+			*intf = new_intf;
+			break;
+		}
+	}
+
+	downgrade_write(&interfaces_sem);
+
+	if (rv == 0) {
+		/* Call all the watcher interfaces to tell them that a
+		   new interface is available. */
+		down_read(&smi_watchers_sem);
+		list_for_each(entry, &smi_watchers) {
+			struct ipmi_smi_watcher *w;
+			w = list_entry(entry, struct ipmi_smi_watcher, link);
+			w->new_smi(i);
+		}
+		up_read(&smi_watchers_sem);
+	}
+
+	up_read(&interfaces_sem);
+
+	if (rv)
+		kfree(new_intf);
+
+	return rv;
+}
+
+static void free_recv_msg_list(struct list_head *q)
+{
+	struct list_head     *entry, *entry2;
+	struct ipmi_recv_msg *msg;
+
+	list_for_each_safe(entry, entry2, q) {
+		msg = list_entry(entry, struct ipmi_recv_msg, link);
+		list_del(entry);
+		ipmi_free_recv_msg(msg);
+	}
+}
+
+static void free_cmd_rcvr_list(struct list_head *q)
+{
+	struct list_head *entry, *entry2;
+	struct cmd_rcvr  *rcvr;
+
+	list_for_each_safe(entry, entry2, q) {
+		rcvr = list_entry(entry, struct cmd_rcvr, link);
+		list_del(entry);
+		kfree(rcvr);
+	}
+}
+
+static void clean_up_interface_data(ipmi_smi_t intf)
+{
+	int i;
+
+	free_recv_msg_list(&(intf->waiting_msgs));
+	free_recv_msg_list(&(intf->waiting_events));
+	free_cmd_rcvr_list(&(intf->cmd_rcvrs));
+
+	for (i=0; i<IPMI_IPMB_NUM_SEQ; i++) {
+		if ((intf->seq_table[i].inuse)
+		    && (intf->seq_table[i].recv_msg))
+		{
+			ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
+		}	
+	}
+}
+
+int ipmi_unregister_smi(ipmi_smi_t intf)
+{
+	int              rv = -ENODEV;
+	int              i;
+	struct list_head *entry;
+	unsigned int     flags;
+
+	down_write(&interfaces_sem);
+	if (list_empty(&(intf->users)))
+	{
+		for (i=0; i<MAX_IPMI_INTERFACES; i++) {
+			if (ipmi_interfaces[i] == intf) {
+				spin_lock_irqsave(&interfaces_lock, flags);
+				ipmi_interfaces[i] = NULL;
+				clean_up_interface_data(intf);
+				spin_unlock_irqrestore(&interfaces_lock,flags);
+				kfree(intf);
+				rv = 0;
+				goto out_call_watcher;
+			}
+		}
+	} else {
+		rv = -EBUSY;
+	}
+	up_write(&interfaces_sem);
+
+	return rv;
+
+ out_call_watcher:
+	downgrade_write(&interfaces_sem);
+
+	/* Call all the watcher interfaces to tell them that
+	   an interface is gone. */
+	down_read(&smi_watchers_sem);
+	list_for_each(entry, &smi_watchers) {
+		struct ipmi_smi_watcher *w;
+		w = list_entry(entry,
+			       struct ipmi_smi_watcher,
+			       link);
+		w->smi_gone(i);
+	}
+	up_read(&smi_watchers_sem);
+	up_read(&interfaces_sem);
+	return 0;
+}
+
+static int handle_get_msg_rsp(ipmi_smi_t          intf,
+			      struct ipmi_smi_msg *msg)
+{
+	struct ipmi_ipmb_addr ipmb_addr;
+	struct ipmi_recv_msg  *recv_msg;
+
+	
+	if (msg->rsp_size < 11)
+		/* Message not big enough, just ignore it. */
+		return 0;
+
+	if (msg->rsp[2] != 0)
+		/* An error getting the response, just ignore it. */
+		return 0;
+
+	ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
+	ipmb_addr.slave_addr = msg->rsp[6];
+	ipmb_addr.channel = msg->rsp[3] & 0x0f;
+	ipmb_addr.lun = msg->rsp[7] & 3;
+
+	/* It's a response from a remote entity.  Look up the sequence
+	   number and handle the response. */
+	if (intf_find_seq(intf,
+			  msg->rsp[7] >> 2,
+			  msg->rsp[3] & 0x0f,
+			  msg->rsp[8],
+			  (msg->rsp[4] >> 2) & (~1),
+			  (struct ipmi_addr *) &(ipmb_addr),
+			  &recv_msg))
+	{
+		/* We were unable to find the sequence number,
+		   so just nuke the message. */
+		return 0;
+	}
+
+	memcpy(recv_msg->msg_data,
+	       &(msg->rsp[9]),
+	       msg->rsp_size - 9);
+	/* THe other fields matched, so no need to set them, except
+           for netfn, which needs to be the response that was
+           returned, not the request value. */
+	recv_msg->msg.netfn = msg->rsp[4] >> 2;
+	recv_msg->msg.data = recv_msg->msg_data;
+	recv_msg->msg.data_len = msg->rsp_size - 10;
+	recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
+	deliver_response(recv_msg);
+
+	return 0;
+}
+
+static int handle_get_msg_cmd(ipmi_smi_t          intf,
+			      struct ipmi_smi_msg *msg)
+{
+	struct list_head *entry;
+	struct cmd_rcvr       *rcvr;
+	int              rv = 0;
+	unsigned char    netfn;
+	unsigned char    cmd;
+	ipmi_user_t      user = NULL;
+	struct ipmi_ipmb_addr *ipmb_addr;
+	struct ipmi_recv_msg  *recv_msg;
+
+	if (msg->rsp_size < 10)
+		/* Message not big enough, just ignore it. */
+		return 0;
+
+	if (msg->rsp[2] != 0) {
+		/* An error getting the response, just ignore it. */
+		return 0;
+	}
+
+	netfn = msg->rsp[4] >> 2;
+	cmd = msg->rsp[8];
+
+	read_lock(&(intf->cmd_rcvr_lock));
+	
+	if (intf->all_cmd_rcvr) {
+		user = intf->all_cmd_rcvr;
+	} else {
+		/* Find the command/netfn. */
+		list_for_each(entry, &(intf->cmd_rcvrs)) {
+			rcvr = list_entry(entry, struct cmd_rcvr, link);
+			if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
+				user = rcvr->user;
+				break;
+			}
+		}
+	}
+	read_unlock(&(intf->cmd_rcvr_lock));
+
+	if (user == NULL) {
+		/* We didn't find a user, deliver an error response. */
+		msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
+		msg->data[1] = IPMI_SEND_MSG_CMD;
+		msg->data[2] = msg->rsp[3];
+		msg->data[3] = msg->rsp[6];
+                msg->data[4] = ((netfn + 1) << 2) | (msg->rsp[7] & 0x3);
+		msg->data[5] = ipmb_checksum(&(msg->data[3]), 2);
+		msg->data[6] = intf->my_address;
+                /* rqseq/lun */
+                msg->data[7] = (msg->rsp[7] & 0xfc) | (msg->rsp[4] & 0x3);
+		msg->data[8] = msg->rsp[8]; /* cmd */
+		msg->data[9] = IPMI_INVALID_CMD_COMPLETION_CODE;
+		msg->data[10] = ipmb_checksum(&(msg->data[6]), 4);
+		msg->data_size = 11;
+
+		intf->handlers->sender(intf->send_info, msg, 0);
+
+		rv = -1; /* We used the message, so return the value that
+			    causes it to not be freed or queued. */
+	} else {
+		/* Deliver the message to the user. */
+		recv_msg = ipmi_alloc_recv_msg();
+		if (! recv_msg) {
+			/* We couldn't allocate memory for the
+                           message, so requeue it for handling
+                           later. */
+			rv = 1;
+		} else {
+			ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr;
+			ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE;
+			ipmb_addr->slave_addr = msg->rsp[6];
+			ipmb_addr->lun = msg->rsp[7] & 3;
+			ipmb_addr->channel = msg->rsp[3];
+
+			recv_msg->user = user;
+			recv_msg->recv_type = IPMI_CMD_RECV_TYPE;
+			recv_msg->msgid = msg->rsp[7] >> 2;
+			recv_msg->msg.netfn = msg->rsp[4] >> 2;
+			recv_msg->msg.cmd = msg->rsp[8];
+			recv_msg->msg.data = recv_msg->msg_data;
+			recv_msg->msg.data_len = msg->rsp_size - 10;
+			memcpy(recv_msg->msg_data,
+			       &(msg->rsp[9]),
+			       msg->rsp_size - 10);
+			deliver_response(recv_msg);
+		}
+	}
+
+	return rv;
+}
+
+static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg,
+				     struct ipmi_smi_msg  *msg)
+{
+	struct ipmi_system_interface_addr *smi_addr;
+	
+	recv_msg->msgid = 0;
+	smi_addr = (struct ipmi_system_interface_addr *) &(recv_msg->addr);
+	smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+	smi_addr->channel = IPMI_BMC_CHANNEL;
+	smi_addr->lun = msg->rsp[0] & 3;
+	recv_msg->recv_type = IPMI_ASYNC_EVENT_RECV_TYPE;
+	recv_msg->msg.netfn = msg->rsp[0] >> 2;
+	recv_msg->msg.cmd = msg->rsp[1];
+	memcpy(recv_msg->msg_data, &(msg->rsp[3]), msg->rsp_size - 3);
+	recv_msg->msg.data = recv_msg->msg_data;
+	recv_msg->msg.data_len = msg->rsp_size - 3;
+}
+
+/* This will be called with the intf->users_lock read-locked, so no need
+   to do that here. */
+static int handle_read_event_rsp(ipmi_smi_t          intf,
+				 struct ipmi_smi_msg *msg)
+{
+	struct ipmi_recv_msg *recv_msg;
+	struct list_head     msgs;
+	struct list_head     *entry, *entry2;
+	ipmi_user_t          user;
+	int                  rv = 0;
+	int                  deliver_count = 0;
+	unsigned long        flags;
+
+	if (msg->rsp_size < 19) {
+		/* Message is too small to be an IPMB event. */
+		return 0;
+	}
+
+	if (msg->rsp[2] != 0) {
+		/* An error getting the event, just ignore it. */
+		return 0;
+	}
+
+	INIT_LIST_HEAD(&msgs);
+
+	spin_lock_irqsave(&(intf->events_lock), flags);
+
+	/* Allocate and fill in one message for every user that is getting
+	   events. */
+	list_for_each(entry, &(intf->users)) {
+		user = list_entry(entry, struct ipmi_user, link);
+
+		if (! user->gets_events)
+			continue;
+
+		recv_msg = ipmi_alloc_recv_msg();
+		if (! recv_msg) {
+			list_for_each_safe(entry, entry2, &msgs) {
+				recv_msg = list_entry(entry,
+						      struct ipmi_recv_msg,
+						      link);
+				list_del(entry);
+				ipmi_free_recv_msg(recv_msg);
+			}
+			/* We couldn't allocate memory for the
+                           message, so requeue it for handling
+                           later. */
+			rv = 1;
+			goto out;
+		}
+
+		deliver_count++;
+
+		copy_event_into_recv_msg(recv_msg, msg);
+		recv_msg->user = user;
+		list_add_tail(&(recv_msg->link), &msgs);
+	}
+
+	if (deliver_count) {
+		/* Now deliver all the messages. */
+		list_for_each_safe(entry, entry2, &msgs) {
+			recv_msg = list_entry(entry,
+					      struct ipmi_recv_msg,
+					      link);
+			list_del(entry);
+			deliver_response(recv_msg);
+		}
+	} else if (intf->waiting_events_count < MAX_EVENTS_IN_QUEUE) {
+		/* No one to receive the message, put it in queue if there's
+		   not already too many things in the queue. */
+		recv_msg = ipmi_alloc_recv_msg();
+		if (! recv_msg) {
+			/* We couldn't allocate memory for the
+                           message, so requeue it for handling
+                           later. */
+			rv = 1;
+			goto out;
+		}
+
+		copy_event_into_recv_msg(recv_msg, msg);
+		list_add_tail(&(recv_msg->link), &(intf->waiting_events));
+	} else {
+		/* There's too many things in the queue, discard this
+		   message. */
+		printk(KERN_WARNING "ipmi: Event queue full, discarding an"
+		       " incoming event\n");
+	}
+
+ out:
+	spin_unlock_irqrestore(&(intf->events_lock), flags);
+
+	return rv;
+}
+
+static int handle_bmc_rsp(ipmi_smi_t          intf,
+			  struct ipmi_smi_msg *msg)
+{
+	struct ipmi_recv_msg *recv_msg;
+	int                  found = 0;
+	struct list_head     *entry;
+
+	recv_msg = (struct ipmi_recv_msg *) msg->user_data;
+
+	/* Make sure the user still exists. */
+	list_for_each(entry, &(intf->users)) {
+		if (list_entry(entry, struct ipmi_user, link)
+		    == recv_msg->user)
+		{
+			/* Found it, so we can deliver it */
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found) {
+		/* The user for the message went away, so give up. */
+		ipmi_free_recv_msg(recv_msg);
+	} else {
+		struct ipmi_system_interface_addr *smi_addr;
+
+		recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
+		recv_msg->msgid = msg->msgid;
+		smi_addr = ((struct ipmi_system_interface_addr *)
+			    &(recv_msg->addr));
+		smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+		smi_addr->channel = IPMI_BMC_CHANNEL;
+		smi_addr->lun = msg->rsp[0] & 3;
+		recv_msg->msg.netfn = msg->rsp[0] >> 2;
+		recv_msg->msg.cmd = msg->rsp[1];
+		memcpy(recv_msg->msg_data,
+		       &(msg->rsp[2]),
+		       msg->rsp_size - 2);
+		recv_msg->msg.data = recv_msg->msg_data;
+		recv_msg->msg.data_len = msg->rsp_size - 2;
+		deliver_response(recv_msg);
+	}
+
+	return 0;
+}
+
+/* Handle a new message.  Return 1 if the message should be requeued,
+   0 if the message should be freed, or -1 if the message should not
+   be freed or requeued. */
+static int handle_new_recv_msg(ipmi_smi_t          intf,
+			       struct ipmi_smi_msg *msg)
+{
+	int requeue;
+
+	if (msg->rsp_size < 2) {
+		/* Message is too small to be correct. */
+		requeue = 0;
+	} else if (msg->rsp[1] == IPMI_GET_MSG_CMD) {
+#if DEBUG_MSGING
+		int m;
+		printk("Response:");
+		for (m=0; m<msg->rsp_size; m++)
+			printk(" %2.2x", msg->rsp[m]);
+		printk("\n");
+#endif
+		/* It's from the receive queue. */
+		if (msg->rsp[4] & 0x04) {
+			/* It's a response, so find the
+			   requesting message and send it up. */
+			requeue = handle_get_msg_rsp(intf, msg);
+		} else {
+			/* It's a command to the SMS from some other
+			   entity.  Handle that. */
+			requeue = handle_get_msg_cmd(intf, msg);
+		}
+	} else if (msg->rsp[1] == IPMI_READ_EVENT_MSG_BUFFER_CMD) {
+		/* It's an asyncronous event. */
+		requeue = handle_read_event_rsp(intf, msg);
+	} else {
+		/* It's a response from the local BMC. */
+		requeue = handle_bmc_rsp(intf, msg);
+	}
+
+	return requeue;
+}
+
+/* Handle a new message from the lower layer. */
+void ipmi_smi_msg_received(ipmi_smi_t          intf,
+			   struct ipmi_smi_msg *msg)
+{
+	unsigned long flags;
+	int           rv;
+
+
+	/* Lock the user lock so the user can't go away while we are
+	   working on it. */
+	read_lock(&(intf->users_lock));
+
+	if ((msg->data_size >= 2) && (msg->data[1] == IPMI_SEND_MSG_CMD)) {
+		/* This is the local response to a send, start the
+                   timer for these. */
+		intf_start_seq_timer(intf, msg->msgid);
+		ipmi_free_smi_msg(msg);
+		goto out_unlock;
+	}
+
+	/* To preserve message order, if the list is not empty, we
+           tack this message onto the end of the list. */
+	spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
+	if (!list_empty(&(intf->waiting_msgs))) {
+		list_add_tail(&(msg->link), &(intf->waiting_msgs));
+		spin_unlock(&(intf->waiting_msgs_lock));
+		goto out_unlock;
+	}
+	spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+		
+	rv = handle_new_recv_msg(intf, msg);
+	if (rv > 0) {
+		/* Could not handle the message now, just add it to a
+                   list to handle later. */
+		spin_lock(&(intf->waiting_msgs_lock));
+		list_add_tail(&(msg->link), &(intf->waiting_msgs));
+		spin_unlock(&(intf->waiting_msgs_lock));
+	} else if (rv == 0) {
+		ipmi_free_smi_msg(msg);
+	}
+
+ out_unlock:
+	read_unlock(&(intf->users_lock));
+}
+
+void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
+{
+	struct list_head *entry;
+	ipmi_user_t      user;
+
+	read_lock(&(intf->users_lock));
+	list_for_each(entry, &(intf->users)) {
+		user = list_entry(entry, struct ipmi_user, link);
+
+		if (! user->handler->ipmi_watchdog_pretimeout)
+			continue;
+
+		user->handler->ipmi_watchdog_pretimeout(user->handler_data);
+	}
+	read_unlock(&(intf->users_lock));
+}
+
+static void
+handle_msg_timeout(struct ipmi_recv_msg *msg)
+{
+	msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
+	msg->msg_data[0] = IPMI_TIMEOUT_COMPLETION_CODE;
+	msg->msg.netfn |= 1; /* Convert to a response. */
+	msg->msg.data_len = 1;
+	msg->msg.data = msg->msg_data;
+	deliver_response(msg);
+}
+
+static void
+send_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
+		   struct ipmi_smi_msg *smi_msg,
+		   unsigned char seq, long seqid)
+{
+	if (!smi_msg)
+		smi_msg = ipmi_alloc_smi_msg();
+	if (!smi_msg)
+		/* If we can't allocate the message, then just return, we
+		   get 4 retries, so this should be ok. */
+		return;
+
+	memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len);
+	smi_msg->data_size = recv_msg->msg.data_len;
+	smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid);
+		
+	/* Send the new message.  We send with a zero priority.  It
+	   timed out, I doubt time is that critical now, and high
+	   priority messages are really only for messages to the local
+	   MC, which don't get resent. */
+	intf->handlers->sender(intf->send_info, smi_msg, 0);
+
+#if DEBUG_MSGING
+	{
+		int m;
+		printk("Resend: ");
+		for (m=0; m<smi_msg->data_size; m++)
+			printk(" %2.2x", smi_msg->data[m]);
+		printk("\n");
+	}
+#endif
+}
+
+static void
+ipmi_timeout_handler(long timeout_period)
+{
+	ipmi_smi_t           intf;
+	struct list_head     timeouts;
+	struct ipmi_recv_msg *msg;
+	struct ipmi_smi_msg  *smi_msg;
+	unsigned long        flags;
+	struct list_head     *entry, *entry2;
+	int                  i, j;
+
+	INIT_LIST_HEAD(&timeouts);
+
+	spin_lock(&interfaces_lock);
+	for (i=0; i<MAX_IPMI_INTERFACES; i++) {
+		intf = ipmi_interfaces[i];
+		if (intf == NULL)
+			continue;
+
+		read_lock(&(intf->users_lock));
+
+		/* See if any waiting messages need to be processed. */
+		spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
+		list_for_each_safe(entry, entry2, &(intf->waiting_msgs)) {
+			smi_msg = list_entry(entry, struct ipmi_smi_msg, link);
+			if (! handle_new_recv_msg(intf, smi_msg)) {
+				list_del(entry);
+				ipmi_free_smi_msg(smi_msg);
+			} else {
+				/* To preserve message order, quit if we
+				   can't handle a message. */
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+
+		/* Go through the seq table and find any messages that
+		   have timed out, putting them in the timeouts
+		   list. */
+		spin_lock_irqsave(&(intf->seq_lock), flags);
+		for (j=0; j<IPMI_IPMB_NUM_SEQ; j++) {
+			struct seq_table *ent = &(intf->seq_table[j]);
+			if (!ent->inuse)
+				continue;
+
+			ent->timeout -= timeout_period;
+			if (ent->timeout > 0)
+				continue;
+
+			if (ent->retries_left == 0) {
+				/* The message has used all its retries. */
+				ent->inuse = 0;
+				msg = ent->recv_msg;
+				list_add_tail(&(msg->link), &timeouts);
+			} else {
+				/* More retries, send again. */
+
+				/* Start with the max timer, set to normal
+				   timer after the message is sent. */
+				ent->timeout = MAX_MSG_TIMEOUT;
+				ent->retries_left--;
+				send_from_recv_msg(intf, ent->recv_msg, NULL,
+						   j, ent->seqid);
+			}
+		}
+		spin_unlock_irqrestore(&(intf->seq_lock), flags);
+
+		list_for_each_safe(entry, entry2, &timeouts) {
+			msg = list_entry(entry, struct ipmi_recv_msg, link);
+			handle_msg_timeout(msg);
+		}
+
+		read_unlock(&(intf->users_lock));
+	}
+	spin_unlock(&interfaces_lock);
+}
+
+static void ipmi_request_event(void)
+{
+	ipmi_smi_t intf;
+	int        i;
+
+	spin_lock(&interfaces_lock);
+	for (i=0; i<MAX_IPMI_INTERFACES; i++) {
+		intf = ipmi_interfaces[i];
+		if (intf == NULL)
+			continue;
+
+		intf->handlers->request_events(intf->send_info);
+	}
+	spin_unlock(&interfaces_lock);
+}
+
+static struct timer_list ipmi_timer;
+
+/* Call every 100 ms. */
+#define IPMI_TIMEOUT_TIME	100
+#define IPMI_TIMEOUT_JIFFIES	(IPMI_TIMEOUT_TIME/(1000/HZ))
+
+/* Request events from the queue every second.  Hopefully, in the
+   future, IPMI will add a way to know immediately if an event is
+   in the queue. */
+#define IPMI_REQUEST_EV_TIME	(1000 / (IPMI_TIMEOUT_TIME))
+
+static volatile int stop_operation = 0;
+static volatile int timer_stopped = 0;
+static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
+
+static void ipmi_timeout(unsigned long data)
+{
+	if (stop_operation) {
+		timer_stopped = 1;
+		return;
+	}
+
+	ticks_to_req_ev--;
+	if (ticks_to_req_ev == 0) {
+		ipmi_request_event();
+		ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
+	}
+
+	ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
+
+	ipmi_timer.expires += IPMI_TIMEOUT_JIFFIES;
+	add_timer(&ipmi_timer);
+}
+
+
+/* FIXME - convert these to slabs. */
+static void free_smi_msg(struct ipmi_smi_msg *msg)
+{
+	kfree(msg);
+}
+
+struct ipmi_smi_msg *ipmi_alloc_smi_msg(void)
+{
+	struct ipmi_smi_msg *rv;
+	rv = kmalloc(sizeof(struct ipmi_smi_msg), GFP_ATOMIC);
+	if (rv)
+		rv->done = free_smi_msg;
+	return rv;
+}
+
+static void free_recv_msg(struct ipmi_recv_msg *msg)
+{
+	kfree(msg);
+}
+
+struct ipmi_recv_msg *ipmi_alloc_recv_msg(void)
+{
+	struct ipmi_recv_msg *rv;
+
+	rv = kmalloc(sizeof(struct ipmi_recv_msg), GFP_ATOMIC);
+	if (rv)
+		rv->done = free_recv_msg;
+	return rv;
+}
+
+#ifdef CONFIG_IPMI_PANIC_EVENT
+
+static void dummy_smi_done_handler(struct ipmi_smi_msg *msg)
+{
+}
+
+static void dummy_recv_done_handler(struct ipmi_recv_msg *msg)
+{
+}
+
+static void send_panic_events(void)
+{
+	struct ipmi_msg                   msg;
+	ipmi_smi_t                        intf;
+	unsigned char                     data[8];
+	int                               i;
+	struct ipmi_system_interface_addr addr;
+	struct ipmi_smi_msg               smi_msg;
+	struct ipmi_recv_msg              recv_msg;
+
+	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+	addr.channel = IPMI_BMC_CHANNEL;
+
+	/* Fill in an event telling that we have failed. */
+	msg.netfn = 0x04; /* Sensor or Event. */
+	msg.cmd = 2; /* Platform event command. */
+	msg.data = data;
+	msg.data_len = 8;
+	data[0] = 0x21; /* Kernel generator ID, IPMI table 5-4 */
+	data[1] = 0x03; /* This is for IPMI 1.0. */
+	data[2] = 0x20; /* OS Critical Stop, IPMI table 36-3 */
+	data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */
+	data[5] = 0xa1; /* Runtime stop OEM bytes 2 & 3. */
+
+	/* These used to have the first three bytes of the panic string,
+	   but not only is that not terribly useful, it's not available
+	   any more. */
+	data[3] = 0;
+	data[6] = 0;
+	data[7] = 0;
+
+	smi_msg.done = dummy_smi_done_handler;
+	recv_msg.done = dummy_recv_done_handler;
+
+	/* For every registered interface, send the event. */
+	for (i=0; i<MAX_IPMI_INTERFACES; i++) {
+		intf = ipmi_interfaces[i];
+		if (intf == NULL)
+			continue;
+
+		intf->handlers->set_run_to_completion(intf->send_info, 1);
+		i_ipmi_request(NULL,
+			       intf,
+			       (struct ipmi_addr *) &addr,
+			       0,
+			       &msg,
+			       &smi_msg,
+			       &recv_msg,
+			       0,
+			       intf->my_address,
+			       intf->my_lun);
+	}
+}
+#endif /* CONFIG_IPMI_PANIC_EVENT */
+
+static int has_paniced = 0;
+
+static int panic_event(struct notifier_block *this,
+		       unsigned long         event,
+                       void                  *ptr)
+{
+	int        i;
+	ipmi_smi_t intf;
+
+	if (has_paniced)
+		return NOTIFY_DONE;
+	has_paniced = 1;
+
+	/* For every registered interface, set it to run to completion. */
+	for (i=0; i<MAX_IPMI_INTERFACES; i++) {
+		intf = ipmi_interfaces[i];
+		if (intf == NULL)
+			continue;
+
+		intf->handlers->set_run_to_completion(intf->send_info, 1);
+	}
+
+#ifdef CONFIG_IPMI_PANIC_EVENT
+	send_panic_events();
+#endif
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+	panic_event,
+	NULL,
+	200   /* priority: INT_MAX >= x >= 0 */
+};
+
+
+static __init int ipmi_init_msghandler(void)
+{
+	int i;
+
+	if (initialized)
+		return 0;
+
+	for (i=0; i<MAX_IPMI_INTERFACES; i++) {
+		ipmi_interfaces[i] = NULL;
+	}
+
+	init_timer(&ipmi_timer);
+	ipmi_timer.data = 0;
+	ipmi_timer.function = ipmi_timeout;
+	ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES;
+	add_timer(&ipmi_timer);
+
+	notifier_chain_register(&panic_notifier_list, &panic_block);
+
+	initialized = 1;
+
+	printk(KERN_INFO "ipmi: message handler initialized\n");
+
+	return 0;
+}
+
+static __exit void cleanup_ipmi(void)
+{
+	if (!initialized)
+		return;
+
+	notifier_chain_unregister(&panic_notifier_list, &panic_block);
+
+	/* This can't be called if any interfaces exist, so no worry about
+	   shutting down the interfaces. */
+
+	/* Tell the timer to stop, then wait for it to stop.  This avoids
+	   problems with race conditions removing the timer here. */
+	stop_operation = 1;
+	while (!timer_stopped) {
+		schedule_timeout(1);
+	}
+
+	initialized = 0;
+}
+module_exit(cleanup_ipmi);
+
+module_init(ipmi_init_msghandler);
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ipmi_alloc_recv_msg);
+EXPORT_SYMBOL(ipmi_create_user);
+EXPORT_SYMBOL(ipmi_destroy_user);
+EXPORT_SYMBOL(ipmi_get_version);
+EXPORT_SYMBOL(ipmi_request);
+EXPORT_SYMBOL(ipmi_request_supply_msgs);
+EXPORT_SYMBOL(ipmi_request_with_source);
+EXPORT_SYMBOL(ipmi_register_smi);
+EXPORT_SYMBOL(ipmi_unregister_smi);
+EXPORT_SYMBOL(ipmi_register_for_cmd);
+EXPORT_SYMBOL(ipmi_unregister_for_cmd);
+EXPORT_SYMBOL(ipmi_smi_msg_received);
+EXPORT_SYMBOL(ipmi_smi_watchdog_pretimeout);
+EXPORT_SYMBOL(ipmi_alloc_smi_msg);
+EXPORT_SYMBOL(ipmi_register_all_cmd_rcvr);
+EXPORT_SYMBOL(ipmi_unregister_all_cmd_rcvr);
+EXPORT_SYMBOL(ipmi_addr_length);
+EXPORT_SYMBOL(ipmi_validate_addr);
+EXPORT_SYMBOL(ipmi_set_gets_events);
+EXPORT_SYMBOL(ipmi_addr_equal);
+EXPORT_SYMBOL(ipmi_smi_watcher_register);
+EXPORT_SYMBOL(ipmi_smi_watcher_unregister);
+EXPORT_SYMBOL(ipmi_set_my_address);
+EXPORT_SYMBOL(ipmi_get_my_address);
+EXPORT_SYMBOL(ipmi_set_my_LUN);
+EXPORT_SYMBOL(ipmi_get_my_LUN);
diff -Nru a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/ipmi/ipmi_watchdog.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,1114 @@
+/*
+ * ipmi_watchdog.c
+ *
+ * A watchdog timer based upon the IPMI interface.
+ *
+ * Author: MontaVista Software, Inc.
+ *         Corey Minyard <minyard@mvista.com>
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/ipmi.h>
+#include <linux/ipmi_smi.h>
+#include <linux/watchdog.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/rwsem.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+#include <linux/notifier.h>
+#include <linux/nmi.h>
+#include <linux/reboot.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#ifdef CONFIG_X86_LOCAL_APIC
+#include <asm/apic.h>
+#endif
+
+/*
+ * The IPMI command/response information for the watchdog timer.
+ */
+
+/* values for byte 1 of the set command, byte 2 of the get response. */
+#define WDOG_DONT_LOG		(1 << 7)
+#define WDOG_DONT_STOP_ON_SET	(1 << 6)
+#define WDOG_SET_TIMER_USE(byte, use) \
+	byte = ((byte) & 0xf8) | ((use) & 0x7)
+#define WDOG_GET_TIMER_USE(byte) ((byte) & 0x7)
+#define WDOG_TIMER_USE_BIOS_FRB2	1
+#define WDOG_TIMER_USE_BIOS_POST	2
+#define WDOG_TIMER_USE_OS_LOAD		3
+#define WDOG_TIMER_USE_SMS_OS		4
+#define WDOG_TIMER_USE_OEM		5
+
+/* values for byte 2 of the set command, byte 3 of the get response. */
+#define WDOG_SET_PRETIMEOUT_ACT(byte, use) \
+	byte = ((byte) & 0x8f) | (((use) & 0x7) << 4)
+#define WDOG_GET_PRETIMEOUT_ACT(byte) (((byte) >> 4) & 0x7)
+#define WDOG_PRETIMEOUT_NONE		0
+#define WDOG_PRETIMEOUT_SMI		1
+#define WDOG_PRETIMEOUT_NMI		2
+#define WDOG_PRETIMEOUT_MSG_INT		3
+
+/* Operations that can be performed on a pretimout. */
+#define WDOG_PREOP_NONE		0
+#define WDOG_PREOP_PANIC	1
+#define WDOG_PREOP_GIVE_DATA	2 /* Cause data to be available to
+                                     read.  Doesn't work in NMI
+                                     mode. */
+
+/* Actions to perform on a full timeout. */
+#define WDOG_SET_TIMEOUT_ACT(byte, use) \
+	byte = ((byte) & 0xf8) | ((use) & 0x7)
+#define WDOG_GET_TIMEOUT_ACT(byte) ((byte) & 0x7)
+#define WDOG_TIMEOUT_NONE		0
+#define WDOG_TIMEOUT_RESET		1
+#define WDOG_TIMEOUT_POWER_DOWN		2
+#define WDOG_TIMEOUT_POWER_CYCLE	3
+
+/* Byte 3 of the get command, byte 4 of the get response is the
+   pre-timeout in seconds. */
+
+/* Bits for setting byte 4 of the set command, byte 5 of the get response. */
+#define WDOG_EXPIRE_CLEAR_BIOS_FRB2	(1 << 1)
+#define WDOG_EXPIRE_CLEAR_BIOS_POST	(1 << 2)
+#define WDOG_EXPIRE_CLEAR_OS_LOAD	(1 << 3)
+#define WDOG_EXPIRE_CLEAR_SMS_OS	(1 << 4)
+#define WDOG_EXPIRE_CLEAR_OEM		(1 << 5)
+
+/* Setting/getting the watchdog timer value.  This is for bytes 5 and
+   6 (the timeout time) of the set command, and bytes 6 and 7 (the
+   timeout time) and 8 and 9 (the current countdown value) of the
+   response.  The timeout value is given in seconds (in the command it
+   is 100ms intervals). */
+#define WDOG_SET_TIMEOUT(byte1, byte2, val) \
+	(byte1) = (((val) * 10) & 0xff), (byte2) = (((val) * 10) >> 8)
+#define WDOG_GET_TIMEOUT(byte1, byte2) \
+	(((byte1) | ((byte2) << 8)) / 10)
+
+#define IPMI_WDOG_RESET_TIMER		0x22
+#define IPMI_WDOG_SET_TIMER		0x24
+#define IPMI_WDOG_GET_TIMER		0x25
+
+/* These are here until the real ones get into the watchdog.h interface. */
+#ifndef WDIOC_GETTIMEOUT
+#define	WDIOC_GETTIMEOUT        _IOW(WATCHDOG_IOCTL_BASE, 20, int)
+#endif
+#ifndef WDIOC_SET_PRETIMEOUT
+#define	WDIOC_SET_PRETIMEOUT     _IOW(WATCHDOG_IOCTL_BASE, 21, int)
+#endif
+#ifndef WDIOC_GET_PRETIMEOUT
+#define	WDIOC_GET_PRETIMEOUT     _IOW(WATCHDOG_IOCTL_BASE, 22, int)
+#endif
+
+static ipmi_user_t watchdog_user = NULL;
+
+/* Default the timeout to 10 seconds. */
+static int timeout = 10;
+
+/* The pre-timeout is disabled by default. */
+static int pretimeout = 0;
+
+/* Default action is to reset the board on a timeout. */
+static unsigned char action_val = WDOG_TIMEOUT_RESET;
+
+static char *action = "reset";
+
+static unsigned char preaction_val = WDOG_PRETIMEOUT_NONE;
+
+static char *preaction = "pre_none";
+
+static unsigned char preop_val = WDOG_PREOP_NONE;
+
+static char *preop = "preop_none";
+static spinlock_t ipmi_read_lock = SPIN_LOCK_UNLOCKED;
+static char data_to_read = 0;
+static DECLARE_WAIT_QUEUE_HEAD(read_q);
+static struct fasync_struct *fasync_q = NULL;
+static char pretimeout_since_last_heartbeat = 0;
+
+MODULE_PARM(timeout, "i");
+MODULE_PARM(pretimeout, "i");
+MODULE_PARM(action, "s");
+MODULE_PARM(preaction, "s");
+MODULE_PARM(preop, "s");
+
+/* Default state of the timer. */
+static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+
+/* If shutting down via IPMI, we ignore the heartbeat. */
+static int ipmi_ignore_heartbeat = 0;
+
+/* Is someone using the watchdog?  Only one user is allowed. */
+static int ipmi_wdog_open = 0;
+
+/* If true, the driver will start running as soon as it is configured
+   and ready. */
+static int start_now = 0;
+
+/* If set to 1, the heartbeat command will set the state to reset and
+   start the timer.  The timer doesn't normally run when the driver is
+   first opened until the heartbeat is set the first time, this
+   variable is used to accomplish this. */
+static int ipmi_start_timer_on_heartbeat = 0;
+
+/* IPMI version of the BMC. */
+static unsigned char ipmi_version_major;
+static unsigned char ipmi_version_minor;
+
+
+static int ipmi_heartbeat(void);
+static void panic_halt_ipmi_heartbeat(void);
+
+
+/* We use a semaphore to make sure that only one thing can send a set
+   timeout at one time, because we only have one copy of the data.
+   The semaphore is claimed when the set_timeout is sent and freed
+   when both messages are free. */
+static atomic_t set_timeout_tofree = ATOMIC_INIT(0);
+static DECLARE_MUTEX(set_timeout_lock);
+static void set_timeout_free_smi(struct ipmi_smi_msg *msg)
+{
+    if (atomic_dec_and_test(&set_timeout_tofree))
+	    up(&set_timeout_lock);
+}
+static void set_timeout_free_recv(struct ipmi_recv_msg *msg)
+{
+    if (atomic_dec_and_test(&set_timeout_tofree))
+	    up(&set_timeout_lock);
+}
+static struct ipmi_smi_msg set_timeout_smi_msg =
+{
+	.done = set_timeout_free_smi
+};
+static struct ipmi_recv_msg set_timeout_recv_msg =
+{
+	.done = set_timeout_free_recv
+};
+ 
+static int i_ipmi_set_timeout(struct ipmi_smi_msg  *smi_msg,
+			      struct ipmi_recv_msg *recv_msg,
+			      int                  *send_heartbeat_now)
+{
+	struct ipmi_msg    msg;
+	unsigned char      data[6];
+	int                rv;
+	struct ipmi_system_interface_addr addr;
+
+
+	*send_heartbeat_now = 0;
+	data[0] = 0;
+	WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
+
+	if ((ipmi_version_major > 1)
+	    || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5)))
+	{
+		/* This is an IPMI 1.5-only feature. */
+		data[0] |= WDOG_DONT_STOP_ON_SET;
+	} else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
+		/* In ipmi 1.0, setting the timer stops the watchdog, we
+		   need to start it back up again. */
+		*send_heartbeat_now = 1;
+	}
+
+	data[1] = 0;
+	WDOG_SET_TIMEOUT_ACT(data[1], ipmi_watchdog_state);
+	if (pretimeout > 0) {
+	    WDOG_SET_PRETIMEOUT_ACT(data[1], preaction_val);
+	    data[2] = pretimeout;
+	} else {
+	    WDOG_SET_PRETIMEOUT_ACT(data[1], WDOG_PRETIMEOUT_NONE);
+	    data[2] = 0; /* No pretimeout. */
+	}
+	data[3] = 0;
+	WDOG_SET_TIMEOUT(data[4], data[5], timeout);
+
+	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+	addr.channel = IPMI_BMC_CHANNEL;
+	addr.lun = 0;
+
+	msg.netfn = 0x06;
+	msg.cmd = IPMI_WDOG_SET_TIMER;
+	msg.data = data;
+	msg.data_len = sizeof(data);
+	rv = ipmi_request_supply_msgs(watchdog_user,
+				      (struct ipmi_addr *) &addr,
+				      0,
+				      &msg,
+				      smi_msg,
+				      recv_msg,
+				      1);
+	if (rv) {
+		printk(KERN_WARNING "IPMI Watchdog, set timeout error: %d\n",
+		       rv);
+	}
+
+	return rv;
+}
+
+static int ipmi_set_timeout(void)
+{
+	int send_heartbeat_now;
+	int rv;
+
+
+	/* We can only send one of these at a time. */
+	down(&set_timeout_lock);
+
+	atomic_set(&set_timeout_tofree, 2);
+
+	rv = i_ipmi_set_timeout(&set_timeout_smi_msg,
+				&set_timeout_recv_msg,
+				&send_heartbeat_now);
+	if (rv) {
+		up(&set_timeout_lock);
+	} else {
+		if (send_heartbeat_now)
+			rv = ipmi_heartbeat();
+	}
+
+	return rv;
+}
+
+static void dummy_smi_free(struct ipmi_smi_msg *msg)
+{
+}
+static void dummy_recv_free(struct ipmi_recv_msg *msg)
+{
+}
+static struct ipmi_smi_msg panic_halt_smi_msg =
+{
+	.done = dummy_smi_free
+};
+static struct ipmi_recv_msg panic_halt_recv_msg =
+{
+	.done = dummy_recv_free
+};
+
+/* Special call, doesn't claim any locks.  This is only to be called
+   at panic or halt time, in run-to-completion mode, when the caller
+   is the only CPU and the only thing that will be going IPMI
+   calls. */
+static void panic_halt_ipmi_set_timeout(void)
+{
+	int send_heartbeat_now;
+	int rv;
+
+	rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
+				&panic_halt_recv_msg,
+				&send_heartbeat_now);
+	if (!rv) {
+		if (send_heartbeat_now)
+			panic_halt_ipmi_heartbeat();
+	}
+}
+
+/* Do a delayed shutdown, with the delay in milliseconds.  If power_off is
+   false, do a reset.  If power_off is true, do a power down.  This is
+   primarily for the IMB code's shutdown. */
+void ipmi_delayed_shutdown(long delay, int power_off)
+{
+	ipmi_ignore_heartbeat = 1;
+	if (power_off) 
+		ipmi_watchdog_state = WDOG_TIMEOUT_POWER_DOWN;
+	else
+		ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
+	timeout = delay;
+	ipmi_set_timeout();
+}
+
+/* We use a semaphore to make sure that only one thing can send a
+   heartbeat at one time, because we only have one copy of the data.
+   The semaphore is claimed when the set_timeout is sent and freed
+   when both messages are free. */
+static atomic_t heartbeat_tofree = ATOMIC_INIT(0);
+static DECLARE_MUTEX(heartbeat_lock);
+static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock);
+static void heartbeat_free_smi(struct ipmi_smi_msg *msg)
+{
+    if (atomic_dec_and_test(&heartbeat_tofree))
+	    up(&heartbeat_wait_lock);
+}
+static void heartbeat_free_recv(struct ipmi_recv_msg *msg)
+{
+    if (atomic_dec_and_test(&heartbeat_tofree))
+	    up(&heartbeat_wait_lock);
+}
+static struct ipmi_smi_msg heartbeat_smi_msg =
+{
+	.done = heartbeat_free_smi
+};
+static struct ipmi_recv_msg heartbeat_recv_msg =
+{
+	.done = heartbeat_free_recv
+};
+ 
+static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg =
+{
+	.done = dummy_smi_free
+};
+static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg =
+{
+	.done = dummy_recv_free
+};
+ 
+static int ipmi_heartbeat(void)
+{
+	struct ipmi_msg                   msg;
+	int                               rv;
+	struct ipmi_system_interface_addr addr;
+
+	if (ipmi_ignore_heartbeat) {
+		return 0;
+	}
+
+	if (ipmi_start_timer_on_heartbeat) {
+		ipmi_start_timer_on_heartbeat = 0;
+		ipmi_watchdog_state = action_val;
+		return ipmi_set_timeout();
+	}
+
+	if (pretimeout_since_last_heartbeat) {
+		/* A pretimeout occurred, make sure we set the timeout.
+		   We don't want to set the action, though, we want to
+		   leave that alone (thus it can't be combined with the
+		   above operation. */
+		pretimeout_since_last_heartbeat = 0;
+		return ipmi_set_timeout();
+	}
+
+	down(&heartbeat_lock);
+
+	atomic_set(&heartbeat_tofree, 2);
+
+	/* Don't reset the timer if we have the timer turned off, that
+           re-enables the watchdog. */
+	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) {
+		up(&heartbeat_lock);
+		return 0;
+	}
+
+	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+	addr.channel = IPMI_BMC_CHANNEL;
+	addr.lun = 0;
+
+	msg.netfn = 0x06;
+	msg.cmd = IPMI_WDOG_RESET_TIMER;
+	msg.data = NULL;
+	msg.data_len = 0;
+	rv = ipmi_request_supply_msgs(watchdog_user,
+				      (struct ipmi_addr *) &addr,
+				      0,
+				      &msg,
+				      &heartbeat_smi_msg,
+				      &heartbeat_recv_msg,
+				      1);
+	if (rv) {
+		up(&heartbeat_lock);
+		printk(KERN_WARNING "IPMI Watchdog, heartbeat failure: %d\n",
+		       rv);
+		return rv;
+	}
+
+	/* Wait for the heartbeat to be sent. */
+	down(&heartbeat_wait_lock);
+
+	if (heartbeat_recv_msg.msg.data[0] != 0) {
+	    /* Got an error in the heartbeat response.  It was already
+	       reported in ipmi_wdog_msg_handler, but we should return
+	       an error here. */
+	    rv = -EINVAL;
+	}
+
+	up(&heartbeat_lock);
+
+	return rv;
+}
+
+static void panic_halt_ipmi_heartbeat(void)
+{
+	struct ipmi_msg                   msg;
+	struct ipmi_system_interface_addr addr;
+
+
+	/* Don't reset the timer if we have the timer turned off, that
+           re-enables the watchdog. */
+	if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
+		return;
+
+	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
+	addr.channel = IPMI_BMC_CHANNEL;
+	addr.lun = 0;
+
+	msg.netfn = 0x06;
+	msg.cmd = IPMI_WDOG_RESET_TIMER;
+	msg.data = NULL;
+	msg.data_len = 0;
+	ipmi_request_supply_msgs(watchdog_user,
+				 (struct ipmi_addr *) &addr,
+				 0,
+				 &msg,
+				 &panic_halt_heartbeat_smi_msg,
+				 &panic_halt_heartbeat_recv_msg,
+				 1);
+}
+
+static struct watchdog_info ident=
+{
+	0, /* WDIOF_SETTIMEOUT, */
+	1,
+	"IPMI"
+};
+
+static int ipmi_ioctl(struct inode *inode, struct file *file,
+		      unsigned int cmd, unsigned long arg)
+{
+	int i;
+	int val;
+
+	switch(cmd) {
+	case WDIOC_GETSUPPORT:
+		i = copy_to_user((void*)arg, &ident, sizeof(ident));
+		return i ? -EFAULT : 0;
+
+	case WDIOC_SETTIMEOUT:
+		i = copy_from_user(&val, (void *) arg, sizeof(int));
+		if (i)
+			return -EFAULT;
+		timeout = val;
+		return ipmi_set_timeout();
+
+	case WDIOC_GETTIMEOUT:
+		i = copy_to_user((void *) arg,
+				 &timeout,
+				 sizeof(timeout));
+		if (i)
+			return -EFAULT;
+		return 0;
+
+	case WDIOC_SET_PRETIMEOUT:
+		i = copy_from_user(&val, (void *) arg, sizeof(int));
+		if (i)
+			return -EFAULT;
+		pretimeout = val;
+		return ipmi_set_timeout();
+
+	case WDIOC_GET_PRETIMEOUT:
+		i = copy_to_user((void *) arg,
+				 &pretimeout,
+				 sizeof(pretimeout));
+		if (i)
+			return -EFAULT;
+		return 0;
+
+	case WDIOC_KEEPALIVE:
+		return ipmi_heartbeat();
+
+	case WDIOC_SETOPTIONS:
+		i = copy_from_user(&val, (void *) arg, sizeof(int));
+		if (i)
+			return -EFAULT;
+		if (val & WDIOS_DISABLECARD)
+		{
+			ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+			ipmi_set_timeout();
+			ipmi_start_timer_on_heartbeat = 0;
+		}
+
+		if (val & WDIOS_ENABLECARD)
+		{
+			ipmi_watchdog_state = action_val;
+			ipmi_set_timeout();
+		}
+		return 0;
+
+	case WDIOC_GETSTATUS:
+		val = 0;
+		return copy_to_user((void *) arg, &val, sizeof(val));
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static ssize_t ipmi_write(struct file *file,
+			  const char  *buf,
+			  size_t      len,
+			  loff_t      *ppos)
+{
+	int rv;
+
+	/*  Can't seek (pwrite) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	if (len) {
+		rv = ipmi_heartbeat();
+		if (rv)
+			return rv;
+		return 1;
+	}
+	return 0;
+}
+
+static ssize_t ipmi_read(struct file *file,
+			 char        *buf,
+			 size_t      count,
+			 loff_t      *ppos)
+{
+	int          rv = 0;
+	wait_queue_t wait;
+
+	/*  Can't seek (pread) on this device  */
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	if (count <= 0)
+		return 0;
+
+	/* Reading returns if the pretimeout has gone off, and it only does
+	   it once per pretimeout. */
+	spin_lock(&ipmi_read_lock);
+	if (!data_to_read) {
+		if (file->f_flags & O_NONBLOCK) {
+			rv = -EAGAIN;
+			goto out;
+		}
+		
+		init_waitqueue_entry(&wait, current);
+		add_wait_queue(&read_q, &wait);
+		while (!data_to_read) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			spin_unlock(&ipmi_read_lock);
+			schedule();
+			spin_lock(&ipmi_read_lock);
+		}
+		remove_wait_queue(&read_q, &wait);
+	    
+		if (signal_pending(current)) {
+			rv = -ERESTARTSYS;
+			goto out;
+		}
+	}
+	data_to_read = 0;
+
+ out:
+	spin_unlock(&ipmi_read_lock);
+
+	if (rv == 0) {
+		if (copy_to_user(buf, &data_to_read, 1))
+			rv = -EFAULT;
+		else
+			rv = 1;
+	}
+
+	return rv;
+}
+
+static int ipmi_open(struct inode *ino, struct file *filep)
+{
+        switch (minor(ino->i_rdev))
+        {
+                case WATCHDOG_MINOR:
+                    if (ipmi_wdog_open)
+                        return -EBUSY;
+
+                    ipmi_wdog_open = 1;
+
+		    /* Don't start the timer now, let it start on the
+		       first heartbeat. */
+		    ipmi_start_timer_on_heartbeat = 1;
+                    return(0);
+
+                default:
+                    return (-ENODEV);
+        }
+}
+
+static unsigned int ipmi_poll(struct file *file, poll_table *wait)
+{
+	unsigned int mask = 0;
+	
+	poll_wait(file, &read_q, wait);
+
+	spin_lock(&ipmi_read_lock);
+	if (data_to_read)
+		mask |= (POLLIN | POLLRDNORM);
+	spin_unlock(&ipmi_read_lock);
+
+	return mask;
+}
+
+static int ipmi_fasync(int fd, struct file *file, int on)
+{
+	int result;
+
+	result = fasync_helper(fd, file, on, &fasync_q);
+
+	return (result);
+}
+
+static int ipmi_close(struct inode *ino, struct file *filep)
+{
+	if (minor(ino->i_rdev)==WATCHDOG_MINOR)
+	{
+#ifndef CONFIG_WATCHDOG_NOWAYOUT	
+		ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+		ipmi_set_timeout();
+#endif		
+	        ipmi_wdog_open = 0;
+	}
+
+	ipmi_fasync (-1, filep, 0);
+
+	return 0;
+}
+
+static struct file_operations ipmi_wdog_fops = {
+	.owner   = THIS_MODULE,
+	.read    = ipmi_read,
+	.poll    = ipmi_poll,
+	.write   = ipmi_write,
+	.ioctl   = ipmi_ioctl,
+	.open    = ipmi_open,
+	.release = ipmi_close,
+	.fasync  = ipmi_fasync,
+};
+
+static struct miscdevice ipmi_wdog_miscdev = {
+	WATCHDOG_MINOR,
+	"watchdog",
+	&ipmi_wdog_fops
+};
+
+static DECLARE_RWSEM(register_sem);
+
+static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
+				  void                 *handler_data)
+{
+	if (msg->msg.data[0] != 0) {
+		printk(KERN_ERR "IPMI Watchdog response: Error %x on cmd %x\n",
+		       msg->msg.data[0],
+		       msg->msg.cmd);
+	}
+	
+	ipmi_free_recv_msg(msg);
+}
+
+static void ipmi_wdog_pretimeout_handler(void *handler_data)
+{
+	if (preaction_val != WDOG_PRETIMEOUT_NONE) {
+		if (preop_val == WDOG_PREOP_PANIC)
+			panic("Watchdog pre-timeout");
+		else if (preop_val == WDOG_PREOP_GIVE_DATA) {
+			spin_lock(&ipmi_read_lock);
+			data_to_read = 1;
+			wake_up_interruptible(&read_q);
+			kill_fasync(&fasync_q, SIGIO, POLL_IN);
+
+			/* On some machines, the heartbeat will give
+			   an error and not work unless we re-enable
+			   the timer.   So do so. */
+			pretimeout_since_last_heartbeat = 1;
+
+			spin_unlock(&ipmi_read_lock);
+		}
+	}
+}
+
+static struct ipmi_user_hndl ipmi_hndlrs =
+{
+	.ipmi_recv_hndl           = ipmi_wdog_msg_handler,
+	.ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler
+};
+
+static void ipmi_register_watchdog(int ipmi_intf)
+{
+	int rv = -EBUSY;
+
+	down_read(&register_sem);
+	if (watchdog_user)
+		goto out;
+
+	rv = ipmi_create_user(ipmi_intf, &ipmi_hndlrs, NULL, &watchdog_user);
+	if (rv < 0) {
+		printk("IPMI watchdog: Unable to register with ipmi\n");
+		goto out;
+	}
+
+	ipmi_get_version(watchdog_user,
+			 &ipmi_version_major,
+			 &ipmi_version_minor);
+
+	rv = misc_register(&ipmi_wdog_miscdev);
+	if (rv < 0) {
+		ipmi_destroy_user(watchdog_user);
+		watchdog_user = NULL;
+		printk("IPMI watchdog: Unable to register misc device\n");
+	}
+
+ out:
+	up_write(&register_sem);
+
+	if ((start_now) && (rv == 0)) {
+		/* Run from startup, so start the timer now. */
+		start_now = 0; /* Disable this function after first startup. */
+		ipmi_watchdog_state = action_val;
+		ipmi_set_timeout();
+		printk("Starting IPMI Watchdog now!\n");
+	}
+}
+
+#ifdef HAVE_NMI_HANDLER
+static int
+ipmi_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled)
+{
+	/* If no one else handled the NMI, we assume it was the IPMI
+           watchdog. */
+	if ((!handled) && (preop_val == WDOG_PREOP_PANIC))
+		panic("IPMI watchdog pre-timeout");
+	return NOTIFY_DONE;
+}
+
+static struct nmi_handler ipmi_nmi_handler =
+{
+	.link     = LIST_HEAD_INIT(ipmi_nmi_handler.link),
+	.dev_name = "ipmi_watchdog",
+	.dev_id   = NULL,
+	.handler  = ipmi_nmi,
+	.priority = 0, /* Call us last. */
+};
+#endif
+
+static int wdog_reboot_handler(struct notifier_block *this,
+			       unsigned long         code,
+			       void                  *unused)
+{
+	static int reboot_event_handled = 0;
+
+	if ((watchdog_user) && (!reboot_event_handled)) {
+		/* Make sure we only do this once. */
+		reboot_event_handled = 1;
+
+		if (code == SYS_DOWN || code == SYS_HALT) {
+			/* Disable the WDT if we are shutting down. */
+			ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+			panic_halt_ipmi_set_timeout();
+		} else {
+			/* Set a long timer to let the reboot happens, but
+			   reboot if it hangs. */
+			timeout = 120;
+			pretimeout = 0;
+			ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
+			panic_halt_ipmi_set_timeout();
+		}
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block wdog_reboot_notifier = {
+	wdog_reboot_handler,
+	NULL,
+	0
+};
+
+extern int panic_timeout; /* Why isn't this defined anywhere? */
+
+static int wdog_panic_handler(struct notifier_block *this,
+			      unsigned long         event,
+			      void                  *unused)
+{
+	static int panic_event_handled = 0;
+
+	/* On a panic, if we have a panic timeout, make sure that the thing
+	   reboots, even if it hangs during that panic. */
+	if (watchdog_user && !panic_event_handled && (panic_timeout > 0)) {
+		/* Make sure the panic doesn't hang, and make sure we
+		   do this only once. */
+		panic_event_handled = 1;
+	    
+		timeout = panic_timeout + 120;
+		if (timeout > 255)
+			timeout = 255;
+		pretimeout = 0;
+		ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
+		panic_halt_ipmi_set_timeout();
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block wdog_panic_notifier = {
+	wdog_panic_handler,
+	NULL,
+	150   /* priority: INT_MAX >= x >= 0 */
+};
+
+
+static void ipmi_new_smi(int if_num)
+{
+	ipmi_register_watchdog(if_num);
+}
+
+static void ipmi_smi_gone(int if_num)
+{
+	/* This can never be called, because once the watchdog is
+	   registered, the interface can't go away until the watchdog
+	   is unregistered. */
+}
+
+static struct ipmi_smi_watcher smi_watcher =
+{
+	.new_smi  = ipmi_new_smi,
+	.smi_gone = ipmi_smi_gone
+};
+
+static int __init ipmi_wdog_init(void)
+{
+	int rv;
+
+	if (strcmp(action, "reset") == 0) {
+		action_val = WDOG_TIMEOUT_RESET;
+	} else if (strcmp(action, "none") == 0) {
+		action_val = WDOG_TIMEOUT_NONE;
+	} else if (strcmp(action, "power_cycle") == 0) {
+		action_val = WDOG_TIMEOUT_POWER_CYCLE;
+	} else if (strcmp(action, "power_off") == 0) {
+		action_val = WDOG_TIMEOUT_POWER_DOWN;
+	} else {
+		action_val = WDOG_TIMEOUT_RESET;
+		printk("ipmi_watchdog: Unknown action '%s', defaulting to"
+		       " reset\n", action);
+	}
+
+	if (strcmp(preaction, "pre_none") == 0) {
+		preaction_val = WDOG_PRETIMEOUT_NONE;
+	} else if (strcmp(preaction, "pre_smi") == 0) {
+		preaction_val = WDOG_PRETIMEOUT_SMI;
+#ifdef HAVE_NMI_HANDLER
+	} else if (strcmp(preaction, "pre_nmi") == 0) {
+		preaction_val = WDOG_PRETIMEOUT_NMI;
+#endif
+	} else if (strcmp(preaction, "pre_int") == 0) {
+		preaction_val = WDOG_PRETIMEOUT_MSG_INT;
+	} else {
+		action_val = WDOG_PRETIMEOUT_NONE;
+		printk("ipmi_watchdog: Unknown preaction '%s', defaulting to"
+		       " none\n", preaction);
+	}
+
+	if (strcmp(preop, "preop_none") == 0) {
+		preop_val = WDOG_PREOP_NONE;
+	} else if (strcmp(preop, "preop_panic") == 0) {
+		preop_val = WDOG_PREOP_PANIC;
+	} else if (strcmp(preop, "preop_give_data") == 0) {
+		preop_val = WDOG_PREOP_GIVE_DATA;
+	} else {
+		action_val = WDOG_PREOP_NONE;
+		printk("ipmi_watchdog: Unknown preop '%s', defaulting to"
+		       " none\n", preop);
+	}
+
+#ifdef HAVE_NMI_HANDLER
+	if (preaction_val == WDOG_PRETIMEOUT_NMI) {
+		if (preop_val == WDOG_PREOP_GIVE_DATA) {
+			printk(KERN_WARNING
+			       "ipmi_watchdog: Pretimeout op is to give data"
+			       " but NMI pretimeout is enabled, setting"
+			       " pretimeout op to none\n");
+			preop_val = WDOG_PREOP_NONE;
+		}
+#ifdef CONFIG_X86_LOCAL_APIC
+		if (nmi_watchdog == NMI_IO_APIC) {
+			printk(KERN_WARNING
+			       "ipmi_watchdog: nmi_watchdog is set to IO APIC"
+			       " mode (value is %d), that is incompatible"
+			       " with using NMI in the IPMI watchdog."
+			       " Disabling IPMI nmi pretimeout.\n",
+			       nmi_watchdog);
+			preaction_val = WDOG_PRETIMEOUT_NONE;
+		} else {
+#endif
+		rv = request_nmi(&ipmi_nmi_handler);
+		if (rv) {
+			printk(KERN_WARNING
+			       "ipmi_watchdog: Can't register nmi handler\n");
+			return rv;
+		}
+#ifdef CONFIG_X86_LOCAL_APIC
+		}
+#endif
+	}
+#endif
+
+	rv = ipmi_smi_watcher_register(&smi_watcher);
+	if (rv) {
+#ifdef HAVE_NMI_HANDLER
+		if (preaction_val == WDOG_PRETIMEOUT_NMI)
+			release_nmi(&ipmi_nmi_handler);
+#endif
+		printk(KERN_WARNING
+		       "ipmi_watchdog: can't register smi watcher\n");
+		return rv;
+	}
+
+	register_reboot_notifier(&wdog_reboot_notifier);
+	notifier_chain_register(&panic_notifier_list, &wdog_panic_notifier);
+
+	printk(KERN_INFO "IPMI watchdog by "
+	       "Corey Minyard (minyard@mvista.com)\n");
+
+	return 0;
+}
+
+#ifdef MODULE
+static void ipmi_unregister_watchdog(void)
+{
+	int rv;
+
+	down_write(&register_sem);
+
+#ifdef HAVE_NMI_HANDLER
+	if (preaction_val == WDOG_PRETIMEOUT_NMI)
+		release_nmi(&ipmi_nmi_handler);
+#endif
+
+	notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier);
+	unregister_reboot_notifier(&wdog_reboot_notifier);
+
+	if (! watchdog_user)
+		goto out;
+
+	/* Make sure no one can call us any more. */
+	misc_deregister(&ipmi_wdog_miscdev);
+
+	/*  Disable the timer. */
+	ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
+	ipmi_set_timeout();
+
+	/* Wait to make sure the message makes it out.  The lower layer has
+	   pointers to our buffers, we want to make sure they are done before
+	   we release our memory. */
+	while (atomic_read(&set_timeout_tofree)) {
+		schedule_timeout(1);
+	}
+
+	/* Disconnect from IPMI. */
+	rv = ipmi_destroy_user(watchdog_user);
+	if (rv) {
+		printk(KERN_WARNING
+		       "IPMI Watchdog, error unlinking from IPMI: %d\n",
+		       rv);
+	}
+	watchdog_user = NULL;
+
+ out:
+	up_write(&register_sem);
+}
+
+static void __exit ipmi_wdog_exit(void)
+{
+	ipmi_smi_watcher_unregister(&smi_watcher);
+	ipmi_unregister_watchdog();
+}
+module_exit(ipmi_wdog_exit);
+#else
+static int __init ipmi_wdog_setup(char *str)
+{
+	int  val;
+	int  rv;
+	char *option;
+
+	rv = get_option(&str, &val);
+	if (rv == 0)
+		return 1;
+	if (val > 0)
+		timeout = val;
+	if (rv == 1)
+		return 1;
+
+	rv = get_option(&str, &val);
+	if (rv == 0)
+		return 1;
+	if (val >= 0)
+		pretimeout = val;
+	if (rv == 1)
+		return 1;
+
+	while ((option = strsep(&str, ",")) != NULL) {
+		if (strcmp(option, "reset") == 0) {
+			action = "reset";
+		}
+		else if (strcmp(option, "none") == 0) {
+			action = "none";
+		}
+		else if (strcmp(option, "power_cycle") == 0) {
+			action = "power_cycle";
+		}
+		else if (strcmp(option, "power_off") == 0) {
+			action = "power_off";
+		}
+		else if (strcmp(option, "pre_none") == 0) {
+			preaction = "pre_none";
+		}
+		else if (strcmp(option, "pre_smi") == 0) {
+			preaction = "pre_smi";
+		}
+#ifdef HAVE_NMI_HANDLER
+		else if (strcmp(option, "pre_nmi") == 0) {
+			preaction = "pre_nmi";
+		}
+#endif
+		else if (strcmp(option, "pre_int") == 0) {
+			preaction = "pre_int";
+		}
+		else if (strcmp(option, "start_now") == 0) {
+			start_now = 1;
+		}
+		else if (strcmp(option, "preop_none") == 0) {
+			preop = "preop_none";
+		}
+		else if (strcmp(option, "preop_panic") == 0) {
+			preop = "preop_panic";
+		}
+		else if (strcmp(option, "preop_none") == 0) {
+			preop = "preop_give_data";
+		} else {
+		    printk("Unknown IPMI watchdog option: '%s'\n", option);
+		}
+	}
+
+	return 1;
+}
+__setup("ipmi_wdog=", ipmi_wdog_setup);
+#endif
+
+EXPORT_SYMBOL(ipmi_delayed_shutdown);
+
+module_init(ipmi_wdog_init);
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
--- a/drivers/char/n_hdlc.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/char/n_hdlc.c	Mon Jan 13 21:59:49 2003
@@ -185,10 +185,10 @@
 
 /* debug level can be set by insmod for debugging purposes */
 #define DEBUG_LEVEL_INFO	1
-int debuglevel=0;
+static int debuglevel;
 
 /* max frame size for memory allocations */
-ssize_t	maxframe=4096;
+static ssize_t	maxframe=4096;
 
 /* TTY callbacks */
 
diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
--- a/drivers/ide/ide-probe.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/ide/ide-probe.c	Mon Jan 13 21:59:50 2003
@@ -848,7 +848,7 @@
  * but anything else has led to problems on some machines.  We re-enable
  * interrupts as much as we can safely do in most places.
  */
-int init_irq (ide_hwif_t *hwif)
+static int init_irq (ide_hwif_t *hwif)
 {
 	unsigned long flags;
 	unsigned int index;
@@ -993,8 +993,6 @@
 	printk("\n");
 	return 0;
 }
-
-EXPORT_SYMBOL(init_irq);
 
 static int ata_lock(dev_t dev, void *data)
 {
diff -Nru a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
--- a/drivers/ide/legacy/umc8672.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/ide/legacy/umc8672.c	Mon Jan 13 21:59:49 2003
@@ -137,7 +137,7 @@
 	unsigned long flags;
 
 	local_irq_save(flags);
-	if (check_region(0x108, 2)) {
+	if (!request_region(0x108, 2, "umc8672")) {
 		local_irq_restore(flags);
 		printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n");
 		return 1;
@@ -146,6 +146,7 @@
 	if (in_umc (0xd5) != 0xa0) {
 		local_irq_restore(flags);
 		printk(KERN_ERR "umc8672: not found\n");
+		release_region(0x108, 2);
 		return 1;  
 	}
 	outb_p(0xa5,0x108); /* disable umc */
@@ -153,7 +154,6 @@
 	umc_set_speeds (current_speeds);
 	local_irq_restore(flags);
 
-	request_region(0x108, 2, "umc8672");
 	ide_hwifs[0].chipset = ide_umc8672;
 	ide_hwifs[1].chipset = ide_umc8672;
 	ide_hwifs[0].tuneproc = &tune_umc;
diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
--- a/drivers/ide/pci/amd74xx.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/ide/pci/amd74xx.c	Mon Jan 13 21:59:51 2003
@@ -54,11 +54,11 @@
 	unsigned long base;
 	unsigned char flags;
 } amd_ide_chips[] = {
-	{ PCI_DEVICE_ID_AMD_8111_IDE,  0x00, 0x40, AMD_UDMA_100 },			/* AMD-8111 */
-	{ PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, 0x40, AMD_UDMA_100 },			/* AMD-768 Opus */
-	{ PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO },	/* AMD-766 Viper */
-	{ PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA },	/* AMD-756 Viper */
 	{ PCI_DEVICE_ID_AMD_COBRA_7401, 0x00, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA },	/* AMD-755 Cobra */
+	{ PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA },	/* AMD-756 Viper */
+	{ PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO },	/* AMD-766 Viper */
+	{ PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, 0x40, AMD_UDMA_100 },			/* AMD-768 Opus */
+	{ PCI_DEVICE_ID_AMD_8111_IDE,  0x00, 0x40, AMD_UDMA_100 },			/* AMD-8111 */
         { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x00, 0x50, AMD_UDMA_100 },                  /* nVidia nForce */
 
 	{ 0 }
diff -Nru a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
--- a/drivers/ide/pci/cs5520.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/ide/pci/cs5520.c	Mon Jan 13 21:59:49 2003
@@ -166,6 +166,8 @@
 	/* ATAPI is harder so leave it for now */
 	if(!error && drive->media == ide_disk)
 		error = hwif->ide_dma_on(drive);
+
+	return error;
 }	
 	
 static void cs5520_tune_drive(ide_drive_t *drive, u8 pio)
diff -Nru a/drivers/ide/pci/generic.h b/drivers/ide/pci/generic.h
--- a/drivers/ide/pci/generic.h	Mon Jan 13 21:59:49 2003
+++ b/drivers/ide/pci/generic.h	Mon Jan 13 21:59:49 2003
@@ -135,6 +135,7 @@
 	}
 };
 
+#if 0
 static ide_pci_device_t unknown_chipset[] __devinitdata = {
 	{	/* 0 */
 		.vendor		= 0,
@@ -157,5 +158,6 @@
 	}
 
 };
+#endif
 
 #endif /* IDE_GENERIC_H */
diff -Nru a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
--- a/drivers/ide/pci/sc1200.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/ide/pci/sc1200.c	Mon Jan 13 21:59:50 2003
@@ -427,8 +427,6 @@
 
 static int sc1200_suspend (struct pci_dev *dev, u32 state)
 {
-	ide_hwif_t	*hwif = NULL;
-
 	printk("SC1200: suspend(%u)\n", state);
 	/* You don't need to iterate over disks -- sysfs should have done that for you already */ 
 
diff -Nru a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c	Mon Jan 13 21:59:50 2003
@@ -63,7 +63,7 @@
 	  .driver_data = (unsigned long) "Fritz!Card PnP",
 	  .devs = { { "AVM0900" } } }
 };
-//MODULE_DEVICE_TABLE(pnpc, fcpnp_ids); FIXME
+MODULE_DEVICE_TABLE(pnp_card, fcpnp_ids);
 
 static int protocol = 2;       /* EURO-ISDN Default */
 MODULE_PARM(protocol, "i");
@@ -911,7 +911,7 @@
 #ifdef __ISAPNP__
 
 static int __devinit fcpnp_probe(struct pnp_card *card,
-				 const struct pnp_card_id *card_id)
+				 const struct pnp_card_device_id *card_id)
 {
 	struct fritz_adapter *adapter;
 	struct pnp_dev *pnp_dev;
diff -Nru a/drivers/isdn/i4l/isdn_ppp_ccp.c b/drivers/isdn/i4l/isdn_ppp_ccp.c
--- a/drivers/isdn/i4l/isdn_ppp_ccp.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/isdn/i4l/isdn_ppp_ccp.c	Mon Jan 13 21:59:49 2003
@@ -241,6 +241,8 @@
 	struct ippp_ccp *ccp;
 
 	ccp = kmalloc(sizeof(*ccp), GFP_ATOMIC); // FIXME
+	if (!cpp)
+		return NULL;
 	memset(ccp, 0, sizeof(*ccp));
 	ccp->mru = 1524;      /* MRU, default 1524 */
 	ccp->reset = kmalloc(sizeof(*ccp->reset), GFP_ATOMIC); // FIXME alloc together?
diff -Nru a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c
--- a/drivers/mca/mca-bus.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/mca/mca-bus.c	Mon Jan 13 21:59:49 2003
@@ -69,47 +69,28 @@
 };
 EXPORT_SYMBOL (mca_bus_type);
 
-static ssize_t mca_show_pos_id(struct device *dev, char *buf, size_t count,
-			       loff_t off)
+static ssize_t mca_show_pos_id(struct device *dev, char *buf)
 {
 	/* four digits, \n and trailing \0 */
-	char mybuf[6];
 	struct mca_device *mca_dev = to_mca_device(dev);
 	int len;
 
 	if(mca_dev->pos_id < MCA_DUMMY_POS_START)
-		len = sprintf(mybuf, "%04x\n", mca_dev->pos_id);
+		len = sprintf(buf, "%04x\n", mca_dev->pos_id);
 	else
-		len = sprintf(mybuf, "none\n");
-
-	len++;
-	if(len > off) {
-		len = min((size_t)(len - off), count);
-		memcpy(buf + off, mybuf + off, len);
-	} else {
-		len = 0;
-	}
+		len = sprintf(buf, "none\n");
 	return len;
 }
-static ssize_t mca_show_pos(struct device *dev, char *buf, size_t count,
-			    loff_t off)
+static ssize_t mca_show_pos(struct device *dev, char *buf)
 {
 	/* enough for 8 two byte hex chars plus space and new line */
-	char mybuf[26];
 	int j, len=0;
 	struct mca_device *mca_dev = to_mca_device(dev);
 
 	for(j=0; j<8; j++)
-		len += sprintf(mybuf+len, "%02x ", mca_dev->pos[j]);
+		len += sprintf(buf+len, "%02x ", mca_dev->pos[j]);
 	/* change last trailing space to new line */
-	mybuf[len-1] = '\n';
-	len++;
-	if(len > off) {
-		len = min((size_t)(len - off), count);
-		memcpy(buf + off, mybuf + off, len);
-	} else {
-		len = 0;
-	}
+	buf[len-1] = '\n';
 	return len;
 }
 
diff -Nru a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
--- a/drivers/media/radio/radio-maxiradio.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/media/radio/radio-maxiradio.c	Mon Jan 13 21:59:51 2003
@@ -54,7 +54,7 @@
 
 
 /* TEA5757 pin mappings */
-const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ;
+static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ;
 
 static int radio_nr = -1;
 MODULE_PARM(radio_nr, "i");
diff -Nru a/drivers/net/aironet4500_card.c b/drivers/net/aironet4500_card.c
--- a/drivers/net/aironet4500_card.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/net/aironet4500_card.c	Mon Jan 13 21:59:50 2003
@@ -455,10 +455,7 @@
 
 		if (awc_proc_unset_fun)
 			awc_proc_unset_fun(i);
-		if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER)<0)
-			printk("isapnp cfg failed at release \n");
-		isapnp_deactivate(logdev->PNP_DEV_NUMBER);
-		isapnp_cfg_end();
+		pnp_device_detach(logdev);
 
 		release_region(aironet4500_devices[i]->base_addr, AIRONET4X00_IO_SIZE);
 //		release_region(isa_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis");
diff -Nru a/drivers/net/fec.c b/drivers/net/fec.c
--- a/drivers/net/fec.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/net/fec.c	Mon Jan 13 21:59:49 2003
@@ -1646,6 +1646,8 @@
 	/* Allocate some private information.
 	*/
 	fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL);
+	if (!fep)
+		return -ENOMEM;
 	memset(fep, 0, sizeof(*fep));
 
 	/* Create an Ethernet device instance.
diff -Nru a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
--- a/drivers/net/hamradio/bpqether.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/net/hamradio/bpqether.c	Mon Jan 13 21:59:49 2003
@@ -159,6 +159,8 @@
 	);
 }
 
+static spinlock_t bpq_lock = SPIN_LOCK_UNLOCKED;
+
 /*
  *	Sanity check: remove all devices that ceased to exists and
  *	return '1' if the given BPQ device was affected.
@@ -169,8 +171,7 @@
 	int result = 0;
 	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&bpq_lock, flags);
 
 	bpq_prev = NULL;
 
@@ -196,7 +197,7 @@
 			bpq_prev = bpq;
 	}
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&bpq_lock, flags);
 
 	return result;
 }
@@ -446,8 +447,9 @@
 	int len     = 0;
 	off_t pos   = 0;
 	off_t begin = 0;
+	unsigned long flags;
 
-	cli();
+	spin_lock_irqsave(&bpq_lock, flags);
 
 	len += sprintf(buffer, "dev   ether      destination        accept from\n");
 
@@ -470,7 +472,7 @@
 			break;
 	}
 
-	sti();
+	spin_unlock_irqrestore(&bpq_lock, flags);
 
 	*start = buffer + (offset - begin);
 	len   -= (offset - begin);
@@ -491,6 +493,7 @@
 {
 	int k;
 	struct bpqdev *bpq, *bpq2;
+	unsigned long flags;
 
 	if ((bpq = kmalloc(sizeof(struct bpqdev), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
@@ -553,7 +556,7 @@
 	dev->mtu             = AX25_DEF_PACLEN;
 	dev->addr_len        = AX25_ADDR_LEN;
 
-	cli();
+	spin_lock_irqsave(&bpq_lock, flags);
 
 	if (bpq_devices == NULL) {
 		bpq_devices = bpq;
@@ -562,7 +565,7 @@
 		bpq2->next = bpq;
 	}
 
-	sti();
+	spin_unlock_irqrestore(&bpq_lock, flags);
 
 	return 0;
 }
@@ -615,7 +618,13 @@
 
 	printk(banner);
 
-	proc_net_create("bpqether", 0, bpq_get_info);
+	if (!proc_net_create("bpqether", 0, bpq_get_info)) {
+		printk(KERN_ERR
+			"bpq: cannot create /proc/net/bpqether entry.\n");
+		unregister_netdevice_notifier(&bpq_dev_notifier);
+		dev_remove_pack(&bpq_packet_type);
+		return -ENOENT;
+	}
 
 	read_lock_bh(&dev_base_lock);
 	for (dev = dev_base; dev != NULL; dev = dev->next) {
diff -Nru a/drivers/net/ne.c b/drivers/net/ne.c
--- a/drivers/net/ne.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/net/ne.c	Mon Jan 13 21:59:49 2003
@@ -206,13 +206,14 @@
 			if (pnp_device_attach(idev) < 0)
 				continue;
 			if (pnp_activate_dev(idev, NULL) < 0) {
-			      __again:
 			      	pnp_device_detach(idev);
 			      	continue;
 			}
 			/* if no io and irq, search for next */
-			if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0))
-				goto __again;
+			if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) {
+				pnp_device_detach(idev);
+				continue;
+			}
 			/* found it */
 			dev->base_addr = pnp_port_start(idev, 0);
 			dev->irq = pnp_irq(idev, 0);
@@ -786,9 +787,9 @@
 		struct net_device *dev = &dev_ne[this_dev];
 		if (dev->priv != NULL) {
 			void *priv = dev->priv;
-			struct pci_dev *idev = (struct pci_dev *)ei_status.priv;
+			struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
 			if (idev)
-				idev->deactivate(idev);
+				pnp_device_detach(idev);
 			free_irq(dev->irq, dev);
 			release_region(dev->base_addr, NE_IO_EXTENT);
 			unregister_netdev(dev);
diff -Nru a/drivers/net/rrunner.c b/drivers/net/rrunner.c
--- a/drivers/net/rrunner.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/net/rrunner.c	Mon Jan 13 21:59:49 2003
@@ -111,16 +111,7 @@
 		goto out2;
 	}
 
-	if (!dev->priv)
-		dev->priv = kmalloc(sizeof(*rrpriv), GFP_KERNEL);
-
-	if (!dev->priv) {
-		ret = -ENOMEM;
-		goto out2;
-	}
-
 	rrpriv = (struct rr_private *)dev->priv;
-	memset(rrpriv, 0, sizeof(*rrpriv));
 
 	SET_MODULE_OWNER(dev);
 
diff -Nru a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c
--- a/drivers/net/skfp/fplustm.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/net/skfp/fplustm.c	Mon Jan 13 21:59:49 2003
@@ -390,7 +390,7 @@
 	outpw(FM_A(FM_TREQ0),(unsigned)t_requ) ;
 }
 
-void set_int(p,l)
+static void set_int(p,l)
 char *p;
 int l;
 {
diff -Nru a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
--- a/drivers/net/smc-ultra.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/net/smc-ultra.c	Mon Jan 13 21:59:49 2003
@@ -550,9 +550,9 @@
 			int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
 
 #ifdef __ISAPNP__
-			struct pci_dev *idev = (struct pci_dev *)ei_status.priv;
+			struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
 			if (idev)
-				idev->deactivate(idev);
+				pnp_device_detach(idev);
 #endif
 
 			unregister_netdev(dev);
diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
--- a/drivers/net/wan/cosa.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/net/wan/cosa.c	Mon Jan 13 21:59:49 2003
@@ -227,8 +227,8 @@
 /* NOTE: DMA is not autoprobed!!! */
 static int dma[MAX_CARDS+1] = { 1, 7, 1, 7, 1, 7, 1, 7, 0, };
 #else
-int io[MAX_CARDS+1]  = { 0, };
-int dma[MAX_CARDS+1] = { 0, };
+static int io[MAX_CARDS+1];
+static int dma[MAX_CARDS+1];
 #endif
 /* IRQ can be safely autoprobed */
 static int irq[MAX_CARDS+1] = { -1, -1, -1, -1, -1, -1, 0, };
diff -Nru a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig
--- a/drivers/parisc/Kconfig	Mon Jan 13 21:59:50 2003
+++ b/drivers/parisc/Kconfig	Mon Jan 13 21:59:50 2003
@@ -10,6 +10,13 @@
 	  are not found in B1000, C3000, J5000, A500, L1000, N4000 and upwards.
 	  If in doubt, say "Y".
 
+config HPPB
+	bool "HP-PB bus support"
+	depends on GSC
+	help
+	  The HP-PB bus was used in the Nova class and K-class servers.
+	  If in doubt, say "Y"
+
 config IOMMU_CCIO
 	bool "U2/Uturn I/O MMU"
 	depends on GSC
@@ -60,6 +67,8 @@
 	  Beware that some GSC cards have a Dino onboard and PCI inside them,
 	  so it may be safest to say "Y" anyway.
 
+source "drivers/pci/Kconfig"
+
 config GSC_DINO
 	bool "GSCtoPCI/Dino PCI support"
 	depends on PCI && GSC
@@ -82,22 +91,21 @@
 config IOSAPIC
 	bool
 	depends on PCI_LBA
-	default y
+	default PCI_LBA
 
 config IOMMU_SBA
 	bool
 	depends on PCI_LBA
-	default y
-
-source "drivers/pci/Kconfig"
+	default PCI_LBA
 
 #config PCI_EPIC
 #	bool "EPIC/SAGA PCI support"
 #	depends on PCI
 
 config SUPERIO
-	bool
+	bool "SuperIO (SuckyIO) support"
 	depends on PCI
+	default y
 	help
 	  Say Y here to support the SuperIO chip found in Bxxxx, C3xxx and
 	  J5xxx+ machines. This enables IDE, Floppy, Parallel Port, and
@@ -105,6 +113,7 @@
 
 config CHASSIS_LCD_LED
 	bool "Chassis LCD and LED support"
+	default y
 	help
 	  Say Y here if you want to enable support for the Heartbeat,
 	  Disk/Network activities LEDs on some PA-RISC machines,
diff -Nru a/drivers/parisc/Makefile b/drivers/parisc/Makefile
--- a/drivers/parisc/Makefile	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/Makefile	Mon Jan 13 21:59:49 2003
@@ -2,24 +2,32 @@
 # Makefile for most of the non-PCI devices in PA-RISC machines
 #
 
-export-objs	:= gsc.o superio.o
+export-objs			:= gsc.o superio.o
 
-obj-y := gsc.o power.o
+obj-y :=
 obj-m :=
 obj-n :=
 obj-  :=
 
-obj-$(CONFIG_GSC_DINO) += dino.o
-obj-$(CONFIG_GSC_LASI) += lasi.o asp.o
-obj-$(CONFIG_GSC_WAX) += wax.o
-obj-$(CONFIG_EISA) += eisa.o eisa_enumerator.o eisa_eeprom.o
-obj-$(CONFIG_SUPERIO) += superio.o
-obj-$(CONFIG_PCI_LBA) += lba_pci.o
 # I/O SAPIC is also on IA64 platforms.
 # The two could be merged into a common source some day.
-obj-$(CONFIG_IOSAPIC) += iosapic.o
-obj-$(CONFIG_IOMMU_SBA) += sba_iommu.o
+obj-$(CONFIG_IOSAPIC)		+= iosapic.o
+obj-$(CONFIG_IOMMU_SBA)		+= sba_iommu.o
+obj-$(CONFIG_PCI_LBA)		+= lba_pci.o
+
 # Only use one of them: ccio-rm-dma is for PCX-W systems *only*
-# obj-$(CONFIG_IOMMU_CCIO) += ccio-rm-dma.o
-obj-$(CONFIG_IOMMU_CCIO) += ccio-dma.o
-obj-$(CONFIG_CHASSIS_LCD_LED) += led.o
+# obj-$(CONFIG_IOMMU_CCIO)	+= ccio-rm-dma.o
+obj-$(CONFIG_IOMMU_CCIO)	+= ccio-dma.o
+
+obj-y				+= gsc.o
+
+obj-$(CONFIG_HPPB)		+= hppb.o
+obj-$(CONFIG_GSC_DINO)		+= dino.o
+obj-$(CONFIG_GSC_LASI)		+= lasi.o asp.o
+obj-$(CONFIG_GSC_WAX)		+= wax.o
+obj-$(CONFIG_EISA)		+= eisa.o eisa_enumerator.o eisa_eeprom.o
+
+obj-$(CONFIG_SUPERIO)		+= superio.o
+obj-$(CONFIG_CHASSIS_LCD_LED)	+= led.o
+obj-y				+= power.o
+
diff -Nru a/drivers/parisc/asp.c b/drivers/parisc/asp.c
--- a/drivers/parisc/asp.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/parisc/asp.c	Mon Jan 13 21:59:51 2003
@@ -76,6 +76,8 @@
 
 	printk(KERN_INFO "%s version %d at 0x%lx found.\n", 
 		asp->name, asp->version, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+		 asp->name, asp->version);
 
 	/* the IRQ ASP should use */
 	ret = -EBUSY;
diff -Nru a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
--- a/drivers/parisc/ccio-dma.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/ccio-dma.c	Mon Jan 13 21:59:49 2003
@@ -50,6 +50,7 @@
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/hardware.h>       /* for register_module() */
+#include <asm/parisc-device.h>
 
 /* 
 ** Choose "ccio" since that's what HP-UX calls it.
@@ -599,7 +600,7 @@
  * This function implements the pci_dma_supported function.
  */
 static int 
-ccio_dma_supported(struct pci_dev *dev, u64 mask)
+ccio_dma_supported(struct device *dev, u64 mask)
 {
 	if(dev == NULL) {
 		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
@@ -607,8 +608,6 @@
 		return 0;
 	}
 
-	dev->dma_mask = mask;   /* save it */
-
 	/* only support 32-bit devices (ie PCI/GSC) */
 	return (int)(mask == 0xffffffffUL);
 }
@@ -623,7 +622,8 @@
  * This function implements the pci_map_single function.
  */
 static dma_addr_t 
-ccio_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+ccio_map_single(struct device *dev, void *addr, size_t size,
+		enum dma_data_direction direction)
 {
 	int idx;
 	struct ioc *ioc;
@@ -631,11 +631,9 @@
 	dma_addr_t iovp;
 	dma_addr_t offset;
 	u64 *pdir_start;
-	unsigned long hint = hint_lookup[direction];
+	unsigned long hint = hint_lookup[(int)direction];
 
-	ASSERT(dev);
-	ASSERT(dev->sysdata);
-	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	BUG_ON(!dev);
 	ioc = GET_IOC(dev);
 
 	ASSERT(size > 0);
@@ -692,16 +690,14 @@
  * This function implements the pci_unmap_single function.
  */
 static void 
-ccio_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, 
-		  int direction)
+ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size, 
+		  enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 	unsigned long flags; 
 	dma_addr_t offset = iova & ~IOVP_MASK;
 	
-	ASSERT(dev);
-	ASSERT(dev->sysdata);
-	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	BUG_ON(!dev);
 	ioc = GET_IOC(dev);
 
 	DBG_RUN("%s() iovp 0x%lx/%x\n",
@@ -732,7 +728,7 @@
  * This function implements the pci_alloc_consistent function.
  */
 static void * 
-ccio_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma_handle)
+ccio_alloc_consistent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag)
 {
       void *ret;
 #if 0
@@ -745,7 +741,7 @@
 		return 0;
 	}
 #endif
-        ret = (void *) __get_free_pages(GFP_ATOMIC, get_order(size));
+        ret = (void *) __get_free_pages(flag, get_order(size));
 
 	if (ret) {
 		memset(ret, 0, size);
@@ -765,7 +761,7 @@
  * This function implements the pci_free_consistent function.
  */
 static void 
-ccio_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr, 
+ccio_free_consistent(struct device *dev, size_t size, void *cpu_addr, 
 		     dma_addr_t dma_handle)
 {
 	ccio_unmap_single(dev, dma_handle, size, 0);
@@ -964,17 +960,15 @@
  * This function implements the pci_map_sg function.
  */
 static int
-ccio_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
-	    int direction)
+ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents, 
+	    enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 	int coalesced, filled = 0;
 	unsigned long flags;
-	unsigned long hint = hint_lookup[direction];
+	unsigned long hint = hint_lookup[(int)direction];
 	
-	ASSERT(dev);
-	ASSERT(dev->sysdata);
-	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	BUG_ON(!dev);
 	ioc = GET_IOC(dev);
 	
 	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
@@ -1032,14 +1026,12 @@
  * This function implements the pci_unmap_sg function.
  */
 static void 
-ccio_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, 
-	      int direction)
+ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, 
+	      enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 
-	ASSERT(dev);
-	ASSERT(dev->sysdata);
-	ASSERT(HBA_DATA(dev->sysdata)->iommu);
+	BUG_ON(!dev);
 	ioc = GET_IOC(dev);
 
 	DBG_RUN_SG("%s() START %d entries,  %08lx,%x\n",
@@ -1062,16 +1054,17 @@
 	DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents);
 }
 
-static struct pci_dma_ops ccio_ops = {
-	ccio_dma_supported,
-	ccio_alloc_consistent,
-	ccio_free_consistent,
-	ccio_map_single,
-	ccio_unmap_single,
-	ccio_map_sg,
-	ccio_unmap_sg,
-	NULL,                   /* dma_sync_single : NOP for U2/Uturn */
-	NULL,                   /* dma_sync_sg     : ditto */
+static struct hppa_dma_ops ccio_ops = {
+	.dma_supported =	ccio_dma_supported,
+	.alloc_consistent =	ccio_alloc_consistent,
+	.alloc_noncoherent =	ccio_alloc_consistent,
+	.free_consistent =	ccio_free_consistent,
+	.map_single =		ccio_map_single,
+	.unmap_single =		ccio_unmap_single,
+	.map_sg = 		ccio_map_sg,
+	.unmap_sg = 		ccio_unmap_sg,
+	.dma_sync_single =	NULL,	/* NOP for U2/Uturn */
+	.dma_sync_sg =		NULL,	/* ditto */
 };
 
 #ifdef CONFIG_PROC_FS
@@ -1529,6 +1522,7 @@
 	memset(ioc, 0, sizeof(struct ioc));
 
 	ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
+	strncpy(dev->dev.name, ioc->name, sizeof(dev->dev.name));
 
 	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
 
@@ -1542,6 +1536,12 @@
 	ccio_ioc_init(ioc);
 	ccio_init_resources(ioc);
 	hppa_dma_ops = &ccio_ops;
+	dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
+
+	/* if this fails, no I/O cards will work, so may as well bug */
+	BUG_ON(dev->dev.platform_data == NULL);
+	HBA_DATA(dev->dev.platform_data)->iommu = ioc;
+	
 
 	if (ioc_count == 0) {
 		/* XXX: Create separate entries for each ioc */
@@ -1577,13 +1577,13 @@
 	}
 	memset(ioc->fake_pci_dev, 0, sizeof(struct pci_dev));
 
-	ioc->fake_pci_dev->sysdata = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
-	if(ioc->fake_pci_dev->sysdata == NULL) {
+	ioc->fake_pci_dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL);
+	if(ioc->fake_pci_dev->dev.platform_data == NULL) {
 		printk(KERN_ERR MODULE_NAME ": memory allocation failure\n");
 		return NULL;
 	}
 
-	HBA_DATA(ioc->fake_pci_dev->sysdata)->iommu = ioc;
+	HBA_DATA(ioc->fake_pci_dev->dev.platform_data)->iommu = ioc;
 	return ioc->fake_pci_dev;
 }
 
@@ -1595,7 +1595,7 @@
 };
 
 static struct parisc_driver ccio_driver = {
-	.name =		"U2/Uturn",
+	.name =		"U2:Uturn",
 	.id_table =	ccio_tbl,
 	.probe =	ccio_probe,
 };
diff -Nru a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
--- a/drivers/parisc/ccio-rm-dma.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/ccio-rm-dma.c	Mon Jan 13 21:59:49 2003
@@ -74,8 +74,6 @@
 		return(0);
 	}
 
-	dev->dma_mask = mask;   /* save it */
-
 	/* only support 32-bit devices (ie PCI/GSC) */
 	return((int) (mask >= 0xffffffffUL));
 }
diff -Nru a/drivers/parisc/dino.c b/drivers/parisc/dino.c
--- a/drivers/parisc/dino.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/dino.c	Mon Jan 13 21:59:49 2003
@@ -168,7 +168,7 @@
 static int dino_cfg_read(struct pci_bus *bus, unsigned int devfn, int where,
 		int size, u32 *val)
 {
-	struct dino_device *d = DINO_DEV(bus->sysdata);
+	struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->dev));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
 	unsigned long base_addr = d->hba.base_addr;
@@ -202,7 +202,7 @@
 static int dino_cfg_write(struct pci_bus *bus, unsigned int devfn, int where,
 	int size, u32 val)
 {
-	struct dino_device *d = DINO_DEV(bus->sysdata);
+	struct dino_device *d = DINO_DEV(parisc_walk_tree(bus->dev));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 v = DINO_CFG_TOK(local_bus, devfn, where & ~3);
 	unsigned long base_addr = d->hba.base_addr;
@@ -255,7 +255,7 @@
 	unsigned long flags; \
 	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
 	/* tell HW which IO Port address */ \
-	gsc_writel((u32) addr & ~3, d->base_addr + DINO_PCI_ADDR); \
+	gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
 	/* generate I/O PORT read cycle */ \
 	v = gsc_read##type(d->base_addr+DINO_IO_DATA+(addr&mask)); \
 	spin_unlock_irqrestore(&(DINO_DEV(d)->dinosaur_pen), flags); \
@@ -271,7 +271,7 @@
 { \
 	unsigned long flags; \
 	spin_lock_irqsave(&(DINO_DEV(d)->dinosaur_pen), flags); \
-	/* tell HW which CFG address */ \
+	/* tell HW which IO port address */ \
 	gsc_writel((u32) addr, d->base_addr + DINO_PCI_ADDR); \
 	/* generate cfg write cycle */ \
 	gsc_write##type(cpu_to_le##size(val), d->base_addr+DINO_IO_DATA+(addr&mask)); \
@@ -475,7 +475,7 @@
 dino_card_setup(struct pci_bus *bus, unsigned long base_addr)
 {
 	int i;
-	struct dino_device *dino_dev = DINO_DEV(bus->sysdata);
+	struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
 	struct resource *res;
 
 	res = &dino_dev->hba.lmmio_space;
@@ -498,7 +498,7 @@
 	}
 	gsc_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
 
-	pcibios_assign_unassigned_resources(bus);
+	pci_bus_assign_resources(bus);
 }
 
 static void __init
@@ -545,11 +545,11 @@
 {
 	struct list_head *ln;
         struct pci_dev *dev;
-        struct dino_device *dino_dev = DINO_DEV(bus->sysdata);
+        struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->dev));
 	int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
 
 	DBG(KERN_WARNING "%s(0x%p) bus %d sysdata 0x%p\n",
-			__FUNCTION__, bus, bus->secondary, bus->sysdata);
+			__FUNCTION__, bus, bus->secondary, bus->dev->platform_data);
 
 	/* Firmware doesn't set up card-mode dino, so we have to */
 	if (is_card_dino(&dino_dev->hba.dev->id))
@@ -836,6 +836,8 @@
 	}
 
 	printk("%s version %s found at 0x%lx\n", name, version, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), 
+		 "%s version %s", name, version);
 
 	if (!request_mem_region(dev->hpa, PAGE_SIZE, name)) {
 		printk(KERN_ERR "DINO: Hey! Someone took my MMIO space (0x%ld)!\n",
@@ -891,13 +893,15 @@
 	if (dino_common_init(dev, dino_dev, name))
 		return 1;
 
+	dev->dev.platform_data = dino_dev;
+
 	/*
 	** It's not used to avoid chicken/egg problems
 	** with configuration accessor functions.
 	*/
-	dino_dev->hba.hba_bus = pci_scan_bus(dino_dev->hba.hba_num,
-			&dino_cfg_ops, dino_dev);
-
+	dino_dev->hba.hba_bus = 
+		pci_scan_bus_parented(&dev->dev, dino_dev->hba.hba_num,
+				      &dino_cfg_ops, NULL);
 	return 0;
 }
 
diff -Nru a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
--- a/drivers/parisc/eisa.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/eisa.c	Mon Jan 13 21:59:49 2003
@@ -40,6 +40,7 @@
 #include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/processor.h>
+#include <asm/parisc-device.h>
 #include <asm/delay.h>
 #include <asm/eisa_bus.h>
 
@@ -322,6 +323,7 @@
 
 	printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", 
 		name, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s EISA", name);
 
 	eisa_dev.hba.dev = dev;
 	eisa_dev.hba.iommu = ccio_get_iommu(dev);
diff -Nru a/drivers/parisc/gsc.h b/drivers/parisc/gsc.h
--- a/drivers/parisc/gsc.h	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/gsc.h	Mon Jan 13 21:59:49 2003
@@ -8,6 +8,7 @@
 
 #include <linux/interrupt.h>
 #include <asm/hardware.h>
+#include <asm/parisc-device.h>
 
 #define OFFSET_IRR 0x0000   /* Interrupt request register */
 #define OFFSET_IMR 0x0004   /* Interrupt mask register */
diff -Nru a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/parisc/hppb.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,111 @@
+/*
+** hppb.c:
+**      HP-PB bus driver for the NOVA and K-Class systems.
+**
+**      (c) Copyright 2002 Ryan Bradetich
+**      (c) Copyright 2002 Hewlett-Packard Company
+**
+** 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 Driver currently only supports the console (port 0) on the MUX.
+** Additional work will be needed on this driver to enable the full
+** functionality of the MUX.
+**
+*/
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/parisc-device.h>
+
+#include <linux/pci.h>
+
+struct hppb_card {
+	unsigned long hpa;
+	struct resource mmio_region;
+	struct hppb_card *next;
+};
+
+struct hppb_card hppb_card_head = {
+	.hpa = 0,
+	.next = NULL,
+};
+
+#define IO_IO_LOW  offsetof(struct bc_module, io_io_low)
+#define IO_IO_HIGH offsetof(struct bc_module, io_io_high)
+
+/**
+ * hppb_probe - Determine if the hppb driver should claim this device.
+ * @dev: The device which has been found
+ *
+ * Determine if hppb driver should claim this chip (return 0) or not 
+ * (return 1). If so, initialize the chip and tell other partners in crime 
+ * they have work to do.
+ */
+static int hppb_probe(struct parisc_device *dev)
+{
+	int status;
+	struct hppb_card *card = &hppb_card_head;
+
+	while(card->next) {
+		card = card->next;
+	}
+
+	if(card->hpa) {
+		card->next = kmalloc(sizeof(struct hppb_card), GFP_KERNEL);
+		if(!card->next) {
+			printk(KERN_ERR "HP-PB: Unable to allocate memory.\n");
+			return 1;
+		}
+		memset(card->next, '\0', sizeof(struct hppb_card));
+		card = card->next;
+	}
+        printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "GeckoBoa");
+
+	card->hpa = dev->hpa;
+	card->mmio_region.name = "HP-PB Bus";
+	card->mmio_region.flags = IORESOURCE_MEM;
+
+	card->mmio_region.start = __raw_readl(dev->hpa + IO_IO_LOW);
+	card->mmio_region.end = __raw_readl(dev->hpa + IO_IO_HIGH) - 1;
+
+	status = ccio_request_resource(dev, &card->mmio_region);
+	if(status < 0) {
+		printk(KERN_ERR "%s: failed to claim HP-PB bus space (%08lx, %08lx)\n",
+			__FILE__, card->mmio_region.start, card->mmio_region.end);
+	}
+
+        return 0;
+}
+
+
+static struct parisc_device_id hppb_tbl[] = {
+        { HPHW_BCPORT, HVERSION_REV_ANY_ID, 0x500, 0xc }, 
+        { 0, }
+};
+
+static struct parisc_driver hppb_driver = {
+        .name =         "Gecko Boa",
+        .id_table =     hppb_tbl,
+	.probe =        hppb_probe,
+};
+
+/**
+ * hppb_init - HP-PB bus initalization procedure.
+ *
+ * Register this driver.   
+ */
+void __init hppb_init(void)
+{
+        register_parisc_driver(&hppb_driver);
+}
diff -Nru a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
--- a/drivers/parisc/iosapic.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/iosapic.c	Mon Jan 13 21:59:49 2003
@@ -641,7 +641,7 @@
 
 	if (NULL == isi) {
 		printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
-			pcidev->name);
+			pcidev->dev.name);
 		return(-1);
 	}
 
diff -Nru a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
--- a/drivers/parisc/lasi.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/parisc/lasi.c	Mon Jan 13 21:59:50 2003
@@ -77,7 +77,8 @@
 
 	/* Resets */
 	/* gsc_writel(0xFFFFFFFF, lasi_base+0x2000);*/	/* Parallel */
-	gsc_writel(0xFFFFFFFF, lasi_base+0x4004);	/* Audio */
+	if(pdc_add_valid(lasi_base+0x4004) == PDC_OK)
+		gsc_writel(0xFFFFFFFF, lasi_base+0x4004);	/* Audio */
 	/* gsc_writel(0xFFFFFFFF, lasi_base+0x5000);*/	/* Serial */ 
 	/* gsc_writel(0xFFFFFFFF, lasi_base+0x6000);*/	/* SCSI */
 	gsc_writel(0xFFFFFFFF, lasi_base+0x7000);	/* LAN */
@@ -184,6 +185,8 @@
 	lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf;
 	printk(KERN_INFO "%s version %d at 0x%lx found.\n",
 		lasi->name, lasi->version, lasi->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+		 lasi->name, lasi->version);
 
 	/* initialize the chassis LEDs really early */ 
 	lasi_led_init(lasi->hpa);
diff -Nru a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
--- a/drivers/parisc/lba_pci.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/parisc/lba_pci.c	Mon Jan 13 21:59:50 2003
@@ -48,6 +48,7 @@
 #include <asm/system.h>
 
 #include <asm/hardware.h>	/* for register_parisc_driver() stuff */
+#include <asm/parisc-device.h>
 #include <asm/iosapic.h>	/* for iosapic_register() */
 #include <asm/io.h>		/* read/write stuff */
 
@@ -507,7 +508,7 @@
 
 static int lba_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
 {
-	struct lba_device *d = LBA_DEV(bus->sysdata);
+	struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->dev));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 tok = LBA_CFG_TOK(local_bus, devfn);
 
@@ -591,7 +592,7 @@
 
 static int lba_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
 {
-	struct lba_device *d = LBA_DEV(bus->sysdata);
+	struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->dev));
 	u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
 	u32 tok = LBA_CFG_TOK(local_bus,devfn);
 
@@ -697,11 +698,11 @@
 	u16 fbb_enable = PCI_STATUS_FAST_BACK;
 	u16 status;
 #endif
-	struct lba_device *ldev = LBA_DEV(bus->sysdata);
+	struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->dev));
 	int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
 
 	DBG("lba_fixup_bus(0x%p) bus %d sysdata 0x%p\n",
-		bus, bus->secondary, bus->sysdata);
+		bus, bus->secondary, bus->dev->platform_data);
 
 	/*
 	** Properly Setup MMIO resources for this bus.
@@ -1357,6 +1358,8 @@
 
 	printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
 		MODULE_NAME, version, func_class & 0xf, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %s",
+		 MODULE_NAME, version);
 
 	/* Just in case we find some prototypes... */
 	if (func_class < 2) {
@@ -1425,14 +1428,16 @@
 	** Tell PCI support another PCI bus was found.
 	** Walks PCI bus for us too.
 	*/
+	dev->dev.platform_data = lba_dev;
 	lba_bus = lba_dev->hba.hba_bus =
-		pci_scan_bus(lba_dev->hba.bus_num.start, &lba_cfg_ops, (void *) lba_dev);
+		pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
+				      &lba_cfg_ops, NULL);
 
 #ifdef __LP64__
 	if (is_pdc_pat()) {
 		/* assign resources to un-initialized devices */
-		DBG_PAT("LBA pcibios_assign_unassigned_resources()\n");
-		pcibios_assign_unassigned_resources(lba_bus);
+		DBG_PAT("LBA pci_bus_assign_resources()\n");
+		pci_bus_assign_resources(lba_bus);
 
 #ifdef DEBUG_LBA_PAT
 		DBG_PAT("\nLBA PIOP resource tree\n");
@@ -1464,7 +1469,7 @@
 static struct parisc_driver lba_driver = {
 	.name =		MODULE_NAME,
 	.id_table =	lba_tbl,
-	.probe =	lba_driver_callback
+	.probe =	lba_driver_callback,
 };
 
 /*
diff -Nru a/drivers/parisc/led.c b/drivers/parisc/led.c
--- a/drivers/parisc/led.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/led.c	Mon Jan 13 21:59:49 2003
@@ -404,7 +404,7 @@
 	int major, disk, total;
 	
 	total = 0;
-#ifdef 0
+#if 0
 	/*
 	 * this section will no longer work in 2.5, as we no longer
 	 * have either kstat.dk_drive nor DK_MAX_*.  It can probably
diff -Nru a/drivers/parisc/power.c b/drivers/parisc/power.c
--- a/drivers/parisc/power.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/power.c	Mon Jan 13 21:59:49 2003
@@ -44,8 +44,6 @@
 #include <linux/reboot.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/ctype.h>
 #include <linux/workqueue.h>
 
 #include <asm/pdc.h>
@@ -142,11 +140,7 @@
 DECLARE_TASKLET_DISABLED(power_tasklet, NULL, 0);
 
 /* soft power switch enabled/disabled */
-#ifdef CONFIG_PROC_FS
-static int pwrsw_enabled = 1;
-#else
-#define pwrsw_enabled (1)
-#endif
+int pwrsw_enabled = 1;
 
 /*
  * On gecko style machines (e.g. 712/xx and 715/xx) 
@@ -207,90 +201,6 @@
 
 
 
-/* 
- * /proc filesystem support 
- */
-
-#ifdef CONFIG_SYSCTL
-static int power_proc_read(char *page, char **start, off_t off, int count, 
-	int *eof, void *data)
-{
-	char *out = page;
-	int len;
-
-	out += sprintf(out, "Software power switch support: ");
-	out += sprintf(out, pwrsw_enabled ? "enabled (1)" : "disabled (0)" );
-	out += sprintf(out, "\n");
-
-	len = out - page - off;
-	if (len < count) {
-		*eof = 1;
-		if (len <= 0) return 0;
-	} else {
-		len = count;
-	}
-	*start = page + off;
-	return len;
-}
-
-static int power_proc_write(struct file *file, const char *buf, 
-	unsigned long count, void *data)
-{
-	char *cur, lbuf[count];
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EACCES;
-
-	memset(lbuf, 0, count);
-
-	copy_from_user(lbuf, buf, count);
-	cur = lbuf;
-
-	/* skip initial spaces */
-	while (*cur && isspace(*cur))
-		cur++;
-
-	switch (*cur) {
-	case '0':	pwrsw_enabled = 0;
-			break;
-	case '1':	pwrsw_enabled = 1;
-			break;
-	default:	printk(KERN_CRIT "/proc/" SYSCTL_FILENAME 
-					": Parse error: only '0' or '1' allowed!\n");
-			return -EINVAL;
-	} /* switch() */
-
-	return count;
-}
-
-static struct proc_dir_entry *ent;
-
-static void __init power_create_procfs(void)
-{
-	if (!power_tasklet.func)
-		return;
-	
-	ent = create_proc_entry(SYSCTL_FILENAME, S_IFREG|S_IRUGO|S_IWUSR, 0);
-	if (!ent) return;
-	
-	ent->nlink = 1;
-	ent->read_proc = power_proc_read;
-	ent->write_proc = power_proc_write;
-	ent->owner = THIS_MODULE;
-}
-
-static void __exit power_remove_procfs(void)
-{
-	remove_proc_entry(SYSCTL_FILENAME, NULL);
-}
-
-#else
-#define power_create_procfs()	do { } while (0)
-#define power_remove_procfs()	do { } while (0)
-#endif	/* CONFIG_SYSCTL */
-
-
-
 /* parisc_panic_event() is called by the panic handler.
  * As soon as a panic occurs, our tasklets above will not be
  * executed any longer. This function then re-enables the 
@@ -344,7 +254,6 @@
 	/* Register a call for panic conditions. */
 	notifier_chain_register(&panic_notifier_list, &parisc_panic_block);
 
-	power_create_procfs();
 	tasklet_enable(&power_tasklet);
 
 	return 0;
@@ -357,7 +266,6 @@
 
 	tasklet_disable(&power_tasklet);
 	notifier_chain_unregister(&panic_notifier_list, &parisc_panic_block);
-	power_remove_procfs();
 	power_tasklet.func = NULL;
 	pdc_soft_power_button(0);
 }
diff -Nru a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
--- a/drivers/parisc/sba_iommu.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/parisc/sba_iommu.c	Mon Jan 13 21:59:51 2003
@@ -40,6 +40,7 @@
 #include <linux/proc_fs.h>
 #include <asm/runway.h>		/* for proc_runway_root */
 #include <asm/pdc.h>		/* for PDC_MODEL_* */
+#include <asm/parisc-device.h>
 
 #define MODULE_NAME "SBA"
 
@@ -803,7 +804,7 @@
  * See Documentation/DMA-mapping.txt
  */
 static int
-sba_dma_supported( struct pci_dev *dev, u64 mask)
+sba_dma_supported( struct device *dev, u64 mask)
 {
 	if (dev == NULL) {
 		printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
@@ -811,10 +812,8 @@
 		return(0);
 	}
 
-	dev->dma_mask = mask;	/* save it */
-
 	/* only support 32-bit PCI devices - no DAC support (yet) */
-	return((int) (mask == 0xffffffff));
+	return((int) (mask == 0xffffffffUL));
 }
 
 
@@ -828,7 +827,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static dma_addr_t
-sba_map_single(struct pci_dev *dev, void *addr, size_t size, int direction)
+sba_map_single(struct device *dev, void *addr, size_t size,
+	       enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 	unsigned long flags; 
@@ -840,7 +840,6 @@
 	ASSERT(size > 0);
 	ASSERT(size <= DMA_CHUNK_SIZE);
 
-	ASSERT(dev->sysdata);
 	ioc = GET_IOC(dev);
 	ASSERT(ioc);
 
@@ -906,7 +905,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static void
-sba_unmap_single(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction)
+sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
+		 enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 #if DELAYED_RESOURCE_CNT > 0
@@ -915,7 +915,6 @@
 	unsigned long flags; 
 	dma_addr_t offset;
 
-	ASSERT(dev->sysdata);
 	ioc = GET_IOC(dev);
 	ASSERT(ioc);
 
@@ -976,7 +975,7 @@
  * See Documentation/DMA-mapping.txt
  */
 static void *
-sba_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle)
 {
 	void *ret;
 
@@ -1007,7 +1006,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static void
-sba_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+sba_free_consistent(struct device *hwdev, size_t size, void *vaddr,
+		    dma_addr_t dma_handle)
 {
 	sba_unmap_single(hwdev, dma_handle, size, 0);
 	free_pages((unsigned long) vaddr, get_order(size));
@@ -1269,7 +1269,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static int
-sba_map_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
+	   enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 	int coalesced, filled = 0;
@@ -1277,7 +1278,6 @@
 
 	DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
 
-	ASSERT(dev->sysdata);
 	ioc = GET_IOC(dev);
 	ASSERT(ioc);
 
@@ -1351,7 +1351,8 @@
  * See Documentation/DMA-mapping.txt
  */
 static void 
-sba_unmap_sg(struct pci_dev *dev, struct scatterlist *sglist, int nents, int direction)
+sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
+	     enum dma_data_direction direction)
 {
 	struct ioc *ioc;
 #ifdef ASSERT_PDIR_SANITY
@@ -1361,7 +1362,6 @@
 	DBG_RUN_SG("%s() START %d entries,  %p,%x\n",
 		__FUNCTION__, nents, sg_virt_addr(sglist), sglist->length);
 
-	ASSERT(dev->sysdata);
 	ioc = GET_IOC(dev);
 	ASSERT(ioc);
 
@@ -1395,16 +1395,17 @@
 
 }
 
-static struct pci_dma_ops sba_ops = {
-	sba_dma_supported,
-	sba_alloc_consistent,	/* allocate cacheable host mem */
-	sba_free_consistent,	/* release cacheable host mem */
-	sba_map_single,
-	sba_unmap_single,
-	sba_map_sg,
-	sba_unmap_sg,
-	NULL,			/* dma_sync_single */
-	NULL			/* dma_sync_sg */
+static struct hppa_dma_ops sba_ops = {
+	.dma_supported =	sba_dma_supported,
+	.alloc_consistent =	sba_alloc_consistent,
+	.alloc_noncoherent =	sba_alloc_consistent,
+	.free_consistent =	sba_free_consistent,
+	.map_single =		sba_map_single,
+	.unmap_single =		sba_unmap_single,
+	.map_sg =		sba_map_sg,
+	.unmap_sg =		sba_unmap_sg,
+	.dma_sync_single =	NULL,
+	.dma_sync_sg =		NULL,
 };
 
 
@@ -1977,6 +1978,8 @@
 
 	printk(KERN_INFO "%s found %s at 0x%lx\n",
 		MODULE_NAME, version, dev->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %s",
+		 MODULE_NAME, version);
 
 #ifdef DEBUG_SBA_INIT
 	sba_dump_tlb(dev->hpa);
diff -Nru a/drivers/parisc/superio.c b/drivers/parisc/superio.c
--- a/drivers/parisc/superio.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/parisc/superio.c	Mon Jan 13 21:59:49 2003
@@ -390,7 +390,7 @@
 void __devinit
 superio_serial_init(void)
 {
-#ifdef CONFIG_SERIAL
+#ifdef CONFIG_SERIAL_8250
 	struct serial_struct *serial;
 	int retval;
 	
@@ -443,7 +443,7 @@
 	retval = register_serial(serial);
 	if (retval < 0)
 		printk(KERN_WARNING "SuperIO: Register Serial #1 failed.\n");
-#endif /* CONFIG_SERIAL */
+#endif /* CONFIG_SERIAL_8250 */
 }
 
 EXPORT_SYMBOL(superio_serial_init);
@@ -504,7 +504,7 @@
 #ifdef CONFIG_PARPORT_PC
 		superio_parport_init();
 #endif
-#ifdef CONFIG_SERIAL
+#ifdef CONFIG_SERIAL_8250
 		superio_serial_init();
 #endif
 		/* REVISIT : superio_fdc_init() ? */
@@ -530,6 +530,11 @@
 
 static int __init superio_modinit(void)
 {
+#ifdef CONFIG_SERIAL_8250
+	extern int serial8250_init(void);
+	serial8250_init();
+#endif
+
 	return pci_module_init(&superio_driver);
 }
 
diff -Nru a/drivers/parisc/wax.c b/drivers/parisc/wax.c
--- a/drivers/parisc/wax.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/parisc/wax.c	Mon Jan 13 21:59:50 2003
@@ -83,6 +83,8 @@
 
 	wax->version = 0;   /* gsc_readb(wax->hpa+WAX_VER); */
 	printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s version %d",
+		 wax->name, wax->version);
 
 	/* Stop wax hissing for a bit */
 	wax_init_irq(wax);
diff -Nru a/drivers/pnp/card.c b/drivers/pnp/card.c
--- a/drivers/pnp/card.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/pnp/card.c	Mon Jan 13 21:59:51 2003
@@ -22,9 +22,9 @@
 
 LIST_HEAD(pnp_cards);
 
-static const struct pnp_card_id * match_card(struct pnpc_driver *drv, struct pnp_card *card)
+static const struct pnp_card_device_id * match_card(struct pnpc_driver *drv, struct pnp_card *card)
 {
-	const struct pnp_card_id *drv_id = drv->id_table;
+	const struct pnp_card_device_id *drv_id = drv->id_table;
 	while (*drv_id->id){
 		if (compare_pnp_id(card->id,drv_id->id))
 			return drv_id;
@@ -216,18 +216,15 @@
 	return NULL;
 
 found:
-	spin_lock(&pnp_lock);
-	if(dev->status != PNP_READY){
-		spin_unlock(&pnp_lock);
+	if (pnp_device_attach(dev) < 0)
 		return NULL;
-	}
-	dev->status = PNP_ATTACHED;
-	spin_unlock(&pnp_lock);
 	cdrv = to_pnpc_driver(card->dev.driver);
 	if (dev->active == 0) {
 		if (!(cdrv->flags & PNPC_DRIVER_DO_NOT_ACTIVATE)) {
-			if(pnp_activate_dev(dev,NULL)<0)
+			if(pnp_activate_dev(dev,NULL)<0) {
+				pnp_device_detach(dev);
 				return NULL;
+			}
 		}
 	} else {
 		if ((cdrv->flags & PNPC_DRIVER_DO_NOT_ACTIVATE))
@@ -250,10 +247,8 @@
 {
 	spin_lock(&pnp_lock);
 	list_del(&dev->rdev_list);
-	if (dev->status == PNP_ATTACHED)
-		dev->status = PNP_READY;
 	spin_unlock(&pnp_lock);
-	pnp_disable_dev(dev);
+	pnp_device_detach(dev);
 }
 
 static void pnpc_recover_devices(struct pnp_card *card)
@@ -291,7 +286,7 @@
 	int error = 0;
 	struct pnpc_driver *drv = to_pnpc_driver(dev->driver);
 	struct pnp_card *card = to_pnp_card(dev);
-	const struct pnp_card_id *card_id = NULL;
+	const struct pnp_card_device_id *card_id = NULL;
 
 	pnp_dbg("pnp: match found with the PnP card '%s' and the driver '%s'", dev->bus_id,drv->name);
 
diff -Nru a/drivers/pnp/interface.c b/drivers/pnp/interface.c
--- a/drivers/pnp/interface.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/pnp/interface.c	Mon Jan 13 21:59:49 2003
@@ -284,7 +284,7 @@
 }
 
 static ssize_t
-pnp_set_current_resources(struct device * dmdev, const char * buf)
+pnp_set_current_resources(struct device * dmdev, const char * buf, size_t count)
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
 	char	command[20];
@@ -326,7 +326,7 @@
 		goto done;
 	}
  done:
-	return error < 0 ? error : strlen(buf);
+	return error < 0 ? error : count;
 }
 
 static DEVICE_ATTR(resources,S_IRUGO | S_IWUSR,
diff -Nru a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
--- a/drivers/pnp/isapnp/core.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/pnp/isapnp/core.c	Mon Jan 13 21:59:50 2003
@@ -102,7 +102,6 @@
 /* some prototypes */
 
 static int isapnp_config_prepare(struct pnp_dev *dev);
-extern struct pnp_protocol isapnp_card_protocol;
 extern struct pnp_protocol isapnp_protocol;
 
 static inline void write_data(unsigned char x)
@@ -1125,7 +1124,7 @@
 	isapnp_build_device_list();
 	cards = 0;
 
-	protocol_for_each_card(&isapnp_card_protocol,card) {
+	protocol_for_each_card(&isapnp_protocol,card) {
 		cards++;
 		if (isapnp_verbose) {
 			printk(KERN_INFO "isapnp: Card '%s'\n", card->name[0]?card->name:"Unknown");
diff -Nru a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
--- a/drivers/s390/block/dasd.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/s390/block/dasd.c	Mon Jan 13 21:59:49 2003
@@ -1949,28 +1949,22 @@
  * readonly controls the readonly status of a dasd
  */
 static ssize_t
-dasd_ro_show(struct device *dev, char *buf, size_t count, loff_t off)
+dasd_ro_show(struct device *dev, char *buf)
 {
 	dasd_device_t *device;
 
-	if (off)
-		return 0;
-
 	device = dev->driver_data;
 	if (!device)
-		return snprintf(buf, count, "n/a\n");
+		return snprintf(buf, PAGE_SIZE, "n/a\n");
 
-	return snprintf(buf, count, device->ro_flag ? "1\n" : "0\n");
+	return snprintf(buf, PAGE_SIZE, device->ro_flag ? "1\n" : "0\n");
 }
 
 static ssize_t
-dasd_ro_store(struct device *dev, const char *buf, size_t count, loff_t off)
+dasd_ro_store(struct device *dev, const char *buf, size_t count)
 {
 	dasd_device_t *device = dev->driver_data;
 
-	if (off)
-		return 0;
-
 	if (device)
 		device->ro_flag = (buf[0] == '1') ? 1 : 0;
 	return count;
@@ -1984,29 +1978,22 @@
  */
 /* TODO: Implement */
 static ssize_t 
-dasd_use_diag_show(struct device *dev, char *buf, size_t count, loff_t off)
+dasd_use_diag_show(struct device *dev, char *buf)
 {
 	dasd_device_t *device;
 
-	if (off)
-		return 0;
-
 	device = dev->driver_data;
 	if (!device)
-		return snprintf(buf, count, "n/a\n");
+		return sprintf(buf, "n/a\n");
 
-	return snprintf(buf, count, device->use_diag_flag ? "1\n" : "0\n");
+	return sprintf(buf, device->use_diag_flag ? "1\n" : "0\n");
 }
 
 static ssize_t
-dasd_use_diag_store(struct device *dev, const char *buf, 
-		    size_t count, loff_t off)
+dasd_use_diag_store(struct device *dev, const char *buf, size_t count)
 {
 	dasd_device_t *device = dev->driver_data;
 
-	if (off)
-		return 0;
-
 	if (device)
 		device->use_diag_flag = (buf[0] == '1') ? 1 : 0;
 	return count;
@@ -2020,43 +2007,38 @@
  * an inaccaptable interface */
 /* TODO: Split this up into smaller files! */
 static ssize_t
-dasd_devices_show(struct device *dev, char *buf, size_t count, loff_t off)
+dasd_devices_show(struct device *dev, char *buf)
 {
 	
 	dasd_device_t *device;
 	dasd_devmap_t *devmap;
 
-	if (off)	/* ignore partial write */
-		return 0;
-
 	devmap = NULL;
 	device = dev->driver_data;
 	if (device)
 		devmap = dasd_devmap_from_devno(device->devno);
 
 	if (!devmap)
-		return snprintf(buf, count, "unused\n");
+		return sprintf(buf, "unused\n");
 
-	return min ((size_t) dasd_devices_print(devmap, buf), count);
+	return min ((size_t) dasd_devices_print(devmap, buf), PAGE_SIZE);
 }
 
 static DEVICE_ATTR(dasd, 0444, dasd_devices_show, 0);
 #endif
 
 static ssize_t
-dasd_discipline_show(struct device *dev, char *buf, size_t count, loff_t off)
+dasd_discipline_show(struct device *dev, char *buf)
 {
 	dasd_device_t *device;
 
-	if (off)
-		return 0;
 	device = dev->driver_data;
 	if (!device || !device->discipline)
-		return snprintf(buf, count, "none\n");
-	return snprintf(buf, count, "%s\n", device->discipline->name);
+		return sprintf(buf, "none\n");
+	return snprintf(buf, PAGE_SIZE, "%s\n", device->discipline->name);
 }
 
-static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, 0);
+static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
 
 static int
 dasd_add_sysfs_files(struct ccw_device *cdev)
diff -Nru a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
--- a/drivers/s390/cio/ccwgroup.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/s390/cio/ccwgroup.c	Mon Jan 13 21:59:50 2003
@@ -185,15 +185,11 @@
 }
 
 static ssize_t
-ccwgroup_online_store (struct device *dev, const char *buf, size_t count,
-			loff_t off)
+ccwgroup_online_store (struct device *dev, const char *buf, size_t count)
 {
 	struct ccwgroup_device *gdev;
 	unsigned int value;
 
-	if (off)
-		return 0;
-
 	gdev = to_ccwgroupdev(dev);
 	if (!dev->driver)
 		return count;
@@ -209,16 +205,13 @@
 }
 
 static ssize_t
-ccwgroup_online_show (struct device *dev, char *buf, size_t count, loff_t off)
+ccwgroup_online_show (struct device *dev, char *buf)
 {
 	int online;
 
-	if (off)
-		return 0;
-
 	online = (to_ccwgroupdev(dev)->state == CCWGROUP_ONLINE);
 
-	return snprintf(buf, count, online ? "1\n" : "0\n");
+	return sprintf(buf, online ? "1\n" : "0\n");
 }
 
 static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store);
diff -Nru a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
--- a/drivers/s390/cio/chsc.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/s390/cio/chsc.c	Mon Jan 13 21:59:50 2003
@@ -606,39 +606,36 @@
  * Files for the channel path entries.
  */
 static ssize_t
-chp_status_show(struct device *dev, char *buf, size_t count, loff_t off)
+chp_status_show(struct device *dev, char *buf)
 {
 	struct sys_device *sdev = container_of(dev, struct sys_device, dev);
 	struct channel_path *chp = container_of(sdev, struct channel_path, sdev);
 
 	if (!chp)
-		return off ? 0 : count;
+		return 0;
 
 	switch(chp->state) {
 	case CHP_OFFLINE:
-		return off ? 0 : snprintf(buf, count, "n/a\n");
+		return snprintf(buf, count, "n/a\n");
 	case CHP_LOGICALLY_OFFLINE:
-		return off ? 0 : snprintf(buf, count, "logically offline\n");
+		return snprintf(buf, count, "logically offline\n");
 	case CHP_STANDBY:
-		return off ? 0 : snprintf(buf, count, "n/a\n");
+		return snprintf(buf, count, "n/a\n");
 	case CHP_ONLINE:
-		return off ? 0 : snprintf(buf, count, "online\n");
+		return snprintf(buf, count, "online\n");
 	default:
-		return off ? 0 : count;
+		return 0;
 	}
 }
 
 static ssize_t
-chp_status_write(struct device *dev, const char *buf, size_t count, loff_t off)
+chp_status_write(struct device *dev, const char *buf, size_t count)
 {
 	struct sys_device *sdev = container_of(dev, struct sys_device, dev);
 	struct channel_path *cp = container_of(sdev, struct channel_path, sdev);
 	char cmd[10];
 	int num_args;
 	int error;
-
-	if (off)
-		return 0;
 
 	num_args = sscanf(buf, "%5s", cmd);
 	if (!num_args)
diff -Nru a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
--- a/drivers/s390/cio/device.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/s390/cio/device.c	Mon Jan 13 21:59:50 2003
@@ -157,7 +157,7 @@
  * TODO: Split chpids and pimpampom up? Where is "in use" in the tree?
  */
 static ssize_t
-chpids_show (struct device * dev, char * buf, size_t count, loff_t off)
+chpids_show (struct device * dev, char * buf)
 {
 	struct subchannel *sch = to_subchannel(dev);
 	struct ssd_info *ssd = &sch->ssd_info;
@@ -168,48 +168,48 @@
 		ret += sprintf (buf+ret, "%02x ", ssd->chpid[chp]);
 
 	ret += sprintf (buf+ret, "\n");
-	return off ? 0 : min((ssize_t)count, ret);
+	return min((ssize_t)PAGE_SIZE, ret);
 }
 
 static ssize_t
-pimpampom_show (struct device * dev, char * buf, size_t count, loff_t off)
+pimpampom_show (struct device * dev, char * buf)
 {
 	struct subchannel *sch = to_subchannel(dev);
 	struct pmcw *pmcw = &sch->schib.pmcw;
 
-	return off ? 0 : snprintf (buf, count, "%02x %02x %02x\n",
-				   pmcw->pim, pmcw->pam, pmcw->pom);
+	return sprintf (buf, "%02x %02x %02x\n",
+			pmcw->pim, pmcw->pam, pmcw->pom);
 }
 
 static ssize_t
-devtype_show (struct device *dev, char *buf, size_t count, loff_t off)
+devtype_show (struct device *dev, char *buf)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 	struct ccw_device_id *id = &(cdev->id);
 
 	if (id->dev_type != 0)
-		return off ? 0 : snprintf(buf, count, "%04x/%02x\n",
-					  id->dev_type, id->dev_model);
+		return sprintf(buf, "%04x/%02x\n",
+				id->dev_type, id->dev_model);
 	else
-		return off ? 0 : snprintf(buf, count, "n/a\n");
+		return sprintf(buf, "n/a\n");
 }
 
 static ssize_t
-cutype_show (struct device *dev, char *buf, size_t count, loff_t off)
+cutype_show (struct device *dev, char *buf)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 	struct ccw_device_id *id = &(cdev->id);
 
-	return off ? 0 : snprintf(buf, count, "%04x/%02x\n",
-				  id->cu_type, id->cu_model);
+	return sprintf(buf, "%04x/%02x\n",
+		       id->cu_type, id->cu_model);
 }
 
 static ssize_t
-online_show (struct device *dev, char *buf, size_t count, loff_t off)
+online_show (struct device *dev, char *buf)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 
-	return off ? 0 : snprintf(buf, count, cdev->online ? "yes\n" : "no\n");
+	return sprintf(buf, cdev->online ? "yes\n" : "no\n");
 }
 
 void
@@ -256,13 +256,10 @@
 }
 
 static ssize_t
-online_store (struct device *dev, const char *buf, size_t count, loff_t off)
+online_store (struct device *dev, const char *buf, size_t count)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 	unsigned int value;
-
-	if (off)
-		return 0;
 
 	if (!cdev->drv)
 		return count;
diff -Nru a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
--- a/drivers/s390/net/ctcmain.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/s390/net/ctcmain.c	Mon Jan 13 21:59:49 2003
@@ -2512,26 +2512,23 @@
 #define CTRL_BUFSIZE 40
 
 static ssize_t
-buffer_show(struct device *dev, char *buf, size_t count, loff_t off)
+buffer_show(struct device *dev, char *buf)
 {
 	struct ctc_priv *priv;
 
 	priv = dev->driver_data;
 	if (!priv)
 		return -ENODEV;
-	return off ? 0 : snprintf(buf, count, "%d\n",
-				  priv->channel[READ]->max_bufsize);
+	return sprintf(buf, "%d\n",
+		       priv->channel[READ]->max_bufsize);
 }
 
 static ssize_t
-buffer_write(struct device *dev, const char *buf, size_t count, loff_t off)
+buffer_write(struct device *dev, const char *buf, size_t count)
 {
 	struct ctc_priv *priv;
 	struct net_device *ndev;
 	int bs1;
-
-	if (off)
-		return 0;
 
 	priv = dev->driver_data;
 	if (!priv)
diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
--- a/drivers/s390/net/lcs.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/s390/net/lcs.c	Mon Jan 13 21:59:49 2003
@@ -1637,32 +1637,30 @@
  * show function for portno called by cat or similar things
  */
 static ssize_t
-lcs_portno_show (struct device *dev, char *buf, size_t count,
-		 loff_t off)
+lcs_portno_show (struct device *dev, char *buf)
 {
         struct lcs_card *card;
 
 	card = (struct lcs_card *)dev->driver_data;
 
-        if (off || !card)
+        if (!card)
                 return 0;
 
-        return snprintf(buf, count, "%d\n", card->portno);
+        return sprintf(buf, "%d\n", card->portno);
 }
 
 /**
  * store the value which is piped to file portno
  */
 static ssize_t
-lcs_portno_store (struct device *dev, const char *buf, size_t count,
-		  loff_t off)
+lcs_portno_store (struct device *dev, const char *buf, size_t count)
 {
         struct lcs_card *card;
         int value;
 
 	card = (struct lcs_card *)dev->driver_data;
 
-        if (off || !card)
+        if (!card)
                 return 0;
 
         sscanf(buf, "%u", &value);
diff -Nru a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
--- a/drivers/s390/net/netiucv.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/s390/net/netiucv.c	Mon Jan 13 21:59:50 2003
@@ -1259,16 +1259,16 @@
 #define CTRL_BUFSIZE 40
 
 static ssize_t
-user_show (struct device *dev, char *buf, size_t count, loff_t off)
+user_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 
-	return off ? 0 : snprintf(buf, count, "%s\n", 
-				  netiucv_printname(priv->conn->userid));
+	return snprintf(buf, PAGE_SIZE, "%s\n", 
+			netiucv_printname(priv->conn->userid));
 }
 
 static ssize_t
-user_write (struct device *dev, const char *buf, size_t count, loff_t off)
+user_write (struct device *dev, const char *buf, size_t count)
 {
 	netiucv_priv *priv = dev->driver_data;
 	struct net_device *ndev = container_of((void *)priv, struct net_device, priv);
@@ -1305,16 +1305,16 @@
 static DEVICE_ATTR(user, 0644, user_show, user_write);
 
 static ssize_t
-buffer_show (struct device *dev, char *buf, size_t count, loff_t off)
+buffer_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 
-	return off ? 0 : snprintf(buf, count, "%d\n", 
-				  priv->conn->max_buffsize);
+	return sprintf(buf, "%d\n", 
+		       priv->conn->max_buffsize);
 }
 
 static ssize_t
-buffer_write (struct device *dev, const char *buf, size_t count, loff_t off)
+buffer_write (struct device *dev, const char *buf, size_t count)
 {
 	netiucv_priv *priv = dev->driver_data;
 	struct net_device *ndev = container_of((void *)priv, struct net_device, priv);
@@ -1352,38 +1352,37 @@
 static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
 
 static ssize_t
-dev_fsm_show (struct device *dev, char *buf, size_t count, loff_t off)
+dev_fsm_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
-	return off ? 0 : snprintf(buf, count, "%s\n",
-				  fsm_getstate_str(priv->fsm));
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			fsm_getstate_str(priv->fsm));
 }
 
 static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL);
 
 static ssize_t
-conn_fsm_show (struct device *dev, char *buf, size_t count, loff_t off)
+conn_fsm_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
-	return off ? 0 : snprintf(buf, count, "%s\n",
-				  fsm_getstate_str(priv->conn->fsm));
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			fsm_getstate_str(priv->conn->fsm));
 }
 
 static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL);
 
 static ssize_t
-maxmulti_show (struct device *dev, char *buf, size_t count, loff_t off)
+maxmulti_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
-	return off ? 0 : snprintf(buf, count, "%ld\n",
-				  priv->conn->prof.maxmulti);
+	return sprintf(buf, "%ld\n", priv->conn->prof.maxmulti);
 }
 
 static ssize_t
-maxmulti_write (struct device *dev, const char *buf, size_t count, loff_t off)
+maxmulti_write (struct device *dev, const char *buf, size_t count)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
@@ -1394,16 +1393,15 @@
 static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write);
 
 static ssize_t
-maxcq_show (struct device *dev, char *buf, size_t count, loff_t off)
+maxcq_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
-	return off ? 0 : snprintf(buf, count, "%ld\n",
-				  priv->conn->prof.maxcqueue);
+	return sprintf(buf, "%ld\n", priv->conn->prof.maxcqueue);
 }
 
 static ssize_t
-maxcq_write (struct device *dev, const char *buf, size_t count, loff_t off)
+maxcq_write (struct device *dev, const char *buf, size_t count)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
@@ -1414,16 +1412,15 @@
 static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write);
 
 static ssize_t
-sdoio_show (struct device *dev, char *buf, size_t count, loff_t off)
+sdoio_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
-	return off ? 0 : snprintf(buf, count, "%ld\n",
-				  priv->conn->prof.doios_single);
+	return sprintf(buf, "%ld\n", priv->conn->prof.doios_single);
 }
 
 static ssize_t
-sdoio_write (struct device *dev, const char *buf, size_t count, loff_t off)
+sdoio_write (struct device *dev, const char *buf, size_t count)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
@@ -1434,16 +1431,15 @@
 static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write);
 
 static ssize_t
-mdoio_show (struct device *dev, char *buf, size_t count, loff_t off)
+mdoio_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
-	return off ? 0 : snprintf(buf, count, "%ld\n",
-				  priv->conn->prof.doios_multi);
+	return sprintf(buf, "%ld\n", priv->conn->prof.doios_multi);
 }
 
 static ssize_t
-mdoio_write (struct device *dev, const char *buf, size_t count, loff_t off)
+mdoio_write (struct device *dev, const char *buf, size_t count)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
@@ -1454,16 +1450,15 @@
 static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write);
 
 static ssize_t
-txlen_show (struct device *dev, char *buf, size_t count, loff_t off)
+txlen_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
-	return off ? 0 : snprintf(buf, count, "%ld\n",
-				  priv->conn->prof.txlen);
+	return sprintf(buf, "%ld\n", priv->conn->prof.txlen);
 }
 
 static ssize_t
-txlen_write (struct device *dev, const char *buf, size_t count, loff_t off)
+txlen_write (struct device *dev, const char *buf, size_t count)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
@@ -1474,16 +1469,15 @@
 static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write);
 
 static ssize_t
-txtime_show (struct device *dev, char *buf, size_t count, loff_t off)
+txtime_show (struct device *dev, char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
-	return off ? 0 : snprintf(buf, count, "%ld\n",
-				  priv->conn->prof.tx_time);
+	return snprintf(buf, count, "%ld\n", priv->conn->prof.tx_time);
 }
 
 static ssize_t
-txtime_write (struct device *dev, const char *buf, size_t count, loff_t off)
+txtime_write (struct device *dev, const char *buf)
 {
 	netiucv_priv *priv = dev->driver_data;
 	
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/scsi/53c700.c	Mon Jan 13 21:59:49 2003
@@ -246,7 +246,7 @@
 	int j;
 
 	memory = dma_alloc_noncoherent(hostdata->dev, TOTAL_MEM_SIZE,
-					 &pScript);
+				       &pScript, GFP_KERNEL);
 	if(memory == NULL) {
 		printk(KERN_ERR "53c700: Failed to allocate memory for driver, detatching\n");
 		return NULL;
diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
--- a/drivers/scsi/cpqfcTSinit.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/scsi/cpqfcTSinit.c	Mon Jan 13 21:59:49 2003
@@ -384,7 +384,8 @@
 
       // Since we have two 256-byte I/O port ranges (upper
       // and lower), check them both
-      if( check_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff) )
+      if( !request_region( cpqfcHBAdata->fcChip.Registers.IOBaseU,
+      	                   0xff, DEV_NAME ) )
       {
 	printk("  cpqfcTS address in use: %x\n", 
 			cpqfcHBAdata->fcChip.Registers.IOBaseU);
@@ -393,21 +394,21 @@
 	continue;
       }	
       
-      if( check_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff) )
+      if( !request_region( cpqfcHBAdata->fcChip.Registers.IOBaseL,
+      			   0xff, DEV_NAME ) )
       {
   	printk("  cpqfcTS address in use: %x\n", 
 	      			cpqfcHBAdata->fcChip.Registers.IOBaseL);
+	release_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff );
 	free_irq( HostAdapter->irq, HostAdapter);
         scsi_unregister( HostAdapter);
 	continue;
       }	
       
-      // OK, we should be able to grab everything we need now.
-      request_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff, DEV_NAME);
-      request_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff, DEV_NAME);
-      DEBUG_PCI(printk("  Requesting 255 I/O addresses @ %x\n",
+      // OK, we have grabbed everything we need now.
+      DEBUG_PCI(printk("  Reserved 255 I/O addresses @ %x\n",
         cpqfcHBAdata->fcChip.Registers.IOBaseL ));
-      DEBUG_PCI(printk("  Requesting 255 I/O addresses @ %x\n",
+      DEBUG_PCI(printk("  Reserved 255 I/O addresses @ %x\n",
         cpqfcHBAdata->fcChip.Registers.IOBaseU ));
 
      
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/scsi/dpt_i2o.c	Mon Jan 13 21:59:51 2003
@@ -1491,7 +1491,7 @@
 							pDev->next_lun; pDev = pDev->next_lun){
 					}
 					pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
-					if(pDev == NULL) {
+					if(pDev->next_lun == NULL) {
 						return -ENOMEM;
 					}
 					memset(pDev->next_lun,0,sizeof(struct adpt_device));
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/scsi/hosts.c	Mon Jan 13 21:59:49 2003
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/completion.h>
 
 #define __KERNEL_SYSCALLS__
 
@@ -314,9 +315,10 @@
  **/
 int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
 {
-	dev->class_data = shost;
-	shost->host_gendev = dev;
-
+	if (dev) {
+		dev->class_data = shost;
+		shost->host_gendev = dev;
+	}
 	return __scsi_add_host(shost);
 }
 
@@ -335,10 +337,11 @@
 	 * Next, kill the kernel error recovery thread for this host.
 	 */
 	if (shost->ehandler) {
-		DECLARE_MUTEX_LOCKED(sem);
+		DECLARE_COMPLETION(sem);
 		shost->eh_notify = &sem;
-		send_sig(SIGHUP, shost->ehandler, 1);
-		down(&sem);
+		shost->eh_kill = 1;
+		up(shost->eh_wait);
+		wait_for_completion(&sem);
 		shost->eh_notify = NULL;
 	}
 
@@ -368,7 +371,7 @@
 {
 	struct Scsi_Host *shost, *shost_scr;
 	int gfp_mask;
-	DECLARE_MUTEX_LOCKED(sem);
+	DECLARE_COMPLETION(sem);
 
         /* Check to see if this host has any error handling facilities */
         if(shost_tp->eh_strategy_handler == NULL &&
@@ -464,7 +467,7 @@
 	 * Now wait for the kernel error thread to initialize itself
 	 * as it might be needed when we scan the bus.
 	 */
-	down(&sem);
+	wait_for_completion(&sem);
 	shost->eh_notify = NULL;
 
 	shost->hostt->present++;
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
--- a/drivers/scsi/hosts.h	Mon Jan 13 21:59:49 2003
+++ b/drivers/scsi/hosts.h	Mon Jan 13 21:59:49 2003
@@ -381,11 +381,12 @@
     struct task_struct    * ehandler;  /* Error recovery thread. */
     struct semaphore      * eh_wait;   /* The error recovery thread waits on
                                           this. */
-    struct semaphore      * eh_notify; /* wait for eh to begin */
+    struct completion     * eh_notify; /* wait for eh to begin or end */
     struct semaphore      * eh_action; /* Wait for specific actions on the
                                           host. */
     unsigned int            eh_active:1; /* Indicates the eh thread is awake and active if
                                           this is true. */
+    unsigned int            eh_kill:1; /* set when killing the eh thread */
     wait_queue_head_t       host_wait;
     Scsi_Host_Template    * hostt;
     atomic_t                host_active; /* commands checked out */
diff -Nru a/drivers/scsi/osst.c b/drivers/scsi/osst.c
--- a/drivers/scsi/osst.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/scsi/osst.c	Mon Jan 13 21:59:50 2003
@@ -5325,17 +5325,17 @@
 #endif
 
 /* Driverfs file support */
-static ssize_t osst_device_kdev_read(struct device *driverfs_dev, char *page, size_t count, loff_t off)
+static ssize_t osst_device_kdev_read(struct device *driverfs_dev, char *page)
 {
 	kdev_t kdev; 
 	kdev.value=(int)(long)driverfs_dev->driver_data;
-	return off ? 0 : sprintf(page, "%x\n",kdev.value);
+	return sprintf(page, "%x\n",kdev.value);
 }
 static DEVICE_ATTR(kdev,S_IRUGO,osst_device_kdev_read,NULL);
 
-static ssize_t osst_device_type_read(struct device *driverfs_dev, char *page, size_t count, loff_t off) 
+static ssize_t osst_device_type_read(struct device *driverfs_dev, char *page) 
 {
-	return off ? 0 : sprintf (page, "CHR\n");
+	return sprintf (page, "CHR\n");
 }
 static DEVICE_ATTR(type,S_IRUGO,osst_device_type_read,NULL);
 
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/scsi/scsi_error.c	Mon Jan 13 21:59:49 2003
@@ -27,6 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/smp_lock.h>
+#include <linux/completion.h>
 
 #define __KERNEL_SYSCALLS__
 
@@ -41,20 +42,6 @@
 
 #include <scsi/scsi_ioctl.h> /* grr */
 
-/*
- * We must always allow SHUTDOWN_SIGS.  Even if we are not a module,
- * the host drivers that we are using may be loaded as modules, and
- * when we unload these,  we need to ensure that the error handler thread
- * can be shut down.
- *
- * Note - when we unload a module, we send a SIGHUP.  We mustn't
- * enable SIGTERM, as this is how the init shuts things down when you
- * go to single-user mode.  For that matter, init also sends SIGKILL,
- * so we mustn't enable that one either.  We use SIGHUP instead.  Other
- * options would be SIGPWR, I suppose.
- */
-#define SHUTDOWN_SIGS	(sigmask(SIGHUP))
-
 #ifdef DEBUG
 #define SENSE_TIMEOUT SCSI_TIMEOUT
 #else
@@ -1589,12 +1576,10 @@
 	int rtn;
 	DECLARE_MUTEX_LOCKED(sem);
 
-	/*
-	 * We only listen to signals if the HA was loaded as a module.
-	 * If the HA was compiled into the kernel, then we don't listen
-	 * to any signals.
-	 */
-	siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
+	spin_lock_irq(&current->sig->siglock);
+	sigfillset(&current->blocked);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sig->siglock);
 
 	lock_kernel();
 
@@ -1618,9 +1603,9 @@
 	/*
 	 * Wake up the thread that created us.
 	 */
-	SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent \n"));
+	SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of scsi_eh_%d\n",shost->host_no));
 
-	up(shost->eh_notify);
+	complete(shost->eh_notify);
 
 	while (1) {
 		/*
@@ -1628,7 +1613,7 @@
 		 * away and die.  This typically happens if the user is
 		 * trying to unload a module.
 		 */
-		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler sleeping\n"));
+		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d sleeping\n",shost->host_no));
 
 		/*
 		 * Note - we always use down_interruptible with the semaphore
@@ -1640,10 +1625,10 @@
 		 * semaphores isn't unreasonable.
 		 */
 		down_interruptible(&sem);
-		if (signal_pending(current))
+		if (shost->eh_kill)
 			break;
 
-		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler waking up\n"));
+		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d waking up\n",shost->host_no));
 
 		shost->eh_active = 1;
 
@@ -1671,7 +1656,7 @@
 
 	}
 
-	SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler exiting\n"));
+	SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d exiting\n",shost->host_no));
 
 	/*
 	 * Make sure that nobody tries to wake us up again.
@@ -1691,13 +1676,9 @@
 	/*
 	 * If anyone is waiting for us to exit (i.e. someone trying to unload
 	 * a driver), then wake up that process to let them know we are on
-	 * the way out the door.  This may be overkill - I *think* that we
-	 * could probably just unload the driver and send the signal, and when
-	 * the error handling thread wakes up that it would just exit without
-	 * needing to touch any memory associated with the driver itself.
+	 * the way out the door.
 	 */
-	if (shost->eh_notify != NULL)
-		up(shost->eh_notify);
+	complete_and_exit(shost->eh_notify, 0);
 }
 
 /**
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/scsi/scsi_lib.c	Mon Jan 13 21:59:50 2003
@@ -495,6 +495,7 @@
 	int this_count = SCpnt->bufflen >> 9;
 	request_queue_t *q = SCpnt->device->request_queue;
 	struct request *req = SCpnt->request;
+	int clear_errors = 1;
 
 	/*
 	 * We must do one of several things here:
@@ -528,10 +529,22 @@
 		kfree(SCpnt->buffer);
 	}
 
-	if (blk_pc_request(req)) {
-		req->errors = result & 0xff;
-		if (!result)
+	if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
+		req->errors = (driver_byte(result) & DRIVER_SENSE) ?
+			      (CHECK_CONDITION << 1) : (result & 0xff);
+		if (!result) 
 			req->data_len -= SCpnt->bufflen;
+		else {
+			clear_errors = 0;
+			if (SCpnt->sense_buffer[0] & 0x70) {
+				int len = 8 + SCpnt->sense_buffer[7];
+
+				if (len > SCSI_SENSE_BUFFERSIZE)
+					len = SCSI_SENSE_BUFFERSIZE;
+				memcpy(req->sense, SCpnt->sense_buffer,  len);
+				req->sense_len = len;
+			}
+		}
 	}
 
 	/*
@@ -552,7 +565,8 @@
 					      req->nr_sectors, good_sectors));
 		SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n ", SCpnt->use_sg));
 
-		req->errors = 0;
+		if (clear_errors)
+			req->errors = 0;
 		/*
 		 * If multiple sectors are requested in one buffer, then
 		 * they will have been finished off by the first command.
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/scsi/scsi_sysfs.c	Mon Jan 13 21:59:49 2003
@@ -158,12 +158,12 @@
 	show_function(field, format_string)				\
 									\
 static ssize_t								\
-store_##field (struct device *dev, const char *buf)			\
+store_##field (struct device *dev, const char *buf, size_t count)	\
 {									\
 	struct scsi_device *sdev;					\
 	sdev = to_scsi_device(dev);					\
 	snscanf (buf, 20, format_string, &sdev->field);			\
-	return strlen(buf);						\
+	return count;							\
 }									\
 static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, store_##field)
 
@@ -175,7 +175,7 @@
 	show_function(field, "%d\n")					\
 									\
 static ssize_t								\
-store_##field (struct device *dev, const char *buf)			\
+store_##field (struct device *dev, const char *buf, size_t count)	\
 {									\
 	int ret;							\
 	struct scsi_device *sdev;					\
@@ -183,7 +183,7 @@
 	if (ret >= 0)	{						\
 		sdev = to_scsi_device(dev);				\
 		sdev->field = ret;					\
-		ret = strlen(buf);					\
+		ret = count;						\
 	}								\
 	return ret;							\
 }									\
@@ -213,6 +213,7 @@
 sdev_rd_attr (current_queue_depth, "%d\n");
 sdev_rd_attr (new_queue_depth, "%d\n");
 sdev_rd_attr (type, "%d\n");
+sdev_rd_attr (scsi_level, "%d\n");
 sdev_rd_attr (access_count, "%d\n");
 sdev_rd_attr (vendor, "%.8s\n");
 sdev_rd_attr (model, "%.16s\n");
@@ -224,6 +225,7 @@
 	&dev_attr_current_queue_depth,
 	&dev_attr_new_queue_depth,
 	&dev_attr_type,
+	&dev_attr_scsi_level,
 	&dev_attr_access_count,
 	&dev_attr_vendor,
 	&dev_attr_model,
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/scsi/sd.c	Mon Jan 13 21:59:50 2003
@@ -79,7 +79,7 @@
 	u8		media_present;
 	u8		write_prot;
 	unsigned	WCE : 1;	/* state of disk WCE bit */
-	unsigned	RCD : 1;	/* state of disk RCD bit */
+	unsigned	RCD : 1;	/* state of disk RCD bit, unused */
 };
 
 static LIST_HEAD(sd_devlist);
@@ -217,7 +217,7 @@
 	block = SCpnt->request->sector;
 	this_count = SCpnt->request_bufflen >> 9;
 
-	SCSI_LOG_HLQUEUE(1, printk("sd_command_init: disk=%s, block=%llu, "
+	SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, "
 			    "count=%d\n", disk->disk_name, (unsigned long long)block, this_count));
 
 	if (!sdp || !sdp->online ||
@@ -809,9 +809,22 @@
 		if (media_not_present(sdkp, SRpnt))
 			return;
 
-		/* Look for devices that return NOT_READY.
-		 * Issue command to spin up drive for these cases. */
-		if (the_result && SRpnt->sr_sense_buffer[2] == NOT_READY) {
+		if (the_result == 0)
+			break;		/* all is well now */
+
+		/*
+		 * If manual intervention is required, or this is an
+		 * absent USB storage device, a spinup is meaningless.
+		 */
+		if (SRpnt->sr_sense_buffer[2] == NOT_READY &&
+		    SRpnt->sr_sense_buffer[12] == 4 /* not ready */ &&
+		    SRpnt->sr_sense_buffer[13] == 3)
+			break;		/* manual intervention required */
+
+		/*
+		 * Issue command to spin up drive when not ready
+		 */
+		if (SRpnt->sr_sense_buffer[2] == NOT_READY) {
 			unsigned long time1;
 			if (!spintime) {
 				printk(KERN_NOTICE "%s: Spinning up disk...",
@@ -839,7 +852,7 @@
 			} while(time1);
 			printk(".");
 		}
-	} while (the_result && spintime &&
+	} while (spintime &&
 		 time_after(spintime_value + 100 * HZ, jiffies));
 
 	if (spintime) {
@@ -851,80 +864,6 @@
 }
 
 /*
- * sd_read_cache_type - called only from sd_init_onedisk()
- */
-static void
-sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
-		   struct scsi_request *SRpnt, unsigned char *buffer) {
-
-	unsigned char cmd[10];
-	int the_result, retries;
-
-	retries = 3;
-	do {
-
-		memset((void *) &cmd[0], 0, 10);
-		cmd[0] = MODE_SENSE;
-		cmd[1] = 0x08;	/* DBD */
-		cmd[2] = 0x08;	/* current values, cache page */
-		cmd[4] = 128;	/* allocation length */
-
-
-		memset((void *) buffer, 0, 24);
-		SRpnt->sr_cmd_len = 0;
-		SRpnt->sr_sense_buffer[0] = 0;
-		SRpnt->sr_sense_buffer[2] = 0;
-
-		SRpnt->sr_data_direction = SCSI_DATA_READ;
-		scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
-			    128, SD_TIMEOUT, SD_MAX_RETRIES);
-
-		the_result = SRpnt->sr_result;
-		retries--;
-
-	} while (the_result && retries);
-
-	if (the_result) {
-		if(status_byte(the_result) == CHECK_CONDITION
-		   && (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70
-		   && (SRpnt->sr_sense_buffer[2] & 0x0f) == ILLEGAL_REQUEST
-		   /* The next are ASC 0x24 ASCQ 0x00: Invalid field in CDB */
-		   && SRpnt->sr_sense_buffer[12] == 0x24
-		   && SRpnt->sr_sense_buffer[13] == 0x00) {
-			printk(KERN_NOTICE "SCSI device %s: cache data unavailable\n", diskname);
-		} else {
-			printk(KERN_ERR "%s : MODE SENSE failed.\n"
-			       "%s : status = %x, message = %02x, host = %d, driver = %02x \n",
-			       diskname, diskname,
-			       status_byte(the_result),
-			       msg_byte(the_result),
-			       host_byte(the_result),
-			       driver_byte(the_result)
-			       );
-			if (driver_byte(the_result) & DRIVER_SENSE)
-				print_req_sense("sd", SRpnt);
-			else
-				printk(KERN_ERR "%s : sense not available. \n", diskname);
-			
-			printk(KERN_ERR "%s : assuming drive cache: write through\n", diskname);
-		}
-		sdkp->WCE = 0;
-		sdkp->RCD = 0;
-	} else {
-		const char *types[] = { "write through", "none", "write back", "write back, no read (daft)" };
-		int ct = 0;
-		int offset = buffer[3] + 4; /* offset to start of mode page */
-
-		sdkp->WCE = (buffer[offset + 2] & 0x04) == 0x04;
-		sdkp->RCD = (buffer[offset + 2] & 0x01) == 0x01;
-
-		ct =  sdkp->RCD + 2*sdkp->WCE;
-
-		printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n", diskname, types[ct]);
-	}
-}
-
-/*
  * read disk capacity - called only in sd_init_onedisk()
  */
 static void
@@ -1102,11 +1041,12 @@
 
 static int
 sd_do_mode_sense6(struct scsi_device *sdp, struct scsi_request *SRpnt,
-		  int modepage, unsigned char *buffer, int len) {
+		  int dbd, int modepage, unsigned char *buffer, int len) {
 	unsigned char cmd[8];
 
 	memset((void *) &cmd[0], 0, 8);
 	cmd[0] = MODE_SENSE;
+	cmd[1] = dbd;
 	cmd[2] = modepage;
 	cmd[4] = len;
 
@@ -1115,6 +1055,8 @@
 	SRpnt->sr_sense_buffer[2] = 0;
 	SRpnt->sr_data_direction = SCSI_DATA_READ;
 
+	memset((void *) buffer, 0, len);
+
 	scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
 		      len, SD_TIMEOUT, SD_MAX_RETRIES);
 
@@ -1135,7 +1077,7 @@
 	 * We have to start carefully: some devices hang if we ask
 	 * for more than is available.
 	 */
-	res = sd_do_mode_sense6(sdp, SRpnt, 0x3F, buffer, 4);
+	res = sd_do_mode_sense6(sdp, SRpnt, 0, 0x3F, buffer, 4);
 
 	/*
 	 * Second attempt: ask for page 0
@@ -1143,13 +1085,13 @@
 	 * Sense Key 5: Illegal Request, Sense Code 24: Invalid field in CDB.
 	 */
 	if (res)
-		res = sd_do_mode_sense6(sdp, SRpnt, 0, buffer, 4);
+		res = sd_do_mode_sense6(sdp, SRpnt, 0, 0, buffer, 4);
 
 	/*
 	 * Third attempt: ask 255 bytes, as we did earlier.
 	 */
 	if (res)
-		res = sd_do_mode_sense6(sdp, SRpnt, 0x3F, buffer, 255);
+		res = sd_do_mode_sense6(sdp, SRpnt, 0, 0x3F, buffer, 255);
 
 	if (res) {
 		printk(KERN_WARNING
@@ -1163,6 +1105,65 @@
 	}
 }
 
+/*
+ * sd_read_cache_type - called only from sd_init_onedisk()
+ */
+static void
+sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
+		   struct scsi_request *SRpnt, unsigned char *buffer) {
+	struct scsi_device *sdp = sdkp->device;
+	int len = 0, res;
+
+	const int dbd = 0x08;	   /* DBD */
+	const int modepage = 0x08; /* current values, cache page */
+
+	/* cautiously ask */
+	res = sd_do_mode_sense6(sdp, SRpnt, dbd, modepage, buffer, 4);
+
+	if (res == 0) {
+		/* that went OK, now ask for the proper length */
+		len = buffer[0] + 1;
+		if (len > 128)
+			len = 128;
+		res = sd_do_mode_sense6(sdp, SRpnt, dbd, modepage, buffer, len);
+	}
+
+	if (res == 0 && buffer[3] + 6 < len) {
+		const char *types[] = {
+			"write through", "none", "write back",
+			"write back, no read (daft)"
+		};
+		int ct = 0;
+		int offset = buffer[3] + 4; /* start of mode page */
+
+		sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
+		sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
+
+		ct =  sdkp->RCD + 2*sdkp->WCE;
+
+		printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n",
+		       diskname, types[ct]);
+	} else {
+		if (res == 0 ||
+		    (status_byte(res) == CHECK_CONDITION
+		     && (SRpnt->sr_sense_buffer[0] & 0x70) == 0x70
+		     && (SRpnt->sr_sense_buffer[2] & 0x0f) == ILLEGAL_REQUEST
+		     /* ASC 0x24 ASCQ 0x00: Invalid field in CDB */
+		     && SRpnt->sr_sense_buffer[12] == 0x24
+		     && SRpnt->sr_sense_buffer[13] == 0x00)) {
+			printk(KERN_NOTICE "%s: cache data unavailable\n",
+			       diskname);
+		} else {
+			printk(KERN_ERR "%s: asking for cache data failed\n",
+			       diskname);
+		}
+		printk(KERN_ERR "%s: assuming drive cache: write through\n",
+		       diskname);
+		sdkp->WCE = 0;
+		sdkp->RCD = 0;
+	}
+}
+
 /**
  *	sd_init_onedisk - called the first time a new disk is seen,
  *	performs disk spin up, read_capacity, etc.
@@ -1208,15 +1209,20 @@
 	sdkp->device->sector_size = 512;
 	sdkp->media_present = 1;
 	sdkp->write_prot = 0;
+	sdkp->WCE = 0;
+	sdkp->RCD = 0;
 
 	sd_spinup_disk(sdkp, disk->disk_name, SRpnt, buffer);
-	sd_read_cache_type(sdkp, disk->disk_name, SRpnt, buffer);
 
 	if (sdkp->media_present)
 		sd_read_capacity(sdkp, disk->disk_name, SRpnt, buffer);
 	
 	if (sdp->removable && sdkp->media_present)
 		sd_read_write_protect_flag(sdkp, disk->disk_name, SRpnt, buffer);
+	/* without media there is no reason to ask;
+	   moreover, some devices react badly if we do */
+	if (sdkp->media_present)
+		sd_read_cache_type(sdkp, disk->disk_name, SRpnt, buffer);
 		
 	SRpnt->sr_device->ten = 1;
 	SRpnt->sr_device->remap = 1;
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/scsi/st.c	Mon Jan 13 21:59:50 2003
@@ -3615,19 +3615,17 @@
 #endif
 
 /* Driverfs file support */
-static ssize_t st_device_kdev_read(struct device *driverfs_dev, 
-				   char *page, size_t count, loff_t off)
+static ssize_t st_device_kdev_read(struct device *dev, char *page)
 {
 	kdev_t kdev; 
-	kdev.value=(int)(long)driverfs_dev->driver_data;
-	return off ? 0 : sprintf(page, "%x\n",kdev.value);
+	kdev.value=(int)dev->driver_data;
+	return sprintf(page, "%x\n",kdev.value);
 }
 static DEVICE_ATTR(kdev,S_IRUGO,st_device_kdev_read,NULL);
 
-static ssize_t st_device_type_read(struct device *driverfs_dev, 
-				   char *page, size_t count, loff_t off) 
+static ssize_t st_device_type_read(struct device *ev, char * page)
 {
-	return off ? 0 : sprintf (page, "CHR\n");
+	return sprintf (page, "CHR\n");
 }
 static DEVICE_ATTR(type,S_IRUGO,st_device_type_read,NULL);
 
diff -Nru a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h
--- a/drivers/scsi/sym53c8xx_comm.h	Mon Jan 13 21:59:50 2003
+++ b/drivers/scsi/sym53c8xx_comm.h	Mon Jan 13 21:59:50 2003
@@ -797,7 +797,7 @@
 		dma_addr_t daddr;
 		vp = (m_addr_t) dma_alloc_coherent(mp->bush,
 						PAGE_SIZE<<MEMO_PAGE_ORDER,
-						&daddr);
+						&daddr, GFP_KERNEL);
 		if (vp) {
 			int hc = VTOB_HASH_CODE(vp);
 			vbp->vaddr = vp;
diff -Nru a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
--- a/drivers/serial/68360serial.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/serial/68360serial.c	Mon Jan 13 21:59:51 2003
@@ -324,7 +324,8 @@
 #elif defined(CONFIG_CONSOLE_115200)
   #define CONSOLE_BAUDRATE 115200
 #else
-#error "console baud rate undefined"
+  #warn "console baud rate undefined"
+  #define CONSOLE_BAUDRATE 9600
 #endif
 
 /*
diff -Nru a/drivers/serial/mcfserial.h b/drivers/serial/mcfserial.h
--- a/drivers/serial/mcfserial.h	Mon Jan 13 21:59:49 2003
+++ b/drivers/serial/mcfserial.h	Mon Jan 13 21:59:49 2003
@@ -69,13 +69,8 @@
 	struct work_struct	tqueue_hangup;
 	struct termios		normal_termios;
 	struct termios		callout_termios;
-#if LINUX_VERSION_CODE <= 0x020100
-	struct wait_queue	*open_wait;
-	struct wait_queue	*close_wait;
-#else
 	wait_queue_head_t	open_wait;
 	wait_queue_head_t	close_wait;
-#endif
 
 };
 
diff -Nru a/drivers/serial/nb85e_uart.c b/drivers/serial/nb85e_uart.c
--- a/drivers/serial/nb85e_uart.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/serial/nb85e_uart.c	Mon Jan 13 21:59:51 2003
@@ -1,8 +1,8 @@
 /*
  * drivers/serial/nb85e_uart.c -- Serial I/O using V850E/NB85E on-chip UART
  *
- *  Copyright (C) 2001,02  NEC Corporation
- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03  NEC Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * 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
@@ -31,6 +31,9 @@
 #define NB85E_UART_INIT_CFLAGS	(B115200 | CS8 | CREAD)
 #endif
 
+/* XXX This should be in a header file.  */
+#define NB85E_UART_BRGC_MIN	8
+
 /* A string used for prefixing printed descriptions; since the same UART
    macro is actually used on other chips than the V850E/NB85E.  This must
    be a constant string.  */
@@ -39,6 +42,29 @@
 #endif
 
 
+/* Helper functions for doing baud-rate/frequency calculations.  */
+
+/* Calculate the minimum value for CKSR on this processor.  */
+static inline unsigned cksr_min (void)
+{
+	int min = 0;
+	unsigned freq = NB85E_UART_BASE_FREQ;
+	while (freq > NB85E_UART_CKSR_MAX_FREQ) {
+		freq >>= 1;
+		min++;
+	}
+	return min;
+}
+
+/* Minimum baud rate possible.  */
+#define min_baud() \
+   ((NB85E_UART_BASE_FREQ >> NB85E_UART_CKSR_MAX) / (2 * 255) + 1)
+
+/* Maximum baud rate possible.  The error is quite high at max, though.  */
+#define max_baud() \
+   ((NB85E_UART_BASE_FREQ >> cksr_min()) / (2 * NB85E_UART_BRGC_MIN))
+
+
 /* Low-level UART functions.  */
 
 /* These masks define which control bits affect TX/RX modes, respectively.  */
@@ -60,7 +86,7 @@
    modes' bits in CFLAGS, and a baud-rate of BAUD.  */
 void nb85e_uart_configure (unsigned chan, unsigned cflags, unsigned baud)
 {
-	int cksr_min, flags;
+	int flags;
 	unsigned new_config = 0; /* What we'll write to the control reg. */
 	unsigned new_clk_divlog2; /* New baud-rate generate clock divider. */
 	unsigned new_brgen_count; /* New counter max for baud-rate generator.*/
@@ -68,14 +94,12 @@
 	unsigned old_config, old_clk_divlog2, old_brgen_count;
 
 	/* Calculate new baud-rate generator config values.  */
-	cksr_min = 0;
-	while ((NB85E_UART_BASE_FREQ >> cksr_min) > NB85E_UART_CKSR_MAX_FREQ)
-		cksr_min++;
+
 	/* Calculate the log2 clock divider and baud-rate counter values
 	   (note that the UART divides the resulting clock by 2, so
 	   multiply BAUD by 2 here to compensate).  */
 	calc_counter_params (NB85E_UART_BASE_FREQ, baud * 2,
-			     cksr_min, NB85E_UART_CKSR_MAX, 8/*bits*/,
+			     cksr_min(), NB85E_UART_CKSR_MAX, 8/*bits*/,
 			     &new_clk_divlog2, &new_brgen_count);
 
 	/* Figure out new configuration of control register.  */
@@ -443,10 +467,18 @@
 nb85e_uart_set_termios (struct uart_port *port, struct termios *termios,
 		        struct termios *old)
 {
-	/* FIXME: Which termios flags does this driver support? --rmk */
+	unsigned cflags = termios->c_cflag;
 
-	nb85e_uart_configure (port->line, termios->c_cflags,
-			uart_get_baud_rate(port, termios));
+	/* Restrict flags to legal values.  */
+	if ((cflags & CSIZE) != CS7 && (cflags & CSIZE) != CS8)
+		/* The new value of CSIZE is invalid, use the old value.  */
+		cflags = (cflags & ~CSIZE) | (old->c_cflag & CSIZE);
+
+	termios->c_cflag = cflags;
+
+	nb85e_uart_configure (port->line, cflags,
+			      uart_get_baud_rate (port, termios, old,
+						  min_baud(), max_baud()));
 }
 
 static const char *nb85e_uart_type (struct uart_port *port)
@@ -519,7 +551,6 @@
 		unsigned chan;
 
 		for (chan = 0; chan < NB85E_UART_NUM_CHANNELS; chan++) {
-			int cksr_min;
 			struct uart_port *port = &nb85e_uart_ports[chan];
 			
 			memset (port, 0, sizeof *port);
@@ -550,15 +581,13 @@
 			   the framework will puke during its internal
 			   calculations, and force the baud rate to be 9600.
 			   To be accurate though, just repeat the calculation
-			   we use when actually setting the speed.  */
-			cksr_min = 0;
-			while ((NB85E_UART_BASE_FREQ >> cksr_min)
-			       > NB85E_UART_CKSR_MAX_FREQ)
-				cksr_min++;
-			/* The `* 8' means `* 16 / 2':  16 to account for for
+			   we use when actually setting the speed.
+
+			   The `* 8' means `* 16 / 2':  16 to account for for
 			   the serial framework's built-in bias, and 2 because
 			   there's an additional / 2 in the hardware.  */
-			port->uartclk = (NB85E_UART_BASE_FREQ >> cksr_min) * 8;
+			port->uartclk =
+				(NB85E_UART_BASE_FREQ >> cksr_min()) * 8;
 
 			uart_add_one_port (&nb85e_uart_driver, port);
 		}
diff -Nru a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
--- a/drivers/usb/class/Kconfig	Mon Jan 13 21:59:49 2003
+++ b/drivers/usb/class/Kconfig	Mon Jan 13 21:59:49 2003
@@ -27,8 +27,8 @@
 	  device that can be used only by specialized Bluetooth HCI software.
 
 	  Say Y here if you want to use OpenBT Bluetooth stack (available
-	  at <http://developer.axis.com/software/index.shtml>), or other TTY
-	  based Bluetooth stacks, and want to connect a USB Bluetooth device
+	  at <http://developer.axis.com/software>), or other TTY based
+	  Bluetooth stacks, and want to connect a USB Bluetooth device
 	  to your computer's USB port.
 
 	  Do *not* enable this driver if you want to use generic Linux
diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
--- a/drivers/usb/class/audio.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/usb/class/audio.c	Mon Jan 13 21:59:51 2003
@@ -1420,7 +1420,7 @@
 		urb->number_of_packets = DESCFRAMES;
 		urb->context = as;
 		urb->complete = usbout_completed;
-		if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
+		if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
 			u->flags |= FLG_URB0RUNNING;
 		else
 			u->flags &= ~FLG_RUNNING;
@@ -1433,7 +1433,7 @@
 		urb->number_of_packets = DESCFRAMES;
 		urb->context = as;
 		urb->complete = usbout_completed;
-		if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
+		if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
 			u->flags |= FLG_URB1RUNNING;
 		else
 			u->flags &= ~FLG_RUNNING;
@@ -1448,7 +1448,7 @@
 			urb->context = as;
 			urb->complete = usbout_sync_completed;
 			/* stride: u->syncinterval */
-			if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
+			if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
 				u->flags |= FLG_SYNC0RUNNING;
 			else
 				u->flags &= ~FLG_RUNNING;
@@ -1462,7 +1462,7 @@
 			urb->context = as;
 			urb->complete = usbout_sync_completed;
 			/* stride: u->syncinterval */
-			if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
+			if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
 				u->flags |= FLG_SYNC1RUNNING;
 			else
 				u->flags &= ~FLG_RUNNING;
diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
--- a/drivers/usb/class/usb-midi.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/usb/class/usb-midi.c	Mon Jan 13 21:59:49 2003
@@ -337,7 +337,8 @@
     
 	if (status) {
 		printk(KERN_ERR "usbmidi: Cannot submit urb (%d)\n",status);
-		ret = -EFAULT;
+		ret = -EIO;
+		goto error;
 	}
 
 	add_wait_queue( &ep->wait, &wait );
@@ -354,6 +355,7 @@
 	set_current_state( TASK_RUNNING );
 	remove_wait_queue( &ep->wait, &wait );
 
+error:
 	return ret;
 }
 
@@ -369,7 +371,6 @@
 	struct midi_in_endpoint *ep = (struct midi_in_endpoint *)(urb->context);
 	unsigned char *data = urb->transfer_buffer;
 	int i, j, wake;
-	unsigned long int flags;
 
 	if ( !ep->urbSubmitted ) {
 		return;
@@ -377,7 +378,7 @@
 
 	if ( (urb->status == 0) && (urb->actual_length > 0) ) {
 		wake = 0;
-		spin_lock_irqsave( &ep->lock, flags );
+		spin_lock( &ep->lock );
 
 		for(j = 0; j < urb->actual_length; j += 4) {
 			int cin = (data[j]>>0)&0xf;
@@ -397,7 +398,7 @@
 			}
 		}
 
-		spin_unlock_irqrestore( &ep->lock, flags );
+		spin_unlock ( &ep->lock );
 		if ( wake ) {
 			wake_up( &ep->wait );
 		}
@@ -407,7 +408,7 @@
 	urb->dev = ep->usbdev;
 
 	urb->actual_length = 0;
-	usb_submit_urb(urb, GFP_KERNEL);
+	usb_submit_urb(urb, GFP_ATOMIC);
 }
 
 
@@ -855,7 +856,6 @@
 		add_wait_queue( &open_wait, &wait );
 		up(&open_sem);
 		schedule();
-		__set_current_state(TASK_RUNNING);
 		remove_wait_queue( &open_wait, &wait );
 		if ( signal_pending(current) ) {
 			return -ERESTARTSYS;
diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/usb/host/ehci-dbg.c	Mon Jan 13 21:59:51 2003
@@ -325,7 +325,7 @@
 }
 
 static ssize_t
-show_async (struct device *dev, char *buf, size_t count, loff_t off)
+show_async (struct device *dev, char *buf)
 {
 	struct pci_dev		*pdev;
 	struct ehci_hcd		*ehci;
@@ -334,13 +334,10 @@
 	char			*next;
 	struct ehci_qh		*qh;
 
-	if (off != 0)
-		return 0;
-
 	pdev = container_of (dev, struct pci_dev, dev);
 	ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd);
 	next = buf;
-	size = count;
+	size = PAGE_SIZE;
 
 	/* dumps a snapshot of the async schedule.
 	 * usually empty except for long-term bulk reads, or head.
@@ -358,14 +355,14 @@
 	}
 	spin_unlock_irqrestore (&ehci->lock, flags);
 
-	return count - size;
+	return PAGE_SIZE - size;
 }
 static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
 
 #define DBG_SCHED_LIMIT 64
 
 static ssize_t
-show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
+show_periodic (struct device *dev, char *buf)
 {
 	struct pci_dev		*pdev;
 	struct ehci_hcd		*ehci;
@@ -375,8 +372,6 @@
 	char			*next;
 	unsigned		i, tag;
 
-	if (off != 0)
-		return 0;
 	if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
 		return 0;
 	seen_count = 0;
@@ -384,7 +379,7 @@
 	pdev = container_of (dev, struct pci_dev, dev);
 	ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd);
 	next = buf;
-	size = count;
+	size = PAGE_SIZE;
 
 	temp = snprintf (next, size, "size = %d\n", ehci->periodic_size);
 	size -= temp;
@@ -468,14 +463,14 @@
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	kfree (seen);
 
-	return count - size;
+	return PAGE_SIZE - size;
 }
 static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL);
 
 #undef DBG_SCHED_LIMIT
 
 static ssize_t
-show_registers (struct device *dev, char *buf, size_t count, loff_t off)
+show_registers (struct device *dev, char *buf)
 {
 	struct pci_dev		*pdev;
 	struct ehci_hcd		*ehci;
@@ -485,14 +480,11 @@
 	static char		fmt [] = "%*s\n";
 	static char		label [] = "";
 
-	if (off != 0)
-		return 0;
-
 	pdev = container_of (dev, struct pci_dev, dev);
 	ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd);
 
 	next = buf;
-	size = count;
+	size = PAGE_SIZE;
 
 	spin_lock_irqsave (&ehci->lock, flags);
 
@@ -568,7 +560,7 @@
 
 	spin_unlock_irqrestore (&ehci->lock, flags);
 
-	return count - size;
+	return PAGE_SIZE - size;
 }
 static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
 
diff -Nru a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
--- a/drivers/usb/host/ohci-dbg.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/usb/host/ohci-dbg.c	Mon Jan 13 21:59:51 2003
@@ -9,7 +9,7 @@
  */
  
 /*-------------------------------------------------------------------------*/
- 
+
 #ifdef DEBUG
 
 #define edstring(ed_type) ({ char *temp; \
@@ -396,24 +396,21 @@
 }
 
 static ssize_t
-show_async (struct device *dev, char *buf, size_t count, loff_t off)
+show_async (struct device *dev, char *buf)
 {
 	struct ohci_hcd		*ohci;
 	size_t			temp;
 	unsigned long		flags;
 
-	if (off != 0)
-		return 0;
-
 	ohci = dev_to_ohci(dev);
 
 	/* display control and bulk lists together, for simplicity */
 	spin_lock_irqsave (&ohci->lock, flags);
-	temp = show_list (ohci, buf, count, ohci->ed_controltail);
-	count = show_list (ohci, buf + temp, count - temp, ohci->ed_bulktail);
+	temp = show_list (ohci, buf, PAGE_SIZE, ohci->ed_controltail);
+	temp += show_list (ohci, buf + temp, PAGE_SIZE - temp, ohci->ed_bulktail);
 	spin_unlock_irqrestore (&ohci->lock, flags);
 
-	return temp + count;
+	return temp;
 }
 static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
 
@@ -421,7 +418,7 @@
 #define DBG_SCHED_LIMIT 64
 
 static ssize_t
-show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
+show_periodic (struct device *dev, char *buf)
 {
 	struct ohci_hcd		*ohci;
 	struct ed		**seen, *ed;
@@ -430,15 +427,13 @@
 	char			*next;
 	unsigned		i;
 
-	if (off != 0)
-		return 0;
 	if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
 		return 0;
 	seen_count = 0;
 
 	ohci = dev_to_ohci(dev);
 	next = buf;
-	size = count;
+	size = PAGE_SIZE;
 
 	temp = snprintf (next, size, "size = %d\n", NUM_INTS);
 	size -= temp;
@@ -506,9 +501,10 @@
 	spin_unlock_irqrestore (&ohci->lock, flags);
 	kfree (seen);
 
-	return count - size;
+	return PAGE_SIZE - size;
 }
 static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL);
+
 
 #undef DBG_SCHED_LIMIT
 
diff -Nru a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
--- a/drivers/usb/input/xpad.c	Mon Jan 13 21:59:50 2003
+++ b/drivers/usb/input/xpad.c	Mon Jan 13 21:59:50 2003
@@ -200,8 +200,10 @@
 		return 0;
 	
 	xpad->irq_in->dev = xpad->udev;
-	if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
+	if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) {
+		xpad->open_count--;
 		return -EIO;
+	}
 	
 	return 0;
 }
diff -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c
--- a/drivers/usb/misc/speedtouch.c	Mon Jan 13 21:59:51 2003
+++ b/drivers/usb/misc/speedtouch.c	Mon Jan 13 21:59:51 2003
@@ -57,6 +57,7 @@
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 #include <linux/smp_lock.h>
+#include <linux/interrupt.h>
 
 #include <linux/atm.h>
 #include <linux/atmdev.h>
@@ -87,7 +88,6 @@
 #define SPEEDTOUCH_VENDORID		0x06b9
 #define SPEEDTOUCH_PRODUCTID		0x4061
 
-#define MAX_UDSL			1
 #define UDSL_OBUF_SIZE			32768
 #define UDSL_MINOR			48
 #define UDSL_NUMBER_RCV_URBS		1
@@ -137,33 +137,25 @@
  */
 
 struct udsl_instance_data {
-	int minor;
+	struct tasklet_struct recvqueue_tasklet;
 
 	/* usb device part */
 	struct usb_device *usb_dev;
 	struct udsl_data_ctx *rcvbufs;
 	struct sk_buff_head sndqueue;
-	spinlock_t sndqlock;
 	struct udsl_usb_send_data_context send_ctx[UDSL_NUMBER_SND_URBS];
 	int data_started;
 
 	/* atm device part */
 	struct atm_dev *atm_dev;
 	struct sk_buff_head recvqueue;
-	spinlock_t recvqlock;
 
 	struct atmsar_vcc_data *atmsar_vcc_list;
 };
 
-struct udsl_instance_data *minor_data[MAX_UDSL];
-
 static const char udsl_driver_name[] = "Alcatel SpeedTouch USB";
 
-/* data thread */
-DECLARE_WAIT_QUEUE_HEAD (udsl_wqh);
-static DECLARE_COMPLETION(thread_grave);
 static DECLARE_MUTEX(udsl_usb_ioctl_lock);
-static unsigned int datapid;
 
 #ifdef DEBUG_PACKET
 int udsl_print_packet (const unsigned char *data, int len);
@@ -178,7 +170,7 @@
 static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
 static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
 int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page);
-void udsl_atm_processqueue (struct udsl_instance_data *instance);
+void udsl_atm_processqueue (unsigned long data);
 
 static struct atmdev_ops udsl_atm_devops = {
 	.open =		udsl_atm_open,
@@ -244,19 +236,15 @@
 	struct atm_vcc *walk;
 	struct sk_buff *skb;
 	struct atm_dev *atm_dev;
-	unsigned long iflags;
+
 	if (!instance->atm_dev)
 		return;
 
 	atm_dev = instance->atm_dev;
 
 	/* clean queue */
-	spin_lock_irqsave (&instance->recvqlock, iflags);
-	while (!skb_queue_empty (&instance->recvqueue)) {
-		skb = skb_dequeue (&instance->recvqueue);
+	while ((skb = skb_dequeue (&instance->recvqueue)))
 		dev_kfree_skb (skb);
-	};
-	spin_unlock_irqrestore (&instance->recvqlock, iflags);
 
 	atm_dev->signal = ATM_PHY_SIG_LOST;
 	walk = atm_dev->vccs;
@@ -296,12 +284,13 @@
 
 int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page)
 {
-	struct udsl_instance_data *instance = (struct udsl_instance_data *) atm_dev->dev_data;
+	struct udsl_instance_data *instance = atm_dev->dev_data;
 	int left = *pos;
 
 	if (!left--)
-		return sprintf (page, "Speed Touch USB:%d (%02x:%02x:%02x:%02x:%02x:%02x)\n",
-				instance->minor, atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2],
+		return sprintf (page, "Speed Touch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+				instance->usb_dev->bus->bus_name, instance->usb_dev->devpath,
+				atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2],
 				atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]);
 
 	if (!left--)
@@ -330,8 +319,8 @@
 ****************************************************************************/
 int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
 {
-	struct udsl_atm_dev_data *dev_data = (struct udsl_atm_dev_data *) vcc->dev_data;
-	struct udsl_instance_data *instance = (struct udsl_instance_data *) vcc->dev->dev_data;
+	struct udsl_atm_dev_data *dev_data = vcc->dev_data;
+	struct udsl_instance_data *instance = vcc->dev->dev_data;
 	struct sk_buff *new = NULL;
 	int err;
 
@@ -372,25 +361,15 @@
 };
 
 
-void udsl_atm_processqueue (struct udsl_instance_data *instance)
+void udsl_atm_processqueue (unsigned long data)
 {
+	struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
 	struct atmsar_vcc_data *atmsar_vcc = NULL;
 	struct sk_buff *new = NULL, *skb = NULL, *tmp = NULL;
-	unsigned long iflags;
 
-	/* quick check */
-	spin_lock_irqsave (&instance->recvqlock, iflags);
-	if (skb_queue_empty (&instance->recvqueue)) {
-		spin_unlock_irqrestore (&instance->recvqlock, iflags);
-		return;
-	}
 	PDEBUG ("udsl_atm_processqueue entered\n");
 
-	while (!skb_queue_empty (&instance->recvqueue)) {
-		skb = skb_dequeue (&instance->recvqueue);
-
-		spin_unlock_irqrestore (&instance->recvqlock, iflags);
-
+	while ((skb = skb_dequeue (&instance->recvqueue))) {
 		PDEBUG ("skb = %p, skb->len = %d\n", skb, skb->len);
 		PACKETDEBUG (skb->data, skb->len);
 
@@ -430,73 +409,11 @@
 			}
 		};
 		dev_kfree_skb (skb);
-		spin_lock_irqsave (&instance->recvqlock, iflags);
 	};
 
-	spin_unlock_irqrestore (&instance->recvqlock, iflags);
 	PDEBUG ("udsl_atm_processqueue successfull\n");
 }
 
-int udsl_atm_processqueue_thread (void *data)
-{
-	int i = 0;
-	DECLARE_WAITQUEUE (wait, current);
-
-	lock_kernel ();
-	daemonize ();
-
-	/* Setup a nice name */
-	strcpy (current->comm, "kSpeedSARd");
-
-	add_wait_queue (&udsl_wqh, &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-
-	for (;;) {
-		schedule();
-		if (signal_pending (current))
-			break;
-		PDEBUG ("SpeedSARd awoke\n");
-retry:
-		for (i = 0; i < MAX_UDSL; i++)
-			if (minor_data[i])
-				udsl_atm_processqueue (minor_data[i]);
-		set_current_state(TASK_INTERRUPTIBLE);
-		/* we must check for data recieved and restart processing if there's any */
-		for (i = 0; i < MAX_UDSL; i++) {
-			spin_lock_irq(&minor_data[i]->recvqlock);
-			if (!skb_queue_empty(&minor_data[i]->recvqueue)) {
-				spin_unlock_irq(&minor_data[i]->recvqlock);
-				set_current_state(TASK_RUNNING);
-				goto retry;
-			} else {
-				spin_unlock_irq(&minor_data[i]->recvqlock);
-			}
-		}
-	};
-
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue (&udsl_wqh, &wait);
-	PDEBUG ("SpeedSARd is exiting\n");
-	complete_and_exit(&thread_grave, 0);
-	return 0; //never reached
-}
-
-
-void udsl_atm_sar_start (void)
-{
-	datapid = kernel_thread (udsl_atm_processqueue_thread, (void *) NULL,
-				 CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-}
-
-void udsl_atm_sar_stop (void)
-{
-	int ret;
-	/* Kill the thread */
-	ret = kill_proc (datapid, SIGTERM, 1);
-	if (!ret) {
-		wait_for_completion(&thread_grave);
-	}
-}
 
 /***************************************************************************
 *
@@ -506,7 +423,7 @@
 int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
 {
 	struct udsl_atm_dev_data *dev_data;
-	struct udsl_instance_data *instance = (struct udsl_instance_data *) vcc->dev->dev_data;
+	struct udsl_instance_data *instance = vcc->dev->dev_data;
 
 	PDEBUG ("udsl_atm_open called\n");
 
@@ -515,8 +432,7 @@
 		return -EINVAL;
 
 	MOD_INC_USE_COUNT;
-	dev_data =
-	    (struct udsl_atm_dev_data *) kmalloc (sizeof (struct udsl_atm_dev_data), GFP_KERNEL);
+	dev_data = kmalloc (sizeof (struct udsl_atm_dev_data), GFP_KERNEL);
 	if (!dev_data)
 		return -ENOMEM;
 
@@ -544,8 +460,8 @@
 
 void udsl_atm_close (struct atm_vcc *vcc)
 {
-	struct udsl_atm_dev_data *dev_data = (struct udsl_atm_dev_data *) vcc->dev_data;
-	struct udsl_instance_data *instance = (struct udsl_instance_data *) vcc->dev->dev_data;
+	struct udsl_atm_dev_data *dev_data = vcc->dev_data;
+	struct udsl_instance_data *instance = vcc->dev->dev_data;
 
 	PDEBUG ("udsl_atm_close called\n");
 
@@ -596,7 +512,7 @@
 
 static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
 {
-	struct udsl_usb_send_data_context *ctx = (struct udsl_usb_send_data_context *) urb->context;
+	struct udsl_usb_send_data_context *ctx = urb->context;
 	struct udsl_instance_data *instance = ctx->instance;
 	int err;
 
@@ -604,17 +520,12 @@
 		ctx->skb, urb->status);
 
 	ctx->vcc->pop (ctx->vcc, ctx->skb);
-	ctx->skb = NULL;
 
-	spin_lock (&instance->sndqlock);
-	if (skb_queue_empty (&instance->sndqueue)) {
-		spin_unlock (&instance->sndqlock);
+	if (!(ctx->skb = skb_dequeue (&(instance->sndqueue))))
 		return;
-	}
+
 	/* submit next skb */
-	ctx->skb = skb_dequeue (&(instance->sndqueue));
 	ctx->vcc = ((struct udsl_cb *) (ctx->skb->cb))->vcc;
-	spin_unlock (&instance->sndqlock);
 	usb_fill_bulk_urb (urb,
 		       instance->usb_dev,
 		       usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
@@ -661,13 +572,13 @@
 
 	PACKETDEBUG (skb->data, skb->len);
 
-	spin_lock_irqsave (&instance->sndqlock, flags);
+	spin_lock_irqsave (&instance->sndqueue.lock, flags);
 	((struct udsl_cb *) skb->cb)->vcc = vcc;
 
 	/* we are already queueing */
 	if (!skb_queue_empty (&instance->sndqueue)) {
-		skb_queue_tail (&instance->sndqueue, skb);
-		spin_unlock_irqrestore (&instance->sndqlock, flags);
+		__skb_queue_tail (&instance->sndqueue, skb);
+		spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
 		PDEBUG ("udsl_usb_send_data: already queing, skb (0x%p) queued\n", skb);
 		return 0;
 	}
@@ -678,8 +589,8 @@
 
 	/* we must start queueing */
 	if (i == UDSL_NUMBER_SND_URBS) {
-		skb_queue_tail (&instance->sndqueue, skb);
-		spin_unlock_irqrestore (&instance->sndqlock, flags);
+		__skb_queue_tail (&instance->sndqueue, skb);
+		spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
 		PDEBUG ("udsl_usb_send_data: skb (0x%p) queued\n", skb);
 		return 0;
 	};
@@ -690,7 +601,7 @@
 	instance->send_ctx[i].vcc = vcc;
 	instance->send_ctx[i].instance = instance;
 
-	spin_unlock_irqrestore (&instance->sndqlock, flags);
+	spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
 
 	/* submit packet */
 	usb_fill_bulk_urb (urb,
@@ -722,7 +633,7 @@
 	PDEBUG ("udsl_usb_receive_data entered, got packet %p with length %d an status %d\n", urb,
 		urb->actual_length, urb->status);
 
-	ctx = (struct udsl_data_ctx *) urb->context;
+	ctx = urb->context;
 	if (!ctx || !ctx->skb)
 		return;
 
@@ -736,10 +647,8 @@
 		skb_put (ctx->skb, urb->actual_length);
 
 		/* queue the skb for processing and wake the SAR */
-		spin_lock (&instance->recvqlock);
 		skb_queue_tail (&instance->recvqueue, ctx->skb);
-		spin_unlock (&instance->recvqlock);
-		wake_up (&udsl_wqh);
+		tasklet_schedule (&instance->recvqueue_tasklet);
 		/* get a new skb */
 		ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE);
 		if (!ctx->skb) {
@@ -781,9 +690,7 @@
 		usb_maxpacket (instance->usb_dev,
 			       usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), 0));
 
-	instance->rcvbufs =
-	    (struct udsl_data_ctx *) kmalloc (sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS,
-					      GFP_KERNEL);
+	instance->rcvbufs = kmalloc (sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS, GFP_KERNEL);
 	if (!instance->rcvbufs)
 		return -ENOMEM;
 
@@ -902,18 +809,8 @@
 
 static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data)
 {
-	struct usb_device *dev = interface_to_usbdev (intf);
-	struct udsl_instance_data *instance;
-	int i,retval;
-
-	for (i = 0; i < MAX_UDSL; i++)
-		if (minor_data[i] && (minor_data[i]->usb_dev == dev))
-			break;
-
-	if (i == MAX_UDSL)
-		return -EINVAL;
-
-	instance = minor_data[i];
+	struct udsl_instance_data *instance = usb_get_intfdata (intf);
+	int retval;
 
 	down(&udsl_usb_ioctl_lock);
 	switch (code) {
@@ -950,16 +847,7 @@
 
 	MOD_INC_USE_COUNT;
 
-	for (i = 0; i < MAX_UDSL; i++)
-		if (minor_data[i] == NULL)
-			break;
-
-	if (i >= MAX_UDSL) {
-		printk (KERN_INFO "No minor table space available for SpeedTouch USB\n");
-		return -ENOMEM;
-	};
-
-	PDEBUG ("Device Accepted, assigning minor %d\n", i);
+	PDEBUG ("Device Accepted\n");
 
 	/* device init */
 	instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL);
@@ -970,11 +858,9 @@
 
 	/* initialize structure */
 	memset (instance, 0, sizeof (struct udsl_instance_data));
-	instance->minor = i;
 	instance->usb_dev = dev;
 	instance->rcvbufs = NULL;
-	spin_lock_init (&instance->sndqlock);
-	spin_lock_init (&instance->recvqlock);
+	tasklet_init (&instance->recvqueue_tasklet, udsl_atm_processqueue, (unsigned long) instance);
 
 	udsl_atm_startdevice (instance, &udsl_atm_devops);
 
@@ -987,8 +873,6 @@
 		mac[5]);
 	udsl_atm_set_mac (instance, mac);
 
-	minor_data[instance->minor] = instance;
-
 	usb_set_intfdata (intf, instance);
 	return 0;
 }
@@ -996,11 +880,11 @@
 static void udsl_usb_disconnect (struct usb_interface *intf)
 {
 	struct udsl_instance_data *instance = usb_get_intfdata (intf);
-	int i;
+
+	PDEBUG ("disconnecting\n");
 
 	usb_set_intfdata (intf, NULL);
 	if (instance) {
-		i = instance->minor;
 		/* unlinking receive buffers */
 		udsl_usb_data_exit (instance);
 
@@ -1008,10 +892,7 @@
 		if (instance->atm_dev)
 			udsl_atm_stopdevice (instance);
 
-		PDEBUG ("disconnecting minor %d\n", i);
-
 		kfree (instance);
-		minor_data[i] = NULL;
 
 		MOD_DEC_USE_COUNT;
 	}
@@ -1025,23 +906,13 @@
 
 static int __init udsl_usb_init (void)
 {
-	int i;
-
 	PDEBUG ("Initializing SpeedTouch Driver Version " DRIVER_VERSION "\n");
 
-	for (i = 0; i < MAX_UDSL; i++)
-		minor_data[i] = NULL;
-
-	init_waitqueue_head (&udsl_wqh);
-	udsl_atm_sar_start ();
-
 	return usb_register (&udsl_usb_driver);
 }
 
 static void __exit udsl_usb_cleanup (void)
 {
-	/* killing threads */
-	udsl_atm_sar_stop ();
 	usb_deregister (&udsl_usb_driver);
 }
 
diff -Nru a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
--- a/drivers/usb/serial/digi_acceleport.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/usb/serial/digi_acceleport.c	Mon Jan 13 21:59:49 2003
@@ -507,7 +507,8 @@
 
 static struct usb_serial_device_type digi_acceleport_2_device = {
 	.owner =			THIS_MODULE,
-	.name =				"Digi USB",
+	.name =				"Digi 2 port USB adapter",
+	.short_name =			"digi_2",
 	.id_table =			id_table_2,
 	.num_interrupt_in =		0,
 	.num_bulk_in =			4,
@@ -531,7 +532,8 @@
 
 static struct usb_serial_device_type digi_acceleport_4_device = {
 	.owner =			THIS_MODULE,
-	.name =				"Digi USB",
+	.name =				"Digi 4 port USB adapter",
+	.short_name =			"digi_4",
 	.id_table =			id_table_4,
 	.num_interrupt_in =		0,
 	.num_bulk_in =			5,
diff -Nru a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/usb/serial/usb-serial.c	Mon Jan 13 21:59:49 2003
@@ -910,7 +910,7 @@
 			kfree (serial);
 			return -EIO;
 		}
-		retval = type->probe (serial, id);
+		retval = type->probe (serial, id_pattern);
 		module_put(type->owner);
 
 		if (retval < 0) {
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/usb/serial/visor.c	Mon Jan 13 21:59:49 2003
@@ -177,24 +177,40 @@
 static void visor_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);
 static void visor_read_int_callback	(struct urb *urb, struct pt_regs *regs);
 static int  clie_3_5_startup	(struct usb_serial *serial);
+static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id);
+static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id);
 
 
 static struct usb_device_id id_table [] = {
-	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
-	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
-	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
-	{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
-	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
-	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
-	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) },
-	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) },
-	{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
-	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
-	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) },
-	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
-	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },
+	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
+		.driver_info = (unsigned int)&palm_os_3_probe },
+	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
+	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
 	{ 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_NX60_ID),
+		.driver_info = (unsigned int)&palm_os_4_probe },
 	{ }					/* Terminating entry */
 };
 
@@ -600,99 +616,143 @@
 		dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);
 }
 
-static int visor_probe (struct usb_serial *serial, const struct usb_device_id *id)
+static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id)
 {
 	struct device *dev = &serial->dev->dev;
-	int response;
+	struct visor_connection_info *connection_info;
+	unsigned char *transfer_buffer;
+	char *string;
+	int retval = 0;
 	int i;
 	int num_ports;
-	unsigned char *transfer_buffer =  kmalloc (256, GFP_KERNEL);
 
+	dbg("%s", __FUNCTION__);
+
+	transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL);
 	if (!transfer_buffer) {
-		dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, 256);
+		dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__,
+			sizeof(*connection_info));
 		return -ENOMEM;
 	}
 
-	dbg("%s", __FUNCTION__);
-
-	dbg("%s - Set config to 1", __FUNCTION__);
-	usb_set_configuration (serial->dev, 1);
-
 	/* send a get connection info request */
-	response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_GET_CONNECTION_INFORMATION,
-					0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300);
-	if (response < 0) {
-		dev_err(dev, "%s - error getting connection information\n", __FUNCTION__);
-	} else {
-		struct visor_connection_info *connection_info = (struct visor_connection_info *)transfer_buffer;
-		char *string;
-
-		le16_to_cpus(&connection_info->num_ports);
-		num_ports = connection_info->num_ports;
-		dev_info(dev, "%s: Number of ports: %d\n", serial->type->name, connection_info->num_ports);
-		for (i = 0; i < num_ports; ++i) {
-			switch (connection_info->connections[i].port_function_id) {
-				case VISOR_FUNCTION_GENERIC:
-					string = "Generic";
-					break;
-				case VISOR_FUNCTION_DEBUGGER:
-					string = "Debugger";
-					break;
-				case VISOR_FUNCTION_HOTSYNC:
-					string = "HotSync";
-					break;
-				case VISOR_FUNCTION_CONSOLE:
-					string = "Console";
-					break;
-				case VISOR_FUNCTION_REMOTE_FILE_SYS:
-					string = "Remote File System";
-					break;
-				default:
-					string = "unknown";
-					break;	
-			}
-			dev_info(dev, "%s: port %d, is for %s use\n", serial->type->name,
-				 connection_info->connections[i].port, string);
-		/* save off our num_ports info so that we can use it in the calc_num_ports call */
-		usb_set_serial_data(serial, (void *)(long)num_ports);
-		}
+	retval = usb_control_msg (serial->dev,
+				  usb_rcvctrlpipe(serial->dev, 0),
+				  VISOR_GET_CONNECTION_INFORMATION,
+				  0xc2, 0x0000, 0x0000, transfer_buffer,
+				  sizeof(*connection_info), 300);
+	if (retval < 0) {
+		dev_err(dev, "%s - error %d getting connection information\n",
+			__FUNCTION__, retval);
+		goto exit;
 	}
+		
+	connection_info = (struct visor_connection_info *)transfer_buffer;
 
-	if ((serial->dev->descriptor.idVendor == PALM_VENDOR_ID) ||
-	    ((serial->dev->descriptor.idVendor == SONY_VENDOR_ID) &&
-	     (serial->dev->descriptor.idProduct != SONY_CLIE_4_1_ID))) {
-		/* Palm OS 4.0 Hack */
-		response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
-					    PALM_GET_SOME_UNKNOWN_INFORMATION,
-					    0xc2, 0x0000, 0x0000, transfer_buffer, 
-					    0x14, 300);
-		if (response < 0) {
-			dev_err(dev, "%s - error getting first unknown palm command\n", __FUNCTION__);
-		} else {
-			usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
-		}
-		response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
-					    PALM_GET_SOME_UNKNOWN_INFORMATION,
-					    0xc2, 0x0000, 0x0000, transfer_buffer, 
-					    0x14, 300);
-		if (response < 0) {
-			dev_err(dev, "%s - error getting second unknown palm command\n", __FUNCTION__);
-		} else {
-			usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
+	le16_to_cpus(&connection_info->num_ports);
+	num_ports = connection_info->num_ports;
+	/* handle devices that report invalid stuff here */
+	if (num_ports > 2)
+		num_ports = 2;
+	dev_info(dev, "%s: Number of ports: %d\n", serial->type->name,
+		connection_info->num_ports);
+
+	for (i = 0; i < num_ports; ++i) {
+		switch (connection_info->connections[i].port_function_id) {
+			case VISOR_FUNCTION_GENERIC:
+				string = "Generic";
+				break;
+			case VISOR_FUNCTION_DEBUGGER:
+				string = "Debugger";
+				break;
+			case VISOR_FUNCTION_HOTSYNC:
+				string = "HotSync";
+				break;
+			case VISOR_FUNCTION_CONSOLE:
+				string = "Console";
+				break;
+			case VISOR_FUNCTION_REMOTE_FILE_SYS:
+				string = "Remote File System";
+				break;
+			default:
+				string = "unknown";
+				break;	
 		}
+		dev_info(dev, "%s: port %d, is for %s use\n", serial->type->name,
+			 connection_info->connections[i].port, string);
 	}
 
+	/*
+	 * save off our num_ports info so that we can use it in the
+	 * calc_num_ports callback
+	 */
+	usb_set_serial_data(serial, (void *)(long)num_ports);
+
 	/* ask for the number of bytes available, but ignore the response as it is broken */
-	response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_REQUEST_BYTES_AVAILABLE,
-					0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300);
-	if (response < 0) {
-		dev_err(dev, "%s - error getting bytes available request\n", __FUNCTION__);
-	}
+	retval = usb_control_msg (serial->dev,
+				  usb_rcvctrlpipe(serial->dev, 0),
+				  VISOR_REQUEST_BYTES_AVAILABLE,
+				  0xc2, 0x0000, 0x0005, transfer_buffer,
+				  0x02, 300);
+	if (retval < 0)
+		dev_err(dev, "%s - error %d getting bytes available request\n",
+			__FUNCTION__, retval);
+	retval = 0;
 
+exit:
 	kfree (transfer_buffer);
 
-	/* continue on with initialization */
+	return retval;
+}
+
+static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id)
+{
+	struct device *dev = &serial->dev->dev;
+	struct palm_ext_connection_info *connection_info;
+	unsigned char *transfer_buffer;
+	int retval;
+
+	dbg("%s", __FUNCTION__);
+
+	transfer_buffer =  kmalloc (sizeof (*connection_info), GFP_KERNEL);
+	if (!transfer_buffer) {
+		dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__,
+			sizeof(*connection_info));
+		return -ENOMEM;
+	}
+
+	retval = usb_control_msg (serial->dev,
+				  usb_rcvctrlpipe(serial->dev, 0), 
+				  PALM_GET_EXT_CONNECTION_INFORMATION,
+				  0xc2, 0x0000, 0x0000, transfer_buffer,
+				  sizeof (*connection_info), 300);
+	if (retval < 0)
+		dev_err(dev, "%s - error %d getting connection info\n",
+			__FUNCTION__, retval);
+	else
+		usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
+
+	kfree (transfer_buffer);
 	return 0;
+}
+
+
+static int visor_probe (struct usb_serial *serial, const struct usb_device_id *id)
+{
+	int retval = 0;
+	int (*startup) (struct usb_serial *serial, const struct usb_device_id *id);
+
+	dbg("%s", __FUNCTION__);
+
+	dbg("%s - Set config to 1", __FUNCTION__);
+	usb_set_configuration (serial->dev, 1);
+
+	if (id->driver_info) {
+		startup = (void *)id->driver_info;
+		retval = startup(serial, id);
+	}
+
+	return retval;
 }
 
 static int visor_calc_num_ports (struct usb_serial *serial)
diff -Nru a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h
--- a/drivers/usb/serial/visor.h	Mon Jan 13 21:59:49 2003
+++ b/drivers/usb/serial/visor.h	Mon Jan 13 21:59:49 2003
@@ -94,7 +94,36 @@
  * PALM_GET_SOME_UNKNOWN_INFORMATION is sent by the host during enumeration to
  * get some information from the M series devices, that is currently unknown.
  ****************************************************************************/
-#define PALM_GET_SOME_UNKNOWN_INFORMATION	0x04
+#define PALM_GET_EXT_CONNECTION_INFORMATION	0x04
+
+/**
+ * struct palm_ext_connection_info - return data from a PALM_GET_EXT_CONNECTION_INFORMATION request
+ * @num_ports: maximum number of functions/connections in use
+ * @endpoint_numbers_different: will be 1 if in and out endpoints numbers are
+ *	different, otherwise it is 0.  If value is 1, then
+ *	connections.end_point_info is non-zero.  If value is 0, then
+ *	connections.port contains the endpoint number, which is the same for in
+ *	and out.
+ * @port_function_id: contains the creator id of the applicaton that opened
+ *	this connection.
+ * @port: contains the in/out endpoint number.  Is 0 if in and out endpoint
+ *	numbers are different.
+ * @end_point_info: high nubbe is in endpoint and low nibble will indicate out
+ *	endpoint.  Is 0 if in and out endpoints are the same.
+ *
+ * The maximum number of connections currently supported is 2
+ */
+struct palm_ext_connection_info {
+	__u8 num_ports;		
+	__u8 endpoint_numbers_different;
+	__u16 reserved1;
+	struct {
+		__u32 port_function_id;
+		__u8 port;
+		__u8 end_point_info;
+		__u16 reserved;
+	} connections[2];
+};
 
 #endif
 
diff -Nru a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c
--- a/drivers/usb/storage/debug.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/usb/storage/debug.c	Mon Jan 13 21:59:49 2003
@@ -49,6 +49,7 @@
 void usb_stor_show_command(Scsi_Cmnd *srb)
 {
 	char *what = NULL;
+	int i;
 
 	switch (srb->cmnd[0]) {
 	case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
@@ -143,29 +144,25 @@
 	default: what = "(unknown command)"; break;
 	}
 	US_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len);
-	US_DEBUGP("%02x %02x %02x %02x "
-		  "%02x %02x %02x %02x "
-		  "%02x %02x %02x %02x\n",
-		  srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3],
-		  srb->cmnd[4], srb->cmnd[5], srb->cmnd[6], srb->cmnd[7],
-		  srb->cmnd[8], srb->cmnd[9], srb->cmnd[10],
-		  srb->cmnd[11]);
+	US_DEBUGP("");
+	for (i = 0; i < srb->cmd_len && i < 16; i++)
+		US_DEBUGPX(" %02x", srb->cmnd[i]);
+	US_DEBUGPX("\n");
 }
 
-void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd )
+void usb_stor_print_Scsi_Cmnd(Scsi_Cmnd *cmd)
 {
 	int i=0, bufferSize = cmd->request_bufflen;
-	u8* buffer = cmd->request_buffer;
-	struct scatterlist* sg = (struct scatterlist*)cmd->request_buffer;
+	u8 *buffer = cmd->request_buffer;
+	struct scatterlist *sg = (struct scatterlist*)cmd->request_buffer;
 
-	US_DEBUGP("Dumping information about %p.\n", cmd );
-	US_DEBUGP("cmd->cmnd[0] value is %d.\n", cmd->cmnd[0] );
+	US_DEBUGP("Dumping information about %p.\n", cmd);
+	US_DEBUGP("cmd->cmnd[0] value is %d.\n", cmd->cmnd[0]);
 	US_DEBUGP("(MODE_SENSE is %d and MODE_SENSE_10 is %d)\n",
-		  MODE_SENSE, MODE_SENSE_10 );
+		  MODE_SENSE, MODE_SENSE_10);
 
-	US_DEBUGP("buffer is %p with length %d.\n", buffer, bufferSize );
-	for ( i=0; i<bufferSize; i+=16 )
-	{
+	US_DEBUGP("buffer is %p with length %d.\n", buffer, bufferSize);
+	for (i=0; i<bufferSize; i+=16) {
 		US_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x\n"
 			  "%02x %02x %02x %02x %02x %02x %02x %02x\n",
 			  buffer[i],
@@ -187,8 +184,7 @@
 	}
 
 	US_DEBUGP("Buffer has %d scatterlists.\n", cmd->use_sg );
-	for ( i=0; i<cmd->use_sg; i++ )
-	{
+	for (i=0; i<cmd->use_sg; i++) {
 		char *adr = sg_address(sg[i]);
 		
 		US_DEBUGP("Length of scatterlist %d is %d.\n",i,sg[i].length);
diff -Nru a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c	Mon Jan 13 21:59:49 2003
+++ b/drivers/usb/usb-skeleton.c	Mon Jan 13 21:59:49 2003
@@ -86,7 +86,7 @@
 #define USB_SKEL_MINOR_BASE	0
 #else
 /* Get a minor range for your devices from the usb maintainer */
-#define USB_SKEL_MINOR_BASE	200
+#define USB_SKEL_MINOR_BASE	192
 #endif
 
 /* Structure to hold all of our device specific stuff */
diff -Nru a/fs/Kconfig b/fs/Kconfig
--- a/fs/Kconfig	Mon Jan 13 21:59:50 2003
+++ b/fs/Kconfig	Mon Jan 13 21:59:50 2003
@@ -1339,6 +1339,30 @@
 	default m if NFS_FS!=y && NFSD!=y && (NFS_FS=m || NFSD=m)
 	default y if NFS_FS=y || NFSD=y
 
+config SUNRPC_GSS
+	tristate "Provide RPCSEC_GSS authentication (EXPERIMENTAL)"
+	depends on SUNRPC && EXPERIMENTAL
+	default SUNRPC if NFS_V4=y
+	help
+	  Provides cryptographic authentication for NFS rpc requests.  To
+	  make this useful, you must also select at least one rpcsec_gss
+	  mechanism.
+	  Note: You should always select this option if you wish to use
+	  NFSv4.
+
+config RPCSEC_GSS_KRB5
+	tristate "Kerberos V mechanism for RPCSEC_GSS (EXPERIMENTAL)"
+	depends on SUNRPC_GSS && CRYPTO_DES && CRYPTO_MD5
+	default SUNRPC_GSS if NFS_V4=y
+	help
+	  Provides a gss-api mechanism based on Kerberos V5 (this is
+	  mandatory for RFC3010-compliant NFSv4 implementations).
+	  Requires a userspace daemon;
+		see http://www.citi.umich.edu/projects/nfsv4/.
+
+	  Note: If you select this option, please ensure that you also
+	  enable the MD5 and DES crypto ciphers.
+
 config LOCKD
 	tristate
 	default m if NFS_FS!=y && NFSD!=y && (NFS_FS=m || NFSD=m)
diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c
--- a/fs/nfs/inode.c	Mon Jan 13 21:59:51 2003
+++ b/fs/nfs/inode.c	Mon Jan 13 21:59:51 2003
@@ -346,6 +346,7 @@
 	struct rpc_clnt		*clnt = NULL;
 	struct rpc_timeout	timeparms;
 	int			tcp, err = -EIO;
+	u32			authflavor;
 
 	server           = NFS_SB(sb);
 	sb->s_blocksize_bits = 0;
@@ -408,8 +409,14 @@
 		printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
 		goto out_fail;
 	}
+
+	if (data->flags & NFS_MOUNT_SECFLAVOUR)
+		authflavor = data->pseudoflavor;
+	else
+		authflavor = RPC_AUTH_UNIX;
+
 	clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
-				 server->rpc_ops->version, RPC_AUTH_UNIX);
+				 server->rpc_ops->version, authflavor);
 	if (clnt == NULL) {
 		printk(KERN_WARNING "NFS: cannot create RPC client.\n");
 		xprt_destroy(xprt);
diff -Nru a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
--- a/fs/nfsd/nfsproc.c	Mon Jan 13 21:59:49 2003
+++ b/fs/nfsd/nfsproc.c	Mon Jan 13 21:59:49 2003
@@ -482,7 +482,7 @@
 
 	resp->count = resp->buffer - argp->buffer;
 	if (resp->offset)
-		*resp->offset = (u32)offset;
+		*resp->offset = htonl(offset);
 
 	fh_put(&argp->fh);
 	return nfserr;
diff -Nru a/fs/proc/inode.c b/fs/proc/inode.c
--- a/fs/proc/inode.c	Mon Jan 13 21:59:51 2003
+++ b/fs/proc/inode.c	Mon Jan 13 21:59:51 2003
@@ -23,7 +23,7 @@
 
 extern void free_proc_entry(struct proc_dir_entry *);
 
-struct proc_dir_entry * de_get(struct proc_dir_entry *de)
+static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de)
 {
 	if (de)
 		atomic_inc(&de->count);
@@ -33,7 +33,7 @@
 /*
  * Decrements the use count and checks for deferred deletion.
  */
-void de_put(struct proc_dir_entry *de)
+static void de_put(struct proc_dir_entry *de)
 {
 	if (de) {	
 		lock_kernel();		
diff -Nru a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c
--- a/fs/reiserfs/hashes.c	Mon Jan 13 21:59:51 2003
+++ b/fs/reiserfs/hashes.c	Mon Jan 13 21:59:51 2003
@@ -19,8 +19,7 @@
 //
 
 #include <asm/types.h>
-#include <asm/page.h>
-
+#include <asm/bug.h>
 
 
 #define DELTA 0x9E3779B9
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	Mon Jan 13 21:59:49 2003
+++ b/fs/reiserfs/super.c	Mon Jan 13 21:59:49 2003
@@ -517,7 +517,7 @@
 
 /* possible values for "-o block-allocator=" and bits which are to be set in
    s_mount_opt of reiserfs specific part of in-core super block */
-const arg_desc_t balloc[] = {
+static const arg_desc_t balloc[] = {
     {"noborder", REISERFS_NO_BORDER},
     {"no_unhashed_relocation", REISERFS_NO_UNHASHED_RELOCATION},
     {"hashed_relocation", REISERFS_HASHED_RELOCATION},
@@ -525,7 +525,7 @@
     {NULL, -1}
 };
 
-const arg_desc_t tails[] = {
+static const arg_desc_t tails[] = {
     {"on", REISERFS_LARGETAIL},
     {"off", -1},
     {"small", REISERFS_SMALLTAIL},
diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c
--- a/fs/sysfs/inode.c	Mon Jan 13 21:59:51 2003
+++ b/fs/sysfs/inode.c	Mon Jan 13 21:59:51 2003
@@ -167,14 +167,15 @@
 }
 
 static ssize_t 
-subsys_attr_store(struct kobject * kobj, struct attribute * attr, const char * page)
+subsys_attr_store(struct kobject * kobj, struct attribute * attr, 
+		  const char * page, size_t count)
 {
 	struct subsystem * s = to_subsys(kobj);
 	struct subsys_attribute * sattr = to_sattr(attr);
 	ssize_t ret = 0;
 
 	if (sattr->store)
-		ret = sattr->store(s,page);
+		ret = sattr->store(s,page,count);
 	return ret;
 }
 
@@ -247,7 +248,7 @@
 	error = copy_to_user(buf,buffer->page + *ppos,count);
 	if (!error)
 		*ppos += count;
-	return error ? error : count;
+	return error ? -EFAULT : count;
 }
 
 /**
@@ -308,7 +309,7 @@
 	if (count >= PAGE_SIZE)
 		count = PAGE_SIZE - 1;
 	error = copy_from_user(buffer->page,buf,count);
-	return error ? error : count;
+	return error ? -EFAULT : count;
 }
 
 
@@ -322,13 +323,14 @@
  *	passing the buffer that we acquired in fill_write_buffer().
  */
 
-static int flush_write_buffer(struct file * file, struct sysfs_buffer * buffer)
+static int 
+flush_write_buffer(struct file * file, struct sysfs_buffer * buffer, size_t count)
 {
 	struct attribute * attr = file->f_dentry->d_fsdata;
 	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
 	struct sysfs_ops * ops = buffer->ops;
 
-	return ops->store(kobj,attr,buffer->page);
+	return ops->store(kobj,attr,buffer->page,count);
 }
 
 
@@ -356,7 +358,7 @@
 
 	count = fill_write_buffer(buffer,buf,count);
 	if (count > 0)
-		count = flush_write_buffer(file,buffer);
+		count = flush_write_buffer(file,buffer,count);
 	if (count > 0)
 		*ppos += count;
 	return count;
diff -Nru a/include/asm-alpha/bug.h b/include/asm-alpha/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-alpha/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,14 @@
+#ifndef _ALPHA_BUG_H
+#define _ALPHA_BUG_H
+
+#include <asm/pal.h>
+
+/* ??? Would be nice to use .gprel32 here, but we can't be sure that the
+   function loaded the GP, so this could fail in modules.  */
+#define BUG() \
+  __asm__ __volatile__("call_pal %0  # bugchk\n\t"".long %1\n\t.8byte %2" \
+		       : : "i" (PAL_bugchk), "i"(__LINE__), "i"(__FILE__))
+
+#define PAGE_BUG(page)	BUG()
+
+#endif
diff -Nru a/include/asm-alpha/page.h b/include/asm-alpha/page.h
--- a/include/asm-alpha/page.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-alpha/page.h	Mon Jan 13 21:59:51 2003
@@ -59,14 +59,6 @@
 
 #endif /* STRICT_MM_TYPECHECKS */
 
-/* ??? Would be nice to use .gprel32 here, but we can't be sure that the
-   function loaded the GP, so this could fail in modules.  */
-#define BUG() \
-  __asm__ __volatile__("call_pal %0  # bugchk\n\t"".long %1\n\t.8byte %2" \
-		       : : "i" (PAL_bugchk), "i"(__LINE__), "i"(__FILE__))
-
-#define PAGE_BUG(page)	BUG()
-
 /* Pure 2^n version of get_order */
 extern __inline__ int get_order(unsigned long size)
 {
diff -Nru a/include/asm-arm/bug.h b/include/asm-arm/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-arm/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,20 @@
+#ifndef _ASMARM_BUG_H
+#define _ASMARM_BUG_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+extern volatile void __bug(const char *file, int line, void *data);
+
+/* give file/line information */
+#define BUG()		__bug(__FILE__, __LINE__, NULL)
+#define PAGE_BUG(page)	__bug(__FILE__, __LINE__, page)
+
+#else
+
+/* these just cause an oops */
+#define BUG()		(*(int *)0 = 0)
+#define PAGE_BUG(page)	(*(int *)0 = 0)
+
+#endif
+
diff -Nru a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
--- a/include/asm-arm/dma-mapping.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-arm/dma-mapping.h	Mon Jan 13 21:59:49 2003
@@ -82,10 +82,8 @@
  * device-viewed address.
  */
 static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle)
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
 {
-	int gfp = GFP_ATOMIC;
-
 	if (dev == NULL || dmadev_is_sa1111(dev) || *dev->dma_mask != 0xffffffff)
 		gfp |= GFP_DMA;
 
diff -Nru a/include/asm-arm/page.h b/include/asm-arm/page.h
--- a/include/asm-arm/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-arm/page.h	Mon Jan 13 21:59:49 2003
@@ -160,21 +160,6 @@
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-extern void __bug(const char *file, int line, void *data);
-
-/* give file/line information */
-#define BUG()		__bug(__FILE__, __LINE__, NULL)
-#define PAGE_BUG(page)	__bug(__FILE__, __LINE__, page)
-
-#else
-
-/* these just cause an oops */
-#define BUG()		(*(int *)0 = 0)
-#define PAGE_BUG(page)	(*(int *)0 = 0)
-
-#endif
-
 /* Pure 2^n version of get_order */
 static inline int get_order(unsigned long size)
 {
diff -Nru a/include/asm-cris/bug.h b/include/asm-cris/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-cris/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,12 @@
+#ifndef _CRIS_BUG_H
+#define _CRIS_BUG_H
+
+#define BUG() do { \
+  printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+         BUG(); \
+} while (0)
+
+#endif
diff -Nru a/include/asm-cris/page.h b/include/asm-cris/page.h
--- a/include/asm-cris/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-cris/page.h	Mon Jan 13 21:59:49 2003
@@ -70,18 +70,6 @@
 #define PAGE_OFFSET		KSEG_C   /* kseg_c is mapped to physical ram */
 #endif
 
-#ifndef __ASSEMBLY__
-
-#define BUG() do { \
-  printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-} while (0)
-
-#define PAGE_BUG(page) do { \
-         BUG(); \
-} while (0)
-
-#endif /* __ASSEMBLY__ */
-
 /* macros to convert between really physical and virtual addresses
  * by stripping a selected bit, we can convert between KSEG_x and 0x40000000 where
  * the DRAM really resides
diff -Nru a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
--- a/include/asm-generic/dma-mapping.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-generic/dma-mapping.h	Mon Jan 13 21:59:51 2003
@@ -30,7 +30,8 @@
 }
 
 static inline void *
-dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle)
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		   int flag)
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
@@ -121,7 +122,7 @@
 
 /* Now for the API extensions over the pci_ one */
 
-#define dma_alloc_noncoherent(d, s, h) dma_alloc_coherent(d, s, h)
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
 #define dma_is_consistent(d)	(1)
 
diff -Nru a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h
--- a/include/asm-generic/pci-dma-compat.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-generic/pci-dma-compat.h	Mon Jan 13 21:59:49 2003
@@ -19,7 +19,7 @@
 pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 		     dma_addr_t *dma_handle)
 {
-	return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle);
+	return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle, GFP_ATOMIC);
 }
 
 static inline void
diff -Nru a/include/asm-i386/bug.h b/include/asm-i386/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,27 @@
+#ifndef _I386_BUG_H
+#define _I386_BUG_H
+
+#include <linux/config.h>
+
+/*
+ * Tell the user there is some problem. Beep too, so we can
+ * see^H^H^Hhear bugs in early bootup as well!
+ * The offending file and line are encoded after the "officially
+ * undefined" opcode for parsing in the trap handler.
+ */
+
+#if 1	/* Set to zero for a slightly smaller kernel */
+#define BUG()				\
+ __asm__ __volatile__(	"ud2\n"		\
+			"\t.word %c0\n"	\
+			"\t.long %c1\n"	\
+			 : : "i" (__LINE__), "i" (__FILE__))
+#else
+#define BUG() __asm__ __volatile__("ud2\n")
+#endif
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+#endif
diff -Nru a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h
--- a/include/asm-i386/dma-mapping.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-i386/dma-mapping.h	Mon Jan 13 21:59:51 2003
@@ -3,11 +3,11 @@
 
 #include <asm/cache.h>
 
-#define dma_alloc_noncoherent(d, s, h) dma_alloc_coherent(d, s, h)
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
-			   dma_addr_t *dma_handle);
+			   dma_addr_t *dma_handle, int flag);
 
 void dma_free_coherent(struct device *dev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle);
diff -Nru a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
--- a/include/asm-i386/hw_irq.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-i386/hw_irq.h	Mon Jan 13 21:59:51 2003
@@ -76,7 +76,6 @@
 {
 	unsigned long eip;
 	extern unsigned long prof_cpu_mask;
-	extern char _stext;
 #ifdef CONFIG_PROFILING
 	extern void x86_profile_hook(struct pt_regs *);
  
diff -Nru a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/mach-bigsmp/mach_apic.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,106 @@
+#ifndef __ASM_MACH_APIC_H
+#define __ASM_MACH_APIC_H
+
+#define SEQUENTIAL_APICID
+#ifdef SEQUENTIAL_APICID
+#define xapic_phys_to_log_apicid(phys_apic) ( (1ul << ((phys_apic) & 0x3)) |\
+		((phys_apic<<2) & (~0xf)) )
+#elif CLUSTERED_APICID
+#define xapic_phys_to_log_apicid(phys_apic) ( (1ul << ((phys_apic) & 0x3)) |\
+		((phys_apic) & (~0xf)) )
+#endif
+
+#define no_balance_irq (1)
+#define esr_disable (1)
+
+static inline int apic_id_registered(void)
+{
+	        return (1);
+}
+
+#define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
+#define TARGET_CPUS	((cpu_online_map < 0xf)?cpu_online_map:0xf)
+
+#define APIC_BROADCAST_ID     (0x0f)
+#define check_apicid_used(bitmap, apicid) (0)
+
+static inline unsigned long calculate_ldr(unsigned long old)
+{
+	unsigned long id;
+	id = xapic_phys_to_log_apicid(hard_smp_processor_id());
+	return ((old & ~APIC_LDR_MASK) | SET_APIC_LOGICAL_ID(id));
+}
+
+/*
+ * Set up the logical destination ID.
+ *
+ * Intel recommends to set DFR, LDR and TPR before enabling
+ * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116).  So here it goes...
+ */
+static inline void init_apic_ldr(void)
+{
+	unsigned long val;
+
+	apic_write_around(APIC_DFR, APIC_DFR_VALUE);
+	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+	val = calculate_ldr(val);
+	apic_write_around(APIC_LDR, val);
+}
+
+static inline void clustered_apic_check(void)
+{
+	printk("Enabling APIC mode:  %s.  Using %d I/O APICs\n",
+		"Cluster", nr_ioapics);
+}
+
+static inline int multi_timer_check(int apic, int irq)
+{
+	return 0;
+}
+
+static inline int apicid_to_node(int logical_apicid)
+{
+	return 0;
+}
+
+extern u8 raw_phys_apicid[];
+
+static inline int cpu_present_to_apicid(int mps_cpu)
+{
+	return (int) raw_phys_apicid[mps_cpu];
+}
+
+static inline unsigned long apicid_to_cpu_present(int phys_apicid)
+{
+	return (1ul << phys_apicid);
+}
+
+static inline int mpc_apic_id(struct mpc_config_processor *m, int quad)
+{
+	printk("Processor #%d %ld:%ld APIC version %d\n",
+	        m->mpc_apicid,
+	        (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
+	        (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
+	        m->mpc_apicver);
+	return (m->mpc_apicid);
+}
+
+static inline ulong ioapic_phys_id_map(ulong phys_map)
+{
+	/* For clustered we don't have a good way to do this yet - hack */
+	return (0x0F);
+}
+
+#define WAKE_SECONDARY_VIA_INIT
+
+static inline void setup_portio_remap(void)
+{
+}
+
+static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
+{
+	return (1);
+}
+
+#endif /* __ASM_MACH_APIC_H */
diff -Nru a/include/asm-i386/mach-bigsmp/mach_ipi.h b/include/asm-i386/mach-bigsmp/mach_ipi.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/mach-bigsmp/mach_ipi.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,24 @@
+#ifndef __ASM_MACH_IPI_H
+#define __ASM_MACH_IPI_H
+
+static inline void send_IPI_mask_sequence(int mask, int vector);
+
+static inline void send_IPI_mask(int mask, int vector)
+{
+	send_IPI_mask_sequence(mask, vector);
+}
+
+static inline void send_IPI_allbutself(int vector)
+{
+	unsigned long mask = cpu_online_map & ~(1 << smp_processor_id());
+
+	if (mask)
+		send_IPI_mask(mask, vector);
+}
+
+static inline void send_IPI_all(int vector)
+{
+	send_IPI_mask(cpu_online_map, vector);
+}
+
+#endif /* __ASM_MACH_IPI_H */
diff -Nru a/include/asm-i386/page.h b/include/asm-i386/page.h
--- a/include/asm-i386/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-i386/page.h	Mon Jan 13 21:59:49 2003
@@ -99,27 +99,6 @@
 
 #ifndef __ASSEMBLY__
 
-/*
- * Tell the user there is some problem. Beep too, so we can
- * see^H^H^Hhear bugs in early bootup as well!
- * The offending file and line are encoded after the "officially
- * undefined" opcode for parsing in the trap handler.
- */
-
-#if 1	/* Set to zero for a slightly smaller kernel */
-#define BUG()				\
- __asm__ __volatile__(	"ud2\n"		\
-			"\t.word %c0\n"	\
-			"\t.long %c1\n"	\
-			 : : "i" (__LINE__), "i" (__FILE__))
-#else
-#define BUG() __asm__ __volatile__("ud2\n")
-#endif
-
-#define PAGE_BUG(page) do { \
-	BUG(); \
-} while (0)
-
 /* Pure 2^n version of get_order */
 static __inline__ int get_order(unsigned long size)
 {
diff -Nru a/include/asm-i386/timer.h b/include/asm-i386/timer.h
--- a/include/asm-i386/timer.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-i386/timer.h	Mon Jan 13 21:59:49 2003
@@ -14,6 +14,7 @@
 	int (*init)(void);
 	void (*mark_offset)(void);
 	unsigned long (*get_offset)(void);
+	void (*delay)(unsigned long);
 };
 
 #define TICK_SIZE (tick_nsec / 1000)
diff -Nru a/include/asm-ia64/bug.h b/include/asm-ia64/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ia64/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,12 @@
+#ifndef _ASM_IA64_BUG_H
+#define _ASM_IA64_BUG_H
+
+#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+# define ia64_abort()	__builtin_trap()
+#else
+# define ia64_abort()	(*(volatile int *) 0 = 0)
+#endif
+#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0)
+#define PAGE_BUG(page) do { BUG(); } while (0)
+
+#endif
diff -Nru a/include/asm-ia64/page.h b/include/asm-ia64/page.h
--- a/include/asm-ia64/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-ia64/page.h	Mon Jan 13 21:59:49 2003
@@ -125,14 +125,6 @@
 # define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
 #endif
 
-#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
-# define ia64_abort()	__builtin_trap()
-#else
-# define ia64_abort()	(*(volatile int *) 0 = 0)
-#endif
-#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0)
-#define PAGE_BUG(page) do { BUG(); } while (0)
-
 static __inline__ int
 get_order (unsigned long size)
 {
diff -Nru a/include/asm-m68k/bug.h b/include/asm-m68k/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68k/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,28 @@
+#ifndef _M68K_BUG_H
+#define _M68K_BUG_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifndef CONFIG_SUN3
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	asm volatile("illegal"); \
+} while (0)
+#else
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	panic("BUG!"); \
+} while (0)
+#endif
+#else
+#define BUG() do { \
+	asm volatile("illegal"); \
+} while (0)
+#endif
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+#endif
diff -Nru a/include/asm-m68k/page.h b/include/asm-m68k/page.h
--- a/include/asm-m68k/page.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-m68k/page.h	Mon Jan 13 21:59:51 2003
@@ -178,28 +178,6 @@
 #define virt_addr_valid(kaddr)	((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
 #define pfn_valid(pfn)		virt_addr_valid(pfn_to_virt(pfn))
 
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-#ifndef CONFIG_SUN3
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	asm volatile("illegal"); \
-} while (0)
-#else
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	panic("BUG!"); \
-} while (0)
-#endif
-#else
-#define BUG() do { \
-	asm volatile("illegal"); \
-} while (0)
-#endif
-
-#define PAGE_BUG(page) do { \
-	BUG(); \
-} while (0)
-
 #endif /* __ASSEMBLY__ */
 
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
diff -Nru a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
--- a/include/asm-m68knommu/system.h	Mon Jan 13 21:59:50 2003
+++ b/include/asm-m68knommu/system.h	Mon Jan 13 21:59:50 2003
@@ -102,10 +102,12 @@
 #define smp_mb()	mb()
 #define smp_rmb()	rmb()
 #define smp_wmb()	wmb()
+#define smp_read_barrier_depends()	read_barrier_depends()
 #else
 #define smp_mb()	barrier()
 #define smp_rmb()	barrier()
 #define smp_wmb()	barrier()
+#define smp_read_barrier_depends()	do { } while(0)
 #endif
 
 #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
diff -Nru a/include/asm-mips/bug.h b/include/asm-mips/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-mips/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,8 @@
+/* $Id$ */
+#ifndef __ASM_BUG_H
+#define __ASM_BUG_H
+
+#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
+#define PAGE_BUG(page) do {  BUG(); } while (0)
+
+#endif
diff -Nru a/include/asm-mips/page.h b/include/asm-mips/page.h
--- a/include/asm-mips/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-mips/page.h	Mon Jan 13 21:59:49 2003
@@ -20,9 +20,6 @@
 
 #ifndef _LANGUAGE_ASSEMBLY
 
-#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
-#define PAGE_BUG(page) do {  BUG(); } while (0)
-
 extern void (*_clear_page)(void * page);
 extern void (*_copy_page)(void * to, void * from);
 
diff -Nru a/include/asm-mips64/bug.h b/include/asm-mips64/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-mips64/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,7 @@
+#ifndef _ASM_BUG_H
+#define _ASM_BUG_H
+
+#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
+#define PAGE_BUG(page) do {  BUG(); } while (0)
+
+#endif
diff -Nru a/include/asm-mips64/page.h b/include/asm-mips64/page.h
--- a/include/asm-mips64/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-mips64/page.h	Mon Jan 13 21:59:49 2003
@@ -20,9 +20,6 @@
 
 #ifndef _LANGUAGE_ASSEMBLY
 
-#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0)
-#define PAGE_BUG(page) do {  BUG(); } while (0)
-
 extern void (*_clear_page)(void * page);
 extern void (*_copy_page)(void * to, void * from);
 
diff -Nru a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h
--- a/include/asm-parisc/assembly.h	Mon Jan 13 21:59:50 2003
+++ b/include/asm-parisc/assembly.h	Mon Jan 13 21:59:50 2003
@@ -102,13 +102,19 @@
 	.endm
 
 #ifdef __LP64__
-#define LDREG   ldd
-#define STREG   std
+#define LDREG	ldd
+#define STREG	std
+#define LDREGM	ldd,mb
+#define STREGM	std,ma
 #define RP_OFFSET	16
+#define FRAME_SIZE	128
 #else
-#define LDREG   ldw
-#define STREG   stw
+#define LDREG	ldw
+#define STREG	stw
+#define LDREGM	ldwm
+#define STREGM	stwm
 #define RP_OFFSET	20
+#define FRAME_SIZE	64
 #endif
 
 	.macro loadgp
diff -Nru a/include/asm-parisc/bug.h b/include/asm-parisc/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-parisc/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,18 @@
+#ifndef _PARISC_BUG_H
+#define _PARISC_BUG_H
+
+/*
+ * Tell the user there is some problem. Beep too, so we can
+ * see^H^H^Hhear bugs in early bootup as well!
+ *
+ * We don't beep yet.  prumpf
+ */
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+#endif
diff -Nru a/include/asm-parisc/cache.h b/include/asm-parisc/cache.h
--- a/include/asm-parisc/cache.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/cache.h	Mon Jan 13 21:59:49 2003
@@ -18,8 +18,10 @@
  */
 #ifdef CONFIG_PA20
 #define L1_CACHE_BYTES 64
+#define L1_CACHE_SHIFT 6
 #else
 #define L1_CACHE_BYTES 32
+#define L1_CACHE_SHIFT 5
 #endif
 
 #define L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
diff -Nru a/include/asm-parisc/checksum.h b/include/asm-parisc/checksum.h
--- a/include/asm-parisc/checksum.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/checksum.h	Mon Jan 13 21:59:49 2003
@@ -32,7 +32,8 @@
 /*
  *	Optimized for IP headers, which always checksum on 4 octet boundaries.
  *
- *	Written by Randolph Chung <tausq@debian.org>
+ *	Written by Randolph Chung <tausq@debian.org>, and then mucked with by
+ *	LaMont Jones <lamont@debian.org>
  */
 static inline unsigned short ip_fast_csum(unsigned char * iph,
 					  unsigned int ihl) {
@@ -41,27 +42,23 @@
 
 	__asm__ __volatile__ (
 "	ldws,ma		4(%1), %0\n"
-"	addi		-4, %2, %2\n"
-"	comib,>=	0, %2, 2f\n"
+"	addib,<=	-4, %2, 2f\n"
 "\n"
-"	ldws,ma		4(%1), %%r19\n"
-"	add		%0, %%r19, %0\n"
-"	ldws,ma		4(%1), %%r19\n"
-"	addc		%0, %%r19, %0\n"
-"	ldws,ma		4(%1), %%r19\n"
+"	ldws		4(%1), %%r20\n"
+"	ldws		8(%1), %%r21\n"
+"	add		%0, %%r20, %0\n"
+"	ldws,ma		12(%1), %%r19\n"
+"	addc		%0, %%r21, %0\n"
 "	addc		%0, %%r19, %0\n"
 "1:	ldws,ma		4(%1), %%r19\n"
-"	addib,<>	-1, %2, 1b\n"
+"	addib,<		0, %2, 1b\n"
 "	addc		%0, %%r19, %0\n"
-"	addc		%0, %%r0, %0\n"
 "\n"
-"	zdepi		-1, 31, 16, %%r19\n"
-"	and		%0, %%r19, %%r20\n"
+"	extru		%0, 31, 16, %%r20\n"
 "	extru		%0, 15, 16, %%r21\n"
-"	add		%%r20, %%r21, %0\n"
-"	and		%0, %%r19, %%r20\n"
+"	addc		%%r20, %%r21, %0\n"
 "	extru		%0, 15, 16, %%r21\n"
-"	add		%%r20, %%r21, %0\n"
+"	add		%0, %%r21, %0\n"
 "	subi		-1, %0, %0\n"
 "2:\n"
 	: "=r" (sum), "=r" (iph), "=r" (ihl)
diff -Nru a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-parisc/compat.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,75 @@
+#ifndef _ASM_PARISC_COMPAT_H
+#define _ASM_PARISC_COMPAT_H
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+
+#define COMPAT_USER_HZ 100
+
+typedef u32	compat_size_t;
+typedef s32	compat_ssize_t;
+typedef s32	compat_time_t;
+typedef s32	compat_clock_t;
+typedef s32	compat_pid_t;
+typedef u32	compat_uid_t;
+typedef u32	compat_gid_t;
+typedef u16	compat_mode_t;
+typedef u32	compat_ino_t;
+typedef u32	compat_dev_t;
+typedef s32	compat_off_t;
+typedef u16	compat_nlink_t;
+typedef u16	compat_ipc_pid_t;
+typedef s32	compat_daddr_t;
+typedef u32	compat_caddr_t;
+
+struct compat_timespec {
+	compat_time_t		tv_sec;
+	s32			tv_nsec;
+};
+
+struct compat_timeval {
+	compat_time_t		tv_sec;
+	s32			tv_usec;
+};
+
+struct compat_stat {
+	compat_dev_t		st_dev;	/* dev_t is 32 bits on parisc */
+	compat_ino_t		st_ino;	/* 32 bits */
+	compat_mode_t		st_mode;	/* 16 bits */
+	compat_nlink_t  	st_nlink;	/* 16 bits */
+	u16			st_reserved1;	/* old st_uid */
+	u16			st_reserved2;	/* old st_gid */
+	compat_dev_t		st_rdev;
+	compat_off_t		st_size;
+	compat_time_t		st_atime;
+	u32			st_atime_nsec;
+	compat_time_t		st_mtime;
+	u32			st_mtime_nsec;
+	compat_time_t		st_ctime;
+	u32			st_ctime_nsec;
+	s32			st_blksize;
+	s32			st_blocks;
+	u32			__unused1;	/* ACL stuff */
+	compat_dev_t		__unused2;	/* network */
+	compat_ino_t		__unused3;	/* network */
+	u32			__unused4;	/* cnodes */
+	u16			__unused5;	/* netsite */
+	short			st_fstype;
+	compat_dev_t		st_realdev;
+	u16			st_basemode;
+	u16			st_spareshort;
+	compat_uid_t		st_uid;
+	compat_gid_t		st_gid;
+	u32			st_spare4[3];
+};
+
+struct compat_flock {
+	short			l_type;
+	short			l_whence;
+	compat_off_t		l_start;
+	compat_off_t		l_len;
+	compat_pid_t		l_pid;
+};
+
+#endif /* _ASM_PARISC_COMPAT_H */
diff -Nru a/include/asm-parisc/current.h b/include/asm-parisc/current.h
--- a/include/asm-parisc/current.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-parisc/current.h	Mon Jan 13 21:59:51 2003
@@ -1,7 +1,7 @@
 #ifndef _PARISC_CURRENT_H
 #define _PARISC_CURRENT_H
 
-#include <asm/thread_info.h>
+#include <linux/thread_info.h>
 
 struct task_struct;
 
diff -Nru a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-parisc/dma-mapping.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,228 @@
+#ifndef _PARISC_DMA_MAPPING_H
+#define _PARISC_DMA_MAPPING_H
+
+#include <linux/mm.h>
+#include <asm/cacheflush.h>
+
+/*
+** See Documentation/DMA-mapping.txt
+*/
+struct hppa_dma_ops {
+	int  (*dma_supported)(struct device *dev, u64 mask);
+	void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
+	void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, int flag);
+	void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova);
+	dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction);
+	void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction);
+	int  (*map_sg)(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction);
+	void (*unmap_sg)(struct device *dev, struct scatterlist *sg, int nhwents, enum dma_data_direction direction);
+	void (*dma_sync_single)(struct device *dev, dma_addr_t iova, unsigned long offset, size_t size, enum dma_data_direction direction);
+	void (*dma_sync_sg)(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction);
+};
+
+/*
+** We could live without the hppa_dma_ops indirection if we didn't want
+** to support 4 different coherent dma models with one binary (they will
+** someday be loadable modules):
+**     I/O MMU        consistent method           dma_sync behavior
+**  =============   ======================       =======================
+**  a) PA-7x00LC    uncachable host memory          flush/purge
+**  b) U2/Uturn      cachable host memory              NOP
+**  c) Ike/Astro     cachable host memory              NOP
+**  d) EPIC/SAGA     memory on EPIC/SAGA         flush/reset DMA channel
+**
+** PA-7[13]00LC processors have a GSC bus interface and no I/O MMU.
+**
+** Systems (eg PCX-T workstations) that don't fall into the above
+** categories will need to modify the needed drivers to perform
+** flush/purge and allocate "regular" cacheable pages for everything.
+*/
+
+#ifdef CONFIG_PA11
+extern struct hppa_dma_ops pcxl_dma_ops;
+extern struct hppa_dma_ops pcx_dma_ops;
+#endif
+
+extern struct hppa_dma_ops *hppa_dma_ops;
+
+static inline void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		   int flag)
+{
+	return hppa_dma_ops->alloc_consistent(dev, size, dma_handle, flag);
+}
+
+static inline void *
+dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		      int flag)
+{
+	return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle, flag);
+}
+
+static inline void
+dma_free_coherent(struct device *dev, size_t size, 
+		    void *vaddr, dma_addr_t dma_handle)
+{
+	hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
+}
+
+static inline void
+dma_free_noncoherent(struct device *dev, size_t size, 
+		    void *vaddr, dma_addr_t dma_handle)
+{
+	hppa_dma_ops->free_consistent(dev, size, vaddr, dma_handle);
+}
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+	       enum dma_data_direction direction)
+{
+	return hppa_dma_ops->map_single(dev, ptr, size, direction);
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		 enum dma_data_direction direction)
+{
+	hppa_dma_ops->unmap_single(dev, dma_addr, size, direction);
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	   enum dma_data_direction direction)
+{
+	return hppa_dma_ops->map_sg(dev, sg, nents, direction);
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	     enum dma_data_direction direction)
+{
+	hppa_dma_ops->unmap_sg(dev, sg, nhwentries, direction);
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+	     size_t size, enum dma_data_direction direction)
+{
+	return dma_map_single(dev, (page_address(page) + (offset)), size, direction);
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	       enum dma_data_direction direction)
+{
+	dma_unmap_single(dev, dma_address, size, direction);
+}
+
+
+static inline void
+dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
+		enum dma_data_direction direction)
+{
+	if(hppa_dma_ops->dma_sync_single)
+		hppa_dma_ops->dma_sync_single(dev, dma_handle, 0, size, direction);
+}
+
+static inline void
+dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
+		      unsigned long offset, size_t size,
+		      enum dma_data_direction direction)
+{
+	if(hppa_dma_ops->dma_sync_single)
+		hppa_dma_ops->dma_sync_single(dev, dma_handle, offset, size, direction);
+}
+
+static inline void
+dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
+		 enum dma_data_direction direction)
+{
+	if(hppa_dma_ops->dma_sync_sg)
+		hppa_dma_ops->dma_sync_sg(dev, sg, nelems, direction);
+}
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+	return hppa_dma_ops->dma_supported(dev, mask);
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+	if(!dev->dma_mask || !dma_supported(dev, mask))
+		return -EIO;
+
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
+static inline int
+dma_get_cache_alignment(void)
+{
+	return dcache_stride;
+}
+
+static inline int
+dma_is_consistent(dma_addr_t dma_addr)
+{
+	return (hppa_dma_ops->dma_sync_single == NULL);
+}
+
+static inline void
+dma_cache_sync(void *vaddr, size_t size,
+	       enum dma_data_direction direction)
+{
+	if(hppa_dma_ops->dma_sync_single)
+		flush_kernel_dcache_range((unsigned long)vaddr, size);
+}
+
+static inline void *
+parisc_walk_tree(struct device *dev)
+{
+	struct device *otherdev;
+	if(likely(dev->platform_data != NULL))
+		return dev->platform_data;
+	/* OK, just traverse the bus to find it */
+	for(otherdev = dev->parent; otherdev;
+	    otherdev = otherdev->parent) {
+		if(otherdev->platform_data) {
+			dev->platform_data = otherdev->platform_data;
+			break;
+		}
+	}
+	BUG_ON(!dev->platform_data);
+	return dev->platform_data;
+}
+		
+#define GET_IOC(dev) (HBA_DATA(parisc_walk_tree(dev))->iommu);	
+	
+
+#ifdef CONFIG_IOMMU_CCIO
+struct parisc_device;
+struct ioc;
+void * ccio_get_iommu(const struct parisc_device *dev);
+struct pci_dev * ccio_get_fake(const struct parisc_device *dev);
+int ccio_request_resource(const struct parisc_device *dev,
+		struct resource *res);
+int ccio_allocate_resource(const struct parisc_device *dev,
+		struct resource *res, unsigned long size,
+		unsigned long min, unsigned long max, unsigned long align,
+		void (*alignf)(void *, struct resource *, unsigned long, unsigned long),
+		void *alignf_data);
+#else /* !CONFIG_IOMMU_CCIO */
+#define ccio_get_iommu(dev) NULL
+#define ccio_get_fake(dev) NULL
+#define ccio_request_resource(dev, res) request_resource(&iomem_resource, res)
+#define ccio_allocate_resource(dev, res, size, min, max, align, alignf, data) \
+		allocate_resource(&iomem_resource, res, size, min, max, \
+				align, alignf, data)
+#endif /* !CONFIG_IOMMU_CCIO */
+
+#ifdef CONFIG_IOMMU_SBA
+struct parisc_device;
+void * sba_get_iommu(struct parisc_device *dev);
+#endif
+
+#endif
diff -Nru a/include/asm-parisc/dma.h b/include/asm-parisc/dma.h
--- a/include/asm-parisc/dma.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-parisc/dma.h	Mon Jan 13 21:59:51 2003
@@ -30,7 +30,6 @@
 */
 #define MAX_DMA_ADDRESS (~0UL)
 
-
 /*
 ** We don't have DMA channels... well V-class does but the
 ** Dynamic DMA Mapping interface will support them... right? :^)
@@ -129,6 +128,9 @@
 		dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
 #endif
 }
+
+/* reserve a DMA channel */
+#define request_dma(dmanr, device_id)	(0)
 
 /* Clear the 'DMA Pointer Flip Flop'.
  * Write 0 for LSB/MSB, 1 for MSB/LSB access.
diff -Nru a/include/asm-parisc/hardware.h b/include/asm-parisc/hardware.h
--- a/include/asm-parisc/hardware.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-parisc/hardware.h	Mon Jan 13 21:59:51 2003
@@ -23,31 +23,7 @@
 	const char	name[80];	/* The hardware description */
 };
 
-struct parisc_device {
-	unsigned long   hpa;		/* Hard Physical Address */
-	struct parisc_device_id id;
-	struct parisc_device *parent;
-	struct parisc_device *sibling;
-	struct parisc_device *child;
-	struct parisc_driver *driver;	/* Driver for this device */
-	void		*sysdata;	/* Driver instance private data */
-	char		name[80];	/* The hardware description */
-	int		irq;
-
-	char		hw_path;        /* The module number on this bus */
-	unsigned int	num_addrs;	/* some devices have additional address ranges. */
-	unsigned long	*addr;          /* which will be stored here */
- 
-#ifdef __LP64__
-	/* parms for pdc_pat_cell_module() call */
-	unsigned long	pcell_loc;	/* Physical Cell location */
-	unsigned long	mod_index;	/* PAT specific - Misc Module info */
-
-	/* generic info returned from pdc_pat_cell_module() */
-	unsigned long	mod_info;	/* PAT specific - Misc Module info */
-	unsigned long	pmod_loc;	/* physical Module location */
-#endif
-};
+struct parisc_device;
 
 enum cpu_type {
 	pcx	= 0, /* pa7000		pa 1.0  */
@@ -65,12 +41,7 @@
 
 extern char *cpu_name_version[][2]; /* mapping from enum cpu_type to strings */
 
-struct parisc_driver {
-	struct parisc_driver *next;
-	char *name; 
-	const struct parisc_device_id *id_table;
-	int (*probe) (struct parisc_device *dev); /* New device discovered */
-};
+struct parisc_driver;
 
 struct io_module {
         volatile uint32_t nothing;		/* reg 0 */
diff -Nru a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h
--- a/include/asm-parisc/ide.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/ide.h	Mon Jan 13 21:59:49 2003
@@ -84,13 +84,6 @@
 #define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
 #define ide_release_region(from,extent)		release_region((from), (extent))
 
-/*
- * The following are not needed for the non-m68k ports
- */
-#define ide_ack_intr(hwif)		(1)
-#define ide_release_lock(lock)		do {} while (0)
-#define ide_get_lock(lock, hdlr, data)	do {} while (0)
-
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_PARISC_IDE_H */
diff -Nru a/include/asm-parisc/io.h b/include/asm-parisc/io.h
--- a/include/asm-parisc/io.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/io.h	Mon Jan 13 21:59:49 2003
@@ -37,7 +37,7 @@
  * it's useful if some control registers are in such an area and write combining
  * or read caching is not desirable:
  */
-extern inline void * ioremap_nocache (unsigned long offset, unsigned long size)
+extern inline void * ioremap_nocache(unsigned long offset, unsigned long size)
 {
         return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */);
 }
@@ -49,7 +49,8 @@
  * too lazy to ioremap first'.  kind of like isa_, except that there's
  * no additional base address to add on.
  */
-extern __inline__ unsigned char __raw_readb(unsigned long addr)
+#define __raw_readb(a) ___raw_readb((unsigned long)(a))
+extern __inline__ unsigned char ___raw_readb(unsigned long addr)
 {
 	long flags;
 	unsigned char ret;
@@ -63,7 +64,8 @@
 	return ret;
 }
 
-extern __inline__ unsigned short __raw_readw(unsigned long addr)
+#define __raw_readw(a) ___raw_readw((unsigned long)(a))
+extern __inline__ unsigned short ___raw_readw(unsigned long addr)
 {
 	long flags;
 	unsigned short ret;
@@ -77,7 +79,8 @@
 	return ret;
 }
 
-extern __inline__ unsigned int __raw_readl(unsigned long addr)
+#define __raw_readl(a) ___raw_readl((unsigned long)(a))
+extern __inline__ unsigned int ___raw_readl(unsigned long addr)
 {
 	u32 ret;
 
@@ -88,7 +91,8 @@
 	return ret;
 }
 
-extern __inline__ unsigned long long __raw_readq(unsigned long addr)
+#define __raw_readq(a) ___raw_readq((unsigned long)(a))
+extern __inline__ unsigned long long ___raw_readq(unsigned long addr)
 {
 	unsigned long long ret;
 #ifdef __LP64__
@@ -103,7 +107,8 @@
 	return ret;
 }
 
-extern __inline__ void __raw_writeb(unsigned char val, unsigned long addr)
+#define __raw_writeb(a,b) ___raw_writeb(a, (unsigned long)(b))
+extern __inline__ void ___raw_writeb(unsigned char val, unsigned long addr)
 {
 	long flags;
 	__asm__ __volatile__(
@@ -113,7 +118,8 @@
 	: "=&r" (flags) :  "r" (val), "r" (addr) );
 }
 
-extern __inline__ void __raw_writew(unsigned short val, unsigned long addr)
+#define __raw_writew(a,b) ___raw_writew(a, (unsigned long)(b))
+extern __inline__ void ___raw_writew(unsigned short val, unsigned long addr)
 {
 	long flags;
 	__asm__ __volatile__(
@@ -123,14 +129,16 @@
 	: "=&r" (flags) :  "r" (val), "r" (addr) );
 }
 
-extern __inline__ void __raw_writel(unsigned int val, unsigned long addr)
+#define __raw_writel(a,b) ___raw_writel(a, (unsigned long)(b))
+extern __inline__ void ___raw_writel(unsigned int val, unsigned long addr)
 {
 	__asm__ __volatile__(
 	"	stwas	%0,0(%1)\n"
 	: :  "r" (val), "r" (addr) );
 }
 
-extern __inline__ void __raw_writeq(unsigned long long val, unsigned long addr)
+#define __raw_writeq(a,b) ___raw_writeq(a, (unsigned long)(b))
+extern __inline__ void ___raw_writeq(unsigned long long val, unsigned long addr)
 {
 #ifdef __LP64__
 	__asm__ __volatile__(
@@ -153,19 +161,23 @@
 #define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
 #define writeq(b,addr) (*(volatile u64 *) (addr) = (b))
 #else /* !USE_HPPA_IOREMAP */
-#define readb(addr) __raw_readb((unsigned long)(addr))
-#define readw(addr) le16_to_cpu(__raw_readw((unsigned long)(addr)))
-#define readl(addr) le32_to_cpu(__raw_readl((unsigned long)(addr)))
-#define readq(addr) le64_to_cpu(__raw_readq((unsigned long)(addr)))
-#define writeb(b,addr) __raw_writeb(b,(unsigned long)(addr))
-#define writew(b,addr) __raw_writew(cpu_to_le16(b),(unsigned long)(addr))
-#define writel(b,addr) __raw_writel(cpu_to_le32(b),(unsigned long)(addr))
-#define writeq(b,addr) __raw_writeq(cpu_to_le64(b),(unsigned long)(addr))
+#define readb(addr) __raw_readb(addr)
+#define readw(addr) le16_to_cpu(__raw_readw(addr))
+#define readl(addr) le32_to_cpu(__raw_readl(addr))
+#define readq(addr) le64_to_cpu(__raw_readq(addr))
+#define writeb(b,addr) __raw_writeb(b,addr)
+#define writew(b,addr) __raw_writew(cpu_to_le16(b),addr)
+#define writel(b,addr) __raw_writel(cpu_to_le32(b),addr)
+#define writeq(b,addr) __raw_writeq(cpu_to_le64(b),addr)
 #endif /* !USE_HPPA_IOREMAP */
 
-extern void memcpy_fromio(void *dest, unsigned long src, int count);
-extern void memcpy_toio(unsigned long dest, const void *src, int count);
-extern void memset_io(unsigned long dest, char fill, int count);
+extern void __memcpy_fromio(unsigned long dest, unsigned long src, int count);
+extern void __memcpy_toio(unsigned long dest, unsigned long src, int count);
+extern void __memset_io(unsigned long dest, char fill, int count);
+
+#define memcpy_fromio(a,b,c) __memcpy_fromio((unsigned long)(a), (unsigned long)(b), (c))
+#define memcpy_toio(a,b,c)   __memcpy_toio((unsigned long)(a), (unsigned long)(b), (c))
+#define memset_io(a,b,c)     __memset_io((unsigned long)(a), (b), (c))
 
 /* Support old drivers which don't ioremap.
  * NB this interface is scheduled to disappear in 2.5
@@ -186,12 +198,12 @@
  * These functions support PA-RISC drivers which don't yet call ioremap().
  * They will disappear once the last of these drivers is gone.
  */
-#define gsc_readb(x) __raw_readb((unsigned long)x)
-#define gsc_readw(x) __raw_readw((unsigned long)x)
-#define gsc_readl(x) __raw_readl((unsigned long)x)
-#define gsc_writeb(x, y) __raw_writeb(x, (unsigned long)y)
-#define gsc_writew(x, y) __raw_writew(x, (unsigned long)y)
-#define gsc_writel(x, y) __raw_writel(x, (unsigned long)y)
+#define gsc_readb(x) __raw_readb(x)
+#define gsc_readw(x) __raw_readw(x)
+#define gsc_readl(x) __raw_readl(x)
+#define gsc_writeb(x, y) __raw_writeb(x, y)
+#define gsc_writew(x, y) __raw_writew(x, y)
+#define gsc_writel(x, y) __raw_writel(x, y)
 
 
 /*
@@ -275,7 +287,7 @@
 #define IO_SPACE_LIMIT 0x00ffffff
 
 
-#define dma_cache_inv(_start,_size)		do { flush_kernel_dcache_range(_start,_size); } while(0)
+#define dma_cache_inv(_start,_size)		do { flush_kernel_dcache_range(_start,_size); } while (0)
 #define dma_cache_wback(_start,_size)		do { flush_kernel_dcache_range(_start,_size); } while (0)
 #define dma_cache_wback_inv(_start,_size)	do { flush_kernel_dcache_range(_start,_size); } while (0)
 
diff -Nru a/include/asm-parisc/irq.h b/include/asm-parisc/irq.h
--- a/include/asm-parisc/irq.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/irq.h	Mon Jan 13 21:59:49 2003
@@ -13,6 +13,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/types.h>
+#include <asm/errno.h>
 
 #include <linux/string.h>
 #include <linux/interrupt.h>
@@ -93,5 +94,22 @@
 
 /* soft power switch support (power.c) */
 extern struct tasklet_struct power_tasklet;
+
+struct notifier_block;
+
+#ifdef CONFIG_PROFILING
+int register_profile_notifier(struct notifier_block *nb);
+int unregister_profile_notifier(struct notifier_block *nb);
+#else
+static inline int register_profile_notifier(struct notifier_block *nb)
+{
+    return -ENOSYS;
+}
+
+static inline int unregister_profile_notifier(struct notifier_block *nb)
+{
+    return -ENOSYS;
+}
+#endif
 
 #endif	/* _ASM_PARISC_IRQ_H */
diff -Nru a/include/asm-parisc/keyboard.h b/include/asm-parisc/keyboard.h
--- a/include/asm-parisc/keyboard.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/keyboard.h	Mon Jan 13 21:59:49 2003
@@ -28,7 +28,6 @@
 #include <linux/config.h>
 
 #ifdef __KERNEL__
-#ifdef CONFIG_VT
 
 #include <linux/kernel.h>
 #include <linux/kd.h>
@@ -56,18 +55,11 @@
 	void (*init_hw)(void);
 
 	/* Keyboard driver resource allocation  */
-	void (*kbd_request_region)(void);
 	int (*kbd_request_irq)(void (*handler)(int, void *, struct pt_regs *));
 
-	/* Methods to access the keyboard processor's I/O registers  */
-	unsigned char (*kbd_read_input)(void);
-	void (*kbd_write_output)(unsigned char val);
-	void (*kbd_write_command)(unsigned char val);
-	unsigned char (*kbd_read_status)(void);
-
 	unsigned char sysrq_key;
 	unsigned char *sysrq_xlate;
-} *kbd_ops;
+} kbd_ops;
 
 #define kbd_setkeycode		(*kbd_ops->setkeycode)
 #define kbd_getkeycode		(*kbd_ops->getkeycode)
@@ -80,19 +72,12 @@
 #define	kbd_sysrq_xlate		(kbd_ops->sysrq_xlate)
 
 /* Do the actual calls via kbd_ops vector  */
-#define kbd_request_region() 	kbd_ops->kbd_request_region()
 #define kbd_request_irq(handler) kbd_ops->kbd_request_irq(handler)
-#define kbd_read_input() 	kbd_ops->kbd_read_input()
-#define kbd_write_output(val) 	kbd_ops->kbd_write_output(val)
-#define kbd_write_command(val) 	kbd_ops->kbd_write_command(val)
-#define kbd_read_status() 	kbd_ops->kbd_read_status()
 
 extern unsigned char hp_ps2kbd_sysrq_xlate[128]; 	/* from drivers/char/hp_keyb.c */
 
 extern void unregister_kbd_ops(void);
 extern void register_kbd_ops(struct kbd_ops *ops);
-
-#endif /* CONFIG_VT */
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-parisc/linux_logo.h b/include/asm-parisc/linux_logo.h
--- a/include/asm-parisc/linux_logo.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/linux_logo.h	Mon Jan 13 21:59:49 2003
@@ -1,27 +1,1438 @@
-/* $Id: linux_logo.h,v 1.1.1.1 1999/03/15 19:41:01 pjlahaie Exp $
- * include/asm-parisc/linux_logo.h: This is a linux logo
- *                                to be displayed on boot.
+/* linux_logo.h created with fblogo, 2002/12/21 04:44:04
+ * include/linux/linux_logo.h: This is a linux logo
+ *                             to be displayed on boot.
  *
  * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ *
+ * You can put anything here, but:
+ * LINUX_LOGO_COLORS has to be less than 224
+ * Generated by fblogo version 0.5.0
+ *
+ *
+ * Remember to modify drivers/video/fbcon.c:
+ * Change "#define LOGO_H 80" to "#define LOGO_H 80"
+ * Change "#define LOGO_W 80" to "#define LOGO_W 80"
  *
  * You can put anything here, but:
  * LINUX_LOGO_COLORS has to be less than 224
  * image size has to be 80x80
  * values have to start from 0x20
  * (i.e. RGB(linux_logo_red[0],
- *	     linux_logo_green[0],
- *	     linux_logo_blue[0]) is color 0x20)
+ *           linux_logo_green[0],
+ *           linux_logo_blue[0]) is color 0x20)
  * BW image has to be 80x80 as well, with MS bit
  * on the left
  * Serial_console ascii image can be any size,
  * but should contain %s to display the version
  */
- 
-#include <linux/init.h>
-#include <linux/version.h>
 
-#define linux_logo_banner "Linux/PA-RISC version " UTS_RELEASE
+#ifndef __HAVE_ARCH_LINUX_LOGO
+#define LINUX_LOGO_COLORS 223
+#endif
+#ifdef INCLUDE_LINUX_LOGO_DATA
+#ifndef __HAVE_ARCH_LINUX_LOGO
+unsigned char linux_logo_red[] __initdata = {
+  0x02, 0xFD, 0xF1, 0x02, 0xA2, 0x02, 0x76, 0xFE, 
+  0xB8, 0x32, 0x52, 0xCA, 0x66, 0x8E, 0x46, 0xFD, 
+  0x66, 0xB2, 0xB6, 0x3E, 0xA4, 0xFE, 0x21, 0xDB, 
+  0xEE, 0x2A, 0xCC, 0x9A, 0x1A, 0xFE, 0xFE, 0xA6, 
+  0xC2, 0xFE, 0x94, 0x12, 0xBA, 0xED, 0x8E, 0xFE, 
+  0xAE, 0xBC, 0xC2, 0xCE, 0xE2, 0x4A, 0x0E, 0x6F, 
+  0xBE, 0xA2, 0x02, 0x57, 0x78, 0xFE, 0xDA, 0xDA, 
+  0xFE, 0xEE, 0x8A, 0xF5, 0xB3, 0x0A, 0xCA, 0x77, 
+  0x52, 0xFE, 0x5A, 0x64, 0xFA, 0x96, 0xC2, 0x96, 
+  0xC2, 0x92, 0x4E, 0x52, 0xBE, 0xFE, 0x66, 0x8C, 
+  0xDA, 0xFE, 0xAA, 0x6E, 0xB6, 0x7A, 0xE2, 0x3F, 
+  0xA3, 0x06, 0xE6, 0xD6, 0xE6, 0x56, 0xF2, 0xB6, 
+  0x7E, 0xDD, 0xD6, 0xF9, 0x37, 0x26, 0xE7, 0xEC, 
+  0xBE, 0xDE, 0xA3, 0xFE, 0x92, 0xDE, 0x36, 0xC2, 
+  0x82, 0xEA, 0x26, 0xA7, 0x2D, 0xF2, 0xA6, 0x6A, 
+  0xDA, 0x2E, 0xE2, 0xFE, 0x69, 0xFE, 0x46, 0x9E, 
+  0x5E, 0xFE, 0x82, 0xFE, 0xFC, 0xAA, 0xB8, 0xFE, 
+  0xCE, 0xC6, 0x1D, 0x76, 0xF8, 0x92, 0xE2, 0xD6, 
+  0xFE, 0x9C, 0xCC, 0xB6, 0xE4, 0x0C, 0xE2, 0xC6, 
+  0xD2, 0x16, 0xD3, 0x9C, 0x59, 0x3A, 0xFE, 0x70, 
+  0xBB, 0xA6, 0xF6, 0xFA, 0x76, 0xB6, 0xAE, 0xB7, 
+  0xEE, 0x3E, 0x82, 0xCA, 0xBA, 0x17, 0xAB, 0xAF, 
+  0xCF, 0x86, 0x32, 0xB4, 0x2A, 0xFE, 0xEE, 0xE2, 
+  0x5A, 0xFE, 0x02, 0xFE, 0xEA, 0xFE, 0x77, 0x64, 
+  0xFE, 0xFD, 0xD5, 0xBF, 0x4E, 0xBB, 0xF8, 0x9B, 
+  0x78, 0x6E, 0xFA, 0xC6, 0xFE, 0xB2, 0x12, 0xF2, 
+  0xBE, 0x06, 0xAE, 0xC4, 0xEA, 0xAE, 0xFE, 0xD5, 
+  0x42, 0xBC, 0x86, 0xFE, 0x7A, 0xF0, 0xF1
+};
+
+unsigned char linux_logo_green[] __initdata = {
+  0x02, 0xCF, 0xB7, 0x9A, 0x7A, 0x66, 0x4C, 0xCF, 
+  0xBA, 0x9A, 0x3A, 0x98, 0xCE, 0x66, 0x2E, 0xE0, 
+  0x9A, 0xB6, 0xB6, 0x27, 0x7C, 0xE2, 0x22, 0x9B, 
+  0xE6, 0x1E, 0x9A, 0xCE, 0x1A, 0xE6, 0xEA, 0x6E, 
+  0x86, 0xCE, 0x59, 0x12, 0x96, 0xEE, 0x5A, 0xD4, 
+  0x7E, 0x9A, 0xBA, 0xCE, 0xBE, 0x4A, 0x0E, 0x43, 
+  0xA7, 0x8A, 0x66, 0x3D, 0x4E, 0xEA, 0xDA, 0xAD, 
+  0xE6, 0xCA, 0x62, 0xF6, 0xA4, 0x0A, 0x82, 0x77, 
+  0x52, 0xE9, 0x34, 0x64, 0xC2, 0x7E, 0xB2, 0x96, 
+  0xC2, 0x62, 0x3A, 0x33, 0x91, 0xEC, 0x9A, 0x8C, 
+  0xB6, 0xE2, 0x70, 0x56, 0x76, 0x6A, 0xBE, 0x3E, 
+  0xA2, 0x06, 0xE6, 0xD6, 0xEA, 0x56, 0xC6, 0x9E, 
+  0x7E, 0x9A, 0xAA, 0xFA, 0x22, 0x26, 0xA6, 0xAE, 
+  0xC6, 0xB6, 0x8F, 0xDE, 0x7A, 0xDE, 0x36, 0x83, 
+  0x82, 0xBE, 0x16, 0x9B, 0x1A, 0xBE, 0xA6, 0x5C, 
+  0x9F, 0x2E, 0xAE, 0xD8, 0x6B, 0xBA, 0x46, 0x9E, 
+  0x5E, 0xC6, 0x72, 0xBE, 0xDA, 0x8E, 0xB0, 0xC2, 
+  0x89, 0x92, 0x1E, 0x6A, 0xB7, 0x92, 0xA2, 0xA2, 
+  0xFE, 0x65, 0xD0, 0xAA, 0xB0, 0x0E, 0xE2, 0xC6, 
+  0xD2, 0x16, 0x91, 0x6E, 0x3B, 0x3A, 0xCA, 0x70, 
+  0xBB, 0xAE, 0xBE, 0xD6, 0x5A, 0x8A, 0x86, 0xBA, 
+  0xC6, 0x42, 0x58, 0xCA, 0x7C, 0x0E, 0xAA, 0x7F, 
+  0x8F, 0x86, 0x32, 0x72, 0x2A, 0xC2, 0xA7, 0xA0, 
+  0x5A, 0xC6, 0x02, 0xFE, 0xEA, 0xEA, 0x7A, 0x3F, 
+  0xC6, 0xCA, 0xA3, 0xBF, 0x4E, 0x91, 0xB8, 0x99, 
+  0x70, 0x5E, 0xBE, 0x7E, 0xFE, 0xB1, 0x06, 0xB1, 
+  0xC2, 0x0A, 0xA2, 0x9D, 0xAA, 0x77, 0xC2, 0x96, 
+  0x42, 0xBE, 0x52, 0xE8, 0x7E, 0xAE, 0xF2
+};
+
+unsigned char linux_logo_blue[] __initdata = {
+ 0x02, 0x03, 0x07, 0x9A, 0x02, 0x66, 0x02, 0x0E, 
+ 0xC3, 0x9A, 0x02, 0x02, 0xCE, 0x02, 0x02, 0x1C, 
+ 0x9A, 0xBE, 0xB6, 0x02, 0x38, 0x2E, 0x23, 0x14, 
+ 0x36, 0x02, 0x32, 0xCE, 0x1C, 0x46, 0x42, 0x0A, 
+ 0x0A, 0x12, 0x03, 0x12, 0x4A, 0xEF, 0x05, 0x16, 
+ 0x26, 0x52, 0xAE, 0xCE, 0x02, 0x4A, 0x0F, 0x03, 
+ 0x6C, 0x56, 0x9A, 0x0D, 0x0C, 0xA2, 0xDB, 0x02, 
+ 0x9A, 0x02, 0x12, 0xF8, 0x85, 0x0B, 0x02, 0x76, 
+ 0x52, 0x07, 0x02, 0x66, 0x0D, 0x46, 0x92, 0x97, 
+ 0xC3, 0x16, 0x1A, 0x07, 0x02, 0x0E, 0xCE, 0x8D, 
+ 0x4E, 0x04, 0x04, 0x2A, 0x03, 0x52, 0x4E, 0x3F, 
+ 0xA1, 0x07, 0xE7, 0xD7, 0xEB, 0x56, 0x02, 0x72, 
+ 0x7F, 0x06, 0x1A, 0xFB, 0x03, 0x27, 0x07, 0x08, 
+ 0xD6, 0x42, 0x6D, 0x07, 0x4E, 0xDF, 0x37, 0x06, 
+ 0x84, 0x02, 0x02, 0x86, 0x02, 0x3A, 0xA7, 0x44, 
+ 0x03, 0x2F, 0x38, 0x0E, 0x70, 0x07, 0x47, 0x9E, 
+ 0x5F, 0x06, 0x56, 0x0B, 0x06, 0x32, 0x9E, 0x02, 
+ 0x03, 0x36, 0x1F, 0x56, 0x03, 0x92, 0x10, 0x03, 
+ 0xF2, 0x03, 0xDB, 0x92, 0x1C, 0x1A, 0xE2, 0xC8, 
+ 0xD2, 0x17, 0x03, 0x02, 0x03, 0x3B, 0x0D, 0x70, 
+ 0xBA, 0xBA, 0x0D, 0x03, 0x06, 0x16, 0x26, 0xBE, 
+ 0x0E, 0x50, 0x02, 0xCA, 0x04, 0x02, 0xA7, 0x03, 
+ 0x0C, 0x86, 0x33, 0x04, 0x2B, 0x09, 0x05, 0x06, 
+ 0x5A, 0x0D, 0x0A, 0xFA, 0xEB, 0x2A, 0x82, 0x04, 
+ 0x02, 0x02, 0x32, 0xBE, 0x4F, 0x35, 0x0C, 0x98, 
+ 0x6C, 0x46, 0x0B, 0x02, 0xFE, 0xB1, 0x02, 0x07, 
+ 0xD2, 0x18, 0x96, 0x48, 0x06, 0x04, 0x0E, 0x07, 
+ 0x43, 0xC6, 0x02, 0x3A, 0x8C, 0x16, 0xF4
+};
+
+unsigned char linux_logo[] __initdata = {
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0x79,
+  0x79, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x79, 0xB9, 0x99, 0xBD, 0x9E, 0x60,
+  0x60, 0xF8, 0x8E, 0x85, 0xB9, 0x79, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x79, 0xAA, 0x9E, 0xDE, 0x96, 0xE3, 0xB7, 0x4B,
+  0x4B, 0x68, 0x32, 0x9F, 0x5F, 0x9E, 0xAA, 0x5D,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4E,
+  0x8E, 0x80, 0xE3, 0xB6, 0xCB, 0x90, 0x80, 0x63,
+  0x63, 0xDE, 0x78, 0xCB, 0xB6, 0xE3, 0xD1, 0x4D,
+  0x3C, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43, 0x4D,
+  0x9F, 0x8D, 0x32, 0x77, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x77, 0x96, 0x7A, 0xE3,
+  0x5F, 0x99, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x5D, 0xF8, 0x96,
+  0x8D, 0xBF, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x99, 0x68,
+  0x7B, 0x6F, 0x8E, 0x5D, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x85, 0x6F, 0xB6,
+  0xD8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x5D, 0x36, 0xB9, 0x20, 0x79,
+  0x6F, 0x8D, 0x6F, 0xD4, 0x79, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x4E, 0x7D, 0xCB, 0xAD,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x3C, 0x63, 0xBF, 0xD4, 0x20,
+  0x20, 0x78, 0xB8, 0x9C, 0xB9, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x36, 0xAD, 0xB6, 0x36,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xAA, 0x5F, 0x90, 0x9E, 0x3C,
+  0x20, 0x5D, 0x4B, 0xED, 0x77, 0x79, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x79, 0x9E, 0xE3, 0x78, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xAA, 0xE4, 0x77, 0xAA, 0x43,
+  0x20, 0x20, 0x7D, 0x8D, 0x5F, 0xB9, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x4E, 0x63, 0x56, 0x9E, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x5D, 0x4E, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x79, 0xB7, 0xCE, 0x8E, 0x79, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xB9, 0x80, 0x7A, 0xB9, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xBF, 0x4B, 0x7D, 0x5D, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xAA, 0xAD, 0xB8, 0x79, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x85, 0xB6, 0x5F, 0x43, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x20,
+  0x20, 0x20, 0xB9, 0x3C, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x79, 0x8E, 0x79, 0x20,
+  0x20, 0x20, 0x20, 0x43, 0xB6, 0x6F, 0x3C, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x20,
+  0x5D, 0xE4, 0x8E, 0x4E, 0x43, 0x20, 0x20, 0x20,
+  0x20, 0x8E, 0x90, 0xCE, 0x90, 0x4E, 0xAA, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0xB7, 0xE7, 0x36, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x20,
+  0xD1, 0x8D, 0x7B, 0xD8, 0x20, 0x20, 0x20, 0x20,
+  0x9E, 0x32, 0x56, 0x45, 0xFE, 0x6F, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0xCB, 0x96, 0xD4, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x85,
+  0xDC, 0xEC, 0xEC, 0xEC, 0xAA, 0x20, 0x20, 0xDA,
+  0x56, 0xEC, 0xEC, 0xB8, 0xEC, 0x83, 0x8E, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x6F, 0xED, 0x8E, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x36, 0x67, 0xCB, 0x20, 0x9C,
+  0x45, 0xAA, 0x9C, 0xEC, 0xDE, 0x20, 0x20, 0xAA,
+  0xEC, 0x83, 0x79, 0xBD, 0xBF, 0xEC, 0x96, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x6F, 0x32, 0x8E, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xAA, 0xAD, 0xB7, 0x20, 0x80,
+  0x80, 0x20, 0xE4, 0x31, 0x67, 0xDA, 0x3C, 0xD4,
+  0xEC, 0xDE, 0x20, 0xDA, 0x8E, 0xB6, 0x7A, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x6F, 0x32, 0x8E, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x3C, 0xD1, 0xDC, 0xB9, 0x5F,
+  0x90, 0x20, 0xF1, 0xFC, 0x7D, 0x39, 0x94, 0xCD,
+  0x28, 0x63, 0x20, 0x20, 0x20, 0xB8, 0xDC, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x6F, 0xC0, 0xBD, 0x79,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x43, 0x5F, 0x7A, 0xB9, 0x9E,
+  0x8D, 0x20, 0x20, 0x5A, 0x87, 0xE0, 0xC2, 0x2B,
+  0x82, 0x51, 0x20, 0x20, 0xB5, 0xEC, 0xC7, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0xAD, 0x68, 0x9E, 0x79,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x43, 0xBF, 0xB6, 0xB9, 0x79,
+  0x83, 0x93, 0xCC, 0xF4, 0xE0, 0xE1, 0x21, 0xC8,
+  0x47, 0x9B, 0x57, 0xC4, 0xB8, 0xEC, 0x77, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x60, 0x4B, 0x60, 0x5D,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x43, 0xBF, 0xB6, 0xB9, 0x20,
+  0x75, 0xD0, 0xF4, 0xA7, 0xE0, 0x21, 0xA4, 0xDD,
+  0x3E, 0xDD, 0x61, 0x71, 0x21, 0xB4, 0x2E, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x60, 0x7B, 0xA0, 0x5D,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x43, 0xBF, 0xB6, 0x85, 0xCD,
+  0xCC, 0x81, 0xAC, 0xE0, 0xE1, 0xC3, 0x8B, 0x3D,
+  0x3E, 0x61, 0x61, 0x6D, 0x71, 0x47, 0xAF, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x8E, 0xB6, 0x5F, 0xB9,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x5D, 0xA0, 0x7B, 0x7D, 0xDF,
+  0xA8, 0xD6, 0xA3, 0xE0, 0x21, 0xA4, 0x35, 0xFB,
+  0x61, 0x61, 0x61, 0x4C, 0x2B, 0x86, 0xCF, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x5D, 0x8D, 0x78, 0x99,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x5D, 0x60, 0xB8, 0x7D, 0x39,
+  0xF5, 0xAC, 0xA7, 0xE1, 0x21, 0x8B, 0x35, 0x71,
+  0x8B, 0x59, 0x6C, 0xD0, 0xD7, 0xD6, 0x5A, 0x20,
+  0x20, 0xB9, 0x20, 0x20, 0x20, 0x90, 0xCB, 0x60,
+  0x5D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x5D, 0x60, 0xB8, 0x7D, 0x20,
+  0xBC, 0xBB, 0x22, 0x21, 0x2F, 0x8B, 0xC3, 0x57,
+  0xCF, 0x3F, 0xBA, 0xD7, 0x81, 0x3A, 0x77, 0x20,
+  0x20, 0xA0, 0x63, 0x36, 0x20, 0xD2, 0x7A, 0x6F,
+  0x36, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x4E, 0xA0, 0x7B, 0x7D, 0x20,
+  0xDE, 0x51, 0x46, 0xF5, 0x6C, 0xCF, 0x72, 0xCC,
+  0x5E, 0xA8, 0x5E, 0xE5, 0x4A, 0xB2, 0xED, 0x20,
+  0x20, 0x43, 0x6F, 0x90, 0x4E, 0x20, 0xED, 0xB7,
+  0x7D, 0x4E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x36, 0xD1, 0x7A, 0x8E, 0x20,
+  0xAD, 0xCB, 0x34, 0xB1, 0xF7, 0xBA, 0xA8, 0xEB,
+  0xD3, 0x74, 0x7F, 0xF9, 0xB2, 0x7A, 0x7B, 0x36,
+  0x20, 0x20, 0xE4, 0xA0, 0x79, 0x20, 0xAA, 0xB6,
+  0x67, 0xD4, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x4E, 0x60, 0x68, 0xC0, 0x79, 0x20,
+  0x6F, 0xB2, 0x68, 0x8A, 0x42, 0x42, 0x42, 0x42,
+  0x34, 0xA6, 0x28, 0xB2, 0xEC, 0xEC, 0xEC, 0x9F,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6F,
+  0x4B, 0x63, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x79, 0x8E, 0x9F, 0xB6, 0xD2, 0x20, 0x20,
+  0xDC, 0x7C, 0xB7, 0xF0, 0x28, 0xF2, 0xF2, 0xED,
+  0xC7, 0xF9, 0xB2, 0x5B, 0xEC, 0xEC, 0xEC, 0xEC,
+  0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xAA,
+  0x56, 0xCE, 0xBD, 0x79, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x79, 0x85, 0xD1, 0x8D, 0xE8, 0x20, 0x20, 0x67,
+  0xEC, 0xEC, 0xB8, 0xF9, 0xF9, 0x28, 0xC7, 0xC7,
+  0x68, 0x8D, 0x83, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0x68, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x63, 0x8D, 0xDE, 0xAA, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x3C, 0xBF, 0x4B, 0xCE, 0x79, 0x20, 0x99, 0xEC,
+  0xEC, 0xEC, 0xFE, 0xF9, 0xC0, 0xC7, 0xC7, 0x4B,
+  0xFE, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0x99, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x79, 0x68, 0x68, 0xD8, 0x43, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43,
+  0x7D, 0xE3, 0x4B, 0x3C, 0x20, 0x20, 0x4B, 0xEC,
+  0xEC, 0xEC, 0xEC, 0x5B, 0x56, 0x56, 0xDC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xCE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x99, 0xB6, 0xED, 0x4D, 0x4E, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4E, 0x9E,
+  0xCE, 0xB6, 0x99, 0x20, 0x20, 0x4D, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0x83, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x77, 0xDC, 0x78, 0xF8, 0x4E, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0x8E, 0xE7,
+  0x7A, 0x60, 0x20, 0x20, 0x20, 0x68, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xBF, 0x7A, 0xE7, 0xBD, 0x79,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0xAA, 0x80, 0x8D,
+  0xBF, 0x20, 0x20, 0x20, 0x4E, 0x56, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0x83, 0x83, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xDB, 0xEC, 0xD8, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0xBF, 0x8D, 0xD1, 0x85,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x5D, 0x4D, 0xE3, 0x32,
+  0x79, 0x20, 0x20, 0x20, 0x99, 0x32, 0xDC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xDC, 0x8D, 0x8D, 0x45, 0x83,
+  0x83, 0x83, 0x83, 0x7A, 0x8D, 0x56, 0x7B, 0xB8,
+  0xB8, 0x8D, 0x78, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x79, 0x78, 0xCB, 0xD8,
+  0x4E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0xAA, 0xD1, 0x7A, 0xD2,
+  0x20, 0x20, 0x20, 0x20, 0xE4, 0xED, 0x7B, 0xFE,
+  0xEC, 0xEC, 0xEC, 0xDB, 0xB6, 0x5B, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xDB, 0xFE, 0x8D, 0x4B, 0xB7, 0x68,
+  0x68, 0xB7, 0xDC, 0x5F, 0x20, 0x20, 0xAA, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x8D, 0x67,
+  0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x79, 0xBD, 0xED, 0xCE, 0x20,
+  0x20, 0x20, 0x20, 0x79, 0x67, 0xDC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xDB, 0x45, 0xEC, 0xDB, 0xDB,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x45,
+  0x8D, 0x4B, 0xB8, 0x83, 0x99, 0x20, 0x20, 0x85,
+  0x5D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0xB7,
+  0x60, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x5D, 0x7D, 0xB8, 0xBF, 0x20,
+  0x20, 0x43, 0x20, 0xBF, 0xFE, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xDB, 0xDB, 0xDB, 0xDB,
+  0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xDC, 0xB6, 0x7B, 0x20, 0x20, 0x20,
+  0xD4, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x99, 0x7A,
+  0xD1, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x3C, 0x80, 0x7A, 0xD2, 0x20,
+  0x36, 0x20, 0x4E, 0x68, 0xEC, 0xEC, 0x5B, 0xEC,
+  0xEC, 0x7C, 0x4B, 0x4B, 0x4B, 0x4B, 0x3B, 0x3B,
+  0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x30, 0x30, 0xC1,
+  0xB6, 0xEC, 0x5B, 0x5B, 0x5B, 0x9E, 0x20, 0x20,
+  0x20, 0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0xED,
+  0xED, 0xBD, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0xD2, 0x96, 0xB8, 0x79, 0x79,
+  0x4E, 0x20, 0xD1, 0x45, 0x83, 0xEC, 0xEC, 0xEC,
+  0xEC, 0x30, 0x25, 0x52, 0x25, 0x25, 0x25, 0x25,
+  0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x29,
+  0xDC, 0xEC, 0xEC, 0xEC, 0x83, 0xB7, 0x20, 0x43,
+  0xD2, 0xB9, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x9C,
+  0x7B, 0x63, 0x4E, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x5D, 0x7D, 0x4B, 0x80, 0x20, 0x85,
+  0x20, 0x79, 0x7A, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0x30, 0x25, 0x25, 0x23, 0x29, 0x2C, 0x3B,
+  0x4B, 0x7C, 0x4B, 0x3B, 0x30, 0x52, 0x25, 0x29,
+  0x5B, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x4E, 0xAA,
+  0xD2, 0x5D, 0xD4, 0x20, 0x20, 0x20, 0x20, 0x5D,
+  0xB6, 0x67, 0x36, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0xAA, 0xD1, 0x7A, 0x99, 0x20, 0xB9,
+  0x20, 0xE4, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0x29, 0x29, 0x3B, 0x7C, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x3B, 0x52, 0x23,
+  0xFE, 0xEC, 0x83, 0xEC, 0xEC, 0xEC, 0x4D, 0x20,
+  0x20, 0x20, 0x5D, 0x85, 0x20, 0x20, 0x20, 0x20,
+  0x96, 0xE3, 0xF8, 0x79, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x79, 0xF8, 0x32, 0x32, 0x20, 0xAA, 0x20,
+  0x20, 0xCB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C,
+  0x30, 0x3B, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x29, 0x25,
+  0x4B, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x6F, 0x20,
+  0x20, 0x20, 0x20, 0x99, 0x20, 0x20, 0x20, 0x20,
+  0xD8, 0x7B, 0x63, 0x4E, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x3C, 0xDE, 0x8D, 0xE4, 0x20, 0x36, 0x20,
+  0x36, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x30,
+  0x4B, 0xEC, 0xEC, 0xEC, 0x7C, 0x3B, 0x30, 0x29,
+  0x29, 0x29, 0x29, 0x3B, 0x7C, 0xEC, 0x29, 0x25,
+  0x3B, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xE3, 0x20,
+  0x20, 0x20, 0x20, 0xD2, 0x20, 0x20, 0x20, 0x20,
+  0x3C, 0x7A, 0x80, 0xB9, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x5D, 0x4D, 0xC0, 0x68, 0x79, 0x20, 0x5D, 0x20,
+  0x90, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x3B, 0x7C,
+  0xEC, 0xEC, 0x3B, 0x29, 0x52, 0x52, 0x29, 0x29,
+  0x29, 0x29, 0x25, 0x25, 0x29, 0x4B, 0x29, 0x25,
+  0x2C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xB6, 0x20,
+  0x20, 0x20, 0x20, 0xD4, 0x20, 0x20, 0x20, 0x20,
+  0x79, 0x7B, 0x67, 0x36, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x85, 0x6F, 0x7A, 0x77, 0x20, 0xB9, 0x20, 0x20,
+  0xB8, 0xEC, 0xEC, 0xEC, 0xEC, 0x4B, 0xEC, 0xEC,
+  0x3B, 0x29, 0x29, 0x6E, 0x4B, 0x7C, 0xEC, 0xEC,
+  0xEC, 0x7C, 0x4B, 0x30, 0x25, 0x52, 0x52, 0x25,
+  0x30, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x5B, 0x20,
+  0x20, 0x20, 0x20, 0x36, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x68, 0xCE, 0x99, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4E,
+  0xD8, 0xCB, 0x67, 0x20, 0x20, 0xAA, 0x20, 0x20,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x30,
+  0x29, 0x3B, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0x6E, 0x25, 0x52, 0x25,
+  0x29, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x20,
+  0x20, 0x20, 0x20, 0xAA, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0xD1, 0xC0, 0xBD, 0x79, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xAA,
+  0x6F, 0x8D, 0x3C, 0x20, 0x20, 0x36, 0x20, 0xB5,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x30, 0x3B,
+  0xEC, 0xEC, 0x7C, 0xEC, 0xEC, 0xEC, 0x7C, 0x7C,
+  0x7C, 0xEC, 0xEC, 0xEC, 0x7C, 0x52, 0x52, 0x25,
+  0x29, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x20,
+  0x20, 0x20, 0x79, 0x43, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0xD1, 0xC0, 0xBD, 0x79, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x99,
+  0xCE, 0x68, 0x20, 0x20, 0x20, 0xBD, 0xF1, 0x36,
+  0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x6E, 0x7C, 0xEC,
+  0xEC, 0xEC, 0x3B, 0x6E, 0x29, 0x29, 0x52, 0x52,
+  0x23, 0x29, 0x3B, 0xEC, 0x7C, 0x23, 0x52, 0x52,
+  0x23, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x20,
+  0x20, 0x20, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0xD1, 0xC0, 0xBD, 0x79, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xBD,
+  0xC0, 0xD1, 0x20, 0x20, 0x20, 0x36, 0x3C, 0x8E,
+  0xEC, 0xEC, 0xEC, 0xEC, 0x4B, 0xEC, 0xEC, 0xEC,
+  0x3B, 0x29, 0x52, 0x29, 0x29, 0x30, 0x30, 0x30,
+  0x29, 0x25, 0x25, 0x29, 0x3B, 0x52, 0x52, 0x52,
+  0x52, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x20,
+  0x20, 0x20, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0xD1, 0xC0, 0xBD, 0x79, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0xBD,
+  0xC0, 0xD1, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x8E,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x3B, 0x30,
+  0x30, 0x3B, 0x4B, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0x4B, 0x29, 0x25, 0x52, 0x52, 0x52, 0x52,
+  0x52, 0x3B, 0xEC, 0xEC, 0xEC, 0xEC, 0x45, 0x20,
+  0x20, 0x3C, 0x4E, 0x4E, 0xB5, 0x20, 0x20, 0x20,
+  0x20, 0x78, 0x32, 0x8E, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x8E,
+  0x32, 0x68, 0xEE, 0xCA, 0x24, 0x84, 0x20, 0xC9,
+  0xEC, 0xEC, 0xEC, 0xEC, 0x7C, 0x30, 0x30, 0x7C,
+  0xEC, 0xEC, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0x29, 0x25, 0x25, 0x25, 0x25,
+  0x25, 0x2C, 0xEC, 0xEC, 0xEC, 0xEC, 0xF9, 0x20,
+  0x79, 0x20, 0x20, 0x20, 0xDA, 0xAA, 0xF8, 0xB9,
+  0x20, 0xCB, 0x78, 0xD4, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x79, 0x5D, 0x5D, 0x43, 0x4D,
+  0x68, 0x8D, 0xAE, 0x47, 0x21, 0xE1, 0x53, 0x20,
+  0x90, 0xEC, 0xEC, 0x7C, 0x30, 0x4B, 0xEC, 0xEC,
+  0xEC, 0xEC, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0x4B, 0x30, 0x30, 0x30, 0x29,
+  0x29, 0x30, 0xEC, 0xB0, 0x58, 0x55, 0x65, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x85, 0xC9,
+  0x5D, 0xFE, 0x9F, 0xD4, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x5D, 0xAA, 0x77, 0x7D, 0xA0, 0x63, 0x9F,
+  0x7A, 0x44, 0xAC, 0xBE, 0x21, 0x21, 0xE0, 0xBC,
+  0x20, 0x9C, 0xEC, 0x3B, 0x7C, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0x7C, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0x7C, 0x7C, 0xEC, 0x95, 0x21, 0x71, 0xC3, 0xCD,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x36, 0x4E,
+  0xA5, 0x56, 0x68, 0xE4, 0x5D, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x5D, 0xBD, 0xD1, 0xC0, 0xB8, 0x7B, 0x56, 0xDC,
+  0xA6, 0x98, 0x9D, 0xBE, 0x21, 0xE1, 0xE1, 0xC2,
+  0x92, 0x20, 0xC9, 0x5B, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0x7A, 0xFE, 0xEC, 0xEC, 0xDB, 0xDB,
+  0xDB, 0xDB, 0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xB4, 0x9D, 0x21, 0x91, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xDA, 0x53,
+  0x6D, 0x38, 0x7A, 0x90, 0x3C, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0xD4, 0xAD, 0xB6, 0xA6, 0x7F, 0xF3, 0x44, 0xE5,
+  0xF7, 0x87, 0xF6, 0xBE, 0xBE, 0xE1, 0xE0, 0xE0,
+  0xAF, 0x20, 0x20, 0xB5, 0x7B, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xDB,
+  0xDB, 0xDB, 0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0x9A, 0x9D, 0xA7, 0x98, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0x22,
+  0x8B, 0x8B, 0x68, 0xE7, 0x36, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D,
+  0x7D, 0x4B, 0x5C, 0xF4, 0x9D, 0xE6, 0xEF, 0x87,
+  0xE6, 0xA3, 0xD9, 0xD9, 0xD9, 0xA1, 0xA1, 0xE0,
+  0x21, 0x2D, 0x20, 0x20, 0x20, 0x96, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xDB,
+  0xDB, 0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xFE, 0xB2, 0xE2, 0xAC, 0x9D, 0x81, 0xDF,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xCF, 0xBE,
+  0x47, 0x47, 0x68, 0x96, 0xD4, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43,
+  0x5F, 0x7A, 0xE2, 0x9D, 0xBE, 0xBE, 0xD9, 0xF6,
+  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xA1, 0xD5,
+  0xE0, 0x7E, 0x92, 0x20, 0x20, 0x20, 0x63, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xDB,
+  0xDB, 0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xB2, 0xF0, 0xE2, 0xEF, 0xEF, 0xD7, 0xCC,
+  0x26, 0x84, 0x94, 0x84, 0x26, 0x40, 0xEF, 0xD9,
+  0x41, 0x41, 0xE3, 0xB7, 0x7D, 0x43, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43,
+  0xDE, 0x7A, 0x37, 0xA3, 0xBE, 0x41, 0xBE, 0xBE,
+  0xD9, 0xD9, 0xF6, 0x64, 0x64, 0xD5, 0xD5, 0xA1,
+  0xA1, 0x21, 0x6C, 0x20, 0x20, 0x20, 0x20, 0xD2,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xDB,
+  0xDB, 0xDB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xB2, 0x88, 0x3A, 0xF4, 0xAC, 0xF4, 0xBA,
+  0xA8, 0x8F, 0x8F, 0x40, 0xBA, 0xF4, 0xD9, 0x41,
+  0x41, 0x41, 0x89, 0x8D, 0x96, 0x9E, 0x4E, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x4E,
+  0x9C, 0x8D, 0xF3, 0xAC, 0xD9, 0x41, 0xBE, 0xD9,
+  0xF6, 0x64, 0x64, 0x64, 0x64, 0x64, 0xD5, 0xD5,
+  0xA1, 0xA1, 0x21, 0x2A, 0x20, 0x20, 0x20, 0x20,
+  0x7D, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0x7B, 0x88, 0xE5, 0xD7, 0x22, 0x22, 0x86,
+  0x98, 0x81, 0x81, 0x98, 0x87, 0xEA, 0xBE, 0xBE,
+  0x41, 0xBE, 0xBE, 0x50, 0x7A, 0x78, 0x4D, 0xB9,
+  0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D,
+  0xD8, 0x7B, 0x49, 0xFD, 0xF6, 0xBE, 0xD9, 0xD9,
+  0x64, 0x64, 0xC2, 0xC2, 0xC2, 0xEA, 0x64, 0xD5,
+  0xD9, 0xA1, 0xE1, 0x57, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x83, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0x7C, 0x88, 0xC6, 0x81, 0xAC, 0xEA, 0x22,
+  0x87, 0x87, 0xF4, 0x87, 0x22, 0xF6, 0xD9, 0xD9,
+  0xBE, 0xBE, 0xBE, 0xD9, 0x50, 0xDC, 0x32, 0xBF,
+  0xD2, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79,
+  0x4D, 0xCB, 0x5C, 0x86, 0xA3, 0xBE, 0xD9, 0xF6,
+  0x64, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x64, 0x64,
+  0xD5, 0xD9, 0xA1, 0x21, 0xBB, 0x20, 0x20, 0x20,
+  0x20, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xFE, 0x9C, 0x46, 0x81, 0x22, 0xD5, 0xA3,
+  0x9D, 0x22, 0x22, 0xE6, 0xEA, 0xF6, 0xD9, 0xD9,
+  0xD9, 0xBE, 0xBE, 0x41, 0x41, 0x70, 0x7B, 0x7B,
+  0x6F, 0x85, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79,
+  0xF8, 0x68, 0xF2, 0xAE, 0xEA, 0xD9, 0xD9, 0x64,
+  0x64, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xEA, 0x64,
+  0xD5, 0xD5, 0xA1, 0xE1, 0xE1, 0x33, 0x20, 0xF1,
+  0x31, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xFC, 0x20, 0x46, 0x98, 0xAC, 0xD5, 0xD9,
+  0xD9, 0xD5, 0x64, 0x64, 0x64, 0x64, 0xF6, 0xD9,
+  0xD9, 0xBE, 0xBE, 0x41, 0x47, 0x9B, 0x41, 0x66,
+  0xB7, 0x4D, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D,
+  0xE4, 0xCB, 0x5C, 0xAE, 0xEA, 0xD9, 0xD9, 0x64,
+  0x64, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x64,
+  0x64, 0xD5, 0xA1, 0xD5, 0x21, 0xAF, 0xCE, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0x63, 0x20, 0x20, 0xB1, 0xD7, 0xE6, 0xD5, 0xD9,
+  0xD5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0xF6,
+  0xD9, 0xBE, 0xBE, 0x41, 0x47, 0x9B, 0x9B, 0x76,
+  0x7B, 0xD8, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x43,
+  0xBF, 0x8D, 0x44, 0xAE, 0xF6, 0xD9, 0xD9, 0xF6,
+  0x64, 0xEA, 0xC2, 0xC2, 0xC2, 0xC2, 0xC2, 0x64,
+  0x64, 0xD5, 0xD5, 0xD5, 0xE0, 0x7E, 0xC5, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xFE, 0x99,
+  0x20, 0x20, 0x20, 0xB1, 0xD7, 0x9D, 0xD5, 0xD9,
+  0xD5, 0x64, 0x64, 0x64, 0x64, 0x64, 0xF6, 0xD9,
+  0xD9, 0xBE, 0x41, 0x41, 0x47, 0x41, 0xD9, 0x66,
+  0x4B, 0x60, 0x5D, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xD4,
+  0x9F, 0xB6, 0xBA, 0x87, 0xD9, 0xBE, 0xD9, 0xD9,
+  0xF6, 0x64, 0x64, 0x64, 0x64, 0xEA, 0x64, 0x64,
+  0x64, 0xD5, 0xD5, 0xD5, 0xD5, 0x7E, 0xAF, 0x8C,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0x90, 0x20, 0x20,
+  0x20, 0x20, 0xEE, 0xB1, 0x86, 0xEA, 0xD9, 0xD9,
+  0xD5, 0x64, 0x64, 0x64, 0x64, 0xF6, 0xD9, 0xD9,
+  0xBE, 0xBE, 0x41, 0x41, 0xBE, 0xE6, 0x9A, 0x8D,
+  0x9F, 0xD2, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0x9E,
+  0xB7, 0xB3, 0xD7, 0xD5, 0x41, 0xBE, 0xBE, 0xD9,
+  0xD9, 0xD9, 0xF6, 0x64, 0x64, 0x64, 0x64, 0x64,
+  0x64, 0xD5, 0xD9, 0xA1, 0xA1, 0x22, 0x86, 0x46,
+  0x77, 0x7B, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+  0xEC, 0xEC, 0x7A, 0xD1, 0x79, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x92, 0x3F, 0x86, 0xEA, 0xD9, 0xD9,
+  0xD9, 0xF6, 0xF6, 0xF6, 0xD9, 0xD9, 0xD9, 0xBE,
+  0xBE, 0xBE, 0xF6, 0xE6, 0xFD, 0x5C, 0xDC, 0xED,
+  0x60, 0x4E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D, 0xD8,
+  0x7B, 0xF3, 0x86, 0xA3, 0xBE, 0xBE, 0xBE, 0xD9,
+  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+  0xD9, 0xD5, 0xD9, 0xD9, 0xA1, 0x9D, 0x86, 0x72,
+  0x94, 0x20, 0xB5, 0xE4, 0x5F, 0x80, 0xBF, 0xA0,
+  0x8E, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x84, 0x72, 0x86, 0xA3, 0xBE, 0xBE,
+  0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xF6, 0xD9,
+  0xF6, 0xFD, 0x37, 0x5C, 0x7B, 0xB8, 0x67, 0x4D,
+  0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D, 0xD8,
+  0xB8, 0xF3, 0x81, 0xF4, 0xAC, 0xE6, 0xEA, 0xEA,
+  0xA3, 0xF6, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9, 0xD9,
+  0xD9, 0xD9, 0xBE, 0xBE, 0xBE, 0xEA, 0xD7, 0x72,
+  0x62, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x6B, 0x74, 0xAE, 0xEA, 0xBE, 0xBE,
+  0xBE, 0xBE, 0xD9, 0xD9, 0xD9, 0xEA, 0xE6, 0x87,
+  0xF7, 0x93, 0xB6, 0xB8, 0x78, 0x63, 0x99, 0x5D,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79, 0xF8,
+  0xC0, 0xCB, 0xA9, 0x8F, 0xA8, 0xD0, 0xF7, 0x81,
+  0xAE, 0x86, 0x87, 0x22, 0xE6, 0xEA, 0xD9, 0xD9,
+  0xBE, 0xBE, 0xBE, 0xBE, 0xD9, 0xEF, 0xD0, 0xB1,
+  0xDF, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x6B, 0x72, 0xF7, 0xEF, 0xD9, 0xD9,
+  0xBE, 0xD9, 0xD9, 0xF6, 0x22, 0x86, 0x81, 0xE5,
+  0x4B, 0x56, 0x78, 0x63, 0x99, 0x43, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3C,
+  0x9C, 0xC0, 0xB6, 0xB6, 0x32, 0x8A, 0x48, 0xD3,
+  0xCC, 0xCC, 0x8F, 0x40, 0xD0, 0x81, 0xF4, 0x22,
+  0xA3, 0xF6, 0xD9, 0xF6, 0xAC, 0x81, 0x74, 0x46,
+  0x62, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x2E, 0xB1, 0x40, 0xAE, 0xAC, 0xF6,
+  0xF6, 0xF6, 0xAC, 0xF4, 0x81, 0xCC, 0x8A, 0xDC,
+  0xC0, 0x5F, 0x8E, 0x4E, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x79,
+  0x3C, 0x4D, 0xBF, 0x67, 0x32, 0xB8, 0x7A, 0xCB,
+  0xCE, 0x8C, 0x69, 0x46, 0xB1, 0x3F, 0xCC, 0xA8,
+  0xBA, 0x98, 0x86, 0xAE, 0xBA, 0x74, 0x42, 0x4F,
+  0x84, 0xD2, 0x32, 0x32, 0xCB, 0x45, 0xDC, 0xDC,
+  0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0x56, 0x32,
+  0xED, 0x80, 0x6A, 0xCA, 0x74, 0xA8, 0x81, 0x86,
+  0x86, 0xAE, 0xBA, 0x40, 0x3F, 0xF2, 0xB6, 0x78,
+  0xE4, 0x3C, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x79, 0x43, 0x36, 0xBD, 0xD8, 0x90, 0x78,
+  0x68, 0x56, 0xDC, 0xCB, 0x93, 0xA2, 0x26, 0x46,
+  0xB1, 0x3F, 0x72, 0x72, 0xB1, 0xFA, 0x4F, 0xBC,
+  0xAD, 0x56, 0x4B, 0xCE, 0xE7, 0x6F, 0x90, 0x80,
+  0x80, 0x80, 0x80, 0x80, 0x80, 0xD1, 0x67, 0x96,
+  0xE3, 0xDC, 0x90, 0xDF, 0xB1, 0x74, 0xCC, 0x8F,
+  0x8F, 0xCC, 0x72, 0x46, 0xCE, 0x56, 0xAD, 0x77,
+  0x4E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x79, 0x5D, 0x3C, 0xD4,
+  0xF8, 0x63, 0xD1, 0x96, 0x68, 0x8D, 0x7A, 0xE7,
+  0x73, 0x4F, 0x4F, 0x26, 0x4F, 0xDF, 0x6B, 0x32,
+  0x56, 0x9F, 0xA0, 0xD2, 0x36, 0x3C, 0xB9, 0xB9,
+  0xB9, 0xB9, 0xB9, 0xB9, 0xB9, 0x3C, 0x36, 0xD4,
+  0xE4, 0x96, 0xB6, 0xE8, 0xBC, 0xFA, 0x42, 0xB1,
+  0xB1, 0x46, 0x54, 0xCE, 0x56, 0xD1, 0xD2, 0x5D,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x79, 0x4E, 0x3C, 0x99, 0x9E, 0xBF, 0xE7, 0xB7,
+  0x7A, 0xCB, 0x6F, 0xE9, 0xE9, 0xE7, 0x56, 0xCB,
+  0x80, 0xD2, 0x4E, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x4E, 0x4D, 0x78, 0x8D, 0xE3, 0x5F, 0x97, 0xE9,
+  0xAB, 0x67, 0xB6, 0xCB, 0x90, 0x99, 0x79, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x79, 0x43, 0xD4, 0xE4,
+  0x80, 0xCE, 0xB7, 0x7B, 0x7B, 0x68, 0xE7, 0x63,
+  0x36, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x4E, 0xBD, 0x80, 0xED, 0x4B, 0x7B, 0x7B,
+  0xB8, 0x68, 0x67, 0xD8, 0x85, 0x79, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D,
+  0x3C, 0x99, 0x4D, 0xD8, 0xD8, 0x9E, 0x85, 0x4E,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x79, 0x3C, 0x8E, 0x60, 0xD8, 0xA0,
+  0x7D, 0xF8, 0x85, 0x4E, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
+};
+
+#endif /* !__HAVE_ARCH_LINUX_LOGO */
+
+#ifndef __HAVE_ARCH_LINUX_LOGOBW
+
+unsigned char linux_logo_bw[] __initdata = {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xbf, 0xfc, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf3, 0xdf, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfd, 0xff, 0xf7, 0xef, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x9f, 0x87, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x0f, 0x03, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x67, 0x33, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xe7, 0x79, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xf7, 0x79, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0xf9, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x60, 0x3b, 0xf7, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x89, 0x07, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x00, 0x03, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x00, 0x0d, 0xfb, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x80, 0x33, 0xfd, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xc0, 0xc3, 0xfd, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0xff, 0x0d, 0xdd, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xfb, 0x40, 0x31, 0xee, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf7, 0x20, 0xc1, 0xee, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf7, 0x1f, 0x00, 0xff, 0x7f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xee, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xde, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xbc, 0x00, 0x00, 0x3f, 0xef, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x3f, 0xf7, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x1f, 0xf7, 0xff, 0xff,
+    0xff, 0xff, 0xfe, 0xff, 0x1c, 0x07, 0xdf, 0xfb, 0xff, 0xff,
+    0xff, 0xff, 0xfd, 0xfc, 0x08, 0x0f, 0xef, 0xfd, 0xff, 0xff,
+    0xff, 0xff, 0xfd, 0xf8, 0x00, 0x01, 0xef, 0xfd, 0xff, 0xff,
+    0xff, 0xff, 0xfb, 0xf0, 0x00, 0x00, 0x7f, 0xfe, 0xff, 0xff,
+    0xff, 0xff, 0xfb, 0xe0, 0x00, 0x00, 0x1f, 0xfe, 0xff, 0xff,
+    0xff, 0xff, 0xf7, 0xe0, 0x00, 0x00, 0x07, 0xbf, 0x7f, 0xff,
+    0xff, 0xff, 0xf7, 0xc0, 0x00, 0x00, 0x03, 0xbf, 0x7f, 0xff,
+    0xff, 0xff, 0xef, 0xc0, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
+    0xff, 0xff, 0xef, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
+    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
+    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x03, 0x03, 0xdf, 0xff,
+    0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x02, 0xfd, 0xdf, 0xff,
+    0xff, 0xff, 0xa3, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xdf, 0xff,
+    0xff, 0xff, 0xc1, 0xc0, 0x00, 0x00, 0x11, 0xff, 0x3f, 0xff,
+    0xff, 0xff, 0x80, 0xe0, 0x00, 0x00, 0x21, 0xfe, 0x3f, 0xff,
+    0xff, 0xff, 0x00, 0x70, 0x00, 0x00, 0x21, 0xfc, 0x3f, 0xff,
+    0xff, 0xfe, 0x00, 0x3c, 0x00, 0x00, 0x20, 0xf8, 0x3f, 0xff,
+    0xff, 0xf0, 0x00, 0x3e, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
+    0xff, 0xc0, 0x00, 0x1f, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
+    0xff, 0xc0, 0x00, 0x1f, 0x80, 0x00, 0x20, 0x00, 0x1f, 0xff,
+    0xff, 0xc0, 0x00, 0x0f, 0x80, 0x00, 0x20, 0x00, 0x07, 0xff,
+    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x20, 0x00, 0x03, 0xff,
+    0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x60, 0x00, 0x01, 0xff,
+    0xff, 0xc0, 0x00, 0x02, 0x00, 0x00, 0xe0, 0x00, 0x01, 0xff,
+    0xff, 0xc0, 0x00, 0x01, 0x00, 0x01, 0xe0, 0x00, 0x01, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x00, 0x03, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x80, 0x3f, 0xe0, 0x00, 0x0f, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x1f, 0xff,
+    0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f, 0xff,
+    0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0xff, 0xff,
+    0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x03, 0xff, 0xff,
+    0xff, 0xff, 0xc0, 0x00, 0x70, 0x00, 0xc0, 0x07, 0xff, 0xff,
+    0xff, 0xff, 0xfc, 0x00, 0x8f, 0xff, 0x20, 0x0f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+#endif /* !__HAVE_ARCH_LINUX_LOGOBW */
+
+#ifndef __HAVE_ARCH_LINUX_LOGO16
+
+unsigned char linux_logo16[] __initdata = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x88, 0x80, 0x00, 0x00, 0x08, 0x88, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
+    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x08, 0x70, 0x00, 0x00, 0x00, 0x77, 0x70, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x87, 0x77, 0x00, 0x00, 0x07, 0xff, 0xf7, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x77, 0xff, 0x00, 0x00, 0x7f, 0x77, 0xf7, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x70, 0x0f, 0x80, 0x00, 0xf7, 0x08, 0x7f, 0x70,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x80, 0x07, 0x80, 0x00, 0xf8, 0x00, 0x8f, 0x70,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
+    0x70, 0x07, 0x88, 0x88, 0xf8, 0x00, 0x8f, 0x70,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0xf0, 0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x77, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x77, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x60,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66, 0x80,
+    0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0x86, 0xe6, 0xe6, 0xe6, 0x66, 0x66, 0x66, 0x80,
+    0x08, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
+    0x86, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x70,
+    0x00, 0x77, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x87, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x78,
+    0x00, 0x88, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x87, 0x76, 0x66, 0x66, 0x77, 0x77, 0xff, 0xf7,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
+    0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff,
+    0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
+    0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff,
+    0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x8f,
+    0xff, 0xf7, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff,
+    0xf0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x7f,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x87, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x77,
+    0xff, 0xf7, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77,
+    0x77, 0x78, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x7f,
+    0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x77,
+    0x77, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7f, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x77, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x80, 0x08, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x77, 0x80, 0x00, 0x08, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0x78, 0x00, 0x08, 0x80, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x08, 0x00, 0x8f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x08, 0x07, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x80, 0x00, 0x08, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x80, 0x0f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x80, 0x8f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x08, 0x00, 0x7f, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x80, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x88, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf0, 0x88, 0x88, 0x80, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x06, 0xe6, 0x00, 0x8f, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x08, 0x80,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff, 0xff,
+    0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x88,
+    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x00,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xf6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x06,
+    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x0e,
+    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x08, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0x76, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0xe6,
+    0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00, 0x08,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00,
+    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00,
+    0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00,
+    0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xf7, 0x8e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x88,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x78, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xef,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
+    0x80, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78,
+    0x00, 0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80,
+    0x00, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
+    0x67, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80, 0x00,
+    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+    0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
+    0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
+    0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
+    0x66, 0x66, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
+    0x60, 0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80,
+    0x00, 0x06, 0x66, 0xe6, 0xe6, 0xe6, 0x66, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x66, 0x66, 0x66, 0x66, 0xe6, 0xe6, 0x66,
+    0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x88, 0x86, 0x66, 0x6e, 0x6e, 0x66, 0x60, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x66, 0x66,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x60,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x66, 0x66, 0x66, 0x60, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+#endif /* !__HAVE_ARCH_LINUX_LOGO16 */
+
+#else /* !INCLUDE_LINUX_LOGO_DATA */
+
+/* prototypes only */
+extern unsigned char linux_logo_red[];
+extern unsigned char linux_logo_green[];
+extern unsigned char linux_logo_blue[];
+extern unsigned char linux_logo[];
+extern unsigned char linux_logo_bw[];
+extern unsigned char linux_logo16[];
 
-#include <linux/linux_logo.h>
+#endif /* !INCLUDE_LINUX_LOGO_DATA */
 
diff -Nru a/include/asm-parisc/module.h b/include/asm-parisc/module.h
--- a/include/asm-parisc/module.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/module.h	Mon Jan 13 21:59:49 2003
@@ -3,10 +3,23 @@
 /*
  * This file contains the parisc architecture specific module code.
  */
+#ifdef __LP64__
+#define Elf_Shdr Elf64_Shdr
+#define Elf_Sym Elf64_Sym
+#define Elf_Ehdr Elf64_Ehdr
+#else
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+#endif
 
 #define module_map(x)		vmalloc(x)
 #define module_unmap(x)		vfree(x)
 #define module_arch_init(x)	(0)
 #define arch_init_modules(x)	do { } while (0)
+
+struct mod_arch_specific
+{
+};
 
 #endif /* _ASM_PARISC_MODULE_H */
diff -Nru a/include/asm-parisc/page.h b/include/asm-parisc/page.h
--- a/include/asm-parisc/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/page.h	Mon Jan 13 21:59:49 2003
@@ -86,20 +86,6 @@
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
-/*
- * Tell the user there is some problem. Beep too, so we can
- * see^H^H^Hhear bugs in early bootup as well!
- *
- * We don't beep yet.  prumpf
- */
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-} while (0)
-
-#define PAGE_BUG(page) do { \
-	BUG(); \
-} while (0)
-
 
 #define LINUX_GATEWAY_SPACE     0
 #define __PAGE_OFFSET           (0x10000000)
diff -Nru a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-parisc/parisc-device.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,43 @@
+#include <linux/device.h>
+
+struct parisc_device {
+	unsigned long   hpa;		/* Hard Physical Address */
+	struct parisc_device_id id;
+	struct parisc_device *parent;
+	struct parisc_device *sibling;
+	struct parisc_device *child;
+	struct parisc_driver *driver;	/* Driver for this device */
+	void		*sysdata;	/* Driver instance private data */
+	char		name[80];	/* The hardware description */
+	int		irq;
+
+	char		hw_path;        /* The module number on this bus */
+	unsigned int	num_addrs;	/* some devices have additional address ranges. */
+	unsigned long	*addr;          /* which will be stored here */
+ 
+#ifdef __LP64__
+	/* parms for pdc_pat_cell_module() call */
+	unsigned long	pcell_loc;	/* Physical Cell location */
+	unsigned long	mod_index;	/* PAT specific - Misc Module info */
+
+	/* generic info returned from pdc_pat_cell_module() */
+	unsigned long	mod_info;	/* PAT specific - Misc Module info */
+	unsigned long	pmod_loc;	/* physical Module location */
+#endif
+	u64		dma_mask;	/* DMA mask for I/O */
+	struct device 	dev;
+};
+
+struct parisc_driver {
+	struct parisc_driver *next;
+	char *name; 
+	const struct parisc_device_id *id_table;
+	int (*probe) (struct parisc_device *dev); /* New device discovered */
+	struct device_driver drv;
+};
+
+
+#define to_parisc_device(d)	container_of(d, struct parisc_device, dev)
+#define to_parisc_driver(d)	container_of(d, struct parisc_driver, drv)
+
+extern struct bus_type parisc_bus_type;
diff -Nru a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
--- a/include/asm-parisc/pci.h	Mon Jan 13 21:59:50 2003
+++ b/include/asm-parisc/pci.h	Mon Jan 13 21:59:50 2003
@@ -131,74 +131,6 @@
 	void (*fixup_bus)(struct pci_bus *bus);
 };
 
-/*
-** See Documentation/DMA-mapping.txt
-*/
-struct pci_dma_ops {
-	int  (*dma_supported)(struct pci_dev *dev, u64 mask);
-	void *(*alloc_consistent)(struct pci_dev *dev, size_t size, dma_addr_t *iova);
-	void (*free_consistent)(struct pci_dev *dev, size_t size, void *vaddr, dma_addr_t iova);
-	dma_addr_t (*map_single)(struct pci_dev *dev, void *addr, size_t size, int direction);
-	void (*unmap_single)(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction);
-	int  (*map_sg)(struct pci_dev *dev, struct scatterlist *sg, int nents, int direction);
-	void (*unmap_sg)(struct pci_dev *dev, struct scatterlist *sg, int nhwents, int direction);
-	void (*dma_sync_single)(struct pci_dev *dev, dma_addr_t iova, size_t size, int direction);
-	void (*dma_sync_sg)(struct pci_dev *dev, struct scatterlist *sg, int nelems, int direction);
-};
-
-
-/*
-** We could live without the hppa_dma_ops indirection if we didn't want
-** to support 4 different coherent dma models with one binary (they will
-** someday be loadable modules):
-**     I/O MMU        consistent method           dma_sync behavior
-**  =============   ======================       =======================
-**  a) PA-7x00LC    uncachable host memory          flush/purge
-**  b) U2/Uturn      cachable host memory              NOP
-**  c) Ike/Astro     cachable host memory              NOP
-**  d) EPIC/SAGA     memory on EPIC/SAGA         flush/reset DMA channel
-**
-** PA-7[13]00LC processors have a GSC bus interface and no I/O MMU.
-**
-** Systems (eg PCX-T workstations) that don't fall into the above
-** categories will need to modify the needed drivers to perform
-** flush/purge and allocate "regular" cacheable pages for everything.
-*/
-
-extern struct pci_dma_ops *hppa_dma_ops;
-
-#ifdef CONFIG_PA11
-extern struct pci_dma_ops pcxl_dma_ops;
-extern struct pci_dma_ops pcx_dma_ops;
-#endif
-
-/*
-** Oops hard if we haven't setup hppa_dma_ops by the time the first driver
-** attempts to initialize.
-** Since panic() is a (void)(), pci_dma_panic() is needed to satisfy
-** the (int)() required by pci_dma_supported() interface.
-*/
-static inline int pci_dma_panic(char *msg)
-{
-	extern void panic(const char *, ...);	/* linux/kernel.h */
-	panic(msg);
-	/* NOTREACHED */
-	return -1;
-}
-
-#define pci_dma_supported(p, m)	( \
-	(NULL == hppa_dma_ops) \
-	?  pci_dma_panic("Dynamic DMA support missing...OOPS!\n(Hint: was Astro/Ike/U2/Uturn not claimed?)\n") \
-	: hppa_dma_ops->dma_supported(p,m) \
-)
-
-#define pci_alloc_consistent(p, s, a)	hppa_dma_ops->alloc_consistent(p,s,a)
-#define pci_free_consistent(p, s, v, a)	hppa_dma_ops->free_consistent(p,s,v,a)
-#define pci_map_single(p, v, s, d)	hppa_dma_ops->map_single(p, v, s, d)
-#define pci_unmap_single(p, a, s, d)	hppa_dma_ops->unmap_single(p, a, s, d)
-#define pci_map_sg(p, sg, n, d)		hppa_dma_ops->map_sg(p, sg, n, d)
-#define pci_unmap_sg(p, sg, n, d)	hppa_dma_ops->unmap_sg(p, sg, n, d)
-
 /* pci_unmap_{single,page} is not a nop, thus... */
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
 	dma_addr_t ADDR_NAME;
@@ -213,24 +145,6 @@
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)		\
 	(((PTR)->LEN_NAME) = (VAL))
 
-/* For U2/Astro/Ike based platforms (which are fully I/O coherent)
-** dma_sync is a NOP. Let's keep the performance path short here.
-*/
-#define pci_dma_sync_single(p, a, s, d)	{ if (hppa_dma_ops->dma_sync_single) \
-	hppa_dma_ops->dma_sync_single(p, a, s, d); \
-	}
-#define pci_dma_sync_sg(p, sg, n, d)	{ if (hppa_dma_ops->dma_sync_sg) \
-	hppa_dma_ops->dma_sync_sg(p, sg, n, d); \
-	}
-
-/* No highmem on parisc, plus we have an IOMMU, so mapping pages is easy. */
-#define pci_map_page(dev, page, off, size, dir) \
-	pci_map_single(dev, (page_address(page) + (off)), size, dir)
-#define pci_unmap_page(dev,addr,sz,dir) pci_unmap_single(dev,addr,sz,dir)
-
-/* Don't support DAC yet. */
-#define pci_dac_dma_supported(pci_dev, mask)	(0)
-
 /*
 ** Stuff declared in arch/parisc/kernel/pci.c
 */
@@ -243,7 +157,6 @@
 #ifdef CONFIG_PCI
 extern void pcibios_register_hba(struct pci_hba_data *);
 extern void pcibios_set_master(struct pci_dev *);
-extern void pcibios_assign_unassigned_resources(struct pci_bus *);
 #else
 extern inline void pcibios_register_hba(struct pci_hba_data *x)
 {
@@ -264,35 +177,13 @@
 #define PCIBIOS_MIN_IO          0x10
 #define PCIBIOS_MIN_MEM         0x1000 /* NBPG - but pci/setup-res.c dies */
 
-/* Return the index of the PCI controller for device PDEV. */
-#define pci_controller_num(PDEV)	(0)
+/* Don't support DAC yet. */
+#define pci_dac_dma_supported(pci_dev, mask)   (0)
 
-#define GET_IOC(dev) ((struct ioc *)(HBA_DATA(dev->sysdata)->iommu))
+/* Return the index of the PCI controller for device PDEV. */
+#define	pci_controller_num(PDEV)	(0)
 
-#ifdef CONFIG_IOMMU_CCIO
-struct parisc_device;
-struct ioc;
-void * ccio_get_iommu(const struct parisc_device *dev);
-struct pci_dev * ccio_get_fake(const struct parisc_device *dev);
-int ccio_request_resource(const struct parisc_device *dev,
-		struct resource *res);
-int ccio_allocate_resource(const struct parisc_device *dev,
-		struct resource *res, unsigned long size,
-		unsigned long min, unsigned long max, unsigned long align,
-		void (*alignf)(void *, struct resource *, unsigned long, unsigned long),
-		void *alignf_data);
-#else /* !CONFIG_IOMMU_CCIO */
-#define ccio_get_iommu(dev) NULL
-#define ccio_get_fake(dev) NULL
-#define ccio_request_resource(dev, res) request_resource(&iomem_resource, res)
-#define ccio_allocate_resource(dev, res, size, min, max, align, alignf, data) \
-		allocate_resource(&iomem_resource, res, size, min, max, \
-				align, alignf, data)
-#endif /* !CONFIG_IOMMU_CCIO */
-
-#ifdef CONFIG_IOMMU_SBA
-struct parisc_device;
-void * sba_get_iommu(struct parisc_device *dev);
-#endif
+/* export the pci_ DMA API in terms of the dma_ one */
+#include <asm-generic/pci-dma-compat.h>
 
 #endif /* __ASM_PARISC_PCI_H */
diff -Nru a/include/asm-parisc/posix_types.h b/include/asm-parisc/posix_types.h
--- a/include/asm-parisc/posix_types.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-parisc/posix_types.h	Mon Jan 13 21:59:51 2003
@@ -55,27 +55,6 @@
 typedef __kernel_uid_t __kernel_old_uid_t;
 typedef __kernel_gid_t __kernel_old_gid_t;
 
-#if defined(__KERNEL__) && defined(__LP64__)
-/* Now 32bit compatibility types */
-typedef unsigned int		__kernel_dev_t32;
-typedef unsigned int		__kernel_ino_t32;
-typedef unsigned short		__kernel_mode_t32;
-typedef unsigned short		__kernel_nlink_t32;
-typedef int			__kernel_off_t32;
-typedef int			__kernel_pid_t32;
-typedef unsigned short		__kernel_ipc_pid_t32;
-typedef unsigned int		__kernel_uid_t32;
-typedef unsigned int		__kernel_gid_t32;
-typedef unsigned int		__kernel_size_t32;
-typedef int			__kernel_ssize_t32;
-typedef int			__kernel_ptrdiff_t32;
-typedef int			__kernel_time_t32;
-typedef int			__kernel_suseconds_t32;
-typedef int			__kernel_clock_t32;
-typedef int			__kernel_daddr_t32;
-typedef unsigned int		__kernel_caddr_t32;
-#endif
-
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #undef __FD_SET
diff -Nru a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
--- a/include/asm-parisc/processor.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-parisc/processor.h	Mon Jan 13 21:59:51 2003
@@ -140,10 +140,7 @@
  * Return saved PC of a blocked thread.  This is used by ps mostly.
  */
 
-static inline unsigned long thread_saved_pc(struct task_struct *t)
-{
-	return 0xabcdef;
-}
+unsigned long thread_saved_pc(struct task_struct *t);
 
 /*
  * Start user thread in another space.
diff -Nru a/include/asm-parisc/stat.h b/include/asm-parisc/stat.h
--- a/include/asm-parisc/stat.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/stat.h	Mon Jan 13 21:59:49 2003
@@ -89,11 +89,11 @@
 
 	signed long long	st_blocks;
 	signed int		st_atime;
-	unsigned int		__unused1;
+	unsigned int		st_atime_nsec;
 	signed int		st_mtime;
-	unsigned int		__unused2;
+	unsigned int		st_mtime_nsec;
 	signed int		st_ctime;
-	unsigned int		__unused3;
+	unsigned int		st_ctime_nsec;
 	unsigned long long	st_ino;
 };
 
diff -Nru a/include/asm-parisc/system.h b/include/asm-parisc/system.h
--- a/include/asm-parisc/system.h	Mon Jan 13 21:59:50 2003
+++ b/include/asm-parisc/system.h	Mon Jan 13 21:59:50 2003
@@ -129,6 +129,7 @@
 #define rmb()		mb()
 #define wmb()		mb()
 #define smp_mb()	mb()
+#define smp_rmb()	mb()
 #define smp_wmb()	mb()
 #define smp_read_barrier_depends()	do { } while(0)
 #define read_barrier_depends()		do { } while(0)
diff -Nru a/include/asm-parisc/thread_info.h b/include/asm-parisc/thread_info.h
--- a/include/asm-parisc/thread_info.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/thread_info.h	Mon Jan 13 21:59:49 2003
@@ -12,6 +12,7 @@
 	__u32 flags;			/* thread_info flags (see TIF_*) */
 	__u32 cpu;			/* current CPU */
 	mm_segment_t addr_limit;	/* user-level address space limit */
+	struct restart_block restart_block;
 	__s32 preempt_count;		/* 0=premptable, <0=BUG; will also serve as bh-counter */
 };
 
@@ -59,9 +60,6 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_32BIT               5       /* 32 bit binary */
-
-#define TIF_WORK_MASK		0x7	/* like TIF_ALLWORK_BITS but sans TIF_SYSCALL_TRACE */
-#define TIF_ALLWORK_MASK	0xf	/* bits 0..3 are "work to do on user-return" bits */
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
diff -Nru a/include/asm-parisc/uaccess.h b/include/asm-parisc/uaccess.h
--- a/include/asm-parisc/uaccess.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/uaccess.h	Mon Jan 13 21:59:49 2003
@@ -37,8 +37,8 @@
 #if BITS_PER_LONG == 32
 #define LDD_KERNEL(ptr)		BUG()
 #define LDD_USER(ptr)		BUG()
-#define STD_KERNEL(x, ptr) __put_kernel_asm64(x,ptr)
-#define STD_USER(x, ptr) __put_user_asm64(x,ptr)
+#define STD_KERNEL(x, ptr) __put_kernel_asm64((u32)x,ptr)
+#define STD_USER(x, ptr) __put_user_asm64((u32)x,ptr)
 #else
 #define LDD_KERNEL(ptr) __get_kernel_asm("ldd",ptr)
 #define LDD_USER(ptr) __get_user_asm("ldd",ptr)
@@ -60,9 +60,6 @@
 	unsigned long addr;  /* address of insn that is allowed to fault.   */
 	long skip;           /* pcoq skip | r9 clear flag | r8 -EFAULT flag */
 };
-
-extern const struct exception_table_entry 
-    *search_exception_table(unsigned long addr);
 
 #define __get_user(x,ptr)                               \
 ({                                                      \
diff -Nru a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
--- a/include/asm-parisc/unistd.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-parisc/unistd.h	Mon Jan 13 21:59:49 2003
@@ -701,8 +701,28 @@
 #define __NR_gettid             (__NR_Linux + 206)
 #define __NR_readahead          (__NR_Linux + 207)
 #define __NR_tkill		(__NR_Linux + 208)
+#define __NR_sendfile64		(__NR_Linux + 209)
+#define __NR_futex		(__NR_Linux + 210)
+#define __NR_sched_setaffinity	(__NR_Linux + 211)
+#define __NR_sched_getaffinity	(__NR_Linux + 212)
+#define __NR_set_thread_area	(__NR_Linux + 213)
+#define __NR_get_thread_area	(__NR_Linux + 214)
+#define __NR_io_setup		(__NR_Linux + 215)
+#define __NR_io_destroy		(__NR_Linux + 216)
+#define __NR_io_getevents	(__NR_Linux + 217)
+#define __NR_io_submit		(__NR_Linux + 218)
+#define __NR_io_cancel		(__NR_Linux + 219)
+#define __NR_alloc_hugepages	(__NR_Linux + 220)
+#define __NR_free_hugepages	(__NR_Linux + 221)
+#define __NR_exit_group		(__NR_Linux + 222)
+#define __NR_lookup_dcookie	(__NR_Linux + 223)
+#define __NR_epoll_create	(__NR_Linux + 224)
+#define __NR_epoll_ctl		(__NR_Linux + 225)
+#define __NR_epoll_wait		(__NR_Linux + 226)
+#define __NR_remap_file_pages	(__NR_Linux + 227)
 
-#define __NR_Linux_syscalls     208
+
+#define __NR_Linux_syscalls     228
 
 #define HPUX_GATEWAY_ADDR       0xC0000004
 #define LINUX_GATEWAY_ADDR      0x100
diff -Nru a/include/asm-ppc/bug.h b/include/asm-ppc/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,21 @@
+#ifndef _PPC_BUG_H
+#define _PPC_BUG_H
+
+#include <linux/config.h>
+#include <asm/system.h> /* for xmon definition */
+
+#ifdef CONFIG_XMON
+extern void xmon(struct pt_regs *);
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	xmon(0); \
+} while (0)
+#else
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	__asm__ __volatile__(".long 0x0"); \
+} while (0)
+#endif
+#define PAGE_BUG(page) do { BUG(); } while (0)
+
+#endif
diff -Nru a/include/asm-ppc/page.h b/include/asm-ppc/page.h
--- a/include/asm-ppc/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-ppc/page.h	Mon Jan 13 21:59:49 2003
@@ -14,9 +14,6 @@
 #define KERNELBASE	PAGE_OFFSET
 
 #ifndef __ASSEMBLY__
-#include <asm/processor.h>	/* for BUG definition */
-
-#define PAGE_BUG(page) do { BUG(); } while (0)
 
 #define STRICT_MM_TYPECHECKS
 
diff -Nru a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
--- a/include/asm-ppc/processor.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-ppc/processor.h	Mon Jan 13 21:59:49 2003
@@ -718,19 +718,6 @@
 
 #define spin_lock_prefetch(x)	prefetchw(x)
 
-#ifdef CONFIG_XMON
-extern void xmon(struct pt_regs *);
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	xmon(0); \
-} while (0)
-#else
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	__asm__ __volatile__(".long 0x0"); \
-} while (0)
-#endif
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_PPC_PROCESSOR_H */
diff -Nru a/include/asm-s390/bug.h b/include/asm-s390/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,13 @@
+#ifndef _S390_BUG_H
+#define _S390_BUG_H
+
+#define BUG() do { \
+        printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+        __asm__ __volatile__(".long 0"); \
+} while (0)                                       
+
+#define PAGE_BUG(page) do { \
+        BUG(); \
+} while (0)                      
+
+#endif
diff -Nru a/include/asm-s390/page.h b/include/asm-s390/page.h
--- a/include/asm-s390/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-s390/page.h	Mon Jan 13 21:59:49 2003
@@ -62,15 +62,6 @@
 #define clear_user_page(page, vaddr, pg)	clear_page(page)
 #define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
-#define BUG() do { \
-        printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-        __asm__ __volatile__(".long 0"); \
-} while (0)                                       
-
-#define PAGE_BUG(page) do { \
-        BUG(); \
-} while (0)                      
-
 /* Pure 2^n version of get_order */
 extern __inline__ int get_order(unsigned long size)
 {
diff -Nru a/include/asm-s390x/bug.h b/include/asm-s390x/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390x/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,13 @@
+#ifndef _S390_BUG_H
+#define _S390_BUG_H
+
+#define BUG() do { \
+        printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+        __asm__ __volatile__(".long 0"); \
+} while (0)                                       
+
+#define PAGE_BUG(page) do { \
+        BUG(); \
+} while (0)                      
+
+#endif
diff -Nru a/include/asm-s390x/page.h b/include/asm-s390x/page.h
--- a/include/asm-s390x/page.h	Mon Jan 13 21:59:50 2003
+++ b/include/asm-s390x/page.h	Mon Jan 13 21:59:50 2003
@@ -60,15 +60,6 @@
 #define clear_user_page(page, vaddr, pg)    clear_page(page)
 #define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
 
-#define BUG() do { \
-        printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-        __asm__ __volatile__(".long 0"); \
-} while (0)                                       
-
-#define PAGE_BUG(page) do { \
-        BUG(); \
-} while (0)                      
-
 /* Pure 2^n version of get_order */
 extern __inline__ int get_order(unsigned long size)
 {
diff -Nru a/include/asm-sh/bug.h b/include/asm-sh/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sh/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,16 @@
+#ifndef __ASM_SH_BUG_H
+#define __ASM_SH_BUG_H
+
+/*
+ * Tell the user there is some problem.
+ */
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	asm volatile("nop"); \
+} while (0)
+
+#define PAGE_BUG(page) do { \
+	BUG(); \
+} while (0)
+
+#endif
diff -Nru a/include/asm-sh/page.h b/include/asm-sh/page.h
--- a/include/asm-sh/page.h	Mon Jan 13 21:59:51 2003
+++ b/include/asm-sh/page.h	Mon Jan 13 21:59:51 2003
@@ -90,18 +90,6 @@
 
 #ifndef __ASSEMBLY__
 
-/*
- * Tell the user there is some problem.
- */
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	asm volatile("nop"); \
-} while (0)
-
-#define PAGE_BUG(page) do { \
-	BUG(); \
-} while (0)
-
 /* Pure 2^n version of get_order */
 static __inline__ int get_order(unsigned long size)
 {
diff -Nru a/include/asm-sparc/bug.h b/include/asm-sparc/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sparc/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,25 @@
+/* $Id$ */
+#ifndef _SPARC_BUG_H
+#define _SPARC_BUG_H
+
+/*
+ * XXX I am hitting compiler bugs with __builtin_trap. This has
+ * hit me before and rusty was blaming his netfilter bugs on
+ * this so lets disable it. - Anton
+ */
+#if 0
+/* We need the mb()'s so we don't trigger a compiler bug - Anton */
+#define BUG() do { \
+	mb(); \
+	__builtin_trap(); \
+	mb(); \
+} while(0)
+#else
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; \
+} while (0)
+#endif
+
+#define PAGE_BUG(page)	BUG()
+
+#endif
diff -Nru a/include/asm-sparc/page.h b/include/asm-sparc/page.h
--- a/include/asm-sparc/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-sparc/page.h	Mon Jan 13 21:59:49 2003
@@ -29,26 +29,6 @@
 
 #ifndef __ASSEMBLY__
 
-/*
- * XXX I am hitting compiler bugs with __builtin_trap. This has
- * hit me before and rusty was blaming his netfilter bugs on
- * this so lets disable it. - Anton
- */
-#if 0
-/* We need the mb()'s so we don't trigger a compiler bug - Anton */
-#define BUG() do { \
-	mb(); \
-	__builtin_trap(); \
-	mb(); \
-} while(0)
-#else
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; \
-} while (0)
-#endif
-
-#define PAGE_BUG(page)	BUG()
-
 #define clear_page(page)	 memset((void *)(page), 0, PAGE_SIZE)
 #define copy_page(to,from) 	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
 #define clear_user_page(addr, vaddr, page)	clear_page(addr)
diff -Nru a/include/asm-sparc64/bug.h b/include/asm-sparc64/bug.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sparc64/bug.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,17 @@
+/* $Id$ */
+
+#ifndef _SPARC64_BUG_H
+#define _SPARC64_BUG_H
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+extern void do_BUG(const char *file, int line);
+#define BUG() do {					\
+	do_BUG(__FILE__, __LINE__);			\
+	__builtin_trap();				\
+} while (0)
+#else
+#define BUG()		__builtin_trap()
+#endif
+
+
+#endif
diff -Nru a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h
--- a/include/asm-sparc64/page.h	Mon Jan 13 21:59:49 2003
+++ b/include/asm-sparc64/page.h	Mon Jan 13 21:59:49 2003
@@ -20,18 +20,6 @@
 
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-extern void do_BUG(const char *file, int line);
-#define BUG() do {					\
-	do_BUG(__FILE__, __LINE__);			\
-	__builtin_trap();				\
-} while (0)
-#else
-#define BUG()		__builtin_trap()
-#endif
-
-#define PAGE_BUG(page)	BUG()
-
 /* Sparc64 is slow at multiplication, we prefer to use some extra space. */
 #define WANT_PAGE_VIRTUAL 1
 
diff -Nru a/include/asm-v850/system.h b/include/asm-v850/system.h
--- a/include/asm-v850/system.h	Mon Jan 13 21:59:50 2003
+++ b/include/asm-v850/system.h	Mon Jan 13 21:59:50 2003
@@ -76,10 +76,12 @@
 #define smp_mb()	mb ()
 #define smp_rmb()	rmb ()
 #define smp_wmb()	wmb ()
+#define smp_read_barrier_depends()	read_barrier_depends()
 #else
 #define smp_mb()	barrier ()
 #define smp_rmb()	barrier ()
 #define smp_wmb()	barrier ()
+#define smp_read_barrier_depends()	((void)0)
 #endif
 
 #define xchg(ptr, with) \
diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h
--- a/include/linux/cpufreq.h	Mon Jan 13 21:59:50 2003
+++ b/include/linux/cpufreq.h	Mon Jan 13 21:59:50 2003
@@ -17,6 +17,7 @@
 #include <linux/config.h>
 #include <linux/notifier.h>
 #include <linux/threads.h>
+#include <linux/device.h>
 
 
 /*********************************************************************
@@ -57,6 +58,7 @@
 	unsigned int            max;    /* in kHz */
         unsigned int            policy; /* see above */
 	struct cpufreq_cpuinfo  cpuinfo;     /* see above */
+	struct intf_data        intf;   /* interface data */
 };
 
 #define CPUFREQ_ADJUST          (0)
@@ -107,19 +109,29 @@
  *                      CPUFREQ DRIVER INTERFACE                     *
  *********************************************************************/
 
+#define CPUFREQ_NAME_LEN 16
+
 struct cpufreq_driver {
 	/* needed by all drivers */
 	int     (*verify)       (struct cpufreq_policy *policy);
 	int     (*setpolicy)    (struct cpufreq_policy *policy);
 	struct cpufreq_policy   *policy;
+	char           		name[CPUFREQ_NAME_LEN];
+	/* optional, for the moment */
+	int     (*init)        (struct cpufreq_policy *policy);
+	int     (*exit)        (struct cpufreq_policy *policy);
 	/* 2.4. compatible API */
 #ifdef CONFIG_CPU_FREQ_24_API
 	unsigned int            cpu_cur_freq[NR_CPUS];
 #endif
 };
 
-int cpufreq_register(struct cpufreq_driver *driver_data);
-int cpufreq_unregister(void);
+int cpufreq_register_driver(struct cpufreq_driver *driver_data);
+int cpufreq_unregister_driver(struct cpufreq_driver *driver_data);
+/* deprecated */
+#define cpufreq_register(x)   cpufreq_register_driver(x)
+#define cpufreq_unregister(x) cpufreq_unregister_driver(NULL)
+
 
 void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state);
 
diff -Nru a/include/linux/dcache.h b/include/linux/dcache.h
--- a/include/linux/dcache.h	Mon Jan 13 21:59:51 2003
+++ b/include/linux/dcache.h	Mon Jan 13 21:59:51 2003
@@ -7,7 +7,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/cache.h>
-#include <asm/page.h>			/* for BUG() */
+#include <asm/bug.h>
 
 struct vfsmount;
 
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	Mon Jan 13 21:59:51 2003
+++ b/include/linux/device.h	Mon Jan 13 21:59:51 2003
@@ -98,7 +98,7 @@
 struct bus_attribute {
 	struct attribute	attr;
 	ssize_t (*show)(struct bus_type *, char * buf);
-	ssize_t (*store)(struct bus_type *, const char * buf);
+	ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
 };
 
 #define BUS_ATTR(_name,_mode,_show,_store)	\
@@ -141,7 +141,7 @@
 struct driver_attribute {
 	struct attribute	attr;
 	ssize_t (*show)(struct device_driver *, char * buf);
-	ssize_t (*store)(struct device_driver *, const char * buf);
+	ssize_t (*store)(struct device_driver *, const char * buf, size_t count);
 };
 
 #define DRIVER_ATTR(_name,_mode,_show,_store)	\
@@ -182,7 +182,7 @@
 struct devclass_attribute {
 	struct attribute	attr;
 	ssize_t (*show)(struct device_class *, char * buf);
-	ssize_t (*store)(struct device_class *, const char * buf);
+	ssize_t (*store)(struct device_class *, const char * buf, size_t count);
 };
 
 #define DEVCLASS_ATTR(_name,_str,_mode,_show,_store)	\
@@ -320,7 +320,7 @@
 struct device_attribute {
 	struct attribute	attr;
 	ssize_t (*show)(struct device * dev, char * buf);
-	ssize_t (*store)(struct device * dev, const char * buf);
+	ssize_t (*store)(struct device * dev, const char * buf, size_t count);
 };
 
 #define DEVICE_ATTR(_name,_mode,_show,_store) \
diff -Nru a/include/linux/elevator.h b/include/linux/elevator.h
--- a/include/linux/elevator.h	Mon Jan 13 21:59:49 2003
+++ b/include/linux/elevator.h	Mon Jan 13 21:59:49 2003
@@ -13,6 +13,7 @@
 typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, struct list_head *);
 typedef int (elevator_queue_empty_fn) (request_queue_t *);
 typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *);
+typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
 typedef struct list_head *(elevator_get_sort_head_fn) (request_queue_t *, struct request *);
 
 typedef int (elevator_init_fn) (request_queue_t *, elevator_t *);
@@ -29,12 +30,17 @@
 	elevator_remove_req_fn *elevator_remove_req_fn;
 
 	elevator_queue_empty_fn *elevator_queue_empty_fn;
-	elevator_get_sort_head_fn *elevator_get_sort_head_fn;
+
+	elevator_request_list_fn *elevator_former_req_fn;
+	elevator_request_list_fn *elevator_latter_req_fn;
 
 	elevator_init_fn *elevator_init_fn;
 	elevator_exit_fn *elevator_exit_fn;
 
 	void *elevator_data;
+
+	struct kobject kobj;
+	struct kobj_type *elevator_ktype;
 };
 
 /*
@@ -48,7 +54,10 @@
 extern void elv_merged_request(request_queue_t *, struct request *);
 extern void elv_remove_request(request_queue_t *, struct request *);
 extern int elv_queue_empty(request_queue_t *);
-extern inline struct list_head *elv_get_sort_head(request_queue_t *, struct request *);
+extern struct request *elv_former_request(request_queue_t *, struct request *);
+extern struct request *elv_latter_request(request_queue_t *, struct request *);
+extern int elv_register_queue(struct gendisk *);
+extern void elv_unregister_queue(struct gendisk *);
 
 #define __elv_add_request_pos(q, rq, pos)	\
 	(q)->elevator.elevator_add_req_fn((q), (rq), (pos))
@@ -63,18 +72,6 @@
  * starvation
  */
 extern elevator_t iosched_deadline;
-
-/*
- * use the /proc/iosched interface, all the below is history ->
- */
-typedef struct blkelv_ioctl_arg_s {
-	int queue_ID;
-	int read_latency;
-	int write_latency;
-	int max_bomb_segments;
-} blkelv_ioctl_arg_t;
-#define BLKELVGET   _IOR(0x12,106,sizeof(blkelv_ioctl_arg_t))
-#define BLKELVSET   _IOW(0x12,107,sizeof(blkelv_ioctl_arg_t))
 
 extern int elevator_init(request_queue_t *, elevator_t *);
 extern void elevator_exit(request_queue_t *);
diff -Nru a/include/linux/elf.h b/include/linux/elf.h
--- a/include/linux/elf.h	Mon Jan 13 21:59:49 2003
+++ b/include/linux/elf.h	Mon Jan 13 21:59:49 2003
@@ -156,11 +156,12 @@
 #define STT_SECTION 3
 #define STT_FILE    4
 
-#define ELF32_ST_BIND(x) ((x) >> 4)
-#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
-
-#define ELF64_ST_BIND(x) ((x) >> 4)
-#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf)
+#define ELF_ST_BIND(x)		((x) >> 4)
+#define ELF_ST_TYPE(x)		(((unsigned int) x) & 0xf)
+#define ELF32_ST_BIND(x)	ELF_ST_BIND(x)
+#define ELF32_ST_TYPE(x)	ELF_ST_TYPE(x)
+#define ELF64_ST_BIND(x)	ELF_ST_BIND(x)
+#define ELF64_ST_TYPE(x)	ELF_ST_TYPE(x)
 
 /* Symbolic values for the entries in the auxiliary table
    put on the initial stack */
diff -Nru a/include/linux/ipmi.h b/include/linux/ipmi.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/ipmi.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,516 @@
+/*
+ * ipmi.h
+ *
+ * MontaVista IPMI interface
+ *
+ * Author: MontaVista Software, Inc.
+ *         Corey Minyard <minyard@mvista.com>
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LINUX_IPMI_H
+#define __LINUX_IPMI_H
+
+#include <linux/ipmi_msgdefs.h>
+
+/*
+ * This file describes an interface to an IPMI driver.  You have to
+ * have a fairly good understanding of IPMI to use this, so go read
+ * the specs first before actually trying to do anything.
+ *
+ * With that said, this driver provides a multi-user interface to the
+ * IPMI driver, and it allows multiple IPMI physical interfaces below
+ * the driver.  The physical interfaces bind as a lower layer on the
+ * driver.  They appear as interfaces to the application using this
+ * interface.
+ *
+ * Multi-user means that multiple applications may use the driver,
+ * send commands, receive responses, etc.  The driver keeps track of
+ * commands the user sends and tracks the responses.  The responses
+ * will go back to the application that send the command.  If the
+ * response doesn't come back in time, the driver will return a
+ * timeout error response to the application.  Asynchronous events
+ * from the BMC event queue will go to all users bound to the driver.
+ * The incoming event queue in the BMC will automatically be flushed
+ * if it becomes full and it is queried once a second to see if
+ * anything is in it.  Incoming commands to the driver will get
+ * delivered as commands.
+ *
+ * This driver provides two main interfaces: one for in-kernel
+ * applications and another for userland applications.  The
+ * capabilities are basically the same for both interface, although
+ * the interfaces are somewhat different.  The stuff in the
+ * #ifdef KERNEL below is the in-kernel interface.  The userland
+ * interface is defined later in the file.  */
+
+
+
+/*
+ * This is an overlay for all the address types, so it's easy to
+ * determine the actual address type.  This is kind of like addresses
+ * work for sockets.
+ */
+#define IPMI_MAX_ADDR_SIZE 32
+struct ipmi_addr
+{
+	 /* Try to take these from the "Channel Medium Type" table
+	    in section 6.5 of the IPMI 1.5 manual. */
+	int   addr_type;
+	short channel;
+	char  data[IPMI_MAX_ADDR_SIZE];
+};
+
+/*
+ * When the address is not used, the type will be set to this value.
+ * The channel is the BMC's channel number for the channel (usually
+ * 0), or IPMC_BMC_CHANNEL if communicating directly with the BMC.
+ */
+#define IPMI_SYSTEM_INTERFACE_ADDR_TYPE	0x0c
+struct ipmi_system_interface_addr
+{
+	int           addr_type;
+	short         channel;
+	unsigned char lun;
+};
+
+/* An IPMB Address. */
+#define IPMI_IPMB_ADDR_TYPE		0x01
+/* Used for broadcast get device id as described in section 17.9 of the
+   IPMI 1.5 manual. */ 
+#define IPMI_IPMB_BROADCAST_ADDR_TYPE	0x41
+struct ipmi_ipmb_addr
+{
+	int           addr_type;
+	short         channel;
+	unsigned char slave_addr;
+	unsigned char lun;
+};
+
+
+/*
+ * Channel for talking directly with the BMC.  When using this
+ * channel, This is for the system interface address type only.  FIXME
+ * - is this right, or should we use -1?
+ */
+#define IPMI_BMC_CHANNEL  0xf
+#define IPMI_NUM_CHANNELS 0x10
+
+
+/*
+ * A raw IPMI message without any addressing.  This covers both
+ * commands and responses.  The completion code is always the first
+ * byte of data in the response (as the spec shows the messages laid
+ * out).
+ */
+struct ipmi_msg
+{
+	unsigned char  netfn;
+	unsigned char  cmd;
+	unsigned short data_len;
+	unsigned char  *data;
+};
+
+/*
+ * Various defines that are useful for IPMI applications.
+ */
+#define IPMI_INVALID_CMD_COMPLETION_CODE	0xC1
+#define IPMI_TIMEOUT_COMPLETION_CODE		0xC3
+#define IPMI_UNKNOWN_ERR_COMPLETION_CODE	0xff
+
+
+/*
+ * Receive types for messages coming from the receive interface.  This
+ * is used for the receive in-kernel interface and in the receive
+ * IOCTL.
+ */
+#define IPMI_RESPONSE_RECV_TYPE		1 /* A response to a command */
+#define IPMI_ASYNC_EVENT_RECV_TYPE	2 /* Something from the event queue */
+#define IPMI_CMD_RECV_TYPE		3 /* A command from somewhere else */
+/* Note that async events and received commands do not have a completion
+   code as the first byte of the incoming data, unlike a response. */
+
+
+
+#ifdef __KERNEL__
+
+/*
+ * The in-kernel interface.
+ */
+#include <linux/list.h>
+
+/* Opaque type for a IPMI message user.  One of these is needed to
+   send and receive messages. */
+typedef struct ipmi_user *ipmi_user_t;
+
+/*
+ * Stuff coming from the recieve interface comes as one of these.
+ * They are allocated, the receiver must free them with
+ * ipmi_free_recv_msg() when done with the message.  The link is not
+ * used after the message is delivered, so the upper layer may use the
+ * link to build a linked list, if it likes.
+ */
+struct ipmi_recv_msg
+{
+	struct list_head link;
+
+	/* The type of message as defined in the "Receive Types"
+           defines above. */
+	int              recv_type;
+
+	ipmi_user_t      user;
+	struct ipmi_addr addr;
+	long             msgid;
+	struct ipmi_msg  msg;
+
+	/* Call this when done with the message.  It will presumably free
+	   the message and do any other necessary cleanup. */
+	void (*done)(struct ipmi_recv_msg *msg);
+
+	/* Place-holder for the data, don't make any assumptions about
+	   the size or existance of this, since it may change. */
+	unsigned char   msg_data[IPMI_MAX_MSG_LENGTH];
+};
+
+/* Allocate and free the receive message. */
+static inline void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
+{
+	msg->done(msg);
+}
+struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
+
+struct ipmi_user_hndl
+{
+        /* Routine type to call when a message needs to be routed to
+	   the upper layer.  This will be called with some locks held,
+	   the only IPMI routines that can be called are ipmi_request
+	   and the alloc/free operations. */
+	void (*ipmi_recv_hndl)(struct ipmi_recv_msg *msg,
+			       void                 *handler_data);
+
+	/* Called when the interface detects a watchdog pre-timeout.  If
+	   this is NULL, it will be ignored for the user. */
+	void (*ipmi_watchdog_pretimeout)(void *handler_data);
+};
+
+/* Create a new user of the IPMI layer on the given interface number. */
+int ipmi_create_user(unsigned int          if_num,
+		     struct ipmi_user_hndl *handler,
+		     void                  *handler_data,
+		     ipmi_user_t           *user);
+
+/* Destroy the given user of the IPMI layer. */
+int ipmi_destroy_user(ipmi_user_t user);
+
+/* Get the IPMI version of the BMC we are talking to. */
+void ipmi_get_version(ipmi_user_t   user,
+		      unsigned char *major,
+		      unsigned char *minor);
+
+/* Set and get the slave address and LUN that we will use for our
+   source messages.  Note that this affects the interface, not just
+   this user, so it will affect all users of this interface.  This is
+   so some initialization code can come in and do the OEM-specific
+   things it takes to determine your address (if not the BMC) and set
+   it for everyone else. */
+void ipmi_set_my_address(ipmi_user_t   user,
+			 unsigned char address);
+unsigned char ipmi_get_my_address(ipmi_user_t user);
+void ipmi_set_my_LUN(ipmi_user_t   user,
+		     unsigned char LUN);
+unsigned char ipmi_get_my_LUN(ipmi_user_t user);
+
+/*
+ * Send a command request from the given user.  The address is the
+ * proper address for the channel type.  If this is a command, then
+ * the message response comes back, the receive handler for this user
+ * will be called with the given msgid value in the recv msg.  If this
+ * is a response to a command, then the msgid will be used as the
+ * sequence number for the response (truncated if necessary), so when
+ * sending a response you should use the sequence number you received
+ * in the msgid field of the received command.  If the priority is >
+ * 0, the message will go into a high-priority queue and be sent
+ * first.  Otherwise, it goes into a normal-priority queue.
+ */
+int ipmi_request(ipmi_user_t      user,
+		 struct ipmi_addr *addr,
+		 long             msgid,
+		 struct ipmi_msg  *msg,
+		 int              priority);
+
+/*
+ * Like ipmi_request, but lets you specify the slave return address.
+ */
+int ipmi_request_with_source(ipmi_user_t      user,
+			     struct ipmi_addr *addr,
+			     long             msgid,
+			     struct ipmi_msg  *msg,
+			     int              priority,
+			     unsigned char    source_address,
+			     unsigned char    source_lun);
+
+/*
+ * Like ipmi_request, but with messages supplied.  This will not
+ * allocate any memory, and the messages may be statically allocated
+ * (just make sure to do the "done" handling on them).  Note that this
+ * is primarily for the watchdog timer, since it should be able to
+ * send messages even if no memory is available.  This is subject to
+ * change as the system changes, so don't use it unless you REALLY
+ * have to.
+ */
+int ipmi_request_supply_msgs(ipmi_user_t          user,
+			     struct ipmi_addr     *addr,
+			     long                 msgid,
+			     struct ipmi_msg      *msg,
+			     void                 *supplied_smi,
+			     struct ipmi_recv_msg *supplied_recv,
+			     int                  priority);
+
+/*
+ * When commands come in to the SMS, the user can register to receive
+ * them.  Only one user can be listening on a specific netfn/cmd pair
+ * at a time, you will get an EBUSY error if the command is already
+ * registered.  If a command is received that does not have a user
+ * registered, the driver will automatically return the proper
+ * error.
+ */
+int ipmi_register_for_cmd(ipmi_user_t   user,
+			  unsigned char netfn,
+			  unsigned char cmd);
+int ipmi_unregister_for_cmd(ipmi_user_t   user,
+			    unsigned char netfn,
+			    unsigned char cmd);
+
+/*
+ * When the user is created, it will not receive IPMI events by
+ * default.  The user must set this to TRUE to get incoming events.
+ * The first user that sets this to TRUE will receive all events that
+ * have been queued while no one was waiting for events.
+ */
+int ipmi_set_gets_events(ipmi_user_t user, int val);
+
+/*
+ * Register the given user to handle all received IPMI commands.  This
+ * will fail if anyone is registered as a command receiver or if
+ * another is already registered to receive all commands.  NOTE THAT
+ * THIS IS FOR EMULATION USERS ONLY, DO NOT USER THIS FOR NORMAL
+ * STUFF.
+ */
+int ipmi_register_all_cmd_rcvr(ipmi_user_t user);
+int ipmi_unregister_all_cmd_rcvr(ipmi_user_t user);
+
+
+/*
+ * Called when a new SMI is registered.  This will also be called on
+ * every existing interface when a new watcher is registered with
+ * ipmi_smi_watcher_register().
+ */
+struct ipmi_smi_watcher
+{
+	struct list_head link;
+
+	/* These two are called with read locks held for the interface
+	   the watcher list.  So you can add and remove users from the
+	   IPMI interface, send messages, etc., but you cannot add
+	   or remove SMI watchers or SMI interfaces. */
+	void (*new_smi)(int if_num);
+	void (*smi_gone)(int if_num);
+};
+
+int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher);
+int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher);
+
+/* The following are various helper functions for dealing with IPMI
+   addresses. */
+
+/* Return the maximum length of an IPMI address given it's type. */
+unsigned int ipmi_addr_length(int addr_type);
+
+/* Validate that the given IPMI address is valid. */
+int ipmi_validate_addr(struct ipmi_addr *addr, int len);
+
+/* Return 1 if the given addresses are equal, 0 if not. */
+int ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2);
+
+#endif /* __KERNEL__ */
+
+
+/*
+ * The userland interface
+ */
+
+/*
+ * The userland interface for the IPMI driver is a standard character
+ * device, with each instance of an interface registered as a minor
+ * number under the major character device.
+ *
+ * The read and write calls do not work, to get messages in and out
+ * requires ioctl calls because of the complexity of the data.  select
+ * and poll do work, so you can wait for input using the file
+ * descriptor, you just can use read to get it.
+ *
+ * In general, you send a command down to the interface and receive
+ * responses back.  You can use the msgid value to correlate commands
+ * and responses, the driver will take care of figuring out which
+ * incoming messages are for which command and find the proper msgid
+ * value to report.  You will only receive reponses for commands you
+ * send.  Asynchronous events, however, go to all open users, so you
+ * must be ready to handle these (or ignore them if you don't care).
+ *
+ * The address type depends upon the channel type.  When talking
+ * directly to the BMC (IPMC_BMC_CHANNEL), the address is ignored
+ * (IPMI_UNUSED_ADDR_TYPE).  When talking to an IPMB channel, you must
+ * supply a valid IPMB address with the addr_type set properly.
+ *
+ * When talking to normal channels, the driver takes care of the
+ * details of formatting and sending messages on that channel.  You do
+ * not, for instance, have to format a send command, you just send
+ * whatever command you want to the channel, the driver will create
+ * the send command, automatically issue receive command and get even
+ * commands, and pass those up to the proper user.
+ */
+
+
+/* The magic IOCTL value for this interface. */
+#define IPMI_IOC_MAGIC 'i'
+
+
+/* Messages sent to the interface are this format. */
+struct ipmi_req
+{
+	unsigned char *addr; /* Address to send the message to. */
+	unsigned int  addr_len;
+
+	long    msgid; /* The sequence number for the message.  This
+			  exact value will be reported back in the
+			  response to this request if it is a command.
+			  If it is a response, this will be used as
+			  the sequence value for the response.  */
+
+	struct ipmi_msg msg;
+};
+/*
+ * Send a message to the interfaces.  error values are:
+ *   - EFAULT - an address supplied was invalid.
+ *   - EINVAL - The address supplied was not valid, or the command
+ *              was not allowed.
+ *   - EMSGSIZE - The message to was too large.
+ *   - ENOMEM - Buffers could not be allocated for the command.
+ */
+#define IPMICTL_SEND_COMMAND		_IOR(IPMI_IOC_MAGIC, 13,	\
+					     struct ipmi_req)
+
+/* Messages received from the interface are this format. */
+struct ipmi_recv
+{
+	int     recv_type; /* Is this a command, response or an
+			      asyncronous event. */
+
+	unsigned char *addr;    /* Address the message was from is put
+				   here.  The caller must supply the
+				   memory. */
+	unsigned int  addr_len; /* The size of the address buffer.
+				   The caller supplies the full buffer
+				   length, this value is updated to
+				   the actual message length when the
+				   message is received. */
+
+	long    msgid; /* The sequence number specified in the request
+			  if this is a response.  If this is a command,
+			  this will be the sequence number from the
+			  command. */
+
+	struct ipmi_msg msg; /* The data field must point to a buffer.
+				The data_size field must be set to the
+				size of the message buffer.  The
+				caller supplies the full buffer
+				length, this value is updated to the
+				actual message length when the message
+				is received. */
+};
+
+/*
+ * Receive a message.  error values:
+ *  - EAGAIN - no messages in the queue.
+ *  - EFAULT - an address supplied was invalid.
+ *  - EINVAL - The address supplied was not valid.
+ *  - EMSGSIZE - The message to was too large to fit into the message buffer,
+ *               the message will be left in the buffer. */
+#define IPMICTL_RECEIVE_MSG		_IOWR(IPMI_IOC_MAGIC, 12,	\
+					      struct ipmi_recv)
+
+/*
+ * Like RECEIVE_MSG, but if the message won't fit in the buffer, it
+ * will truncate the contents instead of leaving the data in the
+ * buffer.
+ */
+#define IPMICTL_RECEIVE_MSG_TRUNC	_IOWR(IPMI_IOC_MAGIC, 11,	\
+					      struct ipmi_recv)
+
+/* Register to get commands from other entities on this interface. */
+struct ipmi_cmdspec
+{
+	unsigned char netfn;
+	unsigned char cmd;
+};
+
+/* 
+ * Register to receive a specific command.  error values:
+ *   - EFAULT - an address supplied was invalid.
+ *   - EBUSY - The netfn/cmd supplied was already in use.
+ *   - ENOMEM - could not allocate memory for the entry.
+ */
+#define IPMICTL_REGISTER_FOR_CMD	_IOR(IPMI_IOC_MAGIC, 14,	\
+					     struct ipmi_cmdspec)
+/*
+ * Unregister a regsitered command.  error values:
+ *  - EFAULT - an address supplied was invalid.
+ *  - ENOENT - The netfn/cmd was not found registered for this user.
+ */
+#define IPMICTL_UNREGISTER_FOR_CMD	_IOR(IPMI_IOC_MAGIC, 15,	\
+					     struct ipmi_cmdspec)
+
+/* 
+ * Set whether this interface receives events.  Note that the first
+ * user registered for events will get all pending events for the
+ * interface.  error values:
+ *  - EFAULT - an address supplied was invalid.
+ */
+#define IPMICTL_SET_GETS_EVENTS_CMD	_IOR(IPMI_IOC_MAGIC, 16, int)
+
+/*
+ * Set and get the slave address and LUN that we will use for our
+ * source messages.  Note that this affects the interface, not just
+ * this user, so it will affect all users of this interface.  This is
+ * so some initialization code can come in and do the OEM-specific
+ * things it takes to determine your address (if not the BMC) and set
+ * it for everyone else.  You should probably leave the LUN alone.
+ */
+#define IPMICTL_SET_MY_ADDRESS_CMD	_IOR(IPMI_IOC_MAGIC, 17, unsigned int)
+#define IPMICTL_GET_MY_ADDRESS_CMD	_IOR(IPMI_IOC_MAGIC, 18, unsigned int)
+#define IPMICTL_SET_MY_LUN_CMD		_IOR(IPMI_IOC_MAGIC, 19, unsigned int)
+#define IPMICTL_GET_MY_LUN_CMD		_IOR(IPMI_IOC_MAGIC, 20, unsigned int)
+
+#endif /* __LINUX_IPMI_H */
diff -Nru a/include/linux/ipmi_msgdefs.h b/include/linux/ipmi_msgdefs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/ipmi_msgdefs.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,58 @@
+/*
+ * ipmi_smi.h
+ *
+ * MontaVista IPMI system management interface
+ *
+ * Author: MontaVista Software, Inc.
+ *         Corey Minyard <minyard@mvista.com>
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LINUX_IPMI_MSGDEFS_H
+#define __LINUX_IPMI_MSGDEFS_H
+
+/* Various definitions for IPMI messages used by almost everything in
+   the IPMI stack. */
+
+#define IPMI_NETFN_APP_REQUEST	0x06
+#define IPMI_NETFN_APP_RESPONSE	0x07
+
+#define IPMI_BMC_SLAVE_ADDR	0x20
+
+#define IPMI_GET_DEVICE_ID_CMD		0x01
+
+#define IPMI_CLEAR_MSG_FLAGS_CMD	0x30
+#define IPMI_GET_MSG_FLAGS_CMD		0x31
+#define IPMI_SEND_MSG_CMD		0x34
+#define IPMI_GET_MSG_CMD		0x33
+
+#define IPMI_SET_BMC_GLOBAL_ENABLES_CMD	0x2e
+#define IPMI_GET_BMC_GLOBAL_ENABLES_CMD	0x2f
+#define IPMI_READ_EVENT_MSG_BUFFER_CMD	0x35
+
+#define IPMI_MAX_MSG_LENGTH	80
+
+#endif /* __LINUX_IPMI_MSGDEFS_H */
diff -Nru a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/ipmi_smi.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,144 @@
+/*
+ * ipmi_smi.h
+ *
+ * MontaVista IPMI system management interface
+ *
+ * Author: MontaVista Software, Inc.
+ *         Corey Minyard <minyard@mvista.com>
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by the
+ *  Free Software Foundation; either version 2 of the License, or (at your
+ *  option) any later version.
+ *
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LINUX_IPMI_SMI_H
+#define __LINUX_IPMI_SMI_H
+
+#include <linux/ipmi_msgdefs.h>
+
+/* This files describes the interface for IPMI system management interface
+   drivers to bind into the IPMI message handler. */
+
+/* Structure for the low-level drivers. */
+typedef struct ipmi_smi *ipmi_smi_t;
+
+/*
+ * Messages to/from the lower layer.  The smi interface will take one
+ * of these to send. After the send has occurred and a response has
+ * been received, it will report this same data structure back up to
+ * the upper layer.  If an error occurs, it should fill in the
+ * response with an error code in the completion code location. When
+ * asyncronous data is received, one of these is allocated, the
+ * data_size is set to zero and the response holds the data from the
+ * get message or get event command that the interface initiated.
+ * Note that it is the interfaces responsibility to detect
+ * asynchronous data and messages and request them from the
+ * interface.
+ */
+struct ipmi_smi_msg
+{
+	struct list_head link;
+
+	long    msgid;
+	void    *user_data;
+
+	/* If 0, add to the end of the queue.  If 1, add to the beginning. */
+	int     prio;
+
+	int           data_size;
+	unsigned char data[IPMI_MAX_MSG_LENGTH];
+
+	int           rsp_size;
+	unsigned char rsp[IPMI_MAX_MSG_LENGTH];
+
+	/* Will be called when the system is done with the message
+           (presumably to free it). */
+	void (*done)(struct ipmi_smi_msg *msg);
+};
+
+struct ipmi_smi_handlers
+{
+	/* Called to enqueue an SMI message to be sent.  This
+	   operation is not allowed to fail.  If an error occurs, it
+	   should report back the error in a received message.  It may
+	   do this in the current call context, since no write locks
+	   are held when this is run.  If the priority is > 0, the
+	   message will go into a high-priority queue and be sent
+	   first.  Otherwise, it goes into a normal-priority queue. */
+	void (*sender)(void                *send_info,
+		       struct ipmi_smi_msg *msg,
+		       int                 priority);
+
+	/* Called by the upper layer to request that we try to get
+	   events from the BMC we are attached to. */
+	void (*request_events)(void *send_info);
+
+	/* Called when someone is using the interface, so the module can
+	   adjust it's use count.  Return zero if successful, or an
+	   errno if not. */
+	int (*new_user)(void *send_info);
+
+	/* Called when someone is no longer using the interface, so the
+	   module can adjust it's use count. */
+	void (*user_left)(void *send_info);
+
+	/* Called when the interface should go into "run to
+	   completion" mode.  If this call sets the value to true, the
+	   interface should make sure that all messages are flushed
+	   out and that none are pending, and any new requests are run
+	   to completion immediately. */
+	void (*set_run_to_completion)(void *send_info, int run_to_completion);
+};
+
+/* Add a low-level interface to the IPMI driver. */
+int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
+		      void                     *send_info,
+		      unsigned char            version_major,
+		      unsigned char            version_minor,
+		      ipmi_smi_t               *intf);
+
+/*
+ * Remove a low-level interface from the IPMI driver.  This will
+ * return an error if the interface is still in use by a user.
+ */
+int ipmi_unregister_smi(ipmi_smi_t intf);
+
+/*
+ * The lower layer reports received messages through this interface.
+ * The data_size should be zero if this is an asyncronous message.  If
+ * the lower layer gets an error sending a message, it should format
+ * an error response in the message response.
+ */
+void ipmi_smi_msg_received(ipmi_smi_t          intf,
+			   struct ipmi_smi_msg *msg);
+
+/* The lower layer received a watchdog pre-timeout on interface. */
+void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf);
+
+struct ipmi_smi_msg *ipmi_alloc_smi_msg(void);
+static inline void ipmi_free_smi_msg(struct ipmi_smi_msg *msg)
+{
+	msg->done(msg);
+}
+
+#endif /* __LINUX_IPMI_SMI_H */
diff -Nru a/include/linux/jbd.h b/include/linux/jbd.h
--- a/include/linux/jbd.h	Mon Jan 13 21:59:51 2003
+++ b/include/linux/jbd.h	Mon Jan 13 21:59:51 2003
@@ -194,6 +194,7 @@
 
 #include <linux/fs.h>
 #include <linux/sched.h>
+#include <asm/bug.h>
 
 #define JBD_ASSERTIONS
 #ifdef JBD_ASSERTIONS
@@ -778,14 +779,6 @@
 {
 	handle->h_aborted = 1;
 }
-
-/* Not all architectures define BUG() */
-#ifndef BUG
- #define BUG() do { \
-        printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	* ((char *) 0) = 0; \
- } while (0)
-#endif /* BUG */
 
 #endif /* __KERNEL__   */
 
diff -Nru a/include/linux/kernel.h b/include/linux/kernel.h
--- a/include/linux/kernel.h	Mon Jan 13 21:59:48 2003
+++ b/include/linux/kernel.h	Mon Jan 13 21:59:48 2003
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <linux/compiler.h>
 #include <asm/byteorder.h>
+#include <asm/bug.h>
 
 /* Optimization barrier */
 /* The "volatile" is due to gcc bugs */
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h	Mon Jan 13 21:59:49 2003
+++ b/include/linux/kobject.h	Mon Jan 13 21:59:49 2003
@@ -166,7 +166,7 @@
 struct subsys_attribute {
 	struct attribute attr;
 	ssize_t (*show)(struct subsystem *, char *);
-	ssize_t (*store)(struct subsystem *, const char *); 
+	ssize_t (*store)(struct subsystem *, const char *, size_t); 
 };
 
 extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
diff -Nru a/include/linux/moduleloader.h b/include/linux/moduleloader.h
--- a/include/linux/moduleloader.h	Mon Jan 13 21:59:49 2003
+++ b/include/linux/moduleloader.h	Mon Jan 13 21:59:49 2003
@@ -5,14 +5,6 @@
 #include <linux/module.h>
 #include <linux/elf.h>
 
-/* Helper function for arch-specific module loaders */
-unsigned long find_symbol_internal(Elf_Shdr *sechdrs,
-				   unsigned int symindex,
-				   const char *strtab,
-				   const char *name,
-				   struct module *mod,
-				   struct kernel_symbol_group **group);
-
 /* These must be implemented by the specific architecture */
 
 /* Adjust arch-specific sections.  Return 0 on success.  */
diff -Nru a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
--- a/include/linux/nfs_mount.h	Mon Jan 13 21:59:49 2003
+++ b/include/linux/nfs_mount.h	Mon Jan 13 21:59:49 2003
@@ -40,6 +40,7 @@
 	int		namlen;			/* 2 */
 	unsigned int	bsize;			/* 3 */
 	struct nfs3_fh	root;			/* 4 */
+	int		pseudoflavor;		/* 4 */
 };
 
 /* bits in the flags field */
@@ -55,10 +56,8 @@
 #define NFS_MOUNT_KERBEROS	0x0100	/* 3 */
 #define NFS_MOUNT_NONLM		0x0200	/* 3 */
 #define NFS_MOUNT_BROKEN_SUID	0x0400	/* 4 */
-#if 0
 #define NFS_MOUNT_STRICTLOCK	0x1000	/* reserved for NFSv4 */
 #define NFS_MOUNT_SECFLAVOUR	0x2000	/* reserved */
-#endif
 #define NFS_MOUNT_FLAGMASK	0xFFFF
 
 #endif
diff -Nru a/include/linux/pnp.h b/include/linux/pnp.h
--- a/include/linux/pnp.h	Mon Jan 13 21:59:51 2003
+++ b/include/linux/pnp.h	Mon Jan 13 21:59:51 2003
@@ -189,7 +189,7 @@
 	unsigned long driver_data;	/* data private to the driver */
 };
 
-struct pnp_card_id {
+struct pnp_card_device_id {
 	char id[7];
 	unsigned long driver_data;	/* data private to the driver */
 	struct {
@@ -216,9 +216,9 @@
 struct pnpc_driver {
 	struct list_head node;
 	char *name;
-	const struct pnp_card_id *id_table;
+	const struct pnp_card_device_id *id_table;
 	unsigned int flags;
-	int  (*probe)  (struct pnp_card *card, const struct pnp_card_id *card_id);
+	int  (*probe)  (struct pnp_card *card, const struct pnp_card_device_id *card_id);
 	void (*remove) (struct pnp_card *card);
 	struct device_driver driver;
 };
diff -Nru a/include/linux/smp.h b/include/linux/smp.h
--- a/include/linux/smp.h	Mon Jan 13 21:59:50 2003
+++ b/include/linux/smp.h	Mon Jan 13 21:59:50 2003
@@ -14,6 +14,7 @@
 #include <linux/compiler.h>
 #include <linux/threads.h>
 #include <asm/smp.h>
+#include <asm/bug.h>
 
 /*
  * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc.
@@ -86,7 +87,6 @@
 void smp_prepare_boot_cpu(void);
 
 #else /* !SMP */
-#include <asm/page.h> /* For BUG() */
 
 /*
  *	These macros fold the SMP functionality into a single CPU system
diff -Nru a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
--- a/include/linux/sunrpc/auth.h	Mon Jan 13 21:59:50 2003
+++ b/include/linux/sunrpc/auth.h	Mon Jan 13 21:59:50 2003
@@ -13,12 +13,25 @@
 
 #include <linux/config.h>
 #include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/msg_prot.h>
+#include <linux/sunrpc/xdr.h>
 
 #include <asm/atomic.h>
 
 /* size of the nodename buffer */
 #define UNX_MAXNODENAME	32
 
+/* Maximum size (in bytes) of an rpc credential or verifier */
+#define RPC_MAX_AUTH_SIZE (400)
+
+/* Work around the lack of a VFS credential */
+struct auth_cred {
+	uid_t	uid;
+	gid_t	gid;
+	int	ngroups;
+	gid_t	*groups;
+};
+
 /*
  * Client user credentials
  */
@@ -56,6 +69,10 @@
 	unsigned int		au_rslack;	/* reply verf size guess */
 	unsigned int		au_flags;	/* various flags */
 	struct rpc_authops *	au_ops;		/* operations */
+	rpc_authflavor_t	au_flavor;	/* pseudoflavor (note may
+						 * differ from the flavor in
+						 * au_ops->au_flavor in gss
+						 * case) */
 
 	/* per-flavor data */
 };
@@ -71,16 +88,16 @@
 #ifdef RPC_DEBUG
 	char *			au_name;
 #endif
-	struct rpc_auth *	(*create)(struct rpc_clnt *);
+	struct rpc_auth *	(*create)(struct rpc_clnt *, rpc_authflavor_t);
 	void			(*destroy)(struct rpc_auth *);
 
-	struct rpc_cred *	(*crcreate)(int);
+	struct rpc_cred *	(*crcreate)(struct rpc_auth*, struct auth_cred *, int);
 };
 
 struct rpc_credops {
 	void			(*crdestroy)(struct rpc_cred *);
 
-	int			(*crmatch)(struct rpc_cred *, int);
+	int			(*crmatch)(struct auth_cred *, struct rpc_cred *, int);
 	u32 *			(*crmarshal)(struct rpc_task *, u32 *, int);
 	int			(*crrefresh)(struct rpc_task *);
 	u32 *			(*crvalidate)(struct rpc_task *, u32 *);
@@ -92,10 +109,13 @@
 extern struct rpc_authops	authdes_ops;
 #endif
 
+u32			pseudoflavor_to_flavor(rpc_authflavor_t);
+
 int			rpcauth_register(struct rpc_authops *);
 int			rpcauth_unregister(struct rpc_authops *);
 struct rpc_auth *	rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
 void			rpcauth_destroy(struct rpc_auth *);
+struct rpc_cred *	rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
 struct rpc_cred *	rpcauth_lookupcred(struct rpc_auth *, int);
 struct rpc_cred *	rpcauth_bindcred(struct rpc_task *);
 void			rpcauth_holdcred(struct rpc_task *);
diff -Nru a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/sunrpc/auth_gss.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,98 @@
+/*
+ * linux/include/linux/auth_gss.h
+ *
+ * Declarations for RPCSEC_GSS
+ *
+ * Dug Song <dugsong@monkey.org>
+ * Andy Adamson <andros@umich.edu>
+ * Bruce Fields <bfields@umich.edu>
+ * Copyright (c) 2000 The Regents of the University of Michigan
+ *
+ * $Id$
+ */
+
+#ifndef _LINUX_SUNRPC_AUTH_GSS_H
+#define _LINUX_SUNRPC_AUTH_GSS_H
+
+#ifdef __KERNEL__
+#ifdef __linux__
+#include <linux/sunrpc/auth.h>
+#include <linux/sunrpc/svc.h>
+#include <linux/sunrpc/gss_api.h>
+#endif
+
+#define RPC_GSS_VERSION		1
+
+#define MAXSEQ 0x80000000 /* maximum legal sequence number, from rfc 2203 */
+
+enum rpc_gss_proc {
+	RPC_GSS_PROC_DATA = 0,
+	RPC_GSS_PROC_INIT = 1,
+	RPC_GSS_PROC_CONTINUE_INIT = 2,
+	RPC_GSS_PROC_DESTROY = 3
+};
+
+enum rpc_gss_svc {
+	RPC_GSS_SVC_NONE = 1,
+	RPC_GSS_SVC_INTEGRITY = 2,
+	RPC_GSS_SVC_PRIVACY = 3
+};
+
+/* on-the-wire gss cred: */
+struct rpc_gss_wire_cred {
+	u32			gc_v;		/* version */
+	u32			gc_proc;	/* control procedure */
+	u32			gc_seq;		/* sequence number */
+	u32			gc_svc;		/* service */
+	struct xdr_netobj	gc_ctx;		/* context handle */
+};
+
+/* on-the-wire gss verifier: */
+struct rpc_gss_wire_verf {
+	u32			gv_flavor;
+	struct xdr_netobj	gv_verf;
+};
+
+/* return from gss NULL PROC init sec context */
+struct rpc_gss_init_res {
+	struct xdr_netobj	gr_ctx;		/* context handle */
+	u32			gr_major;	/* major status */
+	u32			gr_minor;	/* minor status */
+	u32			gr_win;		/* sequence window */
+	struct xdr_netobj	gr_token;	/* token */
+};
+
+#define GSS_SEQ_WIN	5
+
+/* The gss_cl_ctx struct holds all the information the rpcsec_gss client
+ * code needs to know about a single security context.  In particular,
+ * gc_gss_ctx is the context handle that is used to do gss-api calls, while
+ * gc_wire_ctx is the context handle that is used to identify the context on
+ * the wire when communicating with a server. */
+
+struct gss_cl_ctx {
+	atomic_t		count;
+	u32			gc_proc;
+	u32			gc_seq;
+	spinlock_t		gc_seq_lock;
+	struct gss_ctx		*gc_gss_ctx;
+	struct xdr_netobj	gc_wire_ctx;
+	u32			gc_win;
+};
+
+struct gss_cred {
+	struct rpc_cred		gc_base;
+	u32			gc_flavor;
+	struct gss_cl_ctx	*gc_ctx;
+};
+
+#define gc_uid			gc_base.cr_uid
+#define gc_count		gc_base.cr_count
+#define gc_flags		gc_base.cr_flags
+#define gc_expire		gc_base.cr_expire
+
+void print_hexl(u32 *p, u_int length, u_int offset);
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_SUNRPC_AUTH_GSS_H */
+
diff -Nru a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
--- a/include/linux/sunrpc/clnt.h	Mon Jan 13 21:59:50 2003
+++ b/include/linux/sunrpc/clnt.h	Mon Jan 13 21:59:50 2003
@@ -28,6 +28,8 @@
 	__u16			pm_port;
 };
 
+struct rpc_inode;
+
 /*
  * The high-level client handle
  */
@@ -58,6 +60,8 @@
 
 	int			cl_nodelen;	/* nodename length */
 	char 			cl_nodename[UNX_MAXNODENAME];
+	char			cl_pathname[30];/* Path in rpc_pipe_fs */
+	struct dentry *		cl_dentry;	/* inode */
 };
 #define cl_timeout		cl_xprt->timeout
 #define cl_prog			cl_pmap.pm_prog
diff -Nru a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/sunrpc/gss_api.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,132 @@
+/*
+ * linux/include/linux/gss_api.h
+ *
+ * Somewhat simplified version of the gss api.
+ *
+ * Dug Song <dugsong@monkey.org>
+ * Andy Adamson <andros@umich.edu>
+ * Bruce Fields <bfields@umich.edu>
+ * Copyright (c) 2000 The Regents of the University of Michigan
+ *
+ * $Id$
+ */
+
+#ifndef _LINUX_SUNRPC_GSS_API_H
+#define _LINUX_SUNRPC_GSS_API_H
+
+#ifdef __KERNEL__
+#include <linux/sunrpc/xdr.h>
+
+/* The mechanism-independent gss-api context: */
+struct gss_ctx {
+	struct gss_api_mech	*mech_type;
+	void			*internal_ctx_id;
+};
+
+#define GSS_C_NO_BUFFER		((struct xdr_netobj) 0)
+#define GSS_C_NO_CONTEXT	((struct gss_ctx *) 0)
+#define GSS_C_NULL_OID		((struct xdr_netobj) 0)
+
+/*XXX  arbitrary length - is this set somewhere? */
+#define GSS_OID_MAX_LEN 32
+
+/* gss-api prototypes; note that these are somewhat simplified versions of
+ * the prototypes specified in RFC 2744. */
+u32 gss_import_sec_context(
+		struct xdr_netobj	*input_token,
+		struct gss_api_mech	*mech,
+		struct gss_ctx		**ctx_id);
+u32 gss_get_mic(
+		struct gss_ctx		*ctx_id,
+		u32			qop,
+		struct xdr_netobj	*message_buffer,
+		struct xdr_netobj	*message_token);
+u32 gss_verify_mic(
+		struct gss_ctx		*ctx_id,
+		struct xdr_netobj	*signbuf,
+		struct xdr_netobj	*checksum,
+		u32			*qstate);
+u32 gss_delete_sec_context(
+		struct gss_ctx		**ctx_id);
+
+/* We maintain a list of the pseudoflavors (equivalently, mechanism-qop-service
+ * triples) that we currently support: */
+
+struct sup_sec_triple {
+	struct list_head	triples;
+	u32			pseudoflavor;
+	struct gss_api_mech	*mech;
+	u32			qop;
+	u32			service;
+};
+
+int gss_register_triple(u32 pseudoflavor, struct gss_api_mech *mech, u32 qop,
+			u32 service);
+int gss_unregister_triple(u32 pseudoflavor);
+int gss_pseudoflavor_supported(u32 pseudoflavor);
+u32 gss_cmp_triples(u32 oid_len, char *oid_data, u32 qop, u32 service);
+u32 gss_get_pseudoflavor(struct gss_ctx *ctx_id, u32 qop, u32 service);
+u32 gss_pseudoflavor_to_service(u32 pseudoflavor);
+/* Both return NULL on failure: */
+struct gss_api_mech * gss_pseudoflavor_to_mech(u32 pseudoflavor);
+int gss_pseudoflavor_to_mechOID(u32 pseudoflavor, struct xdr_netobj *mech);
+
+/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and
+ * mechanisms may be dynamically registered or unregistered by modules.
+ * Our only built-in mechanism is a trivial debugging mechanism that provides
+ * no actual security; the following function registers that mechanism: */
+
+void gss_mech_register_debug(void);
+
+/* Each mechanism is described by the following struct: */
+struct gss_api_mech {
+	struct xdr_netobj	gm_oid;
+	struct list_head	gm_list;
+	atomic_t		gm_count;
+	struct gss_api_ops	*gm_ops;
+};
+
+/* and must provide the following operations: */
+struct gss_api_ops {
+	char *name;
+	u32 (*gss_import_sec_context)(
+			struct xdr_netobj	*input_token,
+			struct gss_ctx		*ctx_id);
+	u32 (*gss_get_mic)(
+			struct gss_ctx		*ctx_id,
+			u32			qop, 
+			struct xdr_netobj	*message_buffer,
+			struct xdr_netobj	*message_token);
+	u32 (*gss_verify_mic)(
+			struct gss_ctx		*ctx_id,
+			struct xdr_netobj	*signbuf,
+			struct xdr_netobj	*checksum,
+			u32			*qstate);
+	void (*gss_delete_sec_context)(
+			void			*internal_ctx_id);
+};
+
+/* Returns nonzero on failure. */
+int gss_mech_register(struct xdr_netobj *, struct gss_api_ops *);
+
+/* Returns nonzero iff someone still has a reference to this mech. */
+int gss_mech_unregister(struct gss_api_mech *);
+
+/* Returns nonzer iff someone still has a reference to some mech. */
+int gss_mech_unregister_all(void);
+
+/* returns a mechanism descriptor given an OID, an increments the mechanism's
+ * reference count. */
+struct gss_api_mech * gss_mech_get_by_OID(struct xdr_netobj *);
+
+/* Just increments the mechanism's reference count and returns its input: */
+struct gss_api_mech * gss_mech_get(struct gss_api_mech *);
+
+/* Returns nonzero iff you've released the last reference to this mech.
+ * Note that for every succesful gss_get_mech call there must be exactly
+ * one corresponding call to gss_mech_put.*/
+int gss_mech_put(struct gss_api_mech *);
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_SUNRPC_GSS_API_H */
+
diff -Nru a/include/linux/sunrpc/gss_asn1.h b/include/linux/sunrpc/gss_asn1.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/sunrpc/gss_asn1.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,85 @@
+/*
+ *  linux/include/linux/sunrpc/gss_asn1.h
+ *
+ *  minimal asn1 for generic encoding/decoding of gss tokens
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
+ *  lib/gssapi/krb5/gssapiP_krb5.h, and others
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ */
+
+/*
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+
+#include <linux/sunrpc/gss_api.h>
+
+#define SIZEOF_INT 4
+
+/* from gssapi_err_generic.h */
+#define G_BAD_SERVICE_NAME                       (-2045022976L)
+#define G_BAD_STRING_UID                         (-2045022975L)
+#define G_NOUSER                                 (-2045022974L)
+#define G_VALIDATE_FAILED                        (-2045022973L)
+#define G_BUFFER_ALLOC                           (-2045022972L)
+#define G_BAD_MSG_CTX                            (-2045022971L)
+#define G_WRONG_SIZE                             (-2045022970L)
+#define G_BAD_USAGE                              (-2045022969L)
+#define G_UNKNOWN_QOP                            (-2045022968L)
+#define G_NO_HOSTNAME                            (-2045022967L)
+#define G_BAD_HOSTNAME                           (-2045022966L)
+#define G_WRONG_MECH                             (-2045022965L)
+#define G_BAD_TOK_HEADER                         (-2045022964L)
+#define G_BAD_DIRECTION                          (-2045022963L)
+#define G_TOK_TRUNC                              (-2045022962L)
+#define G_REFLECT                                (-2045022961L)
+#define G_WRONG_TOKID                            (-2045022960L)
+
+#define g_OID_equal(o1,o2) \
+   (((o1)->len == (o2)->len) && \
+    (memcmp((o1)->data,(o2)->data,(int) (o1)->len) == 0))
+
+u32 g_verify_token_header(
+     struct xdr_netobj *mech,
+     int *body_size,
+     unsigned char **buf_in,
+     int tok_type,
+     int toksize);
+
+u32 g_get_mech_oid(struct xdr_netobj *mech, struct xdr_netobj * in_buf);
+
+int g_token_size(
+     struct xdr_netobj *mech,
+     unsigned int body_size);
+
+void g_make_token_header(
+     struct xdr_netobj *mech,
+     int body_size,
+     unsigned char **buf,
+     int tok_type);
diff -Nru a/include/linux/sunrpc/gss_err.h b/include/linux/sunrpc/gss_err.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/sunrpc/gss_err.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,177 @@
+/*
+ *  linux/include/sunrpc/gss_err.h
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 include/gssapi/gssapi.h
+ *
+ *  Copyright (c) 2002 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ */
+
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ * 
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LINUX_SUNRPC_GSS_ERR_H
+#define _LINUX_SUNRPC_GSS_ERR_H
+
+#ifdef __KERNEL__
+
+typedef unsigned int OM_uint32;
+
+/*
+ * Flag bits for context-level services.
+ */
+#define GSS_C_DELEG_FLAG 1
+#define GSS_C_MUTUAL_FLAG 2
+#define GSS_C_REPLAY_FLAG 4
+#define GSS_C_SEQUENCE_FLAG 8
+#define GSS_C_CONF_FLAG 16
+#define GSS_C_INTEG_FLAG 32
+#define	GSS_C_ANON_FLAG 64
+#define GSS_C_PROT_READY_FLAG 128
+#define GSS_C_TRANS_FLAG 256
+
+/*
+ * Credential usage options
+ */
+#define GSS_C_BOTH 0
+#define GSS_C_INITIATE 1
+#define GSS_C_ACCEPT 2
+
+/*
+ * Status code types for gss_display_status
+ */
+#define GSS_C_GSS_CODE 1
+#define GSS_C_MECH_CODE 2
+
+
+/*
+ * Define the default Quality of Protection for per-message services.  Note
+ * that an implementation that offers multiple levels of QOP may either reserve
+ * a value (for example zero, as assumed here) to mean "default protection", or
+ * alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
+ * QOP value.  However a value of 0 should always be interpreted by a GSSAPI
+ * implementation as a request for the default protection level.
+ */
+#define GSS_C_QOP_DEFAULT 0
+
+/*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful)
+
+
+/* Major status codes */
+
+#define GSS_S_COMPLETE 0
+
+/*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+#define GSS_C_CALLING_ERROR_OFFSET 24
+#define GSS_C_ROUTINE_ERROR_OFFSET 16
+#define GSS_C_SUPPLEMENTARY_OFFSET 0
+#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
+#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
+#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
+
+/*
+ * The macros that test status codes for error conditions.  Note that the
+ * GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now
+ * evaluates its argument only once.
+ */
+#define GSS_CALLING_ERROR(x) \
+  ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+#define GSS_ROUTINE_ERROR(x) \
+  ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+#define GSS_SUPPLEMENTARY_INFO(x) \
+  ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+#define GSS_ERROR(x) \
+  ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+	  (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+
+/*
+ * Now the actual status code definitions
+ */
+
+/*
+ * Calling errors:
+ */
+#define GSS_S_CALL_INACCESSIBLE_READ \
+                             (((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_INACCESSIBLE_WRITE \
+                             (((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_BAD_STRUCTURE \
+                             (((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET)
+
+/*
+ * Routine errors:
+ */
+#define GSS_S_BAD_MECH (((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAME (((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAMETYPE (((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_BINDINGS (((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_STATUS (((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_SIG (((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CRED (((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CONTEXT (((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_TOKEN (((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_CREDENTIAL \
+     (((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CREDENTIALS_EXPIRED \
+     (((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CONTEXT_EXPIRED \
+     (((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_FAILURE (((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DUPLICATE_ELEMENT \
+     (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NAME_NOT_MN \
+     (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+
+/*
+ * Supplementary info bits:
+ */
+#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
+
+/* XXXX these are not part of the GSSAPI C bindings!  (but should be) */
+
+#define GSS_CALLING_ERROR_FIELD(x) \
+   (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
+#define GSS_ROUTINE_ERROR_FIELD(x) \
+   (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
+#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
+   (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
+
+/* XXXX This is a necessary evil until the spec is fixed */
+#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_SUNRPC_GSS_ERR_H */
diff -Nru a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/sunrpc/gss_krb5.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,160 @@
+/*
+ *  linux/include/linux/sunrpc/gss_krb5_types.h
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
+ *  lib/gssapi/krb5/gssapiP_krb5.h, and others
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ *  Bruce Fields   <bfields@umich.edu>
+ */
+
+/*
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#include <linux/sunrpc/auth_gss.h>
+#include <linux/sunrpc/gss_err.h>
+#include <linux/sunrpc/gss_asn1.h>
+
+struct krb5_ctx {
+	int			initiate; /* 1 = initiating, 0 = accepting */
+	int			seed_init;
+	unsigned char		seed[16];
+	int			signalg;
+	int			sealalg;
+	struct crypto_tfm	*enc;
+	struct crypto_tfm	*seq;
+	s32			endtime;
+	u32			seq_send;
+	u32			seq_recv;
+	struct xdr_netobj	mech_used;
+};
+
+#define KG_TOK_MIC_MSG    0x0101
+#define KG_TOK_WRAP_MSG   0x0201
+
+enum sgn_alg {
+	SGN_ALG_DES_MAC_MD5 = 0x0000,
+	SGN_ALG_MD2_5 = 0x0001,
+	SGN_ALG_DES_MAC = 0x0002,
+	SGN_ALG_3 = 0x0003,		/* not published */
+	SGN_ALG_HMAC_MD5 = 0x0011,	/* microsoft w2k; no support */
+	SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
+};
+enum seal_alg {
+	SEAL_ALG_NONE = 0xffff,
+	SEAL_ALG_DES = 0x0000,
+	SEAL_ALG_1 = 0x0001,		/* not published */
+	SEAL_ALG_MICROSOFT_RC4 = 0x0010,/* microsoft w2k; no support */
+	SEAL_ALG_DES3KD = 0x0002
+};
+
+#define RSA_MD5_CKSUM_LENGTH 16
+
+#define CKSUMTYPE_CRC32			0x0001
+#define CKSUMTYPE_RSA_MD4		0x0002
+#define CKSUMTYPE_RSA_MD4_DES		0x0003
+#define CKSUMTYPE_DESCBC		0x0004
+#define CKSUMTYPE_RSA_MD5		0x0007
+#define CKSUMTYPE_RSA_MD5_DES		0x0008
+#define CKSUMTYPE_NIST_SHA		0x0009
+#define CKSUMTYPE_HMAC_SHA1_DES3	0x000c
+
+/* from gssapi_err_krb5.h */
+#define KG_CCACHE_NOMATCH                        (39756032L)
+#define KG_KEYTAB_NOMATCH                        (39756033L)
+#define KG_TGT_MISSING                           (39756034L)
+#define KG_NO_SUBKEY                             (39756035L)
+#define KG_CONTEXT_ESTABLISHED                   (39756036L)
+#define KG_BAD_SIGN_TYPE                         (39756037L)
+#define KG_BAD_LENGTH                            (39756038L)
+#define KG_CTX_INCOMPLETE                        (39756039L)
+#define KG_CONTEXT                               (39756040L)
+#define KG_CRED                                  (39756041L)
+#define KG_ENC_DESC                              (39756042L)
+#define KG_BAD_SEQ                               (39756043L)
+#define KG_EMPTY_CCACHE                          (39756044L)
+#define KG_NO_CTYPES                             (39756045L)
+
+#define KV5M_PRINCIPAL                           (-1760647423L)
+#define KV5M_KEYBLOCK                            (-1760647421L)
+#define KV5M_CHECKSUM                            (-1760647420L)
+#define KV5M_ADDRESS                             (-1760647390L)
+#define KV5M_AUTHENTICATOR                       (-1760647410L)
+#define KV5M_AUTH_CONTEXT                        (-1760647383L)
+#define KV5M_AUTHDATA                            (-1760647414L)
+#define KV5M_GSS_OID                             (-1760647372L)
+#define KV5M_GSS_QUEUE                           (-1760647371L)
+
+/* per Kerberos v5 protocol spec crypto types from the wire. 
+ * these get mapped to linux kernel crypto routines.  
+ */
+#define ENCTYPE_NULL            0x0000
+#define ENCTYPE_DES_CBC_CRC     0x0001	/* DES cbc mode with CRC-32 */
+#define ENCTYPE_DES_CBC_MD4     0x0002	/* DES cbc mode with RSA-MD4 */
+#define ENCTYPE_DES_CBC_MD5     0x0003	/* DES cbc mode with RSA-MD5 */
+#define ENCTYPE_DES_CBC_RAW     0x0004	/* DES cbc mode raw */
+/* XXX deprecated? */
+#define ENCTYPE_DES3_CBC_SHA    0x0005	/* DES-3 cbc mode with NIST-SHA */
+#define ENCTYPE_DES3_CBC_RAW    0x0006	/* DES-3 cbc mode raw */
+#define ENCTYPE_DES_HMAC_SHA1   0x0008
+#define ENCTYPE_DES3_CBC_SHA1   0x0010
+#define ENCTYPE_UNKNOWN         0x01ff
+
+s32
+krb5_make_checksum(s32 cksumtype,
+		   struct xdr_netobj *input,
+		   struct xdr_netobj *cksum);
+
+u32
+krb5_make_token(struct krb5_ctx *context_handle, int qop_req,
+	struct xdr_netobj * input_message_buffer,
+	struct xdr_netobj * output_message_buffer, int toktype);
+
+u32
+krb5_read_token(struct krb5_ctx *context_handle,
+	  struct xdr_netobj *input_token_buffer,
+	  struct xdr_netobj *message_buffer,
+	  int *qop_state, int toktype);
+
+u32
+krb5_encrypt(struct crypto_tfm * key,
+	     void *iv, void *in, void *out, int length);
+
+u32
+krb5_decrypt(struct crypto_tfm * key,
+	     void *iv, void *in, void *out, int length); 
+
+s32
+krb5_make_seq_num(struct crypto_tfm * key,
+		int direction,
+		s32 seqnum, unsigned char *cksum, unsigned char *buf);
+
+s32
+krb5_get_seq_num(struct crypto_tfm * key,
+	       unsigned char *cksum,
+	       unsigned char *buf, int *direction, s32 * seqnum);
diff -Nru a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
--- a/include/linux/sunrpc/msg_prot.h	Mon Jan 13 21:59:50 2003
+++ b/include/linux/sunrpc/msg_prot.h	Mon Jan 13 21:59:50 2003
@@ -20,7 +20,18 @@
 	RPC_AUTH_SHORT = 2,
 	RPC_AUTH_DES   = 3,
 	RPC_AUTH_KRB   = 4,
+	RPC_AUTH_GSS   = 6,
 	RPC_AUTH_MAXFLAVOR = 8,
+	/* pseudoflavors: */
+	RPC_AUTH_GSS_KRB5  = 390003,
+	RPC_AUTH_GSS_KRB5I = 390004,
+	RPC_AUTH_GSS_KRB5P = 390005,
+	RPC_AUTH_GSS_LKEY  = 390006,
+	RPC_AUTH_GSS_LKEYI = 390007,
+	RPC_AUTH_GSS_LKEYP = 390008,
+	RPC_AUTH_GSS_SPKM  = 390009,
+	RPC_AUTH_GSS_SPKMI = 390010,
+	RPC_AUTH_GSS_SPKMP = 390011,
 };
 
 enum rpc_msg_type {
@@ -53,7 +64,10 @@
 	RPC_AUTH_REJECTEDCRED = 2,
 	RPC_AUTH_BADVERF = 3,
 	RPC_AUTH_REJECTEDVERF = 4,
-	RPC_AUTH_TOOWEAK = 5
+	RPC_AUTH_TOOWEAK = 5,
+	/* RPCSEC_GSS errors */
+	RPCSEC_GSS_CREDPROBLEM = 13,
+	RPCSEC_GSS_CTXPROBLEM = 14
 };
 
 #define RPC_PMAP_PROGRAM	100000
diff -Nru a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/linux/sunrpc/rpc_pipe_fs.h	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,47 @@
+#ifndef _LINUX_SUNRPC_RPC_PIPE_FS_H
+#define _LINUX_SUNRPC_RPC_PIPE_FS_H
+
+#ifdef __KERNEL__
+
+struct rpc_pipe_msg {
+	struct list_head list;
+	void *data;
+	size_t len;
+	size_t copied;
+	int errno;
+};
+
+struct rpc_pipe_ops {
+	ssize_t (*upcall)(struct file *, struct rpc_pipe_msg *, char *, size_t);
+	ssize_t (*downcall)(struct file *, const char *, size_t);
+	void (*destroy_msg)(struct rpc_pipe_msg *);
+};
+
+struct rpc_inode {
+	struct inode vfs_inode;
+	void *private;
+	struct list_head pipe;
+	int pipelen;
+	int nreaders;
+	wait_queue_head_t waitq;
+	struct rpc_pipe_ops *ops;
+};
+
+static inline struct rpc_inode *
+RPC_I(struct inode *inode)
+{
+	return container_of(inode, struct rpc_inode, vfs_inode);
+}
+
+extern void rpc_inode_setowner(struct inode *, void *);
+extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
+
+extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *);
+extern int rpc_rmdir(char *);
+extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *);
+extern int rpc_unlink(char *);
+
+void __rpc_purge_current_upcall(struct file *);
+
+#endif
+#endif
diff -Nru a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
--- a/include/linux/sunrpc/sched.h	Mon Jan 13 21:59:50 2003
+++ b/include/linux/sunrpc/sched.h	Mon Jan 13 21:59:50 2003
@@ -12,6 +12,7 @@
 #include <linux/timer.h>
 #include <linux/sunrpc/types.h>
 #include <linux/wait.h>
+#include <linux/sunrpc/xdr.h>
 
 /*
  * This is the actual RPC procedure call info.
@@ -47,6 +48,8 @@
 	__u8			tk_garb_retry,
 				tk_cred_retry,
 				tk_suid_retry;
+	u32			tk_gss_seqno;	/* rpcsec_gss sequence number
+						   used on this request */
 
 	/*
 	 * timeout_fn   to be executed by timer bottom half
diff -Nru a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
--- a/include/linux/sunrpc/xdr.h	Mon Jan 13 21:59:51 2003
+++ b/include/linux/sunrpc/xdr.h	Mon Jan 13 21:59:51 2003
@@ -80,7 +80,9 @@
 #define	rpc_autherr_badverf	__constant_htonl(RPC_AUTH_BADVERF)
 #define	rpc_autherr_rejectedverf __constant_htonl(RPC_AUTH_REJECTEDVERF)
 #define	rpc_autherr_tooweak	__constant_htonl(RPC_AUTH_TOOWEAK)
-
+#define	rpcsec_gsserr_credproblem	__constant_htonl(RPCSEC_GSS_CREDPROBLEM)
+#define	rpcsec_gsserr_ctxproblem	__constant_htonl(RPCSEC_GSS_CTXPROBLEM)
+#define	rpc_autherr_oldseqnum	__constant_htonl(101)
 
 /*
  * Miscellaneous XDR helper functions
diff -Nru a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
--- a/include/linux/sunrpc/xprt.h	Mon Jan 13 21:59:50 2003
+++ b/include/linux/sunrpc/xprt.h	Mon Jan 13 21:59:50 2003
@@ -187,6 +187,7 @@
 					unsigned long);
 
 void			xprt_reserve(struct rpc_task *);
+int			xprt_prepare_transmit(struct rpc_task *);
 void			xprt_transmit(struct rpc_task *);
 void			xprt_receive(struct rpc_task *);
 int			xprt_adjust_timeout(struct rpc_timeout *);
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h	Mon Jan 13 21:59:49 2003
+++ b/include/linux/sysfs.h	Mon Jan 13 21:59:49 2003
@@ -18,7 +18,7 @@
 
 struct sysfs_ops {
 	ssize_t	(*show)(struct kobject *, struct attribute *,char *);
-	ssize_t	(*store)(struct kobject *,struct attribute *,const char *);
+	ssize_t	(*store)(struct kobject *,struct attribute *,const char *, size_t);
 };
 
 extern int
diff -Nru a/include/net/irda/irias_object.h b/include/net/irda/irias_object.h
--- a/include/net/irda/irias_object.h	Mon Jan 13 21:59:51 2003
+++ b/include/net/irda/irias_object.h	Mon Jan 13 21:59:51 2003
@@ -78,8 +78,6 @@
 	struct ias_value *value; /* Attribute value */
 };
 
-char *strndup(char *str, int max);
-
 struct ias_object *irias_new_object(char *name, int id);
 void irias_insert_object(struct ias_object *obj);
 int  irias_delete_object(struct ias_object *obj);
@@ -104,6 +102,6 @@
 void irias_delete_value(struct ias_value *value);
 
 extern struct ias_value missing;
-extern hashbin_t *objects;
+extern hashbin_t *irias_objects;
 
 #endif
diff -Nru a/include/net/irda/qos.h b/include/net/irda/qos.h
--- a/include/net/irda/qos.h	Mon Jan 13 21:59:49 2003
+++ b/include/net/irda/qos.h	Mon Jan 13 21:59:49 2003
@@ -83,19 +83,12 @@
 extern int sysctl_max_baud_rate;
 extern int sysctl_max_inactive_time;
 
-extern __u32 baud_rates[];
-extern __u32 data_sizes[];
-extern __u32 min_turn_times[];
-extern __u32 add_bofs[];
-extern __u32 compressions[];
-
 void irda_init_max_qos_capabilies(struct qos_info *qos);
 void irda_qos_compute_intersection(struct qos_info *, struct qos_info *);
 
 __u32 irlap_max_line_capacity(__u32 speed, __u32 max_turn_time);
 __u32 irlap_requested_line_capacity(struct qos_info *qos);
 
-int msb_index(__u16 byte);
 void irda_qos_bits_to_value(struct qos_info *qos);
 
 /* So simple, how could we not inline those two ?
diff -Nru a/include/sound/initval.h b/include/sound/initval.h
--- a/include/sound/initval.h	Mon Jan 13 21:59:49 2003
+++ b/include/sound/initval.h	Mon Jan 13 21:59:49 2003
@@ -97,18 +97,6 @@
 }
 #endif
 
-#ifdef SNDRV_LEGACY_FIND_FREE_IOPORT
-static long snd_legacy_find_free_ioport(long *port_table, long size)
-{
-	while (*port_table != -1) {
-		if (!check_region(*port_table, size))
-			return *port_table;
-		port_table++;
-	}
-	return -1;
-}
-#endif
-
 #ifdef SNDRV_LEGACY_FIND_FREE_IRQ
 #include <linux/interrupt.h>
 
diff -Nru a/init/Kconfig b/init/Kconfig
--- a/init/Kconfig	Mon Jan 13 21:59:51 2003
+++ b/init/Kconfig	Mon Jan 13 21:59:51 2003
@@ -156,7 +156,7 @@
 
 config MODULE_FORCE_UNLOAD
 	bool "Forced module unloading"
-	depends on MODULES && EXPERIMENTAL
+	depends on MODULE_UNLOAD && EXPERIMENTAL
 	help
 	  This option allows you to force a module to unload, even if the
 	  kernel believes it is unsafe: the kernel will remove the module
diff -Nru a/kernel/cpufreq.c b/kernel/cpufreq.c
--- a/kernel/cpufreq.c	Mon Jan 13 21:59:49 2003
+++ b/kernel/cpufreq.c	Mon Jan 13 21:59:49 2003
@@ -20,12 +20,17 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_CPU_FREQ_PROC_INTF
 #include <linux/ctype.h>
 #include <linux/proc_fs.h>
-
 #include <asm/uaccess.h>
+#endif
 
 #ifdef CONFIG_CPU_FREQ_24_API
+#include <linux/proc_fs.h>
 #include <linux/sysctl.h>
 #endif
 
@@ -53,18 +58,6 @@
 static DECLARE_MUTEX            (cpufreq_notifier_sem);
 
 
-/**
- * The cpufreq default policy. Can be set by a "cpufreq=..." command
- * line option.
- */
-static struct cpufreq_policy default_policy = {
-	.cpu    = CPUFREQ_ALL_CPUS,
-	.min    = 0,
-	.max    = 0,
-	.policy = 0,
-};
-
-
 #ifdef CONFIG_CPU_FREQ_24_API
 /**
  * A few values needed by the 2.4.-compatible API
@@ -75,11 +68,314 @@
 #endif
 
 
+/*********************************************************************
+ *                          SYSFS INTERFACE                          *
+ *********************************************************************/
+
+/**
+ * cpufreq_parse_governor - parse a governor string
+ */
+static int cpufreq_parse_governor (char *str_governor, unsigned int *governor)
+{
+	if (!strnicmp(str_governor, "performance", 11)) {
+		*governor = CPUFREQ_POLICY_PERFORMANCE;
+		return 0;
+	} else if (!strnicmp(str_governor, "powersave", 9)) {
+		*governor = CPUFREQ_POLICY_POWERSAVE;
+		return 0;
+	} else
+		return -EINVAL;
+}
+
+
+/* forward declarations */
+static int cpufreq_add_dev (struct device * dev);
+static int cpufreq_remove_dev (struct intf_data * dev);
+
+/* drivers/base/cpu.c */
+extern struct device_class cpu_devclass;
+
+static struct device_interface cpufreq_interface = {
+        .name = "cpufreq",
+        .devclass = &cpu_devclass,
+        .add_device = &cpufreq_add_dev,
+        .remove_device = &cpufreq_remove_dev,
+	.kset = { .subsys = &cpu_devclass.subsys, },
+        .devnum = 0,
+};
+
+static inline int to_cpu_nr (struct device *dev)
+{
+	struct sys_device * cpu_sys_dev = container_of(dev, struct sys_device, dev);
+	return (cpu_sys_dev->id);
+}
+
+
+/**
+ * cpufreq_per_cpu_attr_read() / show_##file_name() - print out cpufreq information
+ *
+ * Write out information from cpufreq_driver->policy[cpu]; object must be
+ * "unsigned int".
+ */
+
+#define cpufreq_per_cpu_attr_read(file_name, object) 			\
+static ssize_t show_##file_name 					\
+(struct device *dev, char *buf)						\
+{									\
+	unsigned int value = 0;						\
+									\
+	if (!dev)							\
+		return 0;						\
+									\
+	down(&cpufreq_driver_sem);					\
+	if (cpufreq_driver)						\
+		value = cpufreq_driver->policy[to_cpu_nr(dev)].object;	\
+	up(&cpufreq_driver_sem);					\
+									\
+	return sprintf (buf, "%u\n", value);				\
+}
+
+
+/**
+ * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
+ */
+#define cpufreq_per_cpu_attr_write(file_name, object)			\
+static ssize_t store_##file_name					\
+(struct device *dev, const char *buf, size_t count)			\
+{									\
+	unsigned int ret = -EINVAL;					\
+	struct cpufreq_policy policy;					\
+									\
+	if (!dev)							\
+		return 0;						\
+									\
+	ret = cpufreq_get_policy(&policy, to_cpu_nr(dev));		\
+	if (ret)							\
+		return ret;						\
+									\
+	ret = sscanf (buf, "%u", &policy.object);			\
+	if (ret != 1)							\
+		return -EINVAL;						\
+									\
+	ret = cpufreq_set_policy(&policy);				\
+	if (ret)							\
+		return ret;						\
+									\
+	return count;							\
+}
+
+
+/**
+ * show_scaling_governor - show the current policy for the specified CPU
+ */
+static ssize_t show_scaling_governor (struct device *dev, char *buf)
+{
+	unsigned int value = 0;
+
+	if (!dev)
+		return 0;
+
+	down(&cpufreq_driver_sem);
+	if (cpufreq_driver)
+		value = cpufreq_driver->policy[to_cpu_nr(dev)].policy;
+	up(&cpufreq_driver_sem);
+
+	switch (value) {
+	case CPUFREQ_POLICY_POWERSAVE:
+		return sprintf(buf, "powersave\n");
+	case CPUFREQ_POLICY_PERFORMANCE:
+		return sprintf(buf, "performance\n");
+	}
+
+	return -EINVAL;
+}
+
+
+/**
+ * store_scaling_governor - store policy for the specified CPU
+ */
+static ssize_t 
+store_scaling_governor (struct device *dev, const char *buf, size_t count) 
+{
+	unsigned int ret = -EINVAL;
+	char	str_governor[16];
+	struct cpufreq_policy policy;
+
+	if (!dev)
+		return 0;
+
+	ret = cpufreq_get_policy(&policy, to_cpu_nr(dev));
+	if (ret)
+		return ret;
+
+	ret = sscanf (buf, "%15s", str_governor);
+	if (ret != 1)
+		return -EINVAL;
+
+	if (cpufreq_parse_governor(str_governor, &policy.policy))
+		return -EINVAL;
+
+	ret = cpufreq_set_policy(&policy);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+
+/**
+ * show_scaling_governor - show the current policy for the specified CPU
+ */
+static ssize_t show_scaling_driver (struct device *dev, char *buf)
+{
+	char value[CPUFREQ_NAME_LEN];
+
+	if (!dev)
+		return 0;
+
+	down(&cpufreq_driver_sem);
+	if (cpufreq_driver)
+		strncpy(value, cpufreq_driver->name, CPUFREQ_NAME_LEN);
+	up(&cpufreq_driver_sem);
+
+	return sprintf(buf, "%s\n", value);
+}
+
+
+/**
+ * cpufreq_per_cpu_attr_ro - read-only cpufreq per-CPU file
+ */
+#define cpufreq_per_cpu_attr_ro(file_name, object)			\
+cpufreq_per_cpu_attr_read(file_name, object) 				\
+static DEVICE_ATTR(file_name, S_IRUGO, show_##file_name, NULL);
+
+
+/**
+ * cpufreq_per_cpu_attr_rw - read-write cpufreq per-CPU file
+ */
+#define cpufreq_per_cpu_attr_rw(file_name, object) 			\
+cpufreq_per_cpu_attr_read(file_name, object) 				\
+cpufreq_per_cpu_attr_write(file_name, object) 				\
+static DEVICE_ATTR(file_name, (S_IRUGO | S_IWUSR), show_##file_name, store_##file_name);
+
+
+/* create the file functions */
+cpufreq_per_cpu_attr_ro(cpuinfo_min_freq, cpuinfo.min_freq);
+cpufreq_per_cpu_attr_ro(cpuinfo_max_freq, cpuinfo.max_freq);
+cpufreq_per_cpu_attr_rw(scaling_min_freq, min);
+cpufreq_per_cpu_attr_rw(scaling_max_freq, max);
+
+static DEVICE_ATTR(scaling_governor, (S_IRUGO | S_IWUSR), show_scaling_governor, store_scaling_governor);
+static DEVICE_ATTR(scaling_driver, S_IRUGO, show_scaling_driver, NULL);
+
+
+/**
+ * cpufreq_add_dev - add a CPU device
+ *
+ * Adds the cpufreq interface for a CPU device. 
+ */
+static int cpufreq_add_dev (struct device * dev)
+{
+	unsigned int cpu = to_cpu_nr(dev);
+	int ret = 0;
+	struct cpufreq_policy policy;
+
+	down(&cpufreq_driver_sem);
+	if (!cpufreq_driver) {
+		up(&cpufreq_driver_sem);
+		return -EINVAL;
+	}
+
+	/* call driver. From then on the cpufreq must be able
+	 * to accept all calls to ->verify and ->setpolicy for this CPU
+	 */
+	cpufreq_driver->policy[cpu].cpu = cpu;
+	if (cpufreq_driver->init) {
+		ret = cpufreq_driver->init(&cpufreq_driver->policy[cpu]);
+		if (ret) {
+			up(&cpufreq_driver_sem);
+			return -ENODEV;
+		}
+	}
+
+	/* set default policy on this CPU */
+	policy.policy = cpufreq_driver->policy[cpu].policy;
+	policy.min    = cpufreq_driver->policy[cpu].min;
+	policy.max    = cpufreq_driver->policy[cpu].max;
+	policy.cpu    = cpu;
+
+	up(&cpufreq_driver_sem);
+	ret = cpufreq_set_policy(&policy);
+	if (ret)
+		return -EINVAL;
+	down(&cpufreq_driver_sem);
+
+	/* 2.4-API init for this CPU */
+#ifdef CONFIG_CPU_FREQ_24_API
+	cpu_min_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.min_freq;
+	cpu_max_freq[cpu] = cpufreq_driver->policy[cpu].cpuinfo.max_freq;
+	cpu_cur_freq[cpu] = cpufreq_driver->cpu_cur_freq[cpu];
+#endif
+
+	/* prepare interface data */
+	cpufreq_driver->policy[cpu].intf.dev  = dev;
+	cpufreq_driver->policy[cpu].intf.intf = &cpufreq_interface;
+	strncpy(cpufreq_driver->policy[cpu].intf.kobj.name, cpufreq_interface.name, KOBJ_NAME_LEN);
+	cpufreq_driver->policy[cpu].intf.kobj.parent = &(dev->kobj);
+	cpufreq_driver->policy[cpu].intf.kobj.kset = &(cpufreq_interface.kset);
+
+	/* add interface */
+	/* currently commented out due to deadlock */
+	//ret = interface_add_data(&(cpufreq_driver->policy[cpu].intf));
+	if (ret) {
+		up(&cpufreq_driver_sem);
+		return ret;
+	}
+
+	/* create files */
+	device_create_file (dev, &dev_attr_cpuinfo_min_freq);
+	device_create_file (dev, &dev_attr_cpuinfo_max_freq);
+	device_create_file (dev, &dev_attr_scaling_min_freq);
+	device_create_file (dev, &dev_attr_scaling_max_freq);
+	device_create_file (dev, &dev_attr_scaling_governor);
+	device_create_file (dev, &dev_attr_scaling_driver);
+
+	up(&cpufreq_driver_sem);
+	return ret;
+}
+
+
+/**
+ * cpufreq_remove_dev - remove a CPU device
+ *
+ * Removes the cpufreq interface for a CPU device. Is called with
+ * cpufreq_driver_sem locked.
+ */
+static int cpufreq_remove_dev (struct intf_data *intf)
+{
+	struct device * dev = intf->dev;
+	unsigned int cpu = to_cpu_nr(dev);
+
+	if (cpufreq_driver->exit)
+		cpufreq_driver->exit(&cpufreq_driver->policy[cpu]);
+
+	device_remove_file (dev, &dev_attr_cpuinfo_min_freq);
+	device_remove_file (dev, &dev_attr_cpuinfo_max_freq);
+	device_remove_file (dev, &dev_attr_scaling_min_freq);
+	device_remove_file (dev, &dev_attr_scaling_max_freq);
+	device_remove_file (dev, &dev_attr_scaling_governor);
+	device_remove_file (dev, &dev_attr_scaling_governor);
+
+	return 0;
+}
+
 
 /*********************************************************************
- *                              2.6. API                             *
+ *                      /proc/cpufreq INTERFACE                      *
  *********************************************************************/
 
+#ifdef CONFIG_CPU_FREQ_PROC_INTF
+
 /**
  * cpufreq_parse_policy - parse a policy string
  * @input_string: the string to parse.
@@ -95,10 +391,9 @@
 	unsigned int            min = 0;
 	unsigned int            max = 0;
 	unsigned int            cpu = 0;
-	char			policy_string[42] = {'\0'};
+	char			str_governor[16];
 	struct cpufreq_policy   current_policy;
 	unsigned int            result = -EFAULT;
-	unsigned int            i = 0;
 
 	if (!policy)
 		return -EINVAL;
@@ -108,7 +403,7 @@
 	policy->policy = 0;
 	policy->cpu = CPUFREQ_ALL_CPUS;
 
-	if (sscanf(input_string, "%d:%d:%d:%s", &cpu, &min, &max, policy_string) == 4) 
+	if (sscanf(input_string, "%d:%d:%d:%15s", &cpu, &min, &max, str_governor) == 4) 
 	{
 		policy->min = min;
 		policy->max = max;
@@ -116,7 +411,7 @@
 		result = 0;
 		goto scan_policy;
 	}
-	if (sscanf(input_string, "%d%%%d%%%d%%%s", &cpu, &min, &max, policy_string) == 4)
+	if (sscanf(input_string, "%d%%%d%%%d%%%15s", &cpu, &min, &max, str_governor) == 4)
 	{
 		if (!cpufreq_get_policy(&current_policy, cpu)) {
 			policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
@@ -127,7 +422,7 @@
 		}
 	}
 
-	if (sscanf(input_string, "%d:%d:%s", &min, &max, policy_string) == 3) 
+	if (sscanf(input_string, "%d:%d:%15s", &min, &max, str_governor) == 3) 
 	{
 		policy->min = min;
 		policy->max = max;
@@ -135,7 +430,7 @@
 		goto scan_policy;
 	}
 
-	if (sscanf(input_string, "%d%%%d%%%s", &min, &max, policy_string) == 3)
+	if (sscanf(input_string, "%d%%%d%%%15s", &min, &max, str_governor) == 3)
 	{
 		if (!cpufreq_get_policy(&current_policy, cpu)) {
 			policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
@@ -148,57 +443,12 @@
 	return -EINVAL;
 
 scan_policy:
-
-	for (i=0;i<sizeof(policy_string);i++){
-		if (policy_string[i]=='\0')
-			break;
-		policy_string[i] = tolower(policy_string[i]);
-	}
-
-	if (!strncmp(policy_string, "powersave", 6) ||  
-            !strncmp(policy_string, "eco", 3) ||       
-	    !strncmp(policy_string, "batter", 6) ||
-	    !strncmp(policy_string, "low", 3)) 
-	{
-		result = 0;
-		policy->policy = CPUFREQ_POLICY_POWERSAVE;
-	}
-	else if (!strncmp(policy_string, "performance",6) ||
-	    !strncmp(policy_string, "high",4) ||
-	    !strncmp(policy_string, "full",4))
-	{
-		result = 0;
-		policy->policy = CPUFREQ_POLICY_PERFORMANCE;
-	}
-	else if (!cpufreq_get_policy(&current_policy, policy->cpu))
-	{
-		policy->policy = current_policy.policy;
-	}
-	else
-	{
-		policy->policy = 0;
-	}
+	result = cpufreq_parse_governor(str_governor, &policy->policy);
 
 	return result;
 }
 
 
-/*
- * cpufreq command line parameter.  Must be hard values (kHz)
- *  cpufreq=1000000:2000000:PERFORMANCE   
- * to set the default CPUFreq policy.
- */
-static int __init cpufreq_setup(char *str)
-{
-	cpufreq_parse_policy(str, &default_policy);
-	default_policy.cpu = CPUFREQ_ALL_CPUS;
-	return 1;
-}
-__setup("cpufreq=", cpufreq_setup);
-
-
-#ifdef CONFIG_PROC_FS
-
 /**
  * cpufreq_proc_read - read /proc/cpufreq
  *
@@ -345,12 +595,15 @@
 	remove_proc_entry("cpufreq", &proc_root);
 	return;
 }
-#endif /* CONFIG_PROC_FS */
+#else
+#define cpufreq_proc_init() do {} while(0)
+#define cpufreq_proc_exit() do {} while(0)
+#endif /* CONFIG_CPU_FREQ_PROC_INTF */
 
 
 
 /*********************************************************************
- *                        2.4. COMPATIBLE API                        *
+ *                      /proc/sys/cpu/ INTERFACE                     *
  *********************************************************************/
 
 #ifdef CONFIG_CPU_FREQ_24_API
@@ -983,19 +1236,18 @@
  *********************************************************************/
 
 /**
- * cpufreq_register - register a CPU Frequency driver
- * @driver_data: A struct cpufreq_driver containing the values submitted by the CPU Frequency driver.
+ * cpufreq_register_driver - register a CPU Frequency driver
+ * @driver_data: A struct cpufreq_driver containing the values#
+ * submitted by the CPU Frequency driver.
  *
  *   Registers a CPU Frequency driver to this core code. This code 
  * returns zero on success, -EBUSY when another driver got here first
  * (and isn't unregistered in the meantime). 
  *
  */
-int cpufreq_register(struct cpufreq_driver *driver_data)
+int cpufreq_register_driver(struct cpufreq_driver *driver_data)
 {
-	unsigned int            ret;
-	unsigned int            i;
-	struct cpufreq_policy   policy;
+	int ret = 0;
 
 	if (cpufreq_driver)
 		return -EBUSY;
@@ -1005,91 +1257,81 @@
 		return -EINVAL;
 
 	down(&cpufreq_driver_sem);
-	cpufreq_driver        = driver_data;
-	
-	/* check for a default policy - if it exists, use it on _all_ CPUs*/
-	for (i=0; i<NR_CPUS; i++)
-	{
-		if (default_policy.policy)
-			cpufreq_driver->policy[i].policy = default_policy.policy;
-		if (default_policy.min)
-			cpufreq_driver->policy[i].min = default_policy.min;
-		if (default_policy.max)
-			cpufreq_driver->policy[i].max = default_policy.max;
-	}
 
-	/* set default policy on all CPUs. Must be called per-CPU and not
-	 * with CPUFREQ_ALL_CPUs as there might be no common policy for all
-	 * CPUs (UltraSPARC etc.)
-	 */
-	for (i=0; i<NR_CPUS; i++)
-	{
-		policy.policy = cpufreq_driver->policy[i].policy;
-		policy.min    = cpufreq_driver->policy[i].min;
-		policy.max    = cpufreq_driver->policy[i].max;
-		policy.cpu    = i;
-		up(&cpufreq_driver_sem);
-		ret = cpufreq_set_policy(&policy);
-		down(&cpufreq_driver_sem);
-		if (ret) {
-			cpufreq_driver = NULL;
+	cpufreq_driver = driver_data;
+
+	if (!cpufreq_driver->policy) {
+		/* then we need per-CPU init */
+		if (!cpufreq_driver->init) {
+			up(&cpufreq_driver_sem);
+			return -EINVAL;
+		}
+		cpufreq_driver->policy = kmalloc(NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
+		if (!cpufreq_driver->policy) {
 			up(&cpufreq_driver_sem);
-			return ret;
+			return -ENOMEM;
 		}
 	}
-
+	
 	up(&cpufreq_driver_sem);
 
 	cpufreq_proc_init();
 
 #ifdef CONFIG_CPU_FREQ_24_API
- 	down(&cpufreq_driver_sem);
-	for (i=0; i<NR_CPUS; i++) 
-	{
-		cpu_min_freq[i] = driver_data->policy[i].cpuinfo.min_freq;
-		cpu_max_freq[i] = driver_data->policy[i].cpuinfo.max_freq;
-		cpu_cur_freq[i] = driver_data->cpu_cur_freq[i];
-	}
-	up(&cpufreq_driver_sem);
-
 	cpufreq_sysctl_init();
 #endif
 
-	return 0;
+	ret = interface_register(&cpufreq_interface);
+
+	return ret;
 }
-EXPORT_SYMBOL_GPL(cpufreq_register);
+EXPORT_SYMBOL_GPL(cpufreq_register_driver);
 
 
 /**
- * cpufreq_unregister - unregister the current CPUFreq driver
+ * cpufreq_unregister_driver - unregister the current CPUFreq driver
  *
  *    Unregister the current CPUFreq driver. Only call this if you have 
  * the right to do so, i.e. if you have succeeded in initialising before!
  * Returns zero if successful, and -EINVAL if the cpufreq_driver is
  * currently not initialised.
  */
-int cpufreq_unregister(void)
+int cpufreq_unregister_driver(struct cpufreq_driver *driver)
 {
 	down(&cpufreq_driver_sem);
 
-	if (!cpufreq_driver) {
+	if (!cpufreq_driver || 
+	    ((driver != cpufreq_driver) && (driver != NULL))) { /* compat */
 		up(&cpufreq_driver_sem);
 		return -EINVAL;
 	}
 
-	cpufreq_driver = NULL;
-
-	up(&cpufreq_driver_sem);
-
 	cpufreq_proc_exit();
 
 #ifdef CONFIG_CPU_FREQ_24_API
 	cpufreq_sysctl_exit();
 #endif
 
+	/* remove this workaround as soon as interface_add_data works */
+	{
+		unsigned int i;
+		for (i=0; i<NR_CPUS; i++) {
+			if (cpu_online(i)) 
+				cpufreq_remove_dev(&cpufreq_driver->policy[i].intf);
+		}
+	}
+
+	interface_unregister(&cpufreq_interface);
+
+	if (driver)
+		kfree(cpufreq_driver->policy);
+	cpufreq_driver = NULL;
+
+	up(&cpufreq_driver_sem);
+
 	return 0;
 }
-EXPORT_SYMBOL_GPL(cpufreq_unregister);
+EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
 
 
 #ifdef CONFIG_PM
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Mon Jan 13 21:59:49 2003
+++ b/kernel/ksyms.c	Mon Jan 13 21:59:49 2003
@@ -66,6 +66,8 @@
 
 extern struct timezone sys_tz;
 
+extern int panic_timeout;
+
 #ifdef CONFIG_MODVERSIONS
 const struct module_symbol __export_Using_Versions
 __attribute__((section("__ksymtab"))) = {
@@ -502,6 +504,8 @@
 
 /* misc */
 EXPORT_SYMBOL(panic);
+EXPORT_SYMBOL(panic_notifier_list);
+EXPORT_SYMBOL(panic_timeout);
 EXPORT_SYMBOL(sprintf);
 EXPORT_SYMBOL(snprintf);
 EXPORT_SYMBOL(sscanf);
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c	Mon Jan 13 21:59:50 2003
+++ b/kernel/module.c	Mon Jan 13 21:59:50 2003
@@ -722,28 +722,22 @@
 }
 #endif /* CONFIG_OBSOLETE_MODPARM */
 
-/* Find an symbol for this module (ie. resolve internals first).
-   It we find one, record usage.  Must be holding module_mutex. */
-unsigned long find_symbol_internal(Elf_Shdr *sechdrs,
-				   unsigned int symindex,
-				   const char *strtab,
-				   const char *name,
-				   struct module *mod,
-				   struct kernel_symbol_group **ksg)
+/* Resolve a symbol for this module.  I.e. if we find one, record usage.
+   Must be holding module_mutex. */
+static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
+				    unsigned int symindex,
+				    const char *strtab,
+				    const char *name,
+				    struct module *mod)
 {
+	struct kernel_symbol_group *ksg;
 	unsigned long ret;
 
-	ret = find_local_symbol(sechdrs, symindex, strtab, name);
-	if (ret) {
-		*ksg = NULL;
-		return ret;
-	}
-	/* Look in other modules... */
 	spin_lock_irq(&modlist_lock);
-	ret = __find_symbol(name, ksg, mod->license_gplok);
+	ret = __find_symbol(name, &ksg, mod->license_gplok);
 	if (ret) {
 		/* This can fail due to OOM, or module unloading */
-		if (!use_module(mod, (*ksg)->owner))
+		if (!use_module(mod, ksg->owner))
 			ret = 0;
 	}
 	spin_unlock_irq(&modlist_lock);
@@ -832,21 +826,19 @@
 			    unsigned int strindex,
 			    struct module *mod)
 {
-	unsigned int i;
-	Elf_Sym *sym;
+	Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
+	const char *strtab = (char *)sechdrs[strindex].sh_addr;
+	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
+	int ret = 0;
 
-	/* First simplify defined symbols, so if they become the
-           "answer" to undefined symbols, copying their st_value us
-           correct. */
-	for (sym = (void *)sechdrs[symindex].sh_addr, i = 0;
-	     i < sechdrs[symindex].sh_size / sizeof(Elf_Sym);
-	     i++) {
+	for (i = 1; i < n; i++) {
 		switch (sym[i].st_shndx) {
 		case SHN_COMMON:
 			/* We compiled with -fno-common.  These are not
 			   supposed to happen.  */
 			DEBUGP("Common symbol: %s\n", strtab + sym[i].st_name);
-			return -ENOEXEC;
+			ret = -ENOEXEC;
+			break;
 
 		case SHN_ABS:
 			/* Don't need to do anything */
@@ -855,6 +847,20 @@
 			break;
 
 		case SHN_UNDEF:
+			sym[i].st_value
+			  = resolve_symbol(sechdrs, symindex, strtab,
+					   strtab + sym[i].st_name, mod);
+
+			/* Ok if resolved.  */
+			if (sym[i].st_value != 0)
+				break;
+			/* Ok if weak.  */
+			if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
+				break;
+
+			printk(KERN_WARNING "%s: Unknown symbol %s\n",
+			       mod->name, strtab + sym[i].st_name);
+			ret = -ENOENT;
 			break;
 
 		default:
@@ -862,30 +868,11 @@
 				= (unsigned long)
 				(sechdrs[sym[i].st_shndx].sh_addr
 				 + sym[i].st_value);
+			break;
 		}
 	}
 
-	/* Now try to resolve undefined symbols */
-	for (sym = (void *)sechdrs[symindex].sh_addr, i = 0;
-	     i < sechdrs[symindex].sh_size / sizeof(Elf_Sym);
-	     i++) {
-		if (sym[i].st_shndx == SHN_UNDEF) {
-			/* Look for symbol */
-			struct kernel_symbol_group *ksg = NULL;
-			const char *strtab 
-				= (char *)sechdrs[strindex].sh_addr;
-
-			sym[i].st_value
-				= find_symbol_internal(sechdrs,
-						       symindex,
-						       strtab,
-						       strtab + sym[i].st_name,
-						       mod,
-						       &ksg);
-		}
-	}
-
-	return 0;
+	return ret;
 }
 
 /* Update size with this section: return offset. */
@@ -1422,6 +1409,15 @@
 	seq_printf(m, "%s %lu",
 		   mod->name, mod->init_size + mod->core_size);
 	print_unload_info(m, mod);
+
+	/* Informative for users. */
+	seq_printf(m, " %s",
+		   mod->state == MODULE_STATE_GOING ? "Unloading":
+		   mod->state == MODULE_STATE_COMING ? "Loading":
+		   "Live");
+	/* Used by oprofile and other similar tools. */
+	seq_printf(m, " 0x%p", mod->module_core);
+
 	seq_printf(m, "\n");
 	return 0;
 }
diff -Nru a/kernel/suspend.c b/kernel/suspend.c
--- a/kernel/suspend.c	Mon Jan 13 21:59:49 2003
+++ b/kernel/suspend.c	Mon Jan 13 21:59:49 2003
@@ -680,6 +680,8 @@
 	struct sysinfo i;
 	unsigned int nr_needed_pages = 0;
 
+	drain_local_pages();
+
 	pagedir_nosave = NULL;
 	printk( "/critical section: Counting pages to copy" );
 	nr_copy_pages = count_and_copy_data_pages(NULL);
@@ -714,6 +716,7 @@
 	nr_copy_pages_check = nr_copy_pages;
 	pagedir_order_check = pagedir_order;
 
+	drain_local_pages();	/* During allocating of suspend pagedir, new cold pages may appear. Kill them */
 	if (nr_copy_pages != count_and_copy_data_pages(pagedir_nosave))	/* copy */
 		BUG();
 
diff -Nru a/net/802/tr.c b/net/802/tr.c
--- a/net/802/tr.c	Mon Jan 13 21:59:49 2003
+++ b/net/802/tr.c	Mon Jan 13 21:59:49 2003
@@ -64,7 +64,7 @@
  *	up a lot.
  */
  
-rif_cache rif_table[RIF_TABLE_SIZE]={ NULL, };
+static rif_cache rif_table[RIF_TABLE_SIZE];
 
 static spinlock_t rif_lock = SPIN_LOCK_UNLOCKED;
 
diff -Nru a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
--- a/net/bridge/br_ioctl.c	Mon Jan 13 21:59:49 2003
+++ b/net/bridge/br_ioctl.c	Mon Jan 13 21:59:49 2003
@@ -230,7 +230,7 @@
 	return -EOPNOTSUPP;
 }
 
-DECLARE_MUTEX(ioctl_mutex);
+static DECLARE_MUTEX(ioctl_mutex);
 
 int br_ioctl_deviceless_stub(unsigned long arg)
 {
diff -Nru a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
--- a/net/bridge/netfilter/ebt_log.c	Mon Jan 13 21:59:49 2003
+++ b/net/bridge/netfilter/ebt_log.c	Mon Jan 13 21:59:49 2003
@@ -78,7 +78,7 @@
 	spin_unlock_bh(&ebt_log_lock);
 }
 
-struct ebt_watcher log =
+static struct ebt_watcher log =
 {
 	{NULL, NULL}, EBT_LOG_WATCHER, ebt_log, ebt_log_check, NULL,
 	THIS_MODULE
diff -Nru a/net/irda/iriap.c b/net/irda/iriap.c
--- a/net/irda/iriap.c	Mon Jan 13 21:59:49 2003
+++ b/net/irda/iriap.c	Mon Jan 13 21:59:49 2003
@@ -96,9 +96,10 @@
 		return -ENOMEM;
 
 	/* Object repository - defined in irias_object.c */
-	objects = hashbin_new(HB_LOCK);
-	if (!objects) {
-		WARNING("%s: Can't allocate objects hashbin!\n", __FUNCTION__);
+	irias_objects = hashbin_new(HB_LOCK);
+	if (!irias_objects) {
+		WARNING("%s: Can't allocate irias_objects hashbin!\n",
+			__FUNCTION__);
 		return -ENOMEM;
 	}
 
@@ -147,7 +148,7 @@
 	irlmp_unregister_service(service_handle);
 
 	hashbin_delete(iriap, (FREE_FUNC) __iriap_close);
-	hashbin_delete(objects, (FREE_FUNC) __irias_delete_object);
+	hashbin_delete(irias_objects, (FREE_FUNC) __irias_delete_object);
 }
 
 /*
@@ -971,16 +972,16 @@
 	struct ias_attrib *attrib;
 	unsigned long flags;
 
-	ASSERT( objects != NULL, return 0;);
+	ASSERT( irias_objects != NULL, return 0;);
 
 	len = 0;
 
 	len += sprintf(buf+len, "LM-IAS Objects:\n");
 
-	spin_lock_irqsave(&objects->hb_spinlock, flags);
+	spin_lock_irqsave(&irias_objects->hb_spinlock, flags);
 
-	/* List all objects */
-	obj = (struct ias_object *) hashbin_get_first(objects);
+	/* List all irias_objects */
+	obj = (struct ias_object *) hashbin_get_first(irias_objects);
 	while ( obj != NULL) {
 		ASSERT(obj->magic == IAS_OBJECT_MAGIC, return 0;);
 
@@ -1031,9 +1032,9 @@
 		}
 		spin_unlock(&obj->attribs->hb_spinlock);
 
-	        obj = (struct ias_object *) hashbin_get_next(objects);
+	        obj = (struct ias_object *) hashbin_get_next(irias_objects);
 	}
-	spin_unlock_irqrestore(&objects->hb_spinlock, flags);
+	spin_unlock_irqrestore(&irias_objects->hb_spinlock, flags);
 
 	return len;
 }
diff -Nru a/net/irda/irias_object.c b/net/irda/irias_object.c
--- a/net/irda/irias_object.c	Mon Jan 13 21:59:50 2003
+++ b/net/irda/irias_object.c	Mon Jan 13 21:59:50 2003
@@ -28,7 +28,7 @@
 #include <net/irda/irda.h>
 #include <net/irda/irias_object.h>
 
-hashbin_t *objects = NULL;
+hashbin_t *irias_objects;
 
 /*
  *  Used when a missing value needs to be returned
@@ -42,7 +42,7 @@
  *
  * Faster, check boundary... Jean II
  */
-char *strndup(char *str, int max)
+static char *strndup(char *str, int max)
 {
 	char *new_str;
 	int len;
@@ -151,7 +151,7 @@
 	ASSERT(obj != NULL, return -1;);
 	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return -1;);
 
-	node = hashbin_remove_this(objects, (irda_queue_t *) obj);
+	node = hashbin_remove_this(irias_objects, (irda_queue_t *) obj);
 	if (!node)
 		return 0; /* Already removed */
 
@@ -202,7 +202,7 @@
 	ASSERT(obj != NULL, return;);
 	ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;);
 
-	hashbin_insert(objects, (irda_queue_t *) obj, 0, obj->name);
+	hashbin_insert(irias_objects, (irda_queue_t *) obj, 0, obj->name);
 }
 
 /*
@@ -216,7 +216,7 @@
 	ASSERT(name != NULL, return NULL;);
 
 	/* Unsafe (locking), object might change */
-	return hashbin_lock_find(objects, 0, name);
+	return hashbin_lock_find(irias_objects, 0, name);
 }
 
 /*
@@ -276,7 +276,7 @@
 	unsigned long flags;
 
 	/* Find object */
-	obj = hashbin_lock_find(objects, 0, obj_name);
+	obj = hashbin_lock_find(irias_objects, 0, obj_name);
 	if (obj == NULL) {
 		WARNING("%s: Unable to find object: %s\n", __FUNCTION__,
 			obj_name);
diff -Nru a/net/irda/qos.c b/net/irda/qos.c
--- a/net/irda/qos.c	Mon Jan 13 21:59:51 2003
+++ b/net/irda/qos.c	Mon Jan 13 21:59:51 2003
@@ -96,15 +96,15 @@
 static int irlap_param_min_turn_time(void *instance, irda_param_t *param, 
 				     int get);
 
-__u32 min_turn_times[]  = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
-__u32 baud_rates[]      = { 2400, 9600, 19200, 38400, 57600, 115200, 576000, 
-			    1152000, 4000000, 16000000 };           /* bps */
-__u32 data_sizes[]      = { 64, 128, 256, 512, 1024, 2048 };        /* bytes */
-__u32 add_bofs[]        = { 48, 24, 12, 5, 3, 2, 1, 0 };            /* bytes */
-__u32 max_turn_times[]  = { 500, 250, 100, 50 };                    /* ms */
-__u32 link_disc_times[] = { 3, 8, 12, 16, 20, 25, 30, 40 };         /* secs */
+static __u32 min_turn_times[]  = { 10000, 5000, 1000, 500, 100, 50, 10, 0 }; /* us */
+static __u32 baud_rates[]      = { 2400, 9600, 19200, 38400, 57600, 115200, 576000, 
+				   1152000, 4000000, 16000000 };           /* bps */
+static __u32 data_sizes[]      = { 64, 128, 256, 512, 1024, 2048 };        /* bytes */
+static __u32 add_bofs[]        = { 48, 24, 12, 5, 3, 2, 1, 0 };            /* bytes */
+static __u32 max_turn_times[]  = { 500, 250, 100, 50 };                    /* ms */
+static __u32 link_disc_times[] = { 3, 8, 12, 16, 20, 25, 30, 40 };         /* secs */
 
-__u32 max_line_capacities[10][4] = {
+static __u32 max_line_capacities[10][4] = {
        /* 500 ms     250 ms  100 ms  50 ms (max turn time) */
 	{    100,      0,      0,     0 }, /*     2400 bps */
 	{    400,      0,      0,     0 }, /*     9600 bps */
@@ -185,7 +185,7 @@
  *    Returns index to most significant bit (MSB) in word
  *
  */
-int msb_index (__u16 word) 
+static int msb_index (__u16 word) 
 {
 	__u16 msb = 0x8000;
 	int index = 15;   /* Current MSB */
diff -Nru a/net/sunrpc/Makefile b/net/sunrpc/Makefile
--- a/net/sunrpc/Makefile	Mon Jan 13 21:59:49 2003
+++ b/net/sunrpc/Makefile	Mon Jan 13 21:59:49 2003
@@ -2,6 +2,8 @@
 # Makefile for Linux kernel SUN RPC
 #
 
+obj-$(CONFIG_SUNRPC_GSS) += auth_gss/
+
 obj-$(CONFIG_SUNRPC) += sunrpc.o
 
 export-objs := sunrpc_syms.o
@@ -10,6 +12,6 @@
 	    auth.o auth_null.o auth_unix.o \
 	    svc.o svcsock.o svcauth.o svcauth_unix.o \
 	    pmap_clnt.o timer.o xdr.o \
-	    sunrpc_syms.o cache.o
+	    sunrpc_syms.o cache.o rpc_pipe.o
 sunrpc-$(CONFIG_PROC_FS) += stats.o
 sunrpc-$(CONFIG_SYSCTL) += sysctl.o
diff -Nru a/net/sunrpc/auth.c b/net/sunrpc/auth.c
--- a/net/sunrpc/auth.c	Mon Jan 13 21:59:50 2003
+++ b/net/sunrpc/auth.c	Mon Jan 13 21:59:50 2003
@@ -24,6 +24,13 @@
 	NULL,			/* others can be loadable modules */
 };
 
+u32
+pseudoflavor_to_flavor(u32 flavor) {
+	if (flavor >= RPC_AUTH_MAXFLAVOR)
+		return RPC_AUTH_GSS;
+	return flavor;
+}
+
 int
 rpcauth_register(struct rpc_authops *ops)
 {
@@ -51,13 +58,14 @@
 }
 
 struct rpc_auth *
-rpcauth_create(rpc_authflavor_t flavor, struct rpc_clnt *clnt)
+rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
 {
 	struct rpc_authops	*ops;
+	u32			flavor = pseudoflavor_to_flavor(pseudoflavor);
 
 	if (flavor >= RPC_AUTH_MAXFLAVOR || !(ops = auth_flavors[flavor]))
 		return NULL;
-	clnt->cl_auth = ops->create(clnt);
+	clnt->cl_auth = ops->create(clnt, pseudoflavor);
 	return clnt->cl_auth;
 }
 
@@ -173,8 +181,9 @@
 /*
  * Look up a process' credentials in the authentication cache
  */
-static struct rpc_cred *
-rpcauth_lookup_credcache(struct rpc_auth *auth, int taskflags)
+struct rpc_cred *
+rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
+		int taskflags)
 {
 	LIST_HEAD(free);
 	struct list_head *pos, *next;
@@ -183,7 +192,7 @@
 	int		nr = 0;
 
 	if (!(taskflags & RPC_TASK_ROOTCREDS))
-		nr = current->uid & RPC_CREDCACHE_MASK;
+		nr = acred->uid & RPC_CREDCACHE_MASK;
 retry:
 	spin_lock(&rpc_credcache_lock);
 	if (time_before(auth->au_nextgc, jiffies))
@@ -195,7 +204,7 @@
 			continue;
 		if (rpcauth_prune_expired(entry, &free))
 			continue;
-		if (entry->cr_ops->crmatch(entry, taskflags)) {
+		if (entry->cr_ops->crmatch(acred, entry, taskflags)) {
 			list_del(&entry->cr_hash);
 			cred = entry;
 			break;
@@ -217,7 +226,7 @@
 	rpcauth_destroy_credlist(&free);
 
 	if (!cred) {
-		new = auth->au_ops->crcreate(taskflags);
+		new = auth->au_ops->crcreate(auth, acred, taskflags);
 		if (new) {
 #ifdef RPC_DEBUG
 			new->cr_magic = RPCAUTH_CRED_MAGIC;
@@ -232,19 +241,31 @@
 struct rpc_cred *
 rpcauth_lookupcred(struct rpc_auth *auth, int taskflags)
 {
+	struct auth_cred acred = {
+		.uid = current->fsuid,
+		.gid = current->fsgid,
+		.ngroups = current->ngroups,
+		.groups = current->groups,
+	};
 	dprintk("RPC:     looking up %s cred\n",
 		auth->au_ops->au_name);
-	return rpcauth_lookup_credcache(auth, taskflags);
+	return rpcauth_lookup_credcache(auth, &acred, taskflags);
 }
 
 struct rpc_cred *
 rpcauth_bindcred(struct rpc_task *task)
 {
 	struct rpc_auth *auth = task->tk_auth;
+	struct auth_cred acred = {
+		.uid = current->fsuid,
+		.gid = current->fsgid,
+		.ngroups = current->ngroups,
+		.groups = current->groups,
+	};
 
 	dprintk("RPC: %4d looking up %s cred\n",
 		task->tk_pid, task->tk_auth->au_ops->au_name);
-	task->tk_msg.rpc_cred = rpcauth_lookup_credcache(auth, task->tk_flags);
+	task->tk_msg.rpc_cred = rpcauth_lookup_credcache(auth, &acred, task->tk_flags);
 	if (task->tk_msg.rpc_cred == 0)
 		task->tk_status = -ENOMEM;
 	return task->tk_msg.rpc_cred;
@@ -339,10 +360,7 @@
 int
 rpcauth_uptodatecred(struct rpc_task *task)
 {
-	int retval;
-	spin_lock(&rpc_credcache_lock);
-	retval = !(task->tk_msg.rpc_cred) ||
+	return !(task->tk_msg.rpc_cred) ||
 		(task->tk_msg.rpc_cred->cr_flags & RPCAUTH_CRED_UPTODATE);
-	spin_unlock(&rpc_credcache_lock);
-	return retval;
 }
+
diff -Nru a/net/sunrpc/auth_gss/Makefile b/net/sunrpc/auth_gss/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/Makefile	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,16 @@
+#
+# Makefile for Linux kernel rpcsec_gss implementation
+#
+
+obj-$(CONFIG_SUNRPC_GSS) += auth_rpcgss.o
+
+export-objs := sunrpcgss_syms.o
+
+auth_rpcgss-objs := auth_gss.o gss_pseudoflavors.o gss_generic_token.o \
+	sunrpcgss_syms.o gss_mech_switch.o
+
+obj-$(CONFIG_RPCSEC_GSS_KRB5) += rpcsec_gss_krb5.o
+
+rpcsec_gss_krb5-objs := gss_krb5_mech.o gss_krb5_seal.o gss_krb5_unseal.o \
+	gss_krb5_crypto.o gss_krb5_seqnum.o
+
diff -Nru a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/auth_gss.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,736 @@
+/*
+ * linux/net/sunrpc/auth_gss.c
+ *
+ * RPCSEC_GSS client authentication.
+ * 
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Dug Song       <dugsong@monkey.org>
+ *  Andy Adamson   <andros@umich.edu>
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the University nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  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 REGENTS OR CONTRIBUTORS 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.
+ *
+ * $Id$
+ */
+
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/sched.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/auth.h>
+#include <linux/sunrpc/auth_gss.h>
+#include <linux/sunrpc/gss_err.h>
+#include <linux/sunrpc/rpc_pipe_fs.h>
+#include <asm/uaccess.h>
+
+static struct rpc_authops authgss_ops;
+
+static struct rpc_credops gss_credops;
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY	RPCDBG_AUTH
+#endif
+
+#define NFS_NGROUPS	16
+
+#define GSS_CRED_EXPIRE		(60 * HZ)	/* XXX: reasonable? */
+#define GSS_CRED_SLACK		1024		/* XXX: unused */
+#define GSS_VERF_SLACK		48		/* length of a krb5 verifier.*/
+
+/* XXX this define must match the gssd define
+* as it is passed to gssd to signal the use of
+* machine creds should be part of the shared rpc interface */
+
+#define CA_RUN_AS_MACHINE  0x00000200 
+
+/* dump the buffer in `emacs-hexl' style */
+#define isprint(c)      ((c > 0x1f) && (c < 0x7f))
+
+static rwlock_t gss_ctx_lock = RW_LOCK_UNLOCKED;
+
+struct gss_auth {
+	struct rpc_auth rpc_auth;
+	struct gss_api_mech *mech;
+	struct list_head upcalls;
+	struct dentry *dentry;
+	char path[48];
+	spinlock_t lock;
+};
+
+static void gss_destroy_ctx(struct gss_cl_ctx *);
+static struct rpc_pipe_ops gss_upcall_ops;
+
+void
+print_hexl(u32 *p, u_int length, u_int offset)
+{
+	u_int i, j, jm;
+	u8 c, *cp;
+	
+	dprintk("RPC: print_hexl: length %d\n",length);
+	dprintk("\n");
+	cp = (u8 *) p;
+	
+	for (i = 0; i < length; i += 0x10) {
+		dprintk("  %04x: ", (u_int)(i + offset));
+		jm = length - i;
+		jm = jm > 16 ? 16 : jm;
+		
+		for (j = 0; j < jm; j++) {
+			if ((j % 2) == 1)
+				dprintk("%02x ", (u_int)cp[i+j]);
+			else
+				dprintk("%02x", (u_int)cp[i+j]);
+		}
+		for (; j < 16; j++) {
+			if ((j % 2) == 1)
+				dprintk("   ");
+			else
+				dprintk("  ");
+		}
+		dprintk(" ");
+		
+		for (j = 0; j < jm; j++) {
+			c = cp[i+j];
+			c = isprint(c) ? c : '.';
+			dprintk("%c", c);
+		}
+		dprintk("\n");
+	}
+}
+
+static inline struct gss_cl_ctx *
+gss_get_ctx(struct gss_cl_ctx *ctx)
+{
+	atomic_inc(&ctx->count);
+	return ctx;
+}
+
+static inline void
+gss_put_ctx(struct gss_cl_ctx *ctx)
+{
+	if (atomic_dec_and_test(&ctx->count))
+		gss_destroy_ctx(ctx);
+}
+
+static void
+gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
+{
+	struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
+	struct gss_cl_ctx *old;
+	write_lock(&gss_ctx_lock);
+	old = gss_cred->gc_ctx;
+	gss_cred->gc_ctx = ctx;
+	cred->cr_flags |= RPCAUTH_CRED_UPTODATE;
+	write_unlock(&gss_ctx_lock);
+	if (old)
+		gss_put_ctx(old);
+}
+
+static struct gss_cl_ctx *
+gss_cred_get_ctx(struct rpc_cred *cred)
+{
+	struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
+	struct gss_cl_ctx *ctx = NULL;
+
+	read_lock(&gss_ctx_lock);
+	if ((cred->cr_flags & RPCAUTH_CRED_UPTODATE) && gss_cred->gc_ctx)
+		ctx = gss_get_ctx(gss_cred->gc_ctx);
+	read_unlock(&gss_ctx_lock);
+	return ctx;
+}
+
+static inline int
+simple_get_bytes(char **ptr, const char *end, void *res, int len)
+{
+	char *p, *q;
+	p = *ptr;
+	q = p + len;
+	if (q > end || q < p)
+		return -1;
+	memcpy(res, p, len);
+	*ptr = q;
+	return 0;
+}
+
+static inline int
+simple_get_netobj(char **ptr, const char *end, struct xdr_netobj *res)
+{
+	char *p, *q;
+	p = *ptr;
+	if (simple_get_bytes(&p, end, &res->len, sizeof(res->len)))
+		return -1;
+	q = p + res->len;
+	if (q > end || q < p)
+		return -1;
+	res->data = p;
+	*ptr = q;
+	return 0;
+}
+
+static int
+dup_netobj(struct xdr_netobj *source, struct xdr_netobj *dest)
+{
+	dest->len = source->len;
+	if (!(dest->data = kmalloc(dest->len, GFP_KERNEL)))
+		return -1;
+	memcpy(dest->data, source->data, dest->len);
+	return 0;
+}
+
+static int
+gss_parse_init_downcall(struct gss_api_mech *gm, struct xdr_netobj *buf,
+		struct gss_cl_ctx **gc, uid_t *uid)
+{
+	char *end = buf->data + buf->len;
+	char *p = buf->data;
+	struct gss_cl_ctx *ctx;
+	struct xdr_netobj tmp_buf;
+	unsigned int timeout;
+	int err = -EIO;
+
+	if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto err;
+	}
+	ctx->gc_proc = RPC_GSS_PROC_DATA;
+	ctx->gc_seq = 0;
+	spin_lock_init(&ctx->gc_seq_lock);
+	atomic_set(&ctx->count,1);
+
+	if (simple_get_bytes(&p, end, uid, sizeof(uid)))
+		goto err_free_ctx;
+	/* FIXME: discarded timeout for now */
+	if (simple_get_bytes(&p, end, &timeout, sizeof(timeout)))
+		goto err_free_ctx;
+	if (simple_get_bytes(&p, end, &ctx->gc_win, sizeof(ctx->gc_win)))
+		goto err_free_ctx;
+	if (simple_get_netobj(&p, end, &tmp_buf))
+		goto err_free_ctx;
+	if (dup_netobj(&tmp_buf, &ctx->gc_wire_ctx)) {
+		err = -ENOMEM;
+		goto err_free_ctx;
+	}
+	if (simple_get_netobj(&p, end, &tmp_buf))
+		goto err_free_wire_ctx;
+	if (p != end)
+		goto err_free_wire_ctx;
+	if (gss_import_sec_context(&tmp_buf, gm, &ctx->gc_gss_ctx))
+		goto err_free_wire_ctx;
+	*gc = ctx;
+	return 0;
+err_free_wire_ctx:
+	kfree(ctx->gc_wire_ctx.data);
+err_free_ctx:
+	kfree(ctx);
+err:
+	*gc = NULL;
+	dprintk("RPC: gss_parse_init_downcall returning %d\n", err);
+	return err;
+}
+
+
+struct gss_upcall_msg {
+	struct rpc_pipe_msg msg;
+	struct list_head list;
+	struct rpc_wait_queue waitq;
+	uid_t	uid;
+	atomic_t count;
+};
+
+static void
+gss_release_msg(struct gss_upcall_msg *gss_msg)
+{
+	if (atomic_dec_and_test(&gss_msg->count))
+		kfree(gss_msg);
+}
+
+static struct gss_upcall_msg *
+gss_find_upcall(struct gss_auth *gss_auth, uid_t uid)
+{
+	struct gss_upcall_msg *pos;
+	list_for_each_entry(pos, &gss_auth->upcalls, list) {
+		if (pos->uid == uid)
+			return pos;
+	}
+	return NULL;
+}
+
+static void
+gss_release_callback(struct rpc_task *task)
+{
+	struct rpc_clnt *clnt = task->tk_client;
+	struct gss_auth *gss_auth = container_of(clnt->cl_auth,
+			struct gss_auth, rpc_auth);
+	struct gss_upcall_msg *gss_msg;
+
+	spin_lock(&gss_auth->lock);
+	gss_msg = gss_find_upcall(gss_auth, task->tk_msg.rpc_cred->cr_uid);
+	if (gss_msg) {
+		rpc_wake_up(&gss_msg->waitq);
+		list_del(&gss_msg->list);
+		gss_release_msg(gss_msg);
+	}
+	spin_unlock(&gss_auth->lock);
+}
+
+static int
+gss_upcall(struct rpc_clnt *clnt, struct rpc_task *task, uid_t uid)
+{
+	struct gss_auth *gss_auth = container_of(clnt->cl_auth,
+			struct gss_auth, rpc_auth);
+	struct gss_upcall_msg *gss_msg, *gss_new = NULL;
+	struct rpc_pipe_msg *msg;
+	struct dentry *dentry = gss_auth->dentry;
+	int res;
+
+retry:
+	gss_msg = gss_find_upcall(gss_auth, uid);
+	if (gss_msg == NULL && gss_new == NULL) {
+		spin_unlock(&gss_auth->lock);
+		gss_new = kmalloc(sizeof(*gss_new), GFP_KERNEL);
+		spin_lock(&gss_auth->lock);
+		if (gss_new)
+			goto retry;
+		return -ENOMEM;
+	}
+	if (gss_msg)
+		goto out_sleep;
+	gss_msg = gss_new;
+	memset(gss_new, 0, sizeof(*gss_new));
+	INIT_LIST_HEAD(&gss_new->list);
+	INIT_RPC_WAITQ(&gss_new->waitq, "RPCSEC_GSS upcall waitq");
+	atomic_set(&gss_new->count, 2);
+	msg = &gss_new->msg;
+	msg->data = &gss_new->uid;
+	msg->len = sizeof(gss_new->uid);
+	gss_new->uid = uid;
+	list_add(&gss_new->list, &gss_auth->upcalls);
+	gss_new = NULL;
+	rpc_sleep_on(&gss_msg->waitq, task, gss_release_callback, NULL);
+	spin_unlock(&gss_auth->lock);
+	res = rpc_queue_upcall(dentry->d_inode, msg);
+	spin_lock(&gss_auth->lock);
+	if (res)
+		gss_release_msg(gss_msg);
+	return res;
+out_sleep:
+	rpc_sleep_on(&gss_msg->waitq, task, NULL, NULL);
+	if (gss_new)
+		kfree(gss_new);
+	return 0;
+}
+
+static ssize_t
+gss_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
+		char *dst, size_t buflen)
+{
+	char *data = (char *)msg->data + msg->copied;
+	ssize_t mlen = msg->len - msg->copied;
+	ssize_t left;
+
+	if (mlen > buflen)
+		mlen = buflen;
+	left = copy_to_user(dst, data, mlen);
+	msg->copied += mlen - left;
+	return mlen - left;
+}
+
+static ssize_t
+gss_pipe_downcall(struct file *filp, const char *src, size_t mlen)
+{
+	char buf[1024];
+	struct xdr_netobj obj = {
+		.len	= mlen,
+		.data	= buf,
+	};
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct rpc_inode *rpci = RPC_I(inode);
+	struct rpc_clnt *clnt;
+	struct rpc_auth *auth;
+	struct gss_auth *gss_auth;
+	struct gss_api_mech *mech;
+	struct auth_cred acred = { 0 };
+	struct rpc_cred *cred;
+	struct gss_upcall_msg *gss_msg;
+	struct gss_cl_ctx *ctx;
+	ssize_t left;
+	int err;
+
+	if (mlen > sizeof(buf))
+		return -ENOSPC;
+	left = copy_from_user(buf, src, mlen);
+	if (left)
+		return -EFAULT;
+	clnt = rpci->private;
+	atomic_inc(&clnt->cl_users);
+	auth = clnt->cl_auth;
+	gss_auth = container_of(auth, struct gss_auth, rpc_auth);
+	mech = gss_auth->mech;
+	err = gss_parse_init_downcall(mech, &obj, &ctx, &acred.uid);
+	if (err)
+		goto err;
+	cred = rpcauth_lookup_credcache(auth, &acred, 0);
+	if (!cred)
+		goto err_release_ctx;
+	gss_cred_set_ctx(cred, ctx);
+	spin_lock(&gss_auth->lock);
+	gss_msg = gss_find_upcall(gss_auth, acred.uid);
+	if (gss_msg)
+		rpc_wake_up(&gss_msg->waitq);
+	spin_unlock(&gss_auth->lock);
+	rpc_release_client(clnt);
+	return mlen;
+err_release_ctx:
+	gss_destroy_ctx(ctx);
+err:
+	rpc_release_client(clnt);
+	dprintk("RPC: gss_pipe_downcall returning %d\n", err);
+	return err;
+}
+
+void
+gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
+{
+	struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
+
+	rpc_wake_up(&gss_msg->waitq);
+	gss_release_msg(gss_msg);
+}
+
+/* 
+ * NOTE: we have the opportunity to use different 
+ * parameters based on the input flavor (which must be a pseudoflavor)
+ */
+static struct rpc_auth *
+gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
+{
+	struct gss_auth *gss_auth;
+	struct rpc_auth * auth;
+
+	dprintk("RPC: creating GSS authenticator for client %p\n",clnt);
+	if (!try_module_get(THIS_MODULE))
+		return NULL;
+	if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
+		goto out_dec;
+	gss_auth->mech = gss_pseudoflavor_to_mech(flavor);
+	if (!gss_auth->mech) {
+		printk(KERN_WARNING "%s: Pseudoflavor %d not found!",
+				__FUNCTION__, flavor);
+		goto err_free;
+	}
+	INIT_LIST_HEAD(&gss_auth->upcalls);
+	spin_lock_init(&gss_auth->lock);
+	auth = &gss_auth->rpc_auth;
+	auth->au_cslack = GSS_CRED_SLACK >> 2;
+	auth->au_rslack = GSS_VERF_SLACK >> 2;
+	auth->au_expire = GSS_CRED_EXPIRE;
+	auth->au_ops = &authgss_ops;
+	auth->au_flavor = flavor;
+
+	rpcauth_init_credcache(auth);
+
+	snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s",
+			clnt->cl_pathname,
+			gss_auth->mech->gm_ops->name);
+	gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops);
+	if (IS_ERR(gss_auth->dentry))
+		goto err_free;
+
+	return auth;
+err_free:
+	kfree(gss_auth);
+out_dec:
+	module_put(THIS_MODULE);
+	return NULL;
+}
+
+static void
+gss_destroy(struct rpc_auth *auth)
+{
+	struct gss_auth *gss_auth;
+	dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
+		auth, auth->au_flavor);
+
+	gss_auth = container_of(auth, struct gss_auth, rpc_auth);
+	rpc_unlink(gss_auth->path);
+
+	rpcauth_free_credcache(auth);
+
+	kfree(auth);
+	module_put(THIS_MODULE);
+}
+
+/* gss_destroy_cred (and gss_destroy_ctx) are used to clean up after failure
+ * to create a new cred or context, so they check that things have been
+ * allocated before freeing them. */
+static void
+gss_destroy_ctx(struct gss_cl_ctx *ctx)
+{
+
+	dprintk("RPC: gss_destroy_ctx\n");
+
+	if (ctx->gc_gss_ctx)
+		gss_delete_sec_context(&ctx->gc_gss_ctx);
+
+	if (ctx->gc_wire_ctx.len > 0) {
+		kfree(ctx->gc_wire_ctx.data);
+		ctx->gc_wire_ctx.len = 0;
+	}
+
+	kfree(ctx);
+
+}
+
+static void
+gss_destroy_cred(struct rpc_cred *rc)
+{
+	struct gss_cred *cred = (struct gss_cred *)rc;
+
+	dprintk("RPC: gss_destroy_cred \n");
+
+	if (cred->gc_ctx)
+		gss_put_ctx(cred->gc_ctx);
+	kfree(cred);
+}
+
+static struct rpc_cred *
+gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags)
+{
+	struct gss_cred	*cred = NULL;
+
+	dprintk("RPC: gss_create_cred for uid %d, flavor %d\n",
+		acred->uid, auth->au_flavor);
+
+	if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL)))
+		goto out_err;
+
+	memset(cred, 0, sizeof(*cred));
+	atomic_set(&cred->gc_count, 0);
+	cred->gc_uid = acred->uid;
+	/*
+	 * Note: in order to force a call to call_refresh(), we deliberately
+	 * fail to flag the credential as RPCAUTH_CRED_UPTODATE.
+	 */
+	cred->gc_flags = 0;
+	cred->gc_base.cr_ops = &gss_credops;
+	cred->gc_flavor = auth->au_flavor;
+
+	return (struct rpc_cred *) cred;
+
+out_err:
+	dprintk("RPC: gss_create_cred failed\n");
+	if (cred) gss_destroy_cred((struct rpc_cred *)cred);
+	return NULL;
+}
+
+static int
+gss_match(struct auth_cred *acred, struct rpc_cred *rc, int taskflags)
+{
+	return (rc->cr_uid == acred->uid);
+}
+
+/*
+* Marshal credentials.
+* Maybe we should keep a cached credential for performance reasons.
+*/
+static u32 *
+gss_marshal(struct rpc_task *task, u32 *p, int ruid)
+{
+	struct rpc_cred *cred = task->tk_msg.rpc_cred;
+	struct gss_cred	*gss_cred = container_of(cred, struct gss_cred,
+						 gc_base);
+	struct gss_cl_ctx	*ctx = gss_cred_get_ctx(cred);
+	u32		*cred_len;
+	struct rpc_rqst *req = task->tk_rqstp;
+	struct rpc_clnt *clnt = task->tk_client;
+	struct rpc_xprt *xprt = clnt->cl_xprt;
+	u32             *verfbase = req->rq_svec[0].iov_base; 
+	u32             maj_stat = 0;
+	struct xdr_netobj bufin,bufout;
+	u32		service;
+
+	dprintk("RPC: gss_marshal\n");
+
+	/* We compute the checksum for the verifier over the xdr-encoded bytes
+	 * starting with the xid (which verfbase points to) and ending at
+	 * the end of the credential. */
+	if (xprt->stream)
+		verfbase++; /* See clnt.c:call_header() */
+
+	*p++ = htonl(RPC_AUTH_GSS);
+	cred_len = p++;
+
+	service = gss_pseudoflavor_to_service(gss_cred->gc_flavor);
+	if (service == 0) {
+		dprintk("Bad pseudoflavor %d in gss_marshal\n",
+			gss_cred->gc_flavor);
+		goto out_put_ctx;
+	}
+	spin_lock(&ctx->gc_seq_lock);
+	task->tk_gss_seqno = ctx->gc_seq++;
+	spin_unlock(&ctx->gc_seq_lock);
+
+	*p++ = htonl((u32) RPC_GSS_VERSION);
+	*p++ = htonl((u32) ctx->gc_proc);
+	*p++ = htonl((u32) task->tk_gss_seqno);
+	*p++ = htonl((u32) service);
+	p = xdr_encode_netobj(p, &ctx->gc_wire_ctx);
+	*cred_len = htonl((p - (cred_len + 1)) << 2);
+
+	/* Marshal verifier. */
+	bufin.data = (u8 *)verfbase;
+	bufin.len = (p - verfbase) << 2;
+
+	/* set verifier flavor*/
+	*p++ = htonl(RPC_AUTH_GSS);
+
+	maj_stat = gss_get_mic(ctx->gc_gss_ctx,
+			       GSS_C_QOP_DEFAULT, 
+			       &bufin, &bufout);
+	if(maj_stat != 0){
+		printk("gss_marshal: gss_get_mic FAILED (%d)\n",
+		       maj_stat);
+		goto out_put_ctx;
+	}
+	p = xdr_encode_netobj(p, &bufout);
+	return p;
+out_put_ctx:
+	gss_put_ctx(ctx);
+	return NULL;
+}
+
+/*
+* Refresh credentials. XXX - finish
+*/
+static int
+gss_refresh(struct rpc_task *task)
+{
+	struct rpc_clnt *clnt = task->tk_client;
+	struct gss_auth *gss_auth = container_of(clnt->cl_auth,
+			struct gss_auth, rpc_auth);
+	struct rpc_xprt *xprt = task->tk_xprt;
+	struct rpc_cred *cred = task->tk_msg.rpc_cred;
+	int err = 0;
+
+	task->tk_timeout = xprt->timeout.to_current;
+	spin_lock(&gss_auth->lock);
+	if (gss_cred_get_ctx(cred))
+		goto out;
+	err = gss_upcall(clnt, task, cred->cr_uid);
+out:
+	spin_unlock(&gss_auth->lock);
+	return err;
+}
+
+static u32 *
+gss_validate(struct rpc_task *task, u32 *p)
+{
+	struct gss_cred *cred = (struct gss_cred *)task->tk_msg.rpc_cred; 
+	struct gss_cl_ctx	*ctx = cred->gc_ctx;
+	u32		seq, qop_state;
+	struct xdr_netobj bufin;
+	struct xdr_netobj bufout;
+	u32		flav,len;
+	int             code = 0;
+
+	dprintk("RPC: gss_validate\n");
+
+	flav = ntohl(*p++);
+	if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE) {
+                printk("RPC: giant verf size: %ld\n", (unsigned long) len);
+                return NULL;
+	}
+	dprintk("RPC: gss_validate: verifier flavor %d, len %d\n", flav, len);
+
+	if (flav != RPC_AUTH_GSS) {
+		printk("RPC: bad verf flavor: %ld\n", (unsigned long)flav);
+		return NULL;
+	}
+	seq = htonl(task->tk_gss_seqno);
+	bufin.data = (u8 *) &seq;
+	bufin.len = sizeof(seq);
+	bufout.data = (u8 *) p;
+	bufout.len = len;
+
+	if ((code = gss_verify_mic(ctx->gc_gss_ctx, 
+				   &bufin, &bufout, &qop_state) < 0))
+		return NULL;
+	task->tk_auth->au_rslack = XDR_QUADLEN(len) + 2;
+	dprintk("RPC: GSS gss_validate: gss_verify_mic succeeded.\n");
+	return p + XDR_QUADLEN(len);
+}
+
+static struct rpc_authops authgss_ops = {
+	.au_flavor	= RPC_AUTH_GSS,
+#ifdef RPC_DEBUG
+	.au_name	= "RPCSEC_GSS",
+#endif
+	.create		= gss_create,
+	.destroy	= gss_destroy,
+	.crcreate	= gss_create_cred
+};
+
+static struct rpc_credops gss_credops = {
+	.crdestroy	= gss_destroy_cred,
+	.crmatch	= gss_match,
+	.crmarshal	= gss_marshal,
+	.crrefresh	= gss_refresh,
+	.crvalidate	= gss_validate,
+};
+
+static struct rpc_pipe_ops gss_upcall_ops = {
+	.upcall		= gss_pipe_upcall,
+	.downcall	= gss_pipe_downcall,
+	.destroy_msg	= gss_pipe_destroy_msg,
+};
+
+/*
+ * Initialize RPCSEC_GSS module
+ */
+static int __init init_rpcsec_gss(void)
+{
+	int err = 0;
+
+	err = rpcauth_register(&authgss_ops);
+	return err;
+}
+
+static void __exit exit_rpcsec_gss(void)
+{
+	gss_mech_unregister_all();
+	rpcauth_unregister(&authgss_ops);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_rpcsec_gss)
+module_exit(exit_rpcsec_gss)
diff -Nru a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/gss_generic_token.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,269 @@
+/*
+ *  linux/net/sunrpc/gss_generic_token.c
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/generic/util_token.c
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ */
+
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ * 
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/gss_asn1.h>
+
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY        RPCDBG_AUTH
+#endif
+
+
+/* TWRITE_STR from gssapiP_generic.h */
+#define TWRITE_STR(ptr, str, len) \
+	memcpy((ptr), (char *) (str), (len)); \
+	(ptr) += (len);
+
+/* XXXX this code currently makes the assumption that a mech oid will
+   never be longer than 127 bytes.  This assumption is not inherent in
+   the interfaces, so the code can be fixed if the OSI namespace
+   balloons unexpectedly. */
+
+/* Each token looks like this:
+
+0x60				tag for APPLICATION 0, SEQUENCE
+					(constructed, definite-length)
+	<length>		possible multiple bytes, need to parse/generate
+	0x06			tag for OBJECT IDENTIFIER
+		<moid_length>	compile-time constant string (assume 1 byte)
+		<moid_bytes>	compile-time constant string
+	<inner_bytes>		the ANY containing the application token
+					bytes 0,1 are the token type
+					bytes 2,n are the token data
+
+For the purposes of this abstraction, the token "header" consists of
+the sequence tag and length octets, the mech OID DER encoding, and the
+first two inner bytes, which indicate the token type.  The token
+"body" consists of everything else.
+
+*/
+
+static int
+der_length_size( int length)
+{
+	if (length < (1<<7))
+		return(1);
+	else if (length < (1<<8))
+		return(2);
+#if (SIZEOF_INT == 2)
+	else
+		return(3);
+#else
+	else if (length < (1<<16))
+		return(3);
+	else if (length < (1<<24))
+		return(4);
+	else
+		return(5);
+#endif
+}
+
+static void
+der_write_length(unsigned char **buf, int length)
+{
+	if (length < (1<<7)) {
+		*(*buf)++ = (unsigned char) length;
+	} else {
+		*(*buf)++ = (unsigned char) (der_length_size(length)+127);
+#if (SIZEOF_INT > 2)
+		if (length >= (1<<24))
+			*(*buf)++ = (unsigned char) (length>>24);
+		if (length >= (1<<16))
+			*(*buf)++ = (unsigned char) ((length>>16)&0xff);
+#endif
+		if (length >= (1<<8))
+			*(*buf)++ = (unsigned char) ((length>>8)&0xff);
+		*(*buf)++ = (unsigned char) (length&0xff);
+	}
+}
+
+/* returns decoded length, or < 0 on failure.  Advances buf and
+   decrements bufsize */
+
+static int
+der_read_length(unsigned char **buf, int *bufsize)
+{
+	unsigned char sf;
+	int ret;
+
+	if (*bufsize < 1)
+		return(-1);
+	sf = *(*buf)++;
+	(*bufsize)--;
+	if (sf & 0x80) {
+		if ((sf &= 0x7f) > ((*bufsize)-1))
+			return(-1);
+		if (sf > SIZEOF_INT)
+			return (-1);
+		ret = 0;
+		for (; sf; sf--) {
+			ret = (ret<<8) + (*(*buf)++);
+			(*bufsize)--;
+		}
+	} else {
+		ret = sf;
+	}
+
+	return(ret);
+}
+
+/* returns the length of a token, given the mech oid and the body size */
+
+int
+g_token_size(struct xdr_netobj *mech, unsigned int body_size)
+{
+	/* set body_size to sequence contents size */
+	body_size += 4 + (int) mech->len;         /* NEED overflow check */
+	return(1 + der_length_size(body_size) + body_size);
+}
+
+/* fills in a buffer with the token header.  The buffer is assumed to
+   be the right size.  buf is advanced past the token header */
+
+void
+g_make_token_header(struct xdr_netobj *mech, int body_size, unsigned char **buf,
+		int tok_type)
+{
+	*(*buf)++ = 0x60;
+	der_write_length(buf, 4 + mech->len + body_size);
+	*(*buf)++ = 0x06;
+	*(*buf)++ = (unsigned char) mech->len;
+	TWRITE_STR(*buf, mech->data, ((int) mech->len));
+	*(*buf)++ = (unsigned char) ((tok_type>>8)&0xff);
+	*(*buf)++ = (unsigned char) (tok_type&0xff);
+}
+
+/*
+ * Given a buffer containing a token, reads and verifies the token,
+ * leaving buf advanced past the token header, and setting body_size
+ * to the number of remaining bytes.  Returns 0 on success,
+ * G_BAD_TOK_HEADER for a variety of errors, and G_WRONG_MECH if the
+ * mechanism in the token does not match the mech argument.  buf and
+ * *body_size are left unmodified on error.
+ */
+u32
+g_verify_token_header(struct xdr_netobj *mech, int *body_size,
+		      unsigned char **buf_in, int tok_type, int toksize)
+{
+	unsigned char *buf = *buf_in;
+	int seqsize;
+	struct xdr_netobj toid;
+	int ret = 0;
+
+	if ((toksize-=1) < 0)
+		return(G_BAD_TOK_HEADER);
+	if (*buf++ != 0x60)
+		return(G_BAD_TOK_HEADER);
+
+	if ((seqsize = der_read_length(&buf, &toksize)) < 0)
+		return(G_BAD_TOK_HEADER);
+
+	if (seqsize != toksize)
+		return(G_BAD_TOK_HEADER);
+
+	if ((toksize-=1) < 0)
+		return(G_BAD_TOK_HEADER);
+	if (*buf++ != 0x06)
+		return(G_BAD_TOK_HEADER);
+ 
+	if ((toksize-=1) < 0)
+		return(G_BAD_TOK_HEADER);
+	toid.len = *buf++;
+
+	if ((toksize-=toid.len) < 0)
+		return(G_BAD_TOK_HEADER);
+	toid.data = buf;
+	buf+=toid.len;
+
+	if (! g_OID_equal(&toid, mech)) 
+		ret = G_WRONG_MECH;
+ 
+   /* G_WRONG_MECH is not returned immediately because it's more important
+      to return G_BAD_TOK_HEADER if the token header is in fact bad */
+
+	if ((toksize-=2) < 0)
+		return(G_BAD_TOK_HEADER);
+
+	if (ret)
+		return(ret);
+
+	if ((*buf++ != ((tok_type>>8)&0xff)) || (*buf++ != (tok_type&0xff))) 
+		return(G_WRONG_TOKID);
+
+	if (!ret) {
+		*buf_in = buf;
+		*body_size = toksize;
+	}
+
+	return(ret);
+}
+
+/* Given a buffer containing a token, returns a copy of the mech oid in
+ * the parameter mech. */
+u32
+g_get_mech_oid(struct xdr_netobj *mech, struct xdr_netobj * in_buf)
+{
+	unsigned char *buf = in_buf->data;
+	int len = in_buf->len;
+	int ret=0;
+	int seqsize;
+
+	if ((len-=1) < 0)
+		return(G_BAD_TOK_HEADER);
+	if (*buf++ != 0x60)
+		return(G_BAD_TOK_HEADER);
+
+	if ((seqsize = der_read_length(&buf, &len)) < 0)
+		return(G_BAD_TOK_HEADER);
+
+	if ((len-=1) < 0)
+		return(G_BAD_TOK_HEADER);
+	if (*buf++ != 0x06)
+		return(G_BAD_TOK_HEADER);
+
+	if ((len-=1) < 0)
+		return(G_BAD_TOK_HEADER);
+	mech->len = *buf++;
+
+	if ((len-=mech->len) < 0)
+		return(G_BAD_TOK_HEADER);
+	if (!(mech->data = kmalloc(mech->len, GFP_KERNEL))) 
+		return(G_BUFFER_ALLOC);
+	memcpy(mech->data, buf, mech->len);
+
+	return ret;
+}
diff -Nru a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,168 @@
+/*
+ *  linux/net/sunrpc/gss_krb5_crypto.c
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ *  Bruce Fields   <bfields@umich.edu>
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government.  It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  FundsXpress makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/crypto.h>
+#include <linux/sunrpc/gss_krb5.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY        RPCDBG_AUTH
+#endif
+
+u32
+krb5_encrypt(
+	struct crypto_tfm *tfm,
+	void * iv,
+	void * in,
+	void * out,
+	int length)
+{
+	u32 ret = -EINVAL;
+        struct scatterlist sg[1];
+	u8 local_iv[16] = {0};
+
+	dprintk("RPC: gss_k5encrypt: TOP in %p out %p\nin data:\n", out, in);
+	print_hexl((u32 *)in, length, 0);
+
+	if (length % crypto_tfm_alg_blocksize(tfm) != 0)
+		goto out;
+
+	if (crypto_tfm_alg_ivsize(tfm) > 16) {
+		dprintk("RPC: gss_k5encrypt: tfm iv size to large %d\n",
+		         crypto_tfm_alg_ivsize(tfm));
+		goto out;
+	}
+
+	if (iv)
+		memcpy(local_iv, iv, crypto_tfm_alg_ivsize(tfm));
+	crypto_cipher_set_iv(tfm, local_iv, crypto_tfm_alg_ivsize(tfm));
+
+	memcpy(out, in, length);
+	sg[0].page = virt_to_page(out);
+	sg[0].offset = ((long)out & ~PAGE_MASK);
+	sg[0].length = length;
+
+	ret = crypto_cipher_encrypt(tfm, sg, 1);
+
+out:
+	dprintk("gss_k5encrypt returns %d\n",ret);
+	return(ret);
+}
+
+u32
+krb5_decrypt(
+     struct crypto_tfm *tfm,
+     void * iv,
+     void * in,
+     void * out,
+     int length)
+{
+	u32 ret = -EINVAL;
+	struct scatterlist sg[1];
+	u8 local_iv[16] = {0};
+
+	dprintk("RPC: gss_k5decrypt: TOP in %p out %p\nin data:\n", in, out);
+	print_hexl((u32 *)in,length,0);
+
+	if (length % crypto_tfm_alg_blocksize(tfm) != 0)
+		goto out;
+
+	if (crypto_tfm_alg_ivsize(tfm) > 16) {
+		dprintk("RPC: gss_k5decrypt: tfm iv size to large %d\n",
+			crypto_tfm_alg_ivsize(tfm));
+		goto out;
+	}
+	if (iv)
+		memcpy(local_iv,iv, crypto_tfm_alg_ivsize(tfm));
+	crypto_cipher_set_iv(tfm, local_iv, crypto_tfm_alg_blocksize(tfm));
+
+	memcpy(out, in, length);
+	sg[0].page = virt_to_page(out);
+	sg[0].offset = ((long)out  & ~PAGE_MASK);
+	sg[0].length = length;
+
+	ret = crypto_cipher_decrypt(tfm, sg, 1);
+
+out:
+	dprintk("gss_k5decrypt returns %d\n",ret);
+	return(ret);
+}
+
+s32
+krb5_make_checksum(s32 cksumtype, struct xdr_netobj *input,
+		   struct xdr_netobj *cksum)
+{
+	s32			ret = -EINVAL;
+	struct scatterlist	sg[1];
+	char			*cksumname;
+	struct crypto_tfm	*tfm;
+
+	switch (cksumtype) {
+		case CKSUMTYPE_RSA_MD5:
+			cksumname = "md5";
+			break;
+		default:
+			dprintk("RPC: krb5_make_checksum:"
+				" unsupported checksum %d", cksumtype);
+			goto out;
+	}
+	if (!(tfm = crypto_alloc_tfm(cksumname, 0)))
+		goto out;
+	cksum->len = crypto_tfm_alg_digestsize(tfm);
+
+	if ((cksum->data = kmalloc(cksum->len, GFP_KERNEL)) == NULL) {
+		ret = -ENOMEM;
+		goto out_free_tfm;
+	}
+	sg[0].page = virt_to_page(input->data);
+	sg[0].offset = ((long)input->data & ~PAGE_MASK);
+	sg[0].length = input->len;
+
+	crypto_digest_init(tfm);
+	crypto_digest_update(tfm, sg, 1);
+	crypto_digest_final(tfm, cksum->data);
+
+	ret = 0;
+
+out_free_tfm:
+	crypto_free_tfm(tfm);
+out:
+	dprintk("RPC: gss_k5cksum: returning %d\n", ret);
+	return (ret);
+}
diff -Nru a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,251 @@
+/*
+ *  linux/net/sunrpc/gss_krb5_mech.c
+ *
+ *  Copyright (c) 2001 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson <andros@umich.edu>
+ *  J. Bruce Fields <bfields@umich.edu>
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the University nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  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 REGENTS OR CONTRIBUTORS 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/sunrpc/auth.h>
+#include <linux/sunrpc/gss_krb5.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/crypto.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY	RPCDBG_AUTH
+#endif
+
+struct xdr_netobj gss_mech_krb5_oid =
+   {9, "\052\206\110\206\367\022\001\002\002"};
+
+static inline int
+get_bytes(char **ptr, const char *end, void *res, int len)
+{
+	char *p, *q;
+	p = *ptr;
+	q = p + len;
+	if (q > end || q < p)
+		return -1;
+	memcpy(res, p, len);
+	*ptr = q;
+	return 0;
+}
+
+static inline int
+get_netobj(char **ptr, const char *end, struct xdr_netobj *res)
+{
+	char *p, *q;
+	p = *ptr;
+	if (get_bytes(&p, end, &res->len, sizeof(res->len)))
+		return -1;
+	q = p + res->len;
+	if (q > end || q < p)
+		return -1;
+	if (!(res->data = kmalloc(res->len, GFP_KERNEL)))
+		return -1;
+	memcpy(res->data, p, res->len);
+	*ptr = q;
+	return 0;
+}
+
+static inline int
+get_key(char **p, char *end, struct crypto_tfm **res)
+{
+	struct xdr_netobj	key;
+	int			alg, alg_mode;
+	char			*alg_name;
+
+	if (get_bytes(p, end, &alg, sizeof(alg)))
+		goto out_err;
+	if ((get_netobj(p, end, &key)))
+		goto out_err;
+
+	switch (alg) {
+		case ENCTYPE_DES_CBC_RAW:
+			alg_name = "des";
+			alg_mode = CRYPTO_TFM_MODE_CBC;
+			break;
+		default:
+			dprintk("RPC: get_key: unsupported algorithm %d", alg);
+			goto out_err_free_key;
+	}
+	if (!(*res = crypto_alloc_tfm(alg_name, alg_mode)))
+		goto out_err_free_key;
+	if (crypto_cipher_setkey(*res, key.data, key.len))
+		goto out_err_free_tfm;
+
+	kfree(key.data);
+	return 0;
+
+out_err_free_tfm:
+	crypto_free_tfm(*res);
+out_err_free_key:
+	kfree(key.data);
+out_err:
+	return -1;
+}
+
+static u32
+gss_import_sec_context_kerberos(struct xdr_netobj *inbuf,
+				struct gss_ctx *ctx_id)
+{
+	char	*p = inbuf->data;
+	char	*end = inbuf->data + inbuf->len;
+	struct	krb5_ctx *ctx;
+
+	if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL)))
+		goto out_err;
+	memset(ctx, 0, sizeof(*ctx));
+
+	if (get_bytes(&p, end, &ctx->initiate, sizeof(ctx->initiate)))
+		goto out_err_free_ctx;
+	if (get_bytes(&p, end, &ctx->seed_init, sizeof(ctx->seed_init)))
+		goto out_err_free_ctx;
+	if (get_bytes(&p, end, ctx->seed, sizeof(ctx->seed)))
+		goto out_err_free_ctx;
+	if (get_bytes(&p, end, &ctx->signalg, sizeof(ctx->signalg)))
+		goto out_err_free_ctx;
+	if (get_bytes(&p, end, &ctx->sealalg, sizeof(ctx->sealalg)))
+		goto out_err_free_ctx;
+	if (get_bytes(&p, end, &ctx->endtime, sizeof(ctx->endtime)))
+		goto out_err_free_ctx;
+	if (get_bytes(&p, end, &ctx->seq_send, sizeof(ctx->seq_send)))
+		goto out_err_free_ctx;
+	if (get_netobj(&p, end, &ctx->mech_used))
+		goto out_err_free_ctx;
+	if (get_key(&p, end, &ctx->enc))
+		goto out_err_free_mech;
+	if (get_key(&p, end, &ctx->seq))
+		goto out_err_free_key1;
+	if (p != end)
+		goto out_err_free_key2;
+
+	ctx_id->internal_ctx_id = ctx;
+	dprintk("Succesfully imported new context.\n");
+	return 0;
+
+out_err_free_key2:
+	crypto_free_tfm(ctx->seq);
+out_err_free_key1:
+	crypto_free_tfm(ctx->enc);
+out_err_free_mech:
+	kfree(ctx->mech_used.data);
+out_err_free_ctx:
+	kfree(ctx);
+out_err:
+	return GSS_S_FAILURE;
+}
+
+void
+gss_delete_sec_context_kerberos(void *internal_ctx) {
+	struct krb5_ctx *kctx = internal_ctx;
+
+	if (kctx->seq)
+		crypto_free_tfm(kctx->seq);
+	if (kctx->enc)
+		crypto_free_tfm(kctx->enc);
+	if (kctx->mech_used.data)
+		kfree(kctx->mech_used.data);
+	kfree(kctx);
+}
+
+u32
+gss_verify_mic_kerberos(struct gss_ctx		*ctx,
+			struct xdr_netobj	*signbuf,
+			struct xdr_netobj	*checksum,
+			u32		*qstate) {
+	u32 maj_stat = 0;
+	int qop_state;
+	struct krb5_ctx *kctx = ctx->internal_ctx_id;
+
+	maj_stat = krb5_read_token(kctx, checksum, signbuf, &qop_state,
+				   KG_TOK_MIC_MSG);
+	if (!maj_stat && qop_state)
+	    *qstate = qop_state;
+
+	dprintk("RPC: gss_verify_mic_kerberos returning %d\n", maj_stat);
+	return maj_stat;
+}
+
+u32
+gss_get_mic_kerberos(struct gss_ctx	*ctx,
+		     u32		qop,
+		     struct xdr_netobj	*message_buffer,
+		     struct xdr_netobj	*message_token) {
+	u32 err = 0;
+	struct krb5_ctx *kctx = ctx->internal_ctx_id;
+
+	if (!message_buffer->data) return GSS_S_FAILURE;
+
+	dprintk("RPC: gss_get_mic_kerberos:"
+		" message_buffer->len %d\n",message_buffer->len);
+
+	err = krb5_make_token(kctx, qop, message_buffer,
+			      message_token, KG_TOK_MIC_MSG);
+
+	dprintk("RPC: gss_get_mic_kerberos returning %d\n",err);
+
+	return err;
+}
+
+static struct gss_api_ops gss_kerberos_ops = {
+	.name			= "krb5",
+	.gss_import_sec_context	= gss_import_sec_context_kerberos,
+	.gss_get_mic		= gss_get_mic_kerberos,
+	.gss_verify_mic		= gss_verify_mic_kerberos,
+	.gss_delete_sec_context	= gss_delete_sec_context_kerberos,
+};
+
+/* XXX error checking? reference counting? */
+static int __init init_kerberos_module(void)
+{
+	struct gss_api_mech *gm;
+
+	if (gss_mech_register(&gss_mech_krb5_oid, &gss_kerberos_ops))
+		printk("Failed to register kerberos gss mechanism!\n");
+	gm = gss_mech_get_by_OID(&gss_mech_krb5_oid);
+	gss_register_triple(RPC_AUTH_GSS_KRB5 , gm, 0, RPC_GSS_SVC_NONE);
+	gss_mech_put(gm);
+	return 0;
+}
+
+static void __exit cleanup_kerberos_module(void)
+{
+	gss_unregister_triple(RPC_AUTH_GSS_KRB5);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_kerberos_module);
+module_exit(cleanup_kerberos_module);
diff -Nru a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,214 @@
+/*
+ *  linux/net/sunrpc/gss_krb5_seal.c
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5seal.c
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson	<andros@umich.edu>
+ *  J. Bruce Fields	<bfields@umich.edu>
+ */
+
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government.  It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  FundsXpress makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/sunrpc/gss_krb5.h>
+#include <linux/random.h>
+#include <linux/crypto.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY        RPCDBG_AUTH
+#endif
+
+#define CKSUM_SIZE	8
+
+static inline int
+gss_krb5_padding(int blocksize, int length) {
+	/* Most of the code is block-size independent but in practice we
+	 * use only 8: */
+	BUG_ON(blocksize != 8);
+	return 8 - (length & 7);
+}
+
+/* checksum the plaintext data and the first 8 bytes of the krb5 token header,
+ * as specified by the rfc: */
+static u32
+compute_checksum(s32 checksum_type, char *header, char *body, int body_len,
+		 struct xdr_netobj *md5cksum) {
+	char			*data_ptr;
+	struct xdr_netobj	plaind;
+	u32			code = GSS_S_FAILURE;
+
+	if (!(data_ptr = kmalloc(8 + body_len, GFP_KERNEL)))
+		goto out;
+	memcpy(data_ptr, header, 8);
+	memcpy(data_ptr + 8, body, body_len);
+	plaind.len = 8 + body_len;
+	plaind.data = data_ptr;
+	code = krb5_make_checksum(checksum_type, &plaind, md5cksum);
+	kfree(data_ptr);
+	code = 0;
+
+out:
+	return code;
+}
+
+u32
+krb5_make_token(struct krb5_ctx *ctx, int qop_req,
+		   struct xdr_netobj * text, struct xdr_netobj * token,
+		   int toktype)
+{
+	s32			checksum_type;
+	struct xdr_netobj	md5cksum = {.len = 0, .data = NULL};
+	int			blocksize = 0, tmsglen;
+	unsigned char		*ptr, *krb5_hdr, *msg_start;
+	s32			now;
+
+	dprintk("RPC: gss_krb5_seal");
+
+	now = jiffies;
+
+	if (qop_req != 0)
+		goto out_err;
+
+	switch (ctx->signalg) {
+		case SGN_ALG_DES_MAC_MD5:
+			checksum_type = CKSUMTYPE_RSA_MD5;
+			break;
+		default:
+			dprintk("RPC: gss_krb5_seal: ctx->signalg %d not"
+				" supported\n", ctx->signalg);
+			goto out_err;
+	}
+	if (ctx->sealalg != SEAL_ALG_NONE && ctx->sealalg != SEAL_ALG_DES) {
+		dprintk("RPC: gss_krb5_seal: ctx->sealalg %d not supported\n",
+			ctx->sealalg);
+		goto out_err;
+	}
+
+	if (toktype == KG_TOK_WRAP_MSG) {
+		blocksize = crypto_tfm_alg_blocksize(ctx->enc);
+		tmsglen = blocksize + text->len
+			+ gss_krb5_padding(blocksize, blocksize + text->len);
+	} else {
+		tmsglen = 0;
+	}
+
+	token->len = g_token_size(&ctx->mech_used, 22 + tmsglen);
+	if ((token->data = kmalloc(token->len, GFP_KERNEL)) == NULL)
+		goto out_err;
+
+	ptr = token->data;
+	g_make_token_header(&ctx->mech_used, 22 + tmsglen, &ptr, toktype);
+
+	/* ptr now at byte 2 of header described in rfc 1964, section 1.2.1: */
+	krb5_hdr = ptr - 2;
+	msg_start = krb5_hdr + 24;
+
+	*(u16 *)(krb5_hdr + 2) = htons(ctx->signalg);
+	memset(krb5_hdr + 4, 0xff, 4);
+	if (toktype == KG_TOK_WRAP_MSG)
+		*(u16 *)(krb5_hdr + 4) = htons(ctx->sealalg);
+
+	if (toktype == KG_TOK_WRAP_MSG) {
+		unsigned char pad = gss_krb5_padding(blocksize, text->len);
+
+		get_random_bytes(msg_start, blocksize); /* "confounder" */
+		memcpy(msg_start + blocksize, text->data, text->len);
+
+		memset(msg_start + blocksize + text->len, pad, pad);
+
+		if (compute_checksum(checksum_type, krb5_hdr, msg_start,
+				     tmsglen, &md5cksum))
+			goto out_err;
+
+		if (krb5_encrypt(ctx->enc, NULL, msg_start, msg_start,
+					tmsglen))
+			goto out_err;
+
+	} else { /* Sign only.  */
+		if (compute_checksum(checksum_type, krb5_hdr, text->data,
+					text->len, &md5cksum))
+			goto out_err;
+	}
+
+	switch (ctx->signalg) {
+	case SGN_ALG_DES_MAC_MD5:
+		if (krb5_encrypt(ctx->seq, NULL, md5cksum.data,
+				  md5cksum.data, md5cksum.len))
+			goto out_err;
+		memcpy(krb5_hdr + 16,
+		       md5cksum.data + md5cksum.len - CKSUM_SIZE, CKSUM_SIZE);
+
+		dprintk("make_seal_token: cksum data: \n");
+		print_hexl((u32 *) (krb5_hdr + 16), CKSUM_SIZE, 0);
+		break;
+	default:
+		BUG();
+	}
+
+	kfree(md5cksum.data);
+
+	if ((krb5_make_seq_num(ctx->seq, ctx->initiate ? 0 : 0xff,
+			       ctx->seq_send, krb5_hdr + 16, krb5_hdr + 8)))
+		goto out_err;
+
+	ctx->seq_send++;
+
+	return ((ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE);
+out_err:
+	if (md5cksum.data) kfree(md5cksum.data);
+	if (token->data) kfree(token->data);
+	token->data = 0;
+	token->len = 0;
+	return GSS_S_FAILURE;
+}
diff -Nru a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,88 @@
+/*
+ *  linux/net/sunrpc/gss_krb5_seqnum.c
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/util_seqnum.c
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ */
+
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ * 
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/sunrpc/gss_krb5.h>
+#include <linux/crypto.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY        RPCDBG_AUTH
+#endif
+
+s32
+krb5_make_seq_num(struct crypto_tfm *key,
+		int direction,
+		s32 seqnum,
+		unsigned char *cksum, unsigned char *buf)
+{
+	unsigned char plain[8];
+
+	plain[0] = (unsigned char) (seqnum & 0xff);
+	plain[1] = (unsigned char) ((seqnum >> 8) & 0xff);
+	plain[2] = (unsigned char) ((seqnum >> 16) & 0xff);
+	plain[3] = (unsigned char) ((seqnum >> 24) & 0xff);
+
+	plain[4] = direction;
+	plain[5] = direction;
+	plain[6] = direction;
+	plain[7] = direction;
+
+	return krb5_encrypt(key, cksum, plain, buf, 8);
+}
+
+s32
+krb5_get_seq_num(struct crypto_tfm *key,
+	       unsigned char *cksum,
+	       unsigned char *buf,
+	       int *direction, s32 * seqnum)
+{
+	s32 code;
+	unsigned char plain[8];
+
+	dprintk("krb5_get_seq_num: \n");
+
+	if ((code = krb5_decrypt(key, cksum, buf, plain, 8)))
+		return code;
+
+	if ((plain[4] != plain[5]) || (plain[4] != plain[6])
+				   || (plain[4] != plain[7]))
+		return (s32)KG_BAD_SEQ;
+
+	*direction = plain[4];
+
+	*seqnum = ((plain[0]) |
+		   (plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24));
+
+	return (0);
+}
diff -Nru a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,306 @@
+/*
+ *  linux/net/sunrpc/gss_krb5_unseal.c
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/krb5/k5unseal.c
+ *
+ *  Copyright (c) 2000 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ */
+
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government.  It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  FundsXpress makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/sunrpc/gss_krb5.h>
+#include <linux/crypto.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY        RPCDBG_AUTH
+#endif
+
+
+/* message_buffer is an input if MIC and an output if WRAP. */
+
+u32
+krb5_read_token(struct krb5_ctx *ctx,
+		struct xdr_netobj *read_token,
+		struct xdr_netobj *message_buffer,
+		int *qop_state, int toktype)
+{
+	s32			code;
+	int			tmsglen = 0;
+	int			conflen = 0;
+	int			signalg;
+	int			sealalg;
+	struct xdr_netobj	token = {.len = 0, .data = NULL};
+	s32			checksum_type;
+	struct xdr_netobj	cksum;
+	struct xdr_netobj	md5cksum = {.len = 0, .data = NULL};
+	struct xdr_netobj	plaind;
+	char			*data_ptr;
+	s32			now;
+	unsigned char		*plain = NULL;
+	int			cksum_len = 0;
+	int			plainlen = 0;
+	int			direction;
+	s32			seqnum;
+	unsigned char		*ptr = (unsigned char *)read_token->data;
+	int			bodysize;
+	u32			ret = GSS_S_DEFECTIVE_TOKEN;
+
+	dprintk("RPC: krb5_read_token\n");
+
+	if (g_verify_token_header((struct xdr_netobj *) &ctx->mech_used,
+					&bodysize, &ptr, toktype,
+					read_token->len))
+		goto out;
+
+	if (toktype == KG_TOK_WRAP_MSG) {
+		message_buffer->len = 0;
+		message_buffer->data = NULL;
+	}
+
+	/* get the sign and seal algorithms */
+
+	signalg = ptr[0] + (ptr[1] << 8);
+	sealalg = ptr[2] + (ptr[3] << 8);
+
+	/* Sanity checks */
+
+	if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
+		goto out;
+
+	if (((toktype != KG_TOK_WRAP_MSG) && (sealalg != 0xffff)) ||
+	    ((toktype == KG_TOK_WRAP_MSG) && (sealalg == 0xffff)))
+		goto out;
+
+	/* in the current spec, there is only one valid seal algorithm per
+	   key type, so a simple comparison is ok */
+
+	if ((toktype == KG_TOK_WRAP_MSG) && !(sealalg == ctx->sealalg))
+		goto out;
+
+	/* there are several mappings of seal algorithms to sign algorithms,
+	   but few enough that we can try them all. */
+
+	if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
+	    (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
+	    (ctx->sealalg == SEAL_ALG_DES3KD &&
+	     signalg != SGN_ALG_HMAC_SHA1_DES3_KD))
+		goto out;
+
+	/* starting with a single alg */
+	switch (signalg) {
+	case SGN_ALG_DES_MAC_MD5:
+		cksum_len = 8;
+		break;
+	default:
+		goto out;
+	}
+
+	if (toktype == KG_TOK_WRAP_MSG)
+		tmsglen = bodysize - (14 + cksum_len);
+
+	/* get the token parameters */
+
+	/* decode the message, if WRAP */
+
+	if (toktype == KG_TOK_WRAP_MSG) {
+		dprintk("RPC: krb5_read_token KG_TOK_WRAP_MSG\n");
+
+		plain = kmalloc(tmsglen, GFP_KERNEL);
+		ret = GSS_S_FAILURE;
+		if (plain ==  NULL)
+			goto out;
+
+		code = krb5_decrypt(ctx->enc, NULL,
+				   ptr + 14 + cksum_len, plain,
+				   tmsglen);
+		if (code)
+			goto out;
+
+		plainlen = tmsglen;
+
+		conflen = crypto_tfm_alg_blocksize(ctx->enc);
+		token.len = tmsglen - conflen - plain[tmsglen - 1];
+
+		if (token.len) {
+			token.data = kmalloc(token.len, GFP_KERNEL);
+			if (token.data == NULL)
+				goto out;
+			memcpy(token.data, plain + conflen, token.len);
+		}
+
+	} else if (toktype == KG_TOK_MIC_MSG) {
+		dprintk("RPC: krb5_read_token KG_TOK_MIC_MSG\n");
+		token = *message_buffer;
+		plain = token.data;
+		plainlen = token.len;
+	} else {
+		token.len = 0;
+		token.data = NULL;
+		plain = token.data;
+		plainlen = token.len;
+	}
+
+	dprintk("RPC krb5_read_token: token.len %d plainlen %d\n", token.len,
+		plainlen);
+
+	/* compute the checksum of the message */
+
+	/* initialize the the cksum */
+	switch (signalg) {
+	case SGN_ALG_DES_MAC_MD5:
+		checksum_type = CKSUMTYPE_RSA_MD5;
+		break;
+	default:
+		ret = GSS_S_DEFECTIVE_TOKEN;
+		goto out;
+	}
+
+	switch (signalg) {
+	case SGN_ALG_DES_MAC_MD5:
+		dprintk("RPC krb5_read_token SGN_ALG_DES_MAC_MD5\n");
+		/* compute the checksum of the message.
+		 * 8 = bytes of token body to be checksummed according to spec 
+		 */
+
+		data_ptr = kmalloc(8 + plainlen, GFP_KERNEL);
+		ret = GSS_S_FAILURE;
+		if (!data_ptr)
+			goto out;
+
+		memcpy(data_ptr, ptr - 2, 8);
+		memcpy(data_ptr + 8, plain, plainlen);
+
+		plaind.len = 8 + plainlen;
+		plaind.data = data_ptr;
+
+		code = krb5_make_checksum(checksum_type,
+					    &plaind, &md5cksum);
+
+		kfree(data_ptr);
+
+		if (code)
+			goto out;
+
+		code = krb5_encrypt(ctx->seq, NULL, md5cksum.data,
+					  md5cksum.data, 16);
+		if (code)
+			goto out;
+
+		if (signalg == 0)
+			cksum.len = 8;
+		else
+			cksum.len = 16;
+		cksum.data = md5cksum.data + 16 - cksum.len;
+
+		dprintk
+		    ("RPC: krb5_read_token: memcmp digest cksum.len %d:\n",
+		     cksum.len);
+		dprintk("          md5cksum.data\n");
+		print_hexl((u32 *) md5cksum.data, 16, 0);
+		dprintk("          cksum.data:\n");
+		print_hexl((u32 *) cksum.data, cksum.len, 0);
+		{
+			u32 *p;
+
+			(u8 *) p = ptr + 14;
+			dprintk("          ptr+14:\n");
+			print_hexl(p, cksum.len, 0);
+		}
+
+		code = memcmp(cksum.data, ptr + 14, cksum.len);
+		break;
+	default:
+		ret = GSS_S_DEFECTIVE_TOKEN;
+		goto out;
+	}
+
+	ret = GSS_S_BAD_SIG;
+	if (code)
+		goto out;
+
+	/* it got through unscathed.  Make sure the context is unexpired */
+
+	if (toktype == KG_TOK_WRAP_MSG)
+		*message_buffer = token;
+
+	if (qop_state)
+		*qop_state = GSS_C_QOP_DEFAULT;
+
+	now = jiffies;
+
+	ret = GSS_S_CONTEXT_EXPIRED;
+	if (now > ctx->endtime)
+		goto out;
+
+	/* do sequencing checks */
+
+	ret = GSS_S_BAD_SIG;
+	if ((code = krb5_get_seq_num(ctx->seq, ptr + 14, ptr + 6, &direction,
+				   &seqnum)))
+		goto out;
+
+	if ((ctx->initiate && direction != 0xff) ||
+	    (!ctx->initiate && direction != 0))
+		goto out;
+
+	ret = GSS_S_COMPLETE;
+out:
+	if (md5cksum.data) kfree(md5cksum.data);
+	if (toktype == KG_TOK_WRAP_MSG) {
+		if (plain) kfree(plain);
+		if (ret && token.data) kfree(token.data);
+	}
+	return ret;
+}
diff -Nru a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,243 @@
+/*
+ *  linux/net/sunrpc/gss_mech_switch.c
+ *
+ *  Copyright (c) 2001 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  J. Bruce Fields   <bfields@umich.edu>
+ *
+ *  Redistribution and use in source and binary forms, with or without 
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the 
+ *     documentation and/or other materials provided with the distribution.
+ *  3. Neither the name of the University nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ *  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 REGENTS OR CONTRIBUTORS 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.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+#include <linux/sunrpc/msg_prot.h>
+#include <linux/sunrpc/gss_asn1.h>
+#include <linux/sunrpc/auth_gss.h>
+#include <linux/sunrpc/gss_err.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/gss_api.h>
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/name_lookup.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY        RPCDBG_AUTH
+#endif
+
+static LIST_HEAD(registered_mechs);
+static spinlock_t registered_mechs_lock = SPIN_LOCK_UNLOCKED;
+
+/* Reference counting: The reference count includes the reference in the
+ * global registered_mechs list.  That reference will never diseappear
+ * (so the reference count will never go below 1) until after the mech
+ * is removed from the list.  Nothing can be removed from the list without
+ * first getting the registered_mechs_lock, so a gss_api_mech won't diseappear
+ * from underneath us while we hold the registered_mech_lock.  */
+
+int
+gss_mech_register(struct xdr_netobj * mech_type, struct gss_api_ops * ops)
+{
+	struct gss_api_mech *gm;
+
+	if (!(gm = kmalloc(sizeof(*gm), GFP_KERNEL))) {
+		printk("Failed to allocate memory in gss_mech_register");
+		return -1;
+	}
+	gm->gm_oid.len = mech_type->len;
+	if (!(gm->gm_oid.data = kmalloc(mech_type->len, GFP_KERNEL))) {
+		printk("Failed to allocate memory in gss_mech_register");
+		return -1;
+	}
+	memcpy(gm->gm_oid.data, mech_type->data, mech_type->len);
+	/* We're counting the reference in the registered_mechs list: */
+	atomic_set(&gm->gm_count, 1);
+	gm->gm_ops = ops;
+	
+	spin_lock(&registered_mechs_lock);
+	list_add(&gm->gm_list, &registered_mechs);
+	spin_unlock(&registered_mechs_lock);
+	dprintk("RPC: gss_mech_register: registered mechanism with oid:\n");
+	print_hexl((u32 *)mech_type->data, mech_type->len, 0);
+	return 0;
+}
+
+/* The following must be called with spinlock held: */
+int
+do_gss_mech_unregister(struct gss_api_mech *gm)
+{
+
+	list_del(&gm->gm_list);
+
+	dprintk("RPC: unregistered mechanism with oid:\n");
+	print_hexl((u32 *)gm->gm_oid.data, gm->gm_oid.len, 0);
+	if (!gss_mech_put(gm)) {
+		dprintk("RPC: We just unregistered a gss_mechanism which"
+				" someone is still using.\n");
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+int
+gss_mech_unregister(struct gss_api_mech *gm)
+{
+	int status;
+
+	spin_lock(&registered_mechs_lock);
+	status = do_gss_mech_unregister(gm);
+	spin_unlock(&registered_mechs_lock);
+	return status;
+}
+
+int
+gss_mech_unregister_all(void)
+{
+	struct list_head	*pos;
+	struct gss_api_mech	*gm;
+	int			status = 0;
+
+	spin_lock(&registered_mechs_lock);
+	while (!list_empty(&registered_mechs)) {
+		pos = registered_mechs.next;
+		gm = list_entry(pos, struct gss_api_mech, gm_list);
+		if (do_gss_mech_unregister(gm))
+			status = -1;
+	}
+	spin_unlock(&registered_mechs_lock);
+	return status;
+}
+
+struct gss_api_mech *
+gss_mech_get(struct gss_api_mech *gm)
+{
+	atomic_inc(&gm->gm_count);
+	return gm;
+}
+
+struct gss_api_mech *
+gss_mech_get_by_OID(struct xdr_netobj *mech_type)
+{
+	struct gss_api_mech 	*pos, *gm = NULL;
+
+	dprintk("RPC: gss_mech_get_by_OID searching for mechanism with OID:\n");
+	print_hexl((u32 *)mech_type->data, mech_type->len, 0);
+	spin_lock(&registered_mechs_lock);
+	list_for_each_entry(pos, &registered_mechs, gm_list) {
+		if ((pos->gm_oid.len == mech_type->len)
+			&& !memcmp(pos->gm_oid.data, mech_type->data,
+							mech_type->len)) {
+			gm = gss_mech_get(pos);
+			break;
+		}
+	}
+	spin_unlock(&registered_mechs_lock);
+	dprintk("RPC: gss_mech_get_by_OID %s it\n", gm ? "found" : "didn't find");
+	return gm;
+}
+
+int
+gss_mech_put(struct gss_api_mech * gm)
+{
+	if (atomic_dec_and_test(&gm->gm_count)) {
+		if (gm->gm_oid.len >0)
+			kfree(gm->gm_oid.data);
+		kfree(gm);
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/* The mech could probably be determined from the token instead, but it's just
+ * as easy for now to pass it in. */
+u32
+gss_import_sec_context(struct xdr_netobj	*input_token,
+		       struct gss_api_mech	*mech,
+		       struct gss_ctx		**ctx_id)
+{
+	if (!(*ctx_id = kmalloc(sizeof(**ctx_id), GFP_KERNEL)))
+		return GSS_S_FAILURE;
+	memset(*ctx_id, 0, sizeof(**ctx_id));
+	(*ctx_id)->mech_type = gss_mech_get(mech);
+
+	return mech->gm_ops
+		->gss_import_sec_context(input_token, *ctx_id);
+}
+
+/* gss_verify_mic: hash messages_buffer and return gss verify token. */
+
+u32
+gss_get_mic(struct gss_ctx	*context_handle,
+	    u32			qop,
+	    struct xdr_netobj	*message_buffer,
+	    struct xdr_netobj	*message_token)
+{
+	 return context_handle->mech_type->gm_ops
+		->gss_get_mic(context_handle,
+			      qop,
+			      message_buffer,
+			      message_token);
+}
+
+/* gss_verify_mic: hash messages_buffer and return gss verify token. */
+
+u32
+gss_verify_mic(struct gss_ctx		*context_handle,
+		struct xdr_netobj	*signbuf,
+		struct xdr_netobj	*checksum,
+		u32			*qstate)
+{
+	return context_handle->mech_type->gm_ops
+		->gss_verify_mic(context_handle,
+				 signbuf,
+				 checksum,
+				 qstate);
+}
+
+/* gss_delete_sec_context: free all resources associated with context_handle.
+ * Note this differs from the RFC 2744-specified prototype in that we don't
+ * bother returning an output token, since it would never be used anyway. */
+
+u32
+gss_delete_sec_context(struct gss_ctx	**context_handle)
+{
+	dprintk("gss_delete_sec_context deleting %p\n",*context_handle);
+
+	if (!*context_handle)
+		return(GSS_S_NO_CONTEXT);
+	if ((*context_handle)->internal_ctx_id != 0)
+		(*context_handle)->mech_type->gm_ops
+			->gss_delete_sec_context((*context_handle)
+							->internal_ctx_id);
+	if ((*context_handle)->mech_type)
+		gss_mech_put((*context_handle)->mech_type);
+	kfree(*context_handle);
+	*context_handle=NULL;
+	return GSS_S_COMPLETE;
+}
diff -Nru a/net/sunrpc/auth_gss/gss_pseudoflavors.c b/net/sunrpc/auth_gss/gss_pseudoflavors.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/gss_pseudoflavors.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,235 @@
+/*
+ *  linux/net/sunrpc/gss_union.c
+ *
+ *  Adapted from MIT Kerberos 5-1.2.1 lib/gssapi/generic code
+ *
+ *  Copyright (c) 2001 The Regents of the University of Michigan.
+ *  All rights reserved.
+ *
+ *  Andy Adamson   <andros@umich.edu>
+ *
+ */
+
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */ 
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+#include <linux/sunrpc/gss_asn1.h>
+#include <linux/sunrpc/auth_gss.h>
+
+#ifdef RPC_DEBUG
+# define RPCDBG_FACILITY        RPCDBG_AUTH
+#endif
+
+static LIST_HEAD(registered_triples);
+static spinlock_t registered_triples_lock = SPIN_LOCK_UNLOCKED;
+
+/* The following must be called with spinlock held: */
+static struct sup_sec_triple *
+do_lookup_triple_by_pseudoflavor(u32 pseudoflavor)
+{
+	struct sup_sec_triple *pos, *triple = NULL;
+
+	list_for_each_entry(pos, &registered_triples, triples) {
+		if (pos->pseudoflavor == pseudoflavor) {
+			triple = pos;
+			break;
+		}
+	}
+	return triple;
+}
+
+/* XXX Need to think about reference counting of triples and of mechs.
+ * Currently we do no reference counting of triples, and I think that's
+ * probably OK given the reference counting on mechs, but there's probably
+ * a better way to do all this. */
+
+int
+gss_register_triple(u32 pseudoflavor, struct gss_api_mech *mech,
+			  u32 qop, u32 service)
+{
+	struct sup_sec_triple *triple;
+
+	if (!(triple = kmalloc(sizeof(*triple), GFP_KERNEL))) {
+		printk("Alloc failed in gss_register_triple");
+		goto err;
+	}
+	triple->pseudoflavor = pseudoflavor;
+	triple->mech = gss_mech_get_by_OID(&mech->gm_oid);
+	triple->qop = qop;
+	triple->service = service;
+
+	spin_lock(&registered_triples_lock);
+	if (do_lookup_triple_by_pseudoflavor(pseudoflavor)) {
+		printk("Registered pseudoflavor %d again\n", pseudoflavor);
+		goto err_unlock;
+	}
+	list_add(&triple->triples, &registered_triples);
+	spin_unlock(&registered_triples_lock);
+	dprintk("RPC: registered pseudoflavor %d\n", pseudoflavor);
+
+	return 0;
+
+err_unlock:
+	spin_unlock(&registered_triples_lock);
+err:
+	return -1;
+}
+
+int
+gss_unregister_triple(u32 pseudoflavor)
+{
+	struct sup_sec_triple *triple;
+
+	spin_lock(&registered_triples_lock);
+	if (!(triple = do_lookup_triple_by_pseudoflavor(pseudoflavor))) {
+		spin_unlock(&registered_triples_lock);
+		printk("Can't unregister unregistered pseudoflavor %d\n",
+		       pseudoflavor);
+		return -1;
+	}
+	list_del(&triple->triples);
+	spin_unlock(&registered_triples_lock);
+	gss_mech_put(triple->mech);
+	kfree(triple);
+	return 0;
+
+}
+
+void
+print_sec_triple(struct xdr_netobj *oid,u32 qop,u32 service)
+{
+	dprintk("RPC: print_sec_triple:\n");
+	dprintk("                     oid_len %d\n  oid :\n",oid->len);
+	print_hexl((u32 *)oid->data,oid->len,0);
+	dprintk("                     qop %d\n",qop);
+	dprintk("                     service %d\n",service);
+}
+
+/* Function: gss_get_cmp_triples
+ *
+ * Description: search sec_triples for a matching security triple
+ * return pseudoflavor if match, else 0
+ * (Note that 0 is a valid pseudoflavor, but not for any gss pseudoflavor
+ * (0 means auth_null), so this shouldn't cause confusion.)
+ */
+u32
+gss_cmp_triples(u32 oid_len, char *oid_data, u32 qop, u32 service)
+{
+	struct sup_sec_triple *triple;
+	u32 pseudoflavor = 0;
+	struct xdr_netobj oid;
+
+	oid.len = oid_len;
+	oid.data = oid_data;
+
+	dprintk("RPC: gss_cmp_triples \n");
+	print_sec_triple(&oid,qop,service);
+
+	spin_lock(&registered_triples_lock);
+	list_for_each_entry(triple, &registered_triples, triples) {
+		if((g_OID_equal(&oid, &triple->mech->gm_oid))
+		    && (qop == triple->qop)
+		    && (service == triple->service)) {
+			pseudoflavor = triple->pseudoflavor;
+			break;
+		}
+	}
+	spin_unlock(&registered_triples_lock);
+	dprintk("RPC: gss_cmp_triples return %d\n", pseudoflavor);
+	return pseudoflavor;
+}
+
+u32
+gss_get_pseudoflavor(struct gss_ctx *ctx, u32 qop, u32 service)
+{
+	return gss_cmp_triples(ctx->mech_type->gm_oid.len,
+			       ctx->mech_type->gm_oid.data,
+			       qop, service);
+}
+
+/* Returns nonzero iff the given pseudoflavor is in the supported list.
+ * (Note that without incrementing a reference count or anything, this
+ * doesn't give any guarantees.) */
+int
+gss_pseudoflavor_supported(u32 pseudoflavor)
+{
+	struct sup_sec_triple *triple;
+
+	spin_lock(&registered_triples_lock);
+	triple = do_lookup_triple_by_pseudoflavor(pseudoflavor);
+	spin_unlock(&registered_triples_lock);
+	return (triple ? 1 : 0);
+}
+
+u32
+gss_pseudoflavor_to_service(u32 pseudoflavor)
+{
+	struct sup_sec_triple *triple;
+
+	spin_lock(&registered_triples_lock);
+	triple = do_lookup_triple_by_pseudoflavor(pseudoflavor);
+	spin_unlock(&registered_triples_lock);
+	if (!triple) {
+		dprintk("RPC: gss_pseudoflavor_to_service called with"
+			" unsupported pseudoflavor %d\n", pseudoflavor);
+		return 0;
+	}
+	return triple->service;
+}
+
+struct gss_api_mech *
+gss_pseudoflavor_to_mech(u32 pseudoflavor) {
+	struct sup_sec_triple *triple;
+	struct gss_api_mech *mech = NULL;
+
+	spin_lock(&registered_triples_lock);
+	triple = do_lookup_triple_by_pseudoflavor(pseudoflavor);
+	spin_unlock(&registered_triples_lock);
+	if (triple)
+		mech = gss_mech_get(triple->mech);
+	else
+		dprintk("RPC: gss_pseudoflavor_to_mech called with"
+			" unsupported pseudoflavor %d\n", pseudoflavor);
+	return mech;
+}
+
+int
+gss_pseudoflavor_to_mechOID(u32 pseudoflavor, struct xdr_netobj * oid)
+{
+	struct gss_api_mech *mech;
+
+	mech = gss_pseudoflavor_to_mech(pseudoflavor);
+	if (!mech)  {
+		dprintk("RPC: gss_pseudoflavor_to_mechOID called with"
+			" unsupported pseudoflavor %d\n", pseudoflavor);
+		        return -1;
+	}
+	oid->len = mech->gm_oid.len;
+	if (!(oid->data = kmalloc(oid->len, GFP_KERNEL)))
+		return -1;
+	memcpy(oid->data, mech->gm_oid.data, oid->len);
+	gss_mech_put(mech);
+	return 0;
+}
diff -Nru a/net/sunrpc/auth_gss/sunrpcgss_syms.c b/net/sunrpc/auth_gss/sunrpcgss_syms.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/auth_gss/sunrpcgss_syms.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,34 @@
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/sched.h>
+#include <linux/uio.h>
+#include <linux/unistd.h>
+
+#include <linux/sunrpc/auth_gss.h>
+#include <linux/sunrpc/gss_asn1.h>
+
+/* sec_triples: */
+EXPORT_SYMBOL(gss_register_triple);
+EXPORT_SYMBOL(gss_unregister_triple);
+EXPORT_SYMBOL(gss_cmp_triples);
+EXPORT_SYMBOL(gss_pseudoflavor_to_mechOID);
+EXPORT_SYMBOL(gss_pseudoflavor_supported);
+EXPORT_SYMBOL(gss_pseudoflavor_to_service);
+
+/* registering gss mechanisms to the mech switching code: */
+EXPORT_SYMBOL(gss_mech_register);
+EXPORT_SYMBOL(gss_mech_get);
+EXPORT_SYMBOL(gss_mech_get_by_OID);
+EXPORT_SYMBOL(gss_mech_put);
+
+/* generic functionality in gss code: */
+EXPORT_SYMBOL(g_make_token_header);
+EXPORT_SYMBOL(g_verify_token_header);
+EXPORT_SYMBOL(g_token_size);
+
+/* debug */
+EXPORT_SYMBOL(print_hexl);
diff -Nru a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
--- a/net/sunrpc/auth_null.c	Mon Jan 13 21:59:51 2003
+++ b/net/sunrpc/auth_null.c	Mon Jan 13 21:59:51 2003
@@ -20,7 +20,7 @@
 static struct rpc_credops	null_credops;
 
 static struct rpc_auth *
-nul_create(struct rpc_clnt *clnt)
+nul_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
 {
 	struct rpc_auth	*auth;
 
@@ -48,7 +48,7 @@
  * Create NULL creds for current process
  */
 static struct rpc_cred *
-nul_create_cred(int flags)
+nul_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 {
 	struct rpc_cred	*cred;
 
@@ -56,7 +56,7 @@
 		return NULL;
 	atomic_set(&cred->cr_count, 0);
 	cred->cr_flags = RPCAUTH_CRED_UPTODATE;
-	cred->cr_uid = current->uid;
+	cred->cr_uid = acred->uid;
 	cred->cr_ops = &null_credops;
 
 	return cred;
@@ -75,7 +75,7 @@
  * Match cred handle against current process
  */
 static int
-nul_match(struct rpc_cred *cred, int taskflags)
+nul_match(struct auth_cred *acred, struct rpc_cred *cred, int taskflags)
 {
 	return 1;
 }
diff -Nru a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
--- a/net/sunrpc/auth_unix.c	Mon Jan 13 21:59:50 2003
+++ b/net/sunrpc/auth_unix.c	Mon Jan 13 21:59:50 2003
@@ -14,10 +14,12 @@
 #include <linux/sunrpc/auth.h>
 
 #define NFS_NGROUPS	16
+
 struct unx_cred {
 	struct rpc_cred		uc_base;
-	uid_t			uc_fsuid;
-	gid_t			uc_gid, uc_fsgid;
+	gid_t			uc_gid;
+	uid_t			uc_puid;		/* process uid */
+	gid_t			uc_pgid;		/* process gid */
 	gid_t			uc_gids[NFS_NGROUPS];
 };
 #define uc_uid			uc_base.cr_uid
@@ -36,7 +38,7 @@
 static struct rpc_credops	unix_credops;
 
 static struct rpc_auth *
-unx_create(struct rpc_clnt *clnt)
+unx_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
 {
 	struct rpc_auth	*auth;
 
@@ -62,13 +64,13 @@
 }
 
 static struct rpc_cred *
-unx_create_cred(int flags)
+unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 {
 	struct unx_cred	*cred;
 	int		i;
 
 	dprintk("RPC:      allocating UNIX cred for uid %d gid %d\n",
-				current->uid, current->gid);
+				acred->uid, acred->gid);
 
 	if (!(cred = (struct unx_cred *) kmalloc(sizeof(*cred), GFP_KERNEL)))
 		return NULL;
@@ -76,20 +78,20 @@
 	atomic_set(&cred->uc_count, 0);
 	cred->uc_flags = RPCAUTH_CRED_UPTODATE;
 	if (flags & RPC_TASK_ROOTCREDS) {
-		cred->uc_uid = cred->uc_fsuid = 0;
-		cred->uc_gid = cred->uc_fsgid = 0;
+		cred->uc_uid = cred->uc_puid = 0;
+		cred->uc_gid = cred->uc_pgid = 0;
 		cred->uc_gids[0] = NOGROUP;
 	} else {
-		int groups = current->ngroups;
+		int groups = acred->ngroups;
 		if (groups > NFS_NGROUPS)
 			groups = NFS_NGROUPS;
 
-		cred->uc_uid = current->uid;
-		cred->uc_gid = current->gid;
-		cred->uc_fsuid = current->fsuid;
-		cred->uc_fsgid = current->fsgid;
+		cred->uc_uid = acred->uid;
+		cred->uc_gid = acred->gid;
+		cred->uc_puid = current->uid;
+		cred->uc_pgid = current->gid;
 		for (i = 0; i < groups; i++)
-			cred->uc_gids[i] = (gid_t) current->groups[i];
+			cred->uc_gids[i] = (gid_t) acred->groups[i];
 		if (i < NFS_NGROUPS)
 		  cred->uc_gids[i] = NOGROUP;
 	}
@@ -110,7 +112,7 @@
  * request root creds (e.g. for NFS swapping).
  */
 static int
-unx_match(struct rpc_cred *rcred, int taskflags)
+unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags)
 {
 	struct unx_cred	*cred = (struct unx_cred *) rcred;
 	int		i;
@@ -118,22 +120,22 @@
 	if (!(taskflags & RPC_TASK_ROOTCREDS)) {
 		int groups;
 
-		if (cred->uc_uid != current->uid
-		 || cred->uc_gid != current->gid
-		 || cred->uc_fsuid != current->fsuid
-		 || cred->uc_fsgid != current->fsgid)
+		if (cred->uc_uid != acred->uid
+		 || cred->uc_gid != acred->gid
+		 || cred->uc_puid != current->uid
+		 || cred->uc_pgid != current->gid)
 			return 0;
 
-		groups = current->ngroups;
+		groups = acred->ngroups;
 		if (groups > NFS_NGROUPS)
 			groups = NFS_NGROUPS;
 		for (i = 0; i < groups ; i++)
-			if (cred->uc_gids[i] != (gid_t) current->groups[i])
+			if (cred->uc_gids[i] != (gid_t) acred->groups[i])
 				return 0;
 		return 1;
 	}
-	return (cred->uc_uid == 0 && cred->uc_fsuid == 0
-	     && cred->uc_gid == 0 && cred->uc_fsgid == 0
+	return (cred->uc_uid == 0 && cred->uc_puid == 0
+	     && cred->uc_gid == 0 && cred->uc_pgid == 0
 	     && cred->uc_gids[0] == (gid_t) NOGROUP);
 }
 
@@ -162,12 +164,12 @@
 	p += (n + 3) >> 2;
 
 	/* Note: we don't use real uid if it involves raising priviledge */
-	if (ruid && cred->uc_uid != 0 && cred->uc_gid != 0) {
+	if (ruid && cred->uc_puid != 0 && cred->uc_pgid != 0) {
+		*p++ = htonl((u32) cred->uc_puid);
+		*p++ = htonl((u32) cred->uc_pgid);
+	} else {
 		*p++ = htonl((u32) cred->uc_uid);
 		*p++ = htonl((u32) cred->uc_gid);
-	} else {
-		*p++ = htonl((u32) cred->uc_fsuid);
-		*p++ = htonl((u32) cred->uc_fsgid);
 	}
 	hold = p++;
 	for (i = 0; i < 16 && cred->uc_gids[i] != (gid_t) NOGROUP; i++)
@@ -206,7 +208,7 @@
 	}
 
 	size = ntohl(*p++);
-	if (size > 400) {
+	if (size > RPC_MAX_AUTH_SIZE) {
 		printk("RPC: giant verf size: %u\n", size);
 		return NULL;
 	}
diff -Nru a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
--- a/net/sunrpc/clnt.c	Mon Jan 13 21:59:49 2003
+++ b/net/sunrpc/clnt.c	Mon Jan 13 21:59:49 2003
@@ -30,11 +30,12 @@
 #include <linux/utsname.h>
 
 #include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/rpc_pipe_fs.h>
 
 #include <linux/nfs.h>
 
 
-#define RPC_SLACK_SPACE		512	/* total overkill */
+#define RPC_SLACK_SPACE		(1024)	/* total overkill */
 
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY	RPCDBG_CALL
@@ -108,8 +109,19 @@
 
 	rpc_init_rtt(&clnt->cl_rtt, xprt->timeout.to_initval);
 
-	if (!rpcauth_create(flavor, clnt))
+	snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname),
+			"/%s/clnt%p", clnt->cl_protname, clnt);
+	clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt);
+	if (IS_ERR(clnt->cl_dentry)) {
+		printk(KERN_INFO "RPC: Couldn't create pipefs entry %s\n",
+				clnt->cl_pathname);
+		goto out_no_path;
+	}
+	if (!rpcauth_create(flavor, clnt)) {
+		printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
+				flavor);
 		goto out_no_auth;
+	}
 
 	/* save the nodename */
 	clnt->cl_nodelen = strlen(system_utsname.nodename);
@@ -123,8 +135,8 @@
 	printk(KERN_INFO "RPC: out of memory in rpc_create_client\n");
 	goto out;
 out_no_auth:
-	printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
-		flavor);
+	rpc_rmdir(clnt->cl_pathname);
+out_no_path:
 	kfree(clnt);
 	clnt = NULL;
 	goto out;
@@ -176,6 +188,7 @@
 		rpcauth_destroy(clnt->cl_auth);
 		clnt->cl_auth = NULL;
 	}
+	rpc_rmdir(clnt->cl_pathname);
 	if (clnt->cl_xprt) {
 		xprt_destroy(clnt->cl_xprt);
 		clnt->cl_xprt = NULL;
@@ -470,7 +483,7 @@
 
 	dprintk("RPC: %4d call_allocate (status %d)\n", 
 				task->tk_pid, task->tk_status);
-	task->tk_action = call_encode;
+	task->tk_action = call_bind;
 	if (task->tk_buffer)
 		return;
 
@@ -510,8 +523,6 @@
 	dprintk("RPC: %4d call_encode (status %d)\n", 
 				task->tk_pid, task->tk_status);
 
-	task->tk_action = call_bind;
-
 	/* Default buffer setup */
 	bufsiz = task->tk_bufsize >> 1;
 	sndbuf->head[0].iov_base = (void *)task->tk_buffer;
@@ -533,7 +544,8 @@
 	if (!(p = call_header(task))) {
 		printk(KERN_INFO "RPC: call_header failed, exit EIO\n");
 		rpc_exit(task, -EIO);
-	} else
+		return;
+	}
 	if (encode && (status = encode(req, p, task->tk_msg.rpc_argp)) < 0) {
 		printk(KERN_WARNING "%s: can't encode arguments: %d\n",
 				clnt->cl_protname, -status);
@@ -617,8 +629,17 @@
 	task->tk_action = call_status;
 	if (task->tk_status < 0)
 		return;
+	task->tk_status = xprt_prepare_transmit(task);
+	if (task->tk_status < 0)
+		return;
+	/* Encode here so that rpcsec_gss can use correct sequence number. */
+	call_encode(task);
+	if (task->tk_status < 0)
+		return;
 	xprt_transmit(task);
-	if (!task->tk_msg.rpc_proc->p_decode && task->tk_status >= 0) {
+	if (task->tk_status < 0)
+		return;
+	if (!task->tk_msg.rpc_proc->p_decode) {
 		task->tk_action = NULL;
 		rpc_wake_up_task(task);
 	}
@@ -758,7 +779,7 @@
 		if (RPC_IS_SETUID(task) && task->tk_suid_retry) {
 			dprintk("RPC: %4d retry squashed uid\n", task->tk_pid);
 			task->tk_flags ^= RPC_CALL_REALUID;
-			task->tk_action = call_encode;
+			task->tk_action = call_bind;
 			task->tk_suid_retry--;
 			return;
 		}
@@ -793,13 +814,23 @@
 static void
 call_refreshresult(struct rpc_task *task)
 {
+	int status = task->tk_status;
 	dprintk("RPC: %4d call_refreshresult (status %d)\n", 
 				task->tk_pid, task->tk_status);
 
-	if (task->tk_status < 0)
-		rpc_exit(task, -EACCES);
-	else
-		task->tk_action = call_reserve;
+	task->tk_status = 0;
+	task->tk_action = call_reserve;
+	if (status >= 0)
+		return;
+	switch (status) {
+		case -EPIPE:
+			rpc_delay(task, 3*HZ);
+		case -ETIMEDOUT:
+			task->tk_action = call_refresh;
+			break;
+		default:
+			rpc_exit(task, -EACCES);
+	}
 }
 
 /*
@@ -864,7 +895,7 @@
 			task->tk_garb_retry--;
 			dprintk("RPC: %4d call_verify: retry garbled creds\n",
 							task->tk_pid);
-			task->tk_action = call_encode;
+			task->tk_action = call_bind;
 			return NULL;
 		case RPC_AUTH_TOOWEAK:
 			printk(KERN_NOTICE "call_verify: server requires stronger "
@@ -899,7 +930,7 @@
 	if (task->tk_garb_retry) {
 		task->tk_garb_retry--;
 		dprintk(KERN_WARNING "RPC: garbage, retrying %4d\n", task->tk_pid);
-		task->tk_action = call_encode;
+		task->tk_action = call_bind;
 		return NULL;
 	}
 	printk(KERN_WARNING "RPC: garbage, exit EIO\n");
diff -Nru a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sunrpc/rpc_pipe.c	Mon Jan 13 21:59:51 2003
@@ -0,0 +1,817 @@
+/*
+ * net/sunrpc/rpc_pipe.c
+ *
+ * Userland/kernel interface for rpcauth_gss.
+ * Code shamelessly plagiarized from fs/nfsd/nfsctl.c
+ * and fs/driverfs/inode.c
+ *
+ * Copyright (c) 2002, Trond Myklebust <trond.myklebust@fys.uio.no>
+ *
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/pagemap.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/dnotify.h>
+#include <linux/kernel.h>
+
+#include <asm/ioctls.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/seq_file.h>
+
+#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/rpc_pipe_fs.h>
+
+static struct vfsmount *rpc_mount;
+static spinlock_t rpc_mount_lock = SPIN_LOCK_UNLOCKED;
+static int rpc_mount_count;
+
+static struct file_system_type rpc_pipe_fs_type;
+
+
+static kmem_cache_t *rpc_inode_cachep;
+
+static void
+__rpc_purge_upcall(struct inode *inode, int err)
+{
+	struct rpc_inode *rpci = RPC_I(inode);
+	struct rpc_pipe_msg *msg;
+
+	while (!list_empty(&rpci->pipe)) {
+		msg = list_entry(rpci->pipe.next, struct rpc_pipe_msg, list);
+		list_del_init(&msg->list);
+		msg->errno = err;
+		rpci->ops->destroy_msg(msg);
+	}
+	rpci->pipelen = 0;
+	wake_up(&rpci->waitq);
+}
+
+void
+rpc_purge_upcall(struct inode *inode, int err)
+{
+	down(&inode->i_sem);
+	__rpc_purge_upcall(inode, err);
+	up(&inode->i_sem);
+}
+
+/*
+ * XXX should only be called in ->downcall
+ */
+void
+__rpc_purge_current_upcall(struct file *filp)
+{
+	struct rpc_pipe_msg *msg;
+
+	msg = filp->private_data;
+	filp->private_data = NULL;
+
+	if (msg != NULL)
+		msg->errno = 0;
+}
+
+int
+rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg)
+{
+	struct rpc_inode *rpci = RPC_I(inode);
+	int res = 0;
+
+	down(&inode->i_sem);
+	if (rpci->nreaders) {
+		list_add_tail(&msg->list, &rpci->pipe);
+		rpci->pipelen += msg->len;
+	} else
+		res = -EPIPE;
+	up(&inode->i_sem);
+	wake_up(&rpci->waitq);
+	return res;
+}
+
+void
+rpc_inode_setowner(struct inode *inode, void *private)
+{
+	struct rpc_inode *rpci = RPC_I(inode);
+	down(&inode->i_sem);
+	rpci->private = private;
+	if (!private)
+		__rpc_purge_upcall(inode, -EPIPE);
+	up(&inode->i_sem);
+}
+
+static struct inode *
+rpc_alloc_inode(struct super_block *sb)
+{
+	struct rpc_inode *rpci;
+	rpci = (struct rpc_inode *)kmem_cache_alloc(rpc_inode_cachep, SLAB_KERNEL);
+	if (!rpci)
+		return NULL;
+	return &rpci->vfs_inode;
+}
+
+static void
+rpc_destroy_inode(struct inode *inode)
+{
+	kmem_cache_free(rpc_inode_cachep, RPC_I(inode));
+}
+
+static int
+rpc_pipe_open(struct inode *inode, struct file *filp)
+{
+	struct rpc_inode *rpci = RPC_I(inode);
+	int res = -ENXIO;
+
+	down(&inode->i_sem);
+	if (rpci->private != NULL) {
+		if (filp->f_mode & FMODE_READ)
+			rpci->nreaders ++;
+		res = 0;
+	}
+	up(&inode->i_sem);
+	return res;
+}
+
+static int
+rpc_pipe_release(struct inode *inode, struct file *filp)
+{
+	struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
+	struct rpc_pipe_msg *msg;
+
+	msg = (struct rpc_pipe_msg *)filp->private_data;
+	if (msg != NULL) {
+		msg->errno = -EPIPE;
+		rpci->ops->destroy_msg(msg);
+	}
+	down(&inode->i_sem);
+	if (filp->f_mode & FMODE_READ)
+		rpci->nreaders --;
+	if (!rpci->nreaders)
+		__rpc_purge_upcall(inode, -EPIPE);
+	up(&inode->i_sem);
+	return 0;
+}
+
+static ssize_t
+rpc_pipe_read(struct file *filp, char *buf, size_t len, loff_t *offset)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct rpc_inode *rpci = RPC_I(inode);
+	struct rpc_pipe_msg *msg;
+	int res = 0;
+
+	down(&inode->i_sem);
+	if (!rpci->private) {
+		res = -EPIPE;
+		goto out_unlock;
+	}
+	msg = filp->private_data;
+	if (msg == NULL) {
+		if (!list_empty(&rpci->pipe)) {
+			msg = list_entry(rpci->pipe.next,
+					struct rpc_pipe_msg,
+					list);
+			list_del_init(&msg->list);
+			rpci->pipelen -= msg->len;
+			filp->private_data = msg;
+		}
+		if (msg == NULL)
+			goto out_unlock;
+	}
+	res = rpci->ops->upcall(filp, msg, buf, len);
+	if (res < 0 || msg->len == msg->copied) {
+		filp->private_data = NULL;
+		msg->errno = 0;
+		rpci->ops->destroy_msg(msg);
+	}
+out_unlock:
+	up(&inode->i_sem);
+	return res;
+}
+
+static ssize_t
+rpc_pipe_write(struct file *filp, const char *buf, size_t len, loff_t *offset)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct rpc_inode *rpci = RPC_I(inode);
+	int res;
+
+	down(&inode->i_sem);
+	res = -EPIPE;
+	if (rpci->private != NULL)
+		res = rpci->ops->downcall(filp, buf, len);
+	up(&inode->i_sem);
+	return res;
+}
+
+static unsigned int
+rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
+{
+	struct rpc_inode *rpci;
+	unsigned int mask = 0;
+
+	rpci = RPC_I(filp->f_dentry->d_inode);
+	poll_wait(filp, &rpci->waitq, wait);
+
+	mask = POLLOUT | POLLWRNORM;
+	if (rpci->private == NULL)
+		mask |= POLLERR | POLLHUP;
+	if (!list_empty(&rpci->pipe))
+		mask |= POLLIN | POLLRDNORM;
+	return mask;
+}
+
+static int
+rpc_pipe_ioctl(struct inode *ino, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
+	int len;
+
+	switch (cmd) {
+	case FIONREAD:
+		if (!rpci->private)
+			return -EPIPE;
+		len = rpci->pipelen;
+		if (filp->private_data) {
+			struct rpc_pipe_msg *msg;
+			msg = (struct rpc_pipe_msg *)filp->private_data;
+			len += msg->len - msg->copied;
+		}
+		return put_user(len, (int *)arg);
+	default:
+		return -EINVAL;
+	}
+}
+
+struct inode_operations rpc_pipe_iops = {
+	.lookup		= simple_lookup,
+};
+
+
+struct file_operations rpc_pipe_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.read		= rpc_pipe_read,
+	.write		= rpc_pipe_write,
+	.poll		= rpc_pipe_poll,
+	.ioctl		= rpc_pipe_ioctl,
+	.open		= rpc_pipe_open,
+	.release	= rpc_pipe_release,
+};
+
+static int
+rpc_show_info(struct seq_file *m, void *v)
+{
+	struct rpc_clnt *clnt = m->private;
+
+	seq_printf(m, "RPC server: %s\n", clnt->cl_server);
+	seq_printf(m, "service: %s (%d) version %d\n", clnt->cl_protname,
+			clnt->cl_prog, clnt->cl_vers);
+	seq_printf(m, "address: %u.%u.%u.%u\n",
+			NIPQUAD(clnt->cl_xprt->addr.sin_addr.s_addr));
+	return 0;
+}
+
+static int
+rpc_info_open(struct inode *inode, struct file *file)
+{
+	struct rpc_clnt *clnt;
+	int ret = single_open(file, rpc_show_info, NULL);
+
+	if (!ret) {
+		struct seq_file *m = file->private_data;
+		down(&inode->i_sem);
+		clnt = RPC_I(inode)->private;
+		if (clnt) {
+			atomic_inc(&clnt->cl_users);
+			m->private = clnt;
+		} else {
+			single_release(inode, file);
+			ret = -EINVAL;
+		}
+		up(&inode->i_sem);
+	}
+	return ret;
+}
+
+static int
+rpc_info_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *m = file->private_data;
+	struct rpc_clnt *clnt = (struct rpc_clnt *)m->private;
+
+	if (clnt)
+		rpc_release_client(clnt);
+	return single_release(inode, file);
+}
+
+static struct file_operations rpc_info_operations = {
+	.open		= rpc_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= rpc_info_release,
+};
+
+
+/*
+ * We have a single directory with 1 node in it.
+ */
+enum {
+	RPCAUTH_Root = 1,
+	RPCAUTH_lockd,
+	RPCAUTH_nfs,
+	RPCAUTH_portmap,
+	RPCAUTH_statd,
+	RPCAUTH_RootEOF
+};
+
+/*
+ * Description of fs contents.
+ */
+struct rpc_filelist {
+	char *name;
+	struct file_operations *i_fop;
+	int mode;
+};
+
+static struct rpc_filelist files[] = {
+	[RPCAUTH_lockd] = {
+		.name = "lockd",
+		.mode = S_IFDIR | S_IRUSR | S_IXUSR,
+	},
+	[RPCAUTH_nfs] = {
+		.name = "nfs",
+		.mode = S_IFDIR | S_IRUSR | S_IXUSR,
+	},
+	[RPCAUTH_portmap] = {
+		.name = "portmap",
+		.mode = S_IFDIR | S_IRUSR | S_IXUSR,
+	},
+	[RPCAUTH_statd] = {
+		.name = "statd",
+		.mode = S_IFDIR | S_IRUSR | S_IXUSR,
+	},
+};
+
+enum {
+	RPCAUTH_info = 2,
+	RPCAUTH_EOF
+};
+
+static struct rpc_filelist authfiles[] = {
+	[RPCAUTH_info] = {
+		.name = "info",
+		.i_fop = &rpc_info_operations,
+		.mode = S_IFREG | S_IRUSR,
+	},
+};
+
+static int
+rpc_get_mount(void)
+{
+	struct vfsmount * mnt = NULL;
+
+	spin_lock(&rpc_mount_lock);
+	if (rpc_mount)
+		goto out_get;
+	spin_unlock(&rpc_mount_lock);
+	mnt = kern_mount(&rpc_pipe_fs_type);
+	if (IS_ERR(mnt))
+		return -ENODEV;
+	spin_lock(&rpc_mount_lock);
+	if (!rpc_mount) {
+		rpc_mount = mnt;
+		mnt = NULL;
+		goto out_dontget;
+	}
+out_get:
+	mntget(rpc_mount);
+out_dontget:
+	++rpc_mount_count;
+	spin_unlock(&rpc_mount_lock);
+	if (mnt)
+		mntput(mnt);
+	return 0;
+}
+
+static void
+rpc_put_mount(void)
+{
+	struct vfsmount *mnt;
+
+	spin_lock(&rpc_mount_lock);
+	mnt = rpc_mount;
+	--rpc_mount_count;
+	if (rpc_mount_count == 0)
+		rpc_mount = NULL;
+	else
+		mnt = NULL;
+	spin_unlock(&rpc_mount_lock);
+	if (mnt)
+		mntput(mnt);
+}
+
+static int
+rpc_lookup_path(char *path, struct nameidata *nd, int flags)
+{
+	if (rpc_get_mount()) {
+		printk(KERN_WARNING "%s: %s failed to mount "
+			       "pseudofilesystem \n", __FILE__, __FUNCTION__);
+		return -ENODEV;
+	}
+	nd->mnt = mntget(rpc_mount);
+	nd->dentry = dget(rpc_mount->mnt_sb->s_root);
+	nd->last_type = LAST_ROOT;
+	nd->flags = flags;
+
+	if (path_walk(path, nd)) {
+		printk(KERN_WARNING "%s: %s failed to find path %s\n",
+				__FILE__, __FUNCTION__, path);
+		rpc_put_mount();
+		return -ENOENT;
+	}
+	return 0;
+}
+
+static void
+rpc_release_path(struct nameidata *nd)
+{
+	path_release(nd);
+	rpc_put_mount();
+}
+
+static struct inode *
+rpc_get_inode(struct super_block *sb, int mode)
+{
+	struct inode *inode = new_inode(sb);
+	if (!inode)
+		return NULL;
+	inode->i_mode = mode;
+	inode->i_uid = inode->i_gid = 0;
+	inode->i_blksize = PAGE_CACHE_SIZE;
+	inode->i_blocks = 0;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	switch(mode & S_IFMT) {
+		case S_IFDIR:
+			inode->i_fop = &simple_dir_operations;
+			inode->i_op = &simple_dir_inode_operations;
+			inode->i_nlink++;
+		default:
+			break;
+	}
+	return inode;
+}
+
+/*
+ * FIXME: This probably has races.
+ */
+static void
+rpc_depopulate(struct dentry *dir)
+{
+	LIST_HEAD(head);
+	struct list_head *pos, *next;
+	struct dentry *dentry;
+
+	down(&dir->d_inode->i_sem);
+	spin_lock(&dcache_lock);
+	list_for_each_safe(pos, next, &dir->d_subdirs) {
+		dentry = list_entry(pos, struct dentry, d_child);
+		if (!d_unhashed(dentry)) {
+			dget_locked(dentry);
+			list_del(&dentry->d_hash);
+			list_add(&dentry->d_hash, &head);
+		}
+	}
+	spin_unlock(&dcache_lock);
+	while (!list_empty(&head)) {
+		dentry = list_entry(head.next, struct dentry, d_hash);
+		list_del_init(&dentry->d_hash);
+		if (dentry->d_inode) {
+			rpc_inode_setowner(dentry->d_inode, NULL);
+			simple_unlink(dir->d_inode, dentry);
+		}
+		dput(dentry);
+	}
+	up(&dir->d_inode->i_sem);
+}
+
+static int
+rpc_populate(struct dentry *dir,
+		struct rpc_filelist *files,
+		int start, int eof)
+{
+	void *private = RPC_I(dir->d_inode)->private;
+	struct qstr name;
+	struct dentry *dentry;
+	struct inode *inode;
+	int mode, i;
+	for (i = start; i < eof; i++) {
+		name.name = files[i].name;
+		name.len = strlen(name.name);
+		name.hash = full_name_hash(name.name, name.len);
+		dentry = d_alloc(dir, &name);
+		if (!dentry)
+			goto out_bad;
+		mode = files[i].mode;
+		inode = rpc_get_inode(dir->d_inode->i_sb, mode);
+		if (!inode) {
+			dput(dentry);
+			goto out_bad;
+		}
+		inode->i_ino = i;
+		if (files[i].i_fop)
+			inode->i_fop = files[i].i_fop;
+		if (private)
+			rpc_inode_setowner(inode, private);
+		if (S_ISDIR(mode))
+			dir->d_inode->i_nlink++;
+		d_add(dentry, inode);
+	}
+	return 0;
+out_bad:
+	printk(KERN_WARNING "%s: %s failed to populate directory %s\n",
+			__FILE__, __FUNCTION__, dir->d_name.name);
+	return -ENOMEM;
+}
+
+static int
+__rpc_mkdir(struct inode *dir, struct dentry *dentry)
+{
+	struct inode *inode;
+
+	inode = rpc_get_inode(dir->i_sb, S_IFDIR | S_IRUSR | S_IXUSR);
+	if (!inode)
+		goto out_err;
+	inode->i_ino = iunique(dir->i_sb, 100);
+	d_instantiate(dentry, inode);
+	dir->i_nlink++;
+	inode_dir_notify(dir, DN_CREATE);
+	rpc_get_mount();
+	return 0;
+out_err:
+	printk(KERN_WARNING "%s: %s failed to allocate inode for dentry %s\n",
+			__FILE__, __FUNCTION__, dentry->d_name.name);
+	return -ENOMEM;
+}
+
+static int
+__rpc_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	int error;
+
+	rpc_inode_setowner(dentry->d_inode, NULL);
+	if ((error = simple_rmdir(dir, dentry)) != 0)
+		return error;
+	if (!error) {
+		inode_dir_notify(dir, DN_DELETE);
+		d_drop(dentry);
+		rpc_put_mount();
+	}
+	return 0;
+}
+
+struct dentry *
+rpc_lookup_negative(char *path, struct nameidata *nd)
+{
+	struct dentry *dentry;
+	struct inode *dir;
+	int error;
+
+	if ((error = rpc_lookup_path(path, nd, LOOKUP_PARENT)) != 0)
+		return ERR_PTR(error);
+	dir = nd->dentry->d_inode;
+	down(&dir->i_sem);
+	dentry = lookup_hash(&nd->last, nd->dentry);
+	if (IS_ERR(dentry))
+		goto out_err;
+	if (dentry->d_inode) {
+		dput(dentry);
+		dentry = ERR_PTR(-EEXIST);
+		goto out_err;
+	}
+	return dentry;
+out_err:
+	up(&dir->i_sem);
+	rpc_release_path(nd);
+	return dentry;
+}
+
+
+struct dentry *
+rpc_mkdir(char *path, struct rpc_clnt *rpc_client)
+{
+	struct nameidata nd;
+	struct dentry *dentry;
+	struct inode *dir;
+	int error;
+
+	dentry = rpc_lookup_negative(path, &nd);
+	if (IS_ERR(dentry))
+		return dentry;
+	dir = nd.dentry->d_inode;
+	if ((error = __rpc_mkdir(dir, dentry)) != 0)
+		goto err_dput;
+	RPC_I(dentry->d_inode)->private = rpc_client;
+	error = rpc_populate(dentry, authfiles,
+			RPCAUTH_info, RPCAUTH_EOF);
+	if (error)
+		goto err_depopulate;
+out:
+	up(&dir->i_sem);
+	rpc_release_path(&nd);
+	return dentry;
+err_depopulate:
+	rpc_depopulate(dentry);
+	__rpc_rmdir(dir, dentry);
+err_dput:
+	dput(dentry);
+	printk(KERN_WARNING "%s: %s() failed to create directory %s (errno = %d)\n",
+			__FILE__, __FUNCTION__, path, error);
+	dentry = ERR_PTR(error);
+	goto out;
+}
+
+int
+rpc_rmdir(char *path)
+{
+	struct nameidata nd;
+	struct dentry *dentry;
+	struct inode *dir;
+	int error;
+
+	if ((error = rpc_lookup_path(path, &nd, LOOKUP_PARENT)) != 0)
+		return error;
+	dir = nd.dentry->d_inode;
+	down(&dir->i_sem);
+	dentry = lookup_hash(&nd.last, nd.dentry);
+	if (IS_ERR(dentry)) {
+		error = PTR_ERR(dentry);
+		goto out_release;
+	}
+	rpc_depopulate(dentry);
+	error = __rpc_rmdir(dir, dentry);
+	dput(dentry);
+out_release:
+	up(&dir->i_sem);
+	rpc_release_path(&nd);
+	return error;
+}
+
+struct dentry *
+rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops)
+{
+	struct nameidata nd;
+	struct dentry *dentry;
+	struct inode *dir, *inode;
+	struct rpc_inode *rpci;
+
+	dentry = rpc_lookup_negative(path, &nd);
+	if (IS_ERR(dentry))
+		return dentry;
+	dir = nd.dentry->d_inode;
+	inode = rpc_get_inode(dir->i_sb, S_IFSOCK | S_IRUSR | S_IXUSR);
+	if (!inode)
+		goto err_dput;
+	inode->i_ino = iunique(dir->i_sb, 100);
+	inode->i_fop = &rpc_pipe_fops;
+	d_instantiate(dentry, inode);
+	rpci = RPC_I(inode);
+	rpci->private = private;
+	rpci->ops = ops;
+	inode_dir_notify(dir, DN_CREATE);
+out:
+	up(&dir->i_sem);
+	rpc_release_path(&nd);
+	return dentry;
+err_dput:
+	dput(dentry);
+	dentry = ERR_PTR(-ENOMEM);
+	printk(KERN_WARNING "%s: %s() failed to create pipe %s (errno = %d)\n",
+			__FILE__, __FUNCTION__, path, -ENOMEM);
+	goto out;
+}
+
+int
+rpc_unlink(char *path)
+{
+	struct nameidata nd;
+	struct dentry *dentry;
+	struct inode *dir;
+	int error;
+
+	if ((error = rpc_lookup_path(path, &nd, LOOKUP_PARENT)) != 0)
+		return error;
+	dir = nd.dentry->d_inode;
+	down(&dir->i_sem);
+	dentry = lookup_hash(&nd.last, nd.dentry);
+	if (IS_ERR(dentry)) {
+		error = PTR_ERR(dentry);
+		goto out_release;
+	}
+	d_drop(dentry);
+	if (dentry->d_inode) {
+		rpc_inode_setowner(dentry->d_inode, NULL);
+		error = simple_unlink(dir, dentry);
+	}
+	dput(dentry);
+	inode_dir_notify(dir, DN_DELETE);
+out_release:
+	up(&dir->i_sem);
+	rpc_release_path(&nd);
+	return error;
+}
+
+/*
+ * populate the filesystem
+ */
+static struct super_operations s_ops = {
+	.alloc_inode	= rpc_alloc_inode,
+	.destroy_inode	= rpc_destroy_inode,
+	.statfs		= simple_statfs,
+};
+
+#define RPCAUTH_GSSMAGIC 0x67596969
+
+static int
+rpc_fill_super(struct super_block *sb, void *data, int silent)
+{
+	struct inode *inode;
+	struct dentry *root;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = RPCAUTH_GSSMAGIC;
+	sb->s_op = &s_ops;
+
+	inode = rpc_get_inode(sb, S_IFDIR | 0755);
+	if (!inode)
+		return -ENOMEM;
+	root = d_alloc_root(inode);
+	if (!root) {
+		iput(inode);
+		return -ENOMEM;
+	}
+	if (rpc_populate(root, files, RPCAUTH_Root + 1, RPCAUTH_RootEOF))
+		goto out;
+	sb->s_root = root;
+	return 0;
+out:
+	d_genocide(root);
+	dput(root);
+	return -ENOMEM;
+}
+
+static struct super_block *
+rpc_get_sb(struct file_system_type *fs_type,
+		int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, rpc_fill_super);
+}
+
+static struct file_system_type rpc_pipe_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "rpc_pipefs",
+	.get_sb		= rpc_get_sb,
+	.kill_sb	= kill_litter_super,
+};
+
+static void
+init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+{
+	struct rpc_inode *rpci = (struct rpc_inode *) foo;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		inode_init_once(&rpci->vfs_inode);
+		rpci->private = NULL;
+		rpci->nreaders = 0;
+		INIT_LIST_HEAD(&rpci->pipe);
+		rpci->pipelen = 0;
+		init_waitqueue_head(&rpci->waitq);
+		rpci->ops = NULL;
+	}
+}
+
+int register_rpc_pipefs(void)
+{
+	rpc_inode_cachep = kmem_cache_create("rpc_inode_cache",
+                                             sizeof(struct rpc_inode),
+                                             0, SLAB_HWCACHE_ALIGN,
+                                             init_once, NULL);
+	if (!rpc_inode_cachep)
+		return -ENOMEM;
+	register_filesystem(&rpc_pipe_fs_type);
+	return 0;
+}
+
+void unregister_rpc_pipefs(void)
+{
+	if (kmem_cache_destroy(rpc_inode_cachep))
+		printk(KERN_WARNING "RPC: unable to free inode cache\n");
+	unregister_filesystem(&rpc_pipe_fs_type);
+}
diff -Nru a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
--- a/net/sunrpc/sunrpc_syms.c	Mon Jan 13 21:59:51 2003
+++ b/net/sunrpc/sunrpc_syms.c	Mon Jan 13 21:59:51 2003
@@ -22,6 +22,7 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/sunrpc/auth.h>
+#include <linux/sunrpc/rpc_pipe_fs.h>
 
 
 /* RPC scheduler */
@@ -42,6 +43,7 @@
 EXPORT_SYMBOL(rpc_create_client);
 EXPORT_SYMBOL(rpc_destroy_client);
 EXPORT_SYMBOL(rpc_shutdown_client);
+EXPORT_SYMBOL(rpc_release_client);
 EXPORT_SYMBOL(rpc_killall_tasks);
 EXPORT_SYMBOL(rpc_call_sync);
 EXPORT_SYMBOL(rpc_call_async);
@@ -51,6 +53,11 @@
 EXPORT_SYMBOL(rpc_delay);
 EXPORT_SYMBOL(rpc_restart_call);
 EXPORT_SYMBOL(rpc_setbufsize);
+EXPORT_SYMBOL(rpc_unlink);
+EXPORT_SYMBOL(rpc_wake_up);
+EXPORT_SYMBOL(rpc_queue_upcall);
+EXPORT_SYMBOL(rpc_mkpipe);
+EXPORT_SYMBOL(__rpc_purge_current_upcall);
 
 /* Client transport */
 EXPORT_SYMBOL(xprt_create_proto);
@@ -61,6 +68,9 @@
 EXPORT_SYMBOL(rpcauth_register);
 EXPORT_SYMBOL(rpcauth_unregister);
 EXPORT_SYMBOL(rpcauth_lookupcred);
+EXPORT_SYMBOL(rpcauth_lookup_credcache);
+EXPORT_SYMBOL(rpcauth_free_credcache);
+EXPORT_SYMBOL(rpcauth_init_credcache);
 EXPORT_SYMBOL(put_rpccred);
 
 /* RPC server stuff */
@@ -126,11 +136,18 @@
 EXPORT_SYMBOL(nlm_debug);
 #endif
 
+extern int register_rpc_pipefs(void);
+extern void unregister_rpc_pipefs(void);
+
 static int __init
 init_sunrpc(void)
 {
-	if (rpc_init_mempool() != 0)
-		return -ENOMEM;
+	int err = register_rpc_pipefs();
+	if (err)
+		goto out;
+	err = rpc_init_mempool() != 0;
+	if (err)
+		goto out;
 #ifdef RPC_DEBUG
 	rpc_register_sysctl();
 #endif
@@ -139,12 +156,14 @@
 #endif
 	cache_register(&auth_domain_cache);
 	cache_register(&ip_map_cache);
-	return 0;
+out:
+	return err;
 }
 
 static void __exit
 cleanup_sunrpc(void)
 {
+	unregister_rpc_pipefs();
 	rpc_destroy_mempool();
 	cache_unregister(&auth_domain_cache);
 	cache_unregister(&ip_map_cache);
diff -Nru a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
--- a/net/sunrpc/svcauth_unix.c	Mon Jan 13 21:59:50 2003
+++ b/net/sunrpc/svcauth_unix.c	Mon Jan 13 21:59:50 2003
@@ -19,7 +19,7 @@
  */
 
 
-char *strdup(char *s)
+static char *strdup(char *s)
 {
 	char *rv = kmalloc(strlen(s)+1, GFP_KERNEL);
 	if (rv)
diff -Nru a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
--- a/net/sunrpc/xprt.c	Mon Jan 13 21:59:50 2003
+++ b/net/sunrpc/xprt.c	Mon Jan 13 21:59:50 2003
@@ -83,7 +83,6 @@
  * Local functions
  */
 static void	xprt_request_init(struct rpc_task *, struct rpc_xprt *);
-static void	do_xprt_transmit(struct rpc_task *);
 static inline void	do_xprt_reserve(struct rpc_task *);
 static void	xprt_disconnect(struct rpc_xprt *);
 static void	xprt_conn_status(struct rpc_task *task);
@@ -1091,57 +1090,56 @@
  * Place the actual RPC call.
  * We have to copy the iovec because sendmsg fiddles with its contents.
  */
-void
-xprt_transmit(struct rpc_task *task)
+int
+xprt_prepare_transmit(struct rpc_task *task)
 {
 	struct rpc_rqst	*req = task->tk_rqstp;
 	struct rpc_xprt	*xprt = req->rq_xprt;
+	int err = 0;
 
-	dprintk("RPC: %4d xprt_transmit(%x)\n", task->tk_pid, 
-				*(u32 *)(req->rq_svec[0].iov_base));
+	dprintk("RPC: %4d xprt_prepare_transmit\n", task->tk_pid);
 
 	if (xprt->shutdown)
-		task->tk_status = -EIO;
+		return -EIO;
 
 	if (!xprt_connected(xprt))
-		task->tk_status = -ENOTCONN;
-
-	if (task->tk_status < 0)
-		return;
+		return -ENOTCONN;
 
 	if (task->tk_rpcwait)
 		rpc_remove_wait_queue(task);
 
-	/* set up everything as needed. */
-	/* Write the record marker */
-	if (xprt->stream) {
-		u32	*marker = req->rq_svec[0].iov_base;
-
-		*marker = htonl(0x80000000|(req->rq_slen-sizeof(*marker)));
-	}
-
 	spin_lock_bh(&xprt->sock_lock);
 	if (!__xprt_lock_write(xprt, task)) {
-		spin_unlock_bh(&xprt->sock_lock);
-		return;
+		err = -EAGAIN;
+		goto out_unlock;
 	}
 	if (list_empty(&req->rq_list)) {
 		list_add_tail(&req->rq_list, &xprt->recv);
 		req->rq_received = 0;
 	}
+out_unlock:
 	spin_unlock_bh(&xprt->sock_lock);
-
-	do_xprt_transmit(task);
+	return err;
 }
 
-static void
-do_xprt_transmit(struct rpc_task *task)
+void
+xprt_transmit(struct rpc_task *task)
 {
 	struct rpc_clnt *clnt = task->tk_client;
 	struct rpc_rqst	*req = task->tk_rqstp;
 	struct rpc_xprt	*xprt = req->rq_xprt;
 	int status, retry = 0;
 
+
+	dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
+
+	/* set up everything as needed. */
+	/* Write the record marker */
+	if (xprt->stream) {
+		u32	*marker = req->rq_svec[0].iov_base;
+
+		*marker = htonl(0x80000000|(req->rq_slen-sizeof(*marker)));
+	}
 
 	/* Continue transmitting the packet/record. We must be careful
 	 * to cope with writespace callbacks arriving _after_ we have
diff -Nru a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
--- a/sound/isa/opti9xx/opti92x-ad1848.c	Mon Jan 13 21:59:49 2003
+++ b/sound/isa/opti9xx/opti92x-ad1848.c	Mon Jan 13 21:59:49 2003
@@ -47,7 +47,6 @@
 #endif	/* CS4231 */
 #include <sound/mpu401.h>
 #include <sound/opl3.h>
-#define SNDRV_LEGACY_FIND_FREE_IOPORT
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #define SNDRV_GET_ID
@@ -324,6 +323,16 @@
 };
 
 
+static long snd_legacy_find_free_ioport(long *port_table, long size)
+{
+	while (*port_table != -1) {
+		if (!check_region(*port_table, size))
+			return *port_table;
+		port_table++;
+	}
+	return -1;
+}
+
 static int __init snd_opti9xx_init(opti9xx_t *chip, unsigned short hardware)
 {
 	static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
@@ -816,8 +825,9 @@
 	return (format & OPTi93X_STEREO) ? (size >> 1) : size;
 }
 
-unsigned int rates[] = {  5512,  6615,  8000,  9600, 11025, 16000, 18900,
-			 22050, 27428, 32000, 33075, 37800, 44100, 48000 };
+static unsigned int rates[] = {  5512,  6615,  8000,  9600, 11025, 16000, 
+				18900, 22050, 27428, 32000, 33075, 37800,
+				44100, 48000 };
 #define RATES sizeof(rates) / sizeof(rates[0])
 
 static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
@@ -826,8 +836,9 @@
 	.mask = 0,
 };
 
-unsigned char bits[] = {  0x01,  0x0f,  0x00,  0x0e,  0x03,  0x02,  0x05,
-			  0x07,  0x04,  0x06,  0x0d,  0x09,  0x0b,  0x0c};
+static unsigned char bits[] = {  0x01,  0x0f,  0x00,  0x0e,  0x03,  0x02,
+				 0x05,  0x07,  0x04,  0x06,  0x0d,  0x09,
+				 0x0b,  0x0c};
 
 static unsigned char snd_opti93x_get_freq(unsigned int rate)
 {
diff -Nru a/sound/oss/ad1848.c b/sound/oss/ad1848.c
--- a/sound/oss/ad1848.c	Mon Jan 13 21:59:50 2003
+++ b/sound/oss/ad1848.c	Mon Jan 13 21:59:50 2003
@@ -2983,14 +2983,14 @@
 {
 	int err;
 
-	/* Device already active? Let's use it */
-	if(dev->active)
-		return(dev);
+	err = pnp_device_attach(dev);
+	if (err < 0)
+		return(NULL);
 
 	if((err = pnp_activate_dev(dev,NULL)) < 0) {
 		printk(KERN_ERR "ad1848: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
 
-		pnp_disable_dev(dev);
+		pnp_device_detach(dev);
 
 		return(NULL);
 	}
@@ -3006,12 +3006,11 @@
 	{
 		if((ad1848_dev = activate_dev(ad1848_isapnp_list[slot].name, "ad1848", ad1848_dev)))
 		{
-			get_device(&ad1848_dev->dev);
-			hw_config->io_base 	= ad1848_dev->resource[ad1848_isapnp_list[slot].mss_io].start;
-			hw_config->irq 		= ad1848_dev->irq_resource[ad1848_isapnp_list[slot].irq].start;
-			hw_config->dma 		= ad1848_dev->dma_resource[ad1848_isapnp_list[slot].dma].start;
+			hw_config->io_base 	= pnp_port_start(ad1848_dev, ad1848_isapnp_list[slot].mss_io);
+			hw_config->irq 		= pnp_irq(ad1848_dev, ad1848_isapnp_list[slot].irq);
+			hw_config->dma 		= pnp_dma(ad1848_dev, ad1848_isapnp_list[slot].dma);
 			if(ad1848_isapnp_list[slot].dma2 != -1)
-				hw_config->dma2 = ad1848_dev->dma_resource[ad1848_isapnp_list[slot].dma2].start;
+				hw_config->dma2 = pnp_dma(ad1848_dev, ad1848_isapnp_list[slot].dma2);
 			else
 				hw_config->dma2 = -1;
                         hw_config->card_subtype = ad1848_isapnp_list[slot].type;
@@ -3032,7 +3031,7 @@
 	if(ad1848_init_generic(bus, hw_config, slot)) {
 		/* We got it. */
 
-		printk(KERN_NOTICE "ad1848: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
+		printk(KERN_NOTICE "ad1848: PnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
 		       busname,
 		       hw_config->io_base, hw_config->irq, hw_config->dma,
 		       hw_config->dma2);
@@ -3122,8 +3121,7 @@
 #ifdef CONFIG_PNP
 	if(ad1848_dev){
 		if(audio_activated)
-			pnp_disable_dev(ad1848_dev);
-		put_device(&ad1848_dev->dev);
+			pnp_device_detach(ad1848_dev);
 	}
 #endif
 }
diff -Nru a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
--- a/sound/oss/awe_wave.c	Mon Jan 13 21:59:49 2003
+++ b/sound/oss/awe_wave.c	Mon Jan 13 21:59:49 2003
@@ -267,8 +267,7 @@
  * function prototypes
  */
 
-static int awe_check_port(void);
-static void awe_request_region(void);
+static int awe_request_region(void);
 static void awe_release_region(void);
 
 static void awe_reset_samples(void);
@@ -533,8 +532,8 @@
 		return 0;
 	}
 
-	/* check AWE32 ports are available */
-	if (awe_check_port()) {
+	/* reserve I/O ports for awedrv */
+	if (! awe_request_region()) {
 		printk(KERN_ERR "AWE32: I/O area already used.\n");
 		return 0;
 	}
@@ -545,6 +544,7 @@
 	my_dev = sound_alloc_synthdev();
 	if (my_dev == -1) {
 		printk(KERN_ERR "AWE32 Error: too many synthesizers\n");
+		awe_release_region();
 		return 0;
 	}
 
@@ -559,9 +559,6 @@
 	attach_midiemu();
 #endif
 
-	/* reserve I/O ports for awedrv */
-	awe_request_region();
-
 	/* clear all samples */
 	awe_reset_samples();
 
@@ -737,26 +734,27 @@
 
 
 /*
- * port check / request
+ * port request
  *  0x620-623, 0xA20-A23, 0xE20-E23
  */
 
 static int __init
-awe_check_port(void)
-{
-	if (! port_setuped) return 0;
-	return (check_region(awe_ports[0], 4) ||
-		check_region(awe_ports[1], 4) ||
-		check_region(awe_ports[3], 4));
-}
-
-static void __init
 awe_request_region(void)
 {
-	if (! port_setuped) return;
-	request_region(awe_ports[0], 4, "sound driver (AWE32)");
-	request_region(awe_ports[1], 4, "sound driver (AWE32)");
-	request_region(awe_ports[3], 4, "sound driver (AWE32)");
+	if (! port_setuped) 
+		return 0;
+	if (! request_region(awe_ports[0], 4, "sound driver (AWE32)"))
+		return 0;
+	if (! request_region(awe_ports[1], 4, "sound driver (AWE32)")) 
+		goto err_out;
+	if (! request_region(awe_ports[3], 4, "sound driver (AWE32)"))
+		goto err_out1;
+	return 1;
+err_out1:
+	release_region(awe_ports[1], 4);	  
+err_out:
+	release_region(awe_ports[0], 4);	  
+	return 0;
 }
 
 static void __exit
diff -Nru a/sound/oss/cs4232.c b/sound/oss/cs4232.c
--- a/sound/oss/cs4232.c	Mon Jan 13 21:59:50 2003
+++ b/sound/oss/cs4232.c	Mon Jan 13 21:59:50 2003
@@ -357,7 +357,7 @@
 
 /* All cs4232 based cards have the main ad1848 card either as CSC0000 or
  * CSC0100. */
-static const struct pnp_id cs4232_pnp_table[] = {
+static const struct pnp_device_id cs4232_pnp_table[] = {
 	{ .id = "CSC0100", .driver_data = 0 },
 	{ .id = "CSC0000", .driver_data = 0 },
 	/* Guillemot Turtlebeach something appears to be cs4232 compatible
@@ -366,9 +366,9 @@
 	{ .id = ""}
 };
 
-/*MODULE_DEVICE_TABLE(isapnp, isapnp_cs4232_list);*/
+MODULE_DEVICE_TABLE(pnp, cs4232_pnp_table);
 
-static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_id *card_id, const struct pnp_id *dev_id)
+static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
 	struct address_info *isapnpcfg;
 
@@ -376,30 +376,31 @@
 	if (!isapnpcfg)
 		return -ENOMEM;
 
-	isapnpcfg->irq		= dev->irq_resource[0].start;
-	isapnpcfg->dma		= dev->dma_resource[0].start;
-	isapnpcfg->dma2		= dev->dma_resource[1].start;
-	isapnpcfg->io_base	= dev->resource[0].start;
+	isapnpcfg->irq		= pnp_irq(dev, 0);
+	isapnpcfg->dma		= pnp_dma(dev, 0);
+	isapnpcfg->dma2		= pnp_dma(dev, 1);
+	isapnpcfg->io_base	= pnp_port_start(dev, 0);
 	if (probe_cs4232(isapnpcfg,TRUE) == 0) {
 		printk(KERN_ERR "cs4232: ISA PnP card found, but not detected?\n");
 		kfree(isapnpcfg);
 		return -ENODEV;
 	}
 	attach_cs4232(isapnpcfg);
-	pci_set_drvdata(dev,isapnpcfg);
+	pnp_set_drvdata(dev,isapnpcfg);
 	return 0;
 }
 
 static void cs4232_pnp_remove(struct pnp_dev *dev)
 {
-	struct address_info *cfg = (struct address_info*) dev->driver_data;
-	if (cfg)
+	struct address_info *cfg = pnp_get_drvdata(dev);
+	if (cfg) {
 		unload_cs4232(cfg);
+		kfree(cfg);
+	}
 }
 
 static struct pnp_driver cs4232_driver = {
 	.name		= "cs4232",
-	.card_id_table	= NULL,
 	.id_table	= cs4232_pnp_table,
 	.probe		= cs4232_pnp_probe,
 	.remove		= cs4232_pnp_remove,
diff -Nru a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c
--- a/sound/oss/opl3sa2.c	Mon Jan 13 21:59:49 2003
+++ b/sound/oss/opl3sa2.c	Mon Jan 13 21:59:49 2003
@@ -851,19 +851,19 @@
 	opl3sa2_activated[card] = 1;
 
 	/* Our own config: */
-	cfg[card].io_base = dev->resource[4].start;
+	cfg[card].io_base = dev->io_resource[4].start;
 	cfg[card].irq     = dev->irq_resource[0].start;
 	cfg[card].dma     = dev->dma_resource[0].start;
 	cfg[card].dma2    = dev->dma_resource[1].start;
 
 	/* The MSS config: */
-	cfg_mss[card].io_base      = dev->resource[1].start;
+	cfg_mss[card].io_base      = dev->io_resource[1].start;
 	cfg_mss[card].irq          = dev->irq_resource[0].start;
 	cfg_mss[card].dma          = dev->dma_resource[0].start;
 	cfg_mss[card].dma2         = dev->dma_resource[1].start;
 	cfg_mss[card].card_subtype = 1; /* No IRQ or DMA setup */
 
-	cfg_mpu[card].io_base       = dev->resource[3].start;
+	cfg_mpu[card].io_base       = dev->io_resource[3].start;
 	cfg_mpu[card].irq           = dev->irq_resource[0].start;
 	cfg_mpu[card].dma           = -1;
 	cfg_mpu[card].dma2          = -1;
diff -Nru a/sound/oss/pas2_card.c b/sound/oss/pas2_card.c
--- a/sound/oss/pas2_card.c	Mon Jan 13 21:59:50 2003
+++ b/sound/oss/pas2_card.c	Mon Jan 13 21:59:50 2003
@@ -36,11 +36,11 @@
  * be relative to the given base -register
  */
 
-int             translate_code = 0;
+int      	pas_translate_code = 0;
 static int      pas_intr_mask = 0;
 static int      pas_irq = 0;
 static int      pas_sb_base = 0;
-spinlock_t		lock=SPIN_LOCK_UNLOCKED;
+spinlock_t	pas_lock=SPIN_LOCK_UNLOCKED;
 #ifndef CONFIG_PAS_JOYSTICK
 static int	joystick = 0;
 #else
@@ -79,12 +79,12 @@
 
 unsigned char pas_read(int ioaddr)
 {
-	return inb(ioaddr + translate_code);
+	return inb(ioaddr + pas_translate_code);
 }
 
 void pas_write(unsigned char data, int ioaddr)
 {
-	outb((data), ioaddr + translate_code);
+	outb((data), ioaddr + pas_translate_code);
 }
 
 /******************* Begin of the Interrupt Handler ********************/
@@ -301,7 +301,7 @@
 
 	outb((0xBC), 0x9A01);	/* Activate first board */
 	outb((hw_config->io_base >> 2), 0x9A01);	/* Set base address */
-	translate_code = hw_config->io_base - 0x388;
+	pas_translate_code = hw_config->io_base - 0x388;
 	pas_write(1, 0xBF88);	/* Select one wait states */
 
 	board_id = pas_read(0x0B8B);
diff -Nru a/sound/oss/pas2_midi.c b/sound/oss/pas2_midi.c
--- a/sound/oss/pas2_midi.c	Mon Jan 13 21:59:50 2003
+++ b/sound/oss/pas2_midi.c	Mon Jan 13 21:59:50 2003
@@ -19,7 +19,7 @@
 
 #include "pas2.h"
 
-extern spinlock_t lock;
+extern spinlock_t pas_lock;
 
 static int      midi_busy = 0, input_opened = 0;
 static int      my_dev;
@@ -51,11 +51,11 @@
 	pas_write(0x20 | 0x40,
 		  0x178b);
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&pas_lock, flags);
 
 	if ((err = pas_set_intr(0x10)) < 0)
 	{
-		spin_unlock_irqrestore(&lock, flags);
+		spin_unlock_irqrestore(&pas_lock, flags);
 		return err;
 	}
 	/*
@@ -83,7 +83,7 @@
 
 	pas_write(0xff, 0x1B88);
 
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&pas_lock, flags);
 
 	midi_busy = 1;
 	qlen = qhead = qtail = 0;
@@ -133,7 +133,7 @@
 	 * Drain the local queue first
 	 */
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&pas_lock, flags);
 
 	while (qlen && dump_to_midi(tmp_queue[qhead]))
 	{
@@ -141,7 +141,7 @@
 		qhead++;
 	}
 
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&pas_lock, flags);
 
 	/*
 	 *	Output the byte if the local queue is empty.
@@ -158,13 +158,13 @@
 	if (qlen >= 256)
 		return 0;	/* Local queue full */
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&pas_lock, flags);
 
 	tmp_queue[qtail] = midi_byte;
 	qlen++;
 	qtail++;
 
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&pas_lock, flags);
 
 	return 1;
 }
@@ -244,7 +244,7 @@
 	}
 	if (stat & (0x08 | 0x10))
 	{
-		spin_lock(&lock);/* called in irq context */
+		spin_lock(&pas_lock);/* called in irq context */
 
 		while (qlen && dump_to_midi(tmp_queue[qhead]))
 		{
@@ -252,7 +252,7 @@
 			qhead++;
 		}
 
-		spin_unlock(&lock);
+		spin_unlock(&pas_lock);
 	}
 	if (stat & 0x40)
 	{
diff -Nru a/sound/oss/pas2_mixer.c b/sound/oss/pas2_mixer.c
--- a/sound/oss/pas2_mixer.c	Mon Jan 13 21:59:49 2003
+++ b/sound/oss/pas2_mixer.c	Mon Jan 13 21:59:49 2003
@@ -25,7 +25,7 @@
 #define DEB(what)		/* (what) */
 #endif
 
-extern int      translate_code;
+extern int      pas_translate_code;
 extern char     pas_model;
 extern int     *pas_osp;
 extern int      pas_audiodev;
@@ -71,7 +71,7 @@
 
 	if (pas_model == 4)
 	  {
-		  outw(data | (data << 8), (ioaddr + translate_code) - 1);
+		  outw(data | (data << 8), (ioaddr + pas_translate_code) - 1);
 		  outb((0x80), 0);
 	} else
 		pas_write(data, ioaddr);
diff -Nru a/sound/oss/pas2_pcm.c b/sound/oss/pas2_pcm.c
--- a/sound/oss/pas2_pcm.c	Mon Jan 13 21:59:49 2003
+++ b/sound/oss/pas2_pcm.c	Mon Jan 13 21:59:49 2003
@@ -45,7 +45,7 @@
 int             pas_audiodev = -1;
 static int      open_mode = 0;
 
-extern spinlock_t lock;
+extern spinlock_t pas_lock;
 
 static int pcm_set_speed(int arg)
 {
@@ -104,7 +104,7 @@
 	pcm_filter = tmp;
 #endif
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&pas_lock, flags);
 
 	pas_write(tmp & ~(0x40 | 0x80), 0x0B8A);
 	pas_write(0x00 | 0x30 | 0x04, 0x138B);
@@ -112,7 +112,7 @@
 	pas_write((foo >> 8) & 0xff, 0x1388);
 	pas_write(tmp, 0x0B8A);
 
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&pas_lock, flags);
 
 	return pcm_speed;
 }
@@ -214,14 +214,14 @@
 
 	DEB(printk("pas2_pcm.c: static int pas_audio_open(int mode = %X)\n", mode));
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&pas_lock, flags);
 	if (pcm_busy)
 	{
-		spin_unlock_irqrestore(&lock, flags);
+		spin_unlock_irqrestore(&pas_lock, flags);
 		return -EBUSY;
 	}
 	pcm_busy = 1;
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&pas_lock, flags);
 
 	if ((err = pas_set_intr(PAS_PCM_INTRBITS)) < 0)
 		return err;
@@ -239,14 +239,14 @@
 
 	DEB(printk("pas2_pcm.c: static void pas_audio_close(void)\n"));
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&pas_lock, flags);
 
 	pas_audio_reset(dev);
 	pas_remove_intr(PAS_PCM_INTRBITS);
 	pcm_mode = PCM_NON;
 
 	pcm_busy = 0;
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&pas_lock, flags);
 }
 
 static void pas_audio_output_block(int dev, unsigned long buf, int count,
@@ -265,7 +265,7 @@
 	    cnt == pcm_count)
 		return;
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&pas_lock, flags);
 
 	pas_write(pas_read(0xF8A) & ~0x40,
 		  0xF8A);
@@ -292,7 +292,7 @@
 
 	pcm_mode = PCM_DAC;
 
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&pas_lock, flags);
 }
 
 static void pas_audio_start_input(int dev, unsigned long buf, int count,
@@ -312,7 +312,7 @@
 	    cnt == pcm_count)
 		return;
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&pas_lock, flags);
 
 	/* DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ); */
 
@@ -336,7 +336,7 @@
 
 	pcm_mode = PCM_ADC;
 
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&pas_lock, flags);
 }
 
 #ifndef NO_TRIGGER
@@ -344,7 +344,7 @@
 {
 	unsigned long   flags;
 
-	spin_lock_irqsave(&lock, flags);
+	spin_lock_irqsave(&pas_lock, flags);
 	state &= open_mode;
 
 	if (state & PCM_ENABLE_OUTPUT)
@@ -354,7 +354,7 @@
 	else
 		pas_write(pas_read(0xF8A) & ~0x40, 0xF8A);
 
-	spin_unlock_irqrestore(&lock, flags);
+	spin_unlock_irqrestore(&pas_lock, flags);
 }
 #endif
 
diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
--- a/sound/pci/korg1212/korg1212.c	Mon Jan 13 21:59:49 2003
+++ b/sound/pci/korg1212/korg1212.c	Mon Jan 13 21:59:49 2003
@@ -464,7 +464,7 @@
                              0x0002    // selects source as local clock at 48 kHz
                             };
 
-snd_korg1212rc rc;
+static snd_korg1212rc rc;
 
 
 MODULE_DEVICE_TABLE(pci, snd_korg1212_ids);
