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

diff -urN linux-2.5.63-bk5/Documentation/00-INDEX linux-2.5.63-bk6/Documentation/00-INDEX
--- linux-2.5.63-bk5/Documentation/00-INDEX	Mon Feb 24 11:05:12 2003
+++ linux-2.5.63-bk6/Documentation/00-INDEX	Mon Mar 31 12:19:33 2003
@@ -56,6 +56,8 @@
 	- info on Computone Intelliport II/Plus Multiport Serial Driver
 cpqarray.txt
 	- info on using Compaq's SMART2 Intelligent Disk Array Controllers.
+cpufreq/
+	- info on CPU frequency and voltage scaling
 cris/
 	- directory with info about Linux on CRIS architecture.
 devices.txt
diff -urN linux-2.5.63-bk5/Documentation/cpu-freq/core.txt linux-2.5.63-bk6/Documentation/cpu-freq/core.txt
--- linux-2.5.63-bk5/Documentation/cpu-freq/core.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/Documentation/cpu-freq/core.txt	Mon Mar 31 12:19:33 2003
@@ -0,0 +1,90 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+			  C P U F r e q    C o r e
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+		     David Kimdon <dwhedon@debian.org>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+Contents:
+---------
+1.  CPUFreq core and interfaces
+2.  CPUFreq notifiers
+
+1. General Information
+=======================
+
+The CPUFreq core code is located in linux/kernel/cpufreq.c. This
+cpufreq code offers a standardized interface for the CPUFreq
+architecture drivers (those pieces of code that do actual
+frequency transitions), as well as to "notifiers". These are device
+drivers or other part of the kernel that need to be informed of
+policy changes (ex. thermal modules like ACPI) or of all
+frequency changes (ex. timing code) or even need to force certain
+speed limits (like LCD drivers on ARM architecture). Additionally, the
+kernel "constant" loops_per_jiffy is updated on frequency changes
+here.
+
+
+2. CPUFreq notifiers
+====================
+
+CPUFreq notifiers conform to the standard kernel notifier interface.
+See linux/include/linux/notifier.h for details on notifiers.
+
+There are two different CPUFreq notifiers - policy notifiers and
+transition notifiers.
+
+
+2.1 CPUFreq policy notifiers
+----------------------------
+
+These are notified when a new policy is intended to be set. Each
+CPUFreq policy notifier is called three times for a policy transition:
+
+1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if
+    they see a need for this - may it be thermal considerations or
+    hardware limitations.
+
+2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid
+    hardware failure.
+
+3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy
+   - if two hardware drivers failed to agree on a new policy before this
+   stage, the incompatible hardware shall be shut down, and the user
+   informed of this.
+
+The phase is specified in the second argument to the notifier.
+
+The third argument, a void *pointer, points to a struct cpufreq_policy
+consisting of five values: cpu, min, max, policy and max_cpu_freq. min 
+and max are the lower and upper frequencies (in kHz) of the new
+policy, policy the new policy, cpu the number of the affected CPU or
+CPUFREQ_ALL_CPUS for all CPUs; and max_cpu_freq the maximum supported
+CPU frequency. This value is given for informational purposes only.
+
+
+2.2 CPUFreq transition notifiers
+--------------------------------
+
+These are notified twice when the CPUfreq driver switches the CPU core
+frequency and this change has any external implications.
+
+The second argument specifies the phase - CPUFREQ_PRECHANGE or
+CPUFREQ_POSTCHANGE.
+
+The third argument is a struct cpufreq_freqs with the following
+values:
+cpu	- number of the affected CPU or CPUFREQ_ALL_CPUS
+old	- old frequency
+new	- new frequency
diff -urN linux-2.5.63-bk5/Documentation/cpu-freq/cpu-drivers.txt linux-2.5.63-bk6/Documentation/cpu-freq/cpu-drivers.txt
--- linux-2.5.63-bk5/Documentation/cpu-freq/cpu-drivers.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/Documentation/cpu-freq/cpu-drivers.txt	Mon Mar 31 12:19:33 2003
@@ -0,0 +1,207 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+			   C P U   D r i v e r s 
+
+		       - information for developers -
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+Contents:
+---------
+1.   What To Do?
+1.1  Initialization
+1.2  Per-CPU Initialization
+1.3  verify
+1.4  target or setpolicy?
+1.5  target
+1.6  setpolicy
+2.   Frequency Table Helpers
+
+
+
+1. What To Do?
+==============
+
+So, you just got a brand-new CPU / chipset with datasheets and want to
+add cpufreq support for this CPU / chipset? Great. Here are some hints
+on what is neccessary:
+
+
+1.1 Initialization
+------------------
+
+First of all, in an __initcall level 7 or later (preferrably
+module_init() so that your driver is modularized) function check
+whether this kernel runs on the right CPU and the right chipset. If
+so, register a struct cpufreq_driver with the CPUfreq core using
+cpufreq_register_driver()
+
+What shall this struct cpufreq_driver contain? 
+
+cpufreq_driver.name -		The name of this driver.
+
+cpufreq_driver.init -		A pointer to the per-CPU initialization 
+				function.
+
+cpufreq_driver.verify -		A pointer to a "verfication" funciton.
+
+cpufreq_driver.setpolicy _or_ 
+cpufreq_driver.target -		See below on the differences.
+
+And optionally
+
+cpufreq_driver.exit -		A pointer to a per-CPU cleanup function.
+
+
+
+1.2 Per-CPU Initialization
+--------------------------
+
+Whenever a new CPU is registered with the device model, or after the
+cpufreq driver registers itself, the per-CPU initialization fucntion 
+cpufreq_driver.init is called. It takes a struct cpufreq_policy
+*policy as argument. What to do now?
+
+If necessary, activate the CPUfreq support on your CPU (unlock that
+register etc.).
+
+Then, the driver must fill in the following values:
+
+policy->cpuinfo.min_freq _and_
+policy->cpuinfo.max_freq -	the minimum and maximum frequency 
+				(in kHz) which is supported by 
+				this CPU
+policy->cpuinfo.transition_latency   the time it takes on this CPU to
+				switch between two frequencies (if
+				appropriate, else specify
+				CPUFREQ_ETERNAL)
+
+policy->cur			The current operating frequency of
+				this CPU (if appropriate)
+policy->min, 
+policy->max, 
+policy->policy and, if neccessary,
+policy->governor		must contain the "default policy" for
+				this CPU. A few moments later,
+				cpufreq_driver.verify and either
+				cpufreq_driver.setpolicy or
+				cpufreq_driver.target is called with
+				these values.
+
+For setting some of these values, the frequency table helpers might be
+helpful. See the section 2 for more information on them.
+
+
+1.3 verify
+------------
+
+When the user decides a new policy (consisting of
+"policy,governor,min,max") shall be set, this policy must be validated
+so that incompatible values can be corrected. For verifying these
+values, a frequency table helper and/or the
+cpufreq_verify_within_limits(struct cpufreq_policy *policy, unsigned
+int min_freq, unsigned int max_freq) function might be helpful. See
+section 2 for details on frequency table helpers.
+
+You need to make sure that at least one valid frequency (or operating
+range) is within policy->min and policy->max. If necessary, increase
+policy->max fist, and only if this is no solution, decreas policy->min.
+
+
+1.4 target or setpolicy?
+----------------------------
+
+Most cpufreq drivers or even most cpu frequency scaling algorithms 
+only allow the CPU to be set to one frequency. For these, you use the
+->target call.
+
+Some cpufreq-capable processors switch the frequency between certain
+limits on their own. These shall use the ->setpolicy call
+
+
+1.4. target
+-------------
+
+The target call has three arguments: struct cpufreq_policy *policy,
+unsigned int target_frequency, unsigned int relation.
+
+The CPUfreq driver must set the new frequency when called here. The
+actual frequency must be determined using the following rules:
+
+- keep close to "target_freq"
+- policy->min <= new_freq <= policy->max (THIS MUST BE VALID!!!)
+- if relation==CPUFREQ_REL_L, try to select a new_freq higher than or equal
+  target_freq. ("L for lowest, but no lower than")
+- if relation==CPUFREQ_REL_H, try to select a new_freq lower than or equal
+  target_freq. ("H for highest, but no higher than")
+
+Here again the frequency table helper might assist you - see section 3
+for details.
+
+
+1.5 setpolicy
+---------------
+
+The setpolicy call only takes a struct cpufreq_policy *policy as
+argument. You need to set the lower limit of the in-processor or
+in-chipset dynamic frequency switching to policy->min, the upper limit
+to policy->max, and -if supported- select a performance-oriented
+setting when policy->policy is CPUFREQ_POLICY_PERFORMANCE, and a
+powersaving-oriented setting when CPUFREQ_POLICY_POWERSAVE. Also check
+the reference implementation in arch/i386/kernel/cpu/cpufreq/longrun.c
+
+
+
+2. Frequency Table Helpers
+==========================
+
+As most cpufreq processors only allow for being set to a few specific
+frequencies, a "frequency table" with some functions might assist in
+some work of the processor driver. Such a "frequency table" consists
+of an array of struct cpufreq_freq_table entries, with any value in
+"index" you want to use, and the corresponding frequency in
+"frequency". At the end of the table, you need to add a
+cpufreq_freq_table entry with frequency set to CPUFREQ_TABLE_END. And
+if you want to skip one entry in the table, set the frequency to 
+CPUFREQ_ENTRY_INVALID. The entries don't need to be in ascending
+order.
+
+By calling cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
+					struct cpufreq_frequency_table *table);
+the cpuinfo.min_freq and cpuinfo.max_freq values are detected, and
+policy->min and policy->max are set to the same values. This is
+helpful for the per-CPU initialization stage.
+
+int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
+                                   struct cpufreq_frequency_table *table);
+assures that at least one valid frequency is within policy->min and
+policy->max, and all other criteria are met. This is helpful for the
+->verify call.
+
+int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
+                                   struct cpufreq_frequency_table *table,
+                                   unsigned int target_freq,
+                                   unsigned int relation,
+                                   unsigned int *index);
+
+is the corresponding frequency table helper for the ->target
+stage. Just pass the values to this function, and the unsigned int
+index returns the number of the frequency table entry which contains
+the frequency the CPU shall be set to. PLEASE NOTE: This is not the
+"index" which is in this cpufreq_table_entry.index, but instead
+cpufreq_table[index]. So, the new frequency is
+cpufreq_table[index].frequency, and the value you stored into the
+frequency table "index" field is
+cpufreq_table[index].index.
+
diff -urN linux-2.5.63-bk5/Documentation/cpu-freq/governors.txt linux-2.5.63-bk6/Documentation/cpu-freq/governors.txt
--- linux-2.5.63-bk5/Documentation/cpu-freq/governors.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/Documentation/cpu-freq/governors.txt	Mon Mar 31 12:19:33 2003
@@ -0,0 +1,155 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+		      C P U F r e q   G o v e r n o r s
+
+		   - information for users and developers -
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+Contents:
+---------
+1.   What is a CPUFreq Governor?
+
+2.   Governors In the Linux Kernel
+2.1  Performance
+2.2  Powersave
+2.3  Userspace
+
+3.   The Governor Interface in the CPUfreq Core
+
+
+
+1. What Is A CPUFreq Governor?
+==============================
+
+Most cpufreq drivers (in fact, all except one, longrun) or even most
+cpu frequency scaling algorithms only offer the CPU to be set to one
+frequency. In order to offer dynamic frequency scaling, the cpufreq
+core must be able to tell these drivers of a "target frequency". So
+these specific drivers will be transformed to offer a "->target"
+call instead of the existing "->setpolicy" call. For "longrun", all
+stays the same, though.
+
+How to decide what frequency within the CPUfreq policy should be used?
+That's done using "cpufreq governors". Two are already in this patch
+-- they're the already existing "powersave" and "performance" which
+set the frequency statically to the lowest or highest frequency,
+respectively. At least two more such governors will be ready for
+addition in the near future, but likely many more as there are various
+different theories and models about dynamic frequency scaling
+around. Using such a generic interface as cpufreq offers to scaling
+governors, these can be tested extensively, and the best one can be
+selected for each specific use.
+
+Basically, it's the following flow graph:
+
+CPU can be set to switch independetly	 |	   CPU can only be set
+      within specific "limits"		 |       to specific frequencies
+
+                                 "CPUfreq policy"
+		consists of frequency limits (policy->{min,max})
+  		     and CPUfreq governor to be used
+			 /		      \
+			/		       \
+		       /		       the cpufreq governor decides
+		      /			       (dynamically or statically)
+		     /			       what target_freq to set within
+		    /			       the limits of policy->{min,max}
+		   /			            \
+		  /				     \
+	Using the ->setpolicy call,		 Using the ->target call,
+	    the limits and the			  the frequency closest
+	     "policy" is set.			  to target_freq is set.
+						  It is assured that it
+						  is within policy->{min,max}
+
+
+2. Governors In the Linux Kernel
+================================
+
+2.1 Performance
+---------------
+
+The CPUfreq governor "performance" sets the CPU statically to the
+highest frequency within the borders of scaling_min_freq and
+scaling_max_freq.
+
+
+2.1 Powersave
+-------------
+
+The CPUfreq governor "powersave" sets the CPU statically to the
+lowest frequency within the borders of scaling_min_freq and
+scaling_max_freq.
+
+
+2.2 Userspace
+-------------
+
+The CPUfreq governor "userspace" allows the user, or any userspace
+program running with UID "root", to set the CPU to a specifc frequency
+by making a sysfs file "scaling_setspeed" available in the CPU-device
+directory.
+
+
+
+3. The Governor Interface in the CPUfreq Core
+=============================================
+
+A new governor must register itself with the CPUfreq core using
+"cpufreq_register_governor". The struct cpufreq_governor, which has to
+be passed to that function, must contain the following values:
+
+governor->name -	    A unique name for this governor
+governor->governor -	    The governor callback function
+governor->owner	-	    .THIS_MODULE for the governor module (if 
+			    appropriate)
+
+The governor->governor callback is called with the current (or to-be-set)
+cpufreq_policy struct for that CPU, and an unsigned int event. The
+following events are currently defined:
+
+CPUFREQ_GOV_START:   This governor shall start its duty for the CPU
+		     policy->cpu
+CPUFREQ_GOV_STOP:    This governor shall end its duty for the CPU
+		     policy->cpu
+CPUFREQ_GOV_LIMITS:  The limits for CPU policy->cpu have changed to
+		     policy->min and policy->max.
+
+If you need other "events" externally of your driver, _only_ use the
+cpufreq_governor_l(unsigned int cpu, unsigned int event) call to the
+CPUfreq core to ensure proper locking.
+
+
+The CPUfreq governor may call the CPU processor driver using one of
+these two functions:
+
+inline int cpufreq_driver_target(struct cpufreq_policy *policy,
+                                 unsigned int target_freq,
+                                 unsigned int relation);
+
+inline int cpufreq_driver_target_l(struct cpufreq_policy *policy,
+                                   unsigned int target_freq,
+                                   unsigned int relation);
+
+target_freq must be within policy->min and policy->max, of course.
+What's the difference between these two functions? When your governor
+still is in a direct code path of a call to governor->governor, the
+cpufreq_driver_sem lock is still held in the cpufreq core, and there's
+no need to lock it again (in fact, this would cause a deadlock). So
+use cpufreq_driver_target only in these cases. In all other cases (for
+example, when there's a "daemonized" function that wakes up every
+second), use cpufreq_driver_target_l to lock the cpufreq_driver_sem
+before the command is passed to the cpufreq processor driver.
+
diff -urN linux-2.5.63-bk5/Documentation/cpu-freq/index.txt linux-2.5.63-bk6/Documentation/cpu-freq/index.txt
--- linux-2.5.63-bk5/Documentation/cpu-freq/index.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/Documentation/cpu-freq/index.txt	Mon Mar 31 12:19:33 2003
@@ -0,0 +1,56 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+
+Documents in this directory:
+----------------------------
+core.txt	-	General description of the CPUFreq core and
+			of CPUFreq notifiers
+
+cpu-drivers.txt -	How to implement a new cpufreq processor driver
+
+governors.txt	-	What are cpufreq governors and how to
+			implement them?
+
+index.txt	-	File index, Mailing list and Links (this document)
+
+user-guide.txt	-	User Guide to CPUFreq
+
+
+Mailing List
+------------
+There is a CPU frequency changing CVS commit and general list where
+you can report bugs, problems or submit patches. To post a message,
+send an email to cpufreq@www.linux.org.uk, to subscribe go to
+http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
+mailing list are available to subscribers at
+http://www.linux.org.uk/mailman/private/cpufreq/.
+
+
+Links
+-----
+the FTP archives:
+* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
+
+how to access the CVS repository:
+* http://cvs.arm.linux.org.uk/
+
+the CPUFreq Mailing list:
+* http://www.linux.org.uk/mailman/listinfo/cpufreq
+
+Clock and voltage scaling for the SA-1100:
+* http://www.lart.tudelft.nl/projects/scaling
diff -urN linux-2.5.63-bk5/Documentation/cpu-freq/user-guide.txt linux-2.5.63-bk6/Documentation/cpu-freq/user-guide.txt
--- linux-2.5.63-bk5/Documentation/cpu-freq/user-guide.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/Documentation/cpu-freq/user-guide.txt	Mon Mar 31 12:19:33 2003
@@ -0,0 +1,166 @@
+     CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+		         L i n u x    C P U F r e q
+
+			     U S E R   G U I D E
+
+
+		    Dominik Brodowski  <linux@brodo.de>
+
+
+
+   Clock scaling allows you to change the clock speed of the CPUs on the
+    fly. This is a nice method to save battery power, because the lower
+            the clock speed, the less power the CPU consumes.
+
+
+Contents:
+---------
+1. Supported Architectures and Processors
+1.1 ARM
+1.2 x86
+1.3 sparc64
+
+2. "Policy" / "Governor"?
+2.1 Policy
+2.2 Governor
+
+3. How to change the CPU cpufreq policy and/or speed
+3.1 Preferred interface: sysfs
+3.2 Deprecated interfaces
+
+
+
+1. Supported Architectures and Processors
+=========================================
+
+1.1 ARM
+-------
+
+The following ARM processors are supported by cpufreq:
+
+ARM Integrator
+ARM-SA1100
+ARM-SA1110
+
+
+1.2 x86
+-------
+
+The following processors for the x86 architecture are supported by cpufreq:
+
+AMD Elan - SC400, SC410
+AMD mobile K6-2+
+AMD mobile K6-3+
+Cyrix Media GXm
+Intel mobile PIII [*] and Intel mobile PIII-M on certain chipsets
+Intel Pentium 4, Intel Xeon
+National Semiconductors Geode GX
+Transmeta Crusoe
+varios processors on some ACPI 2.0-compatible systems [**]
+
+[*] only certain Intel mobile PIII processors are supported. If you
+know that you own a speedstep-capable processor, pass the option
+"speedstep_coppermine=1" to the module speedstep.o
+
+[**] Only if "ACPI Processor Performance States" are available
+to the ACPI<->BIOS interface.
+
+
+1.3 sparc64
+-----------
+
+The following processors for the sparc64 architecture are supported by
+cpufreq:
+
+UltraSPARC-III
+
+
+
+2. "Policy" / "Governor" ?
+==========================
+
+Some CPU frequency scaling-capable processor switch between varios
+frequencies and operating voltages "on the fly" without any kernel or
+user involvement. This guarantuees very fast switching to a frequency
+which is high enough to serve the user's needs, but low enough to save
+power.
+
+
+2.1 Policy
+----------
+
+On these systems, all you can do is select the lower and upper
+frequency limit as well as whether you want more aggressive
+power-saving or more instantly avaialble processing power.
+
+
+2.2 Governor
+------------
+
+On all other cpufreq implementations, these boundaries still need to
+be set. Then, a "governor" must be selected. Such a "governor" decides
+what speed the processor shall run within the boundaries. One such
+"governor" is the "userspace" governor. This one allows the user - or
+a yet-to-implement userspace program - to decide what specific speed
+the processor shall run at.
+
+
+3. How to change the CPU cpufreq policy and/or speed
+====================================================
+
+3.1 Preferred Interface: sysfs
+------------------------------
+
+The preferred interface is located in the sysfs filesystem. If you
+mounted it at /sys, the cpufreq interface is located in the 
+cpu-device directory (e.g. /sys/devices/sys/cpu0/ for the first
+CPU).
+
+cpuinfo_min_freq :		this file shows the minimum operating
+				frequency the processor can run at(in kHz) 
+cpuinfo_max_freq :		this file shows the maximum operating
+				frequency the processor can run at(in kHz) 
+scaling_driver :		this file shows what cpufreq driver is
+				used to set the frequency on this CPU
+
+available_scaling_governors :	this file shows the CPUfreq governors
+				available in this kernel. You can see the
+				currently activated governor in
+
+scaling_governor,		and by "echoing" the name of another
+				governor you can change it. Please note
+				that some governors won't load - they only
+				work on some specific architectures or
+				processors.
+scaling_min_freq and 
+scaling_max_freq		show the current "policy limits" (in
+				kHz). By echoing new values into these
+				files, you can change these limits.
+
+
+If you have selected the "userspace" governor which allows you to
+set the CPU operating frequency to a specific value, you can read out
+the current frequency in
+
+scaling_setspeed.		By "echoing" a new frequency into this
+				you can change the speed of the CPU,
+				but only within the limits of
+				scaling_min_freq and scaling_max_freq.
+				
+
+3.2 Deprecated Interfaces
+-------------------------
+
+Depending on your kernel configuration, you might find the following 
+cpufreq-related files:
+/proc/cpufreq
+/proc/sys/cpu/*/speed
+/proc/sys/cpu/*/speed-min
+/proc/sys/cpu/*/speed-max
+
+These are files for deprecated interfaces to cpufreq, which offer far
+less functionality. Because of this, these interfaces aren't described
+here.
+
diff -urN linux-2.5.63-bk5/Documentation/cpufreq linux-2.5.63-bk6/Documentation/cpufreq
--- linux-2.5.63-bk5/Documentation/cpufreq	Mon Feb 24 11:05:39 2003
+++ linux-2.5.63-bk6/Documentation/cpufreq	Wed Dec 31 16:00:00 1969
@@ -1,364 +0,0 @@
-     CPU frequency and voltage scaling code in the Linux(TM) kernel
-
-
-		         L i n u x    C P U F r e q
-
-
-
-
-		    Dominik Brodowski  <linux@brodo.de>
-		     David Kimdon <dwhedon@debian.org>
-
-
-
-   Clock scaling allows you to change the clock speed of the CPUs on the
-    fly. This is a nice method to save battery power, because the lower
-            the clock speed, the less power the CPU consumes.
-
-
-
-Contents:
----------
-1.  Supported architectures
-2.  User interface
-2.1   /proc/cpufreq interface  [2.6]
-2.2.  /proc/sys/cpu/ interface [2.4]
-3.  CPUFreq core and interfaces
-3.1   General information
-3.2   CPUFreq notifiers
-3.3   CPUFreq architecture drivers
-4.  Mailing list and Links
-
-
-
-1. Supported architectures
-==========================
-
-ARM:
-    ARM Integrator, SA 1100, SA1110
---------------------------------
-    This driver will be ported to new CPUFreq core soon, so
-    far it will not work.
-
-
-AMD Elan:
-    SC400, SC410
---------------------------------
-    You need to specify the highest allowed CPU frequency as 
-    a module parameter ("max_freq") or as boot parameter 
-    ("elanfreq="). Else the available speed range will be 
-    limited to the speed at which the CPU runs while this
-    module is loaded.
-
-
-VIA Cyrix Longhaul:
-    VIA Samuel/CyrixIII, VIA Cyrix Samuel/C3, 
-    VIA Cyrix Ezra, VIA Cyrix Ezra-T
---------------------------------
-    If you do not want to scale the Front Side Bus or voltage,
-    pass the module parameter "dont_scale_fsb 1" or
-    "dont_scale_voltage 1". Additionally, it is advised that
-    you pass the current Front Side Bus speed (in MHz) to 
-    this module as module parameter "current_fsb", e.g. 
-    "current_fsb 133" for a Front Side Bus speed of 133 MHz.
-
-
-Intel SpeedStep:
-    certain mobile Intel Pentium III (Coppermine), and all mobile
-    Intel Pentium III-M (Tualatin) and mobile Intel Pentium 4 P4-Ms.
---------------------------------
-    Unfortunately only modern Intel ICH2-M and ICH3-M chipsets are 
-    supported.
-
-
-P4 CPU Clock Modulation:
-    Intel Pentium 4 Xeon processors
----------------------------------
-    Note that you can only switch the speed of two logical CPUs at
-    once - but each phyiscal CPU may have different throttling levels.
-
-
-PowerNow! K6:
-    mobile AMD K6-2+ / mobile K6-3+:
---------------------------------
-    No known issues.
-
-
-Transmeta Crusoe Longrun:
-    Transmeta Crusoe processors:
---------------------------------
-    It is recommended to use the 2.6. /proc/cpufreq interface when
-    using this driver
-
-
-
-2. User Interface
-=================
-
-2.1   /proc/cpufreq interface [2.6]
-***********************************
-
-Starting in the patches for kernel 2.5.33, CPUFreq uses a "policy"
-interface /proc/cpufreq.
-
-When you "cat" this file, you'll find something like:
-
---
-          minimum CPU frequency  -  maximum CPU frequency  -  policy
-CPU  0       1200000 ( 75%)      -     1600000 (100%)      -  performance
---
-
-This means the current policy allows this CPU to be run anywhere
-between 1.2 GHz (the value is in kHz) and 1.6 GHz with an eye towards
-performance.
-
-To change the policy, "echo" the desired new policy into
-/proc/cpufreq. Use one of the following formats:
-
-cpu_nr:min_freq:max_freq:policy
-cpu_nr%min_freq%max_freq%policy
-min_freq:max_freq:policy
-min_freq%max_freq%policy
-
-with cpu_nr being the CPU which shall be affected, min_freq and
-max_freq the lower and upper limit of the CPU core frequency in kHz,
-and policy either "performance" or "powersave".
-A few examples:
-
-root@notebook:#echo -n "0:0:0:powersave" > /proc/cpufreq
-     sets the CPU #0 to the lowest supported frequency.
-
-root@notebook:#echo -n "1%100%100%performance" > /proc/cpufreq
-     sets the CPU #1 to the highest supported frequency.
-
-root@notebook:#echo -n "1000000:2000000:performance" > /proc/cpufreq
-     to set the frequency of all CPUs between 1 GHz and 2 GHz and to
-     the policy "performance".
-
-Please note that the values you "echo" into /proc/cpufreq are
-validated first, and may be limited by hardware or thermal
-considerations. Because of this, a read from /proc/cpufreq might 
-differ from what was written into it.
-
-
-When you read /proc/cpufreq for the first time after a CPUFreq driver
-has been initialized, you'll see the "default policy" for this
-driver. If this does not suit your needs, you can pass a boot
-parameter to the cpufreq core. Use the following syntax for this:
-   "cpufreq=min_freq:max_freq:policy", i.e. you may not chose a
-specific CPU and you need to specify the limits in kHz and not in
-per cent.
-
-
-2.2   /proc/cpufreq interface [2.4]
-***********************************
-
-Previsiously (and still available as a config option), CPUFreq used 
-a "sysctl" interface which is located in 
-	/proc/sys/cpu/0/
-	/proc/sys/cpu/1/ ...	(SMP only)
-
-In these directories, you will find three files of importance for
-CPUFreq: speed-max, speed-min and speed: 
-
-speed		    shows the current CPU frequency in kHz, 
-speed-min	    the minimum supported CPU frequency, and
-speed-max	    the maximum supported CPU frequency.
-
-
-To change the CPU frequency, "echo" the desired CPU frequency (in kHz)
-to speed. For example, to set the CPU speed to the lowest/highest
-allowed frequency do:
-
-root@notebook:# cat /proc/sys/cpu/0/speed-min > /proc/sys/cpu/0/speed
-root@notebook:# cat /proc/sys/cpu/0/speed-max > /proc/sys/cpu/0/speed
-
-
-
-3.  CPUFreq core and interfaces
-===============================
-
-3.1   General information
-*************************
-
-The CPUFreq core code is located in linux/kernel/cpufreq.c. This
-cpufreq code offers a standardized interface for the CPUFreq
-architecture drivers (those pieces of code that do actual
-frequency transitions), as well as to "notifiers". These are device
-drivers or other part of the kernel that need to be informed of
-policy changes (like thermal modules like ACPI) or of all
-frequency changes (like timing code) or even need to force certain
-speed limits (like LCD drivers on ARM architecture). Additionally, the
-kernel "constant" loops_per_jiffy is updated on frequency changes
-here.
-
-
-3.2   CPUFreq notifiers
-***********************
-
-CPUFreq notifiers conform to the standard kernel notifier interface.
-See linux/include/linux/notifier.h for details on notifiers.
-
-There are two different CPUFreq notifiers - policy notifiers and
-transition notifiers.
-
-
-3.2.1 CPUFreq policy notifiers
-******************************
-
-These are notified when a new policy is intended to be set. Each
-CPUFreq policy notifier is called three times for a policy transition:
-
-1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if
-    they see a need for this - may it be thermal considerations or
-    hardware limitations.
-
-2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid
-    hardware failure.
-
-3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy
-   - if two hardware drivers failed to agree on a new policy before this
-   stage, the incompatible hardware shall be shut down, and the user
-   informed of this.
-
-The phase is specified in the second argument to the notifier.
-
-The third argument, a void *pointer, points to a struct cpufreq_policy
-consisting of five values: cpu, min, max, policy and max_cpu_freq. Min 
-and max are the lower and upper frequencies (in kHz) of the new
-policy, policy the new policy, cpu the number of the affected CPU or
-CPUFREQ_ALL_CPUS for all CPUs; and max_cpu_freq the maximum supported
-CPU frequency. This value is given for informational purposes only.
-
-
-3.2.2 CPUFreq transition notifiers
-**********************************
-
-These are notified twice when the CPUfreq driver switches the CPU core
-frequency and this change has any external implications.
-
-The second argument specifies the phase - CPUFREQ_PRECHANGE or
-CPUFREQ_POSTCHANGE.
-
-The third argument is a struct cpufreq_freqs with the following
-values:
-cpu	- number of the affected CPU or CPUFREQ_ALL_CPUS
-old	- old frequency
-new	- new frequency
-
-
-3.3   CPUFreq architecture drivers
-**********************************
-
-CPUFreq architecture drivers are the pieces of kernel code that
-actually perform CPU frequency transitions. These need to be
-initialized separately (separate initcalls), and may be
-modularized. They interact with the CPUFreq core in the following way:
-
-cpufreq_register()
-------------------
-cpufreq_register registers an arch driver to the CPUFreq core. Please
-note that only one arch driver may be registered at any time. -EBUSY
-is returned when an arch driver is already registered. The argument to
-cpufreq_register, struct cpufreq_driver *driver, is described later.
-
-cpufreq_unregister()
---------------------
-cpufreq_unregister unregisters an arch driver, e.g. on module
-unloading. Please note that there is no check done that this is called
-from the driver which actually registered itself to the core, so
-please only call this function when you are sure the arch driver got
-registered correctly before.
-
-cpufreq_notify_transition()
----------------------------
-On "dumb" hardware where only fixed frequency can be set, the driver
-must call cpufreq_notify_transition() once before, and once after the
-actual transition.
-
-struct cpufreq_driver
----------------------
-On initialization, the arch driver is supposed to pass a pointer
-to a struct cpufreq_driver *cpufreq_driver consisting of the following
-entries:
-
-cpufreq_verify_t verify: This is a pointer to a function with the
-	following definition:
-	int verify_function (struct cpufreq_policy *policy).
-	This function must verify the new policy is within the limits
-	supported by the CPU, and at least one supported CPU is within
-	this range. It may be useful to use cpufreq.h /
-	cpufreq_verify_within_limits for this. If this is called with
-        CPUFREQ_ALL_CPUS, and there is no common subset of frequencies
-        for all CPUs, exit with an error.
-
-cpufreq_setpolicy_t setpolicy: This is a pointer to a function with
-	the following definition:
-	int setpolicy_function (struct cpufreq_policy *policy).
-	This function must set the CPU to the new policy. If it is a
-	"dumb" CPU which only allows fixed frequencies to be set, it
-	shall set it to the lowest within the limit for
-	CPUFREQ_POLICY_POWERSAVE, and to the highest for
-	CPUFREQ_POLICY_PERFORMANCE. Once CONFIG_CPU_FREQ_DYNAMIC is
-	implemented, it can use a dynamic method to adjust the speed
-	between the lower and upper limit.
-
-struct cpufreq_policy   *policy: This is an array of NR_CPUS struct
-	cpufreq_policies, containing the current policies set for these
-	CPUs. Note that policy[cpu].max_cpu_freq must contain the
-	absolute maximum CPU frequency supported by the specified cpu.
-
-In case the driver is expected to run with the 2.4.-style API
-(/proc/sys/cpu/.../), two more values must be passed
-#ifdef CONFIG_CPU_FREQ_24_API
-	unsigned int            cpu_min_freq[NR_CPUS];
-	unsigned int            cpu_cur_freq[NR_CPUS];
-#endif
-	with cpu_min_freq[cpu] being the minimum CPU frequency
-	supported by the CPU; and the entries in cpu_cur_freq
-	reflecting the current speed of the appropriate CPU.
-
-Some Requirements to CPUFreq architecture drivers
--------------------------------------------------
-* Only call cpufreq_register() when the ability to switch CPU
-  frequencies is _verified_ or can't be missing. Also, all
-  other initialization must be done beofre this call, as
-  cpfureq_register calls the driver's verify and setpolicy code for
-  each CPU.
-* cpufreq_unregister() may only be called if cpufreq_register() has
-  been successfully(!) called before.
-* kfree() the struct cpufreq_driver only after the call to 
-  cpufreq_unregister(), unless cpufreq_register() failed.
-
-
-
-4. Mailing list and Links
-*************************
-
-
-Mailing List
-------------
-There is a CPU frequency changing CVS commit and general list where
-you can report bugs, problems or submit patches. To post a message,
-send an email to cpufreq@www.linux.org.uk, to subscribe go to
-http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
-mailing list are available to subscribers at
-http://www.linux.org.uk/mailman/private/cpufreq/.
-
-
-Links
------
-the FTP archives:
-* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
-
-how to access the CVS repository:
-* http://cvs.arm.linux.org.uk/
-
-the CPUFreq Mailing list:
-* http://www.linux.org.uk/mailman/listinfo/cpufreq
-
-Clock and voltage scaling for the SA-1100:
-* http://www.lart.tudelft.nl/projects/scaling
-
-CPUFreq project homepage
-* http://www.brodo.de/cpufreq/
diff -urN linux-2.5.63-bk5/Documentation/vm/hugetlbpage.txt linux-2.5.63-bk6/Documentation/vm/hugetlbpage.txt
--- linux-2.5.63-bk5/Documentation/vm/hugetlbpage.txt	Mon Feb 24 11:05:09 2003
+++ linux-2.5.63-bk6/Documentation/vm/hugetlbpage.txt	Mon Mar 31 12:19:33 2003
@@ -1,4 +1,3 @@
-2002  Rohit Seth <rohit.seth@intel.com>
 
 The intent of this file is to give a brief summary of hugetlbpage support in
 the Linux kernel.  This support is built on top of multiple page size support
@@ -11,75 +10,194 @@
 now as bigger and bigger physical memories (several GBs) are more readily
 available.
 
-The current support is provided in kernel using the following two system calls:
+Users can use the huge page support in Linux kernel by either using the mmap
+system call or standard SYSv shared memory system calls (shmget, shmat).
 
-1) sys_alloc_hugepages(int key, unsigned long addr, size_t len, int prot, int flag)
+First the Linux kernel needs to be built with CONFIG_HUGETLB_PAGE (present
+under Processor types and feature)  and CONFIG_HUGETLBFS (present under file
+system option on config menu) config options.
 
-2) sys_free_hugepages(unsigned long addr)
+The kernel built with hugepage support should show the number of configured
+hugepages in the system by running the "cat /proc/meminfo" command.  
 
-Arguments to these system calls are defined as follows:
-
-key: If a user application wants to share hugepages with other
-      processes then this input argument needs to be greater than 0. 
-      Different applications can use the same key to map the same physical
-      memory (mapped by hugeTLBs) in their address space.  When a process
-      forks, then children share the same physical memory with their parent.
-
-      For the cases when an application wishes to keep the huge
-      pages private, the key value of 0 is defined.  In this case
-      kernel allocates hugetlb pages to the process that are not
-      shareable across different processes.  These segments are marked
-      private for the process.  These segments are not copied to
-      children's address space on forks - the child will have no
-      mapping for these virtual addresses.
-
-      The key manangement (and assignment) part is left to user
-      applications.
-
-addr: This is an address hint.  The kernel will perform a sanity check
-      on this address (alignment etc.) before using it.  It is possible that
-      kernel will allocates a different address (on success).
-
-len:  Length of the required segment.  Applications are expected to give
-      HPAGE_SIZE aligned length.  (Else EINVAL is returned.)
-
-prot: The prot parameter specifies the desired memory protection on the
-      requested hugepages.  The possible values are PROT_EXEC, PROT_READ,
-      PROT_WRITE.
-
-flag: This parameter can only take the value IPC_CREAT for the cases
-      when "key" value greater than zero (shared hugepage cases).  It is
-      ignored for values of "key" that are <= 0.
-
-      This parameter indicates that the kernel should create a new huge
-      page segment (corresponding to "key"), if none already exists.  If this
-      flag is not set, then sys_allochugepages() will return ENOENT if there
-      is no segment associated with corresponding "key".
-
-In case of success, sys_alloc_hugepages() return the allocated virtual address.
-
-sys_free_hugepages() frees the hugetlb resources from the calling process's
-address space.  The input argument "addr" specifies the segment that needs to
-be freed.  It is important to note that for the shared hugepage cases, the
-underlying hugepages are freed onlyafter all the users of those pages have
-either freed those hugepages or have exited.
-
-/proc/sys/vm_nr_hugepages indicates the current number of configured hugetlb
-pages in the kernel.  Super user privileges are required for modification of
-this value.  The allocation of hugetlb pages is possible only if there are
-enough physically contiguous free pages in system OR if there are enough
-hugetlb pages free that can be transfered back to regular memory pool.
-
-/proc/meminfo also gives the information about the total number of hugetlb
+/proc/meminfo also provides information about the total number of hugetlb
 pages configured in the kernel.  It also displays information about the
 number of free hugetlb pages at any time.  It also displays information about
-the configured hugepage size - this is needed for generting the proper
+the configured hugepage size - this is needed for generating the proper
 alignment and size of the arguments to the above system calls.
 
-Pages that are used as hugetlb pages are marked reserved inside the kernel. 
-This allows hugetlb pages to be always locked in memory.  The user either
-needs to be super user to use these pages or one of supplementary group
-should include root.  In future there will be support to check RLIMIT_MLOCK
-for limited (number of hugetlb pages) usage to unprivileged applications.
+The output of "cat /proc/meminfo" will have output like:
 
-If the kernel does not support hugepages these system calls will return ENOSYS.
+.....
+HugePages_Total: xxx
+HugePages_Free:  yyy
+Hugepagesize:    zzz KB
+
+/proc/filesystems should also show a filesystem of type "hugetlbfs" configured
+in the kernel.
+
+/proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
+pages in the kernel.  Super user can dynamically request more (or free some
+pre-configured) hugepages. 
+The allocation( or deallocation) of hugetlb pages is posible only if there are
+enough physically contiguous free pages in system (freeing of hugepages is
+possible only if there are enough hugetlb pages free that can be transfered 
+back to regular memory pool).
+
+Pages that are used as hugetlb pages are reserved inside the kernel and can
+not be used for other purposes. 
+
+Once the kernel with Hugetlb page support is built and running, a user can
+use either the mmap system call or shared memory system calls to start using
+the huge pages.  It is required that the system administrator preallocate
+enough memory for huge page purposes.  
+
+Use the following command to dynamically allocate/deallocate hugepages:
+
+	echo 20 > /proc/sys/vm/nr_hugepages
+
+This command will try to configure 20 hugepages in the system.  The success
+or failure of allocation depends on the amount of physically contiguous
+memory that is preset in system at this time.  System administrators may want
+to put this command in one of the local rc init file.  This will enable the
+kernel to request huge pages early in the boot process (when the possibility
+of getting physical contiguous pages is still very high).
+
+If the user applications are going to request hugepages using mmap system
+call, then it is required that system administrator mount a file system of
+type hugetlbfs:
+
+	mount none /mnt/huge -t hugetlbfs
+
+This commands mounts a (psuedo) filesystem of type hugetlbfs on the directory
+/mnt/huge.  Any files created on /mnt/huge uses hugepages.  An example is
+given at the end of this document.
+
+read and write system calls are not supported on files that reside on hugetlb
+file systems.
+
+Also, it is important to note that no such mount command is required if the
+applications are going to use only shmat/shmget system calls.  It is possible
+for same or different applications to use any combination of mmaps and shm*
+calls.  Though the mount of filesystem will be required for using mmaps.
+
+/* Example of using hugepage in user application using Sys V shared memory
+ * system calls.  In this example, app is requesting memory of size 256MB that
+ * is backed by huge pages.  Application uses the flag SHM_HUGETLB in shmget
+ * system call to informt the kernel that it is requesting hugepages.  For
+ * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
+ * That means the addresses starting with 0x800000....will need to be
+ * specified.
+ */
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+extern int errno;
+#define SHM_HUGETLB 04000
+#define LPAGE_SIZE      (256UL*1024UL*1024UL)
+#define         dprintf(x)  printf(x)
+#define ADDR (0x8000000000000000UL)
+main()
+{
+        int shmid;
+        int     i, j, k;
+        volatile        char    *shmaddr;
+
+        if ((shmid =shmget(2, LPAGE_SIZE, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W ))
+< 0) {
+                perror("Failure:");
+                exit(1);
+        }
+        printf("shmid: 0x%x\n", shmid);
+        shmaddr = shmat(shmid, (void *)ADDR, SHM_RND) ;
+        if (errno != 0) {
+                perror("Shared Memory Attach Failure:");
+                exit(2);
+        }
+        printf("shmaddr: %p\n", shmaddr);
+
+        dprintf("Starting the writes:\n");
+        for (i=0;i<LPAGE_SIZE;i++) {
+                shmaddr[i] = (char) (i);
+                if (!(i%(1024*1024))) dprintf(".");
+        }
+        dprintf("\n");
+        dprintf("Starting the Check...");
+        for (i=0; i<LPAGE_SIZE;i++)
+                if (shmaddr[i] != (char)i)
+                        printf("\nIndex %d mismatched.");
+        dprintf("Done.\n");
+        if (shmdt((const void *)shmaddr) != 0) {
+                perror("Detached Failure:");
+                exit (3);
+        }
+}
+*******************************************************************
+*******************************************************************
+
+
+/* Example of using hugepage in user application using mmap 
+ * system call.  Before running this application, make sure that
+ * administrator has mounted the hugetlbfs (on some directory like /mnt) using
+ * the command mount -t hugetlbfs nodev /mnt
+ * In this example, app is requesting memory of size 256MB that
+ * is backed by huge pages.  Application uses the flag SHM_HUGETLB in shmget
+ * system call to informt the kernel that it is requesting hugepages.  For
+ * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
+ * That means the addresses starting with 0x800000....will need to be
+ * specified.
+ */
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#define FILE_NAME "/mnt/hugepagefile"
+#define LENGTH (256*1024*1024)
+#define PROTECTION (PROT_READ | PROT_WRITE)
+#define FLAGS   MAP_SHARED |MAP_FIXED
+#define ADDRESS (char *)(0x60000000UL + 0x8000000000000000UL)
+
+extern errno;
+
+check_bytes(char *addr)
+{
+        printf("First hex is %x\n", *((unsigned int *)addr));
+}
+
+write_bytes(char *addr)
+{
+        int i;
+        for (i=0;i<LENGTH;i++)
+                *(addr+i)=(char)i;
+}
+read_bytes(char *addr)
+{
+        int i;
+        check_bytes(addr);
+        for (i=0;i<LENGTH;i++)
+                if (*(addr+i)!=(char)i) {
+                        printf("Mismatch at %d\n", i);
+                        break;
+                }
+}
+main()
+{
+        unsigned long addr = 0;
+        int fd ;
+
+        fd = open(FILE_NAME, O_CREAT|O_RDWR, 0755);
+        if (fd < 0) {
+                perror("Open failed");
+                exit(errno);
+        }
+        addr = (unsigned long)mmap(ADDRESS, LENGTH, PROTECTION, FLAGS, fd, 0);
+        if (errno != 0)
+                perror("mmap failed");
+        printf("Returned address is %p\n", addr);
+        check_bytes((char*)addr);
+        write_bytes((char*)addr);
+        read_bytes((char *)addr);
+}
diff -urN linux-2.5.63-bk5/Makefile linux-2.5.63-bk6/Makefile
--- linux-2.5.63-bk5/Makefile	Mon Mar 31 12:19:30 2003
+++ linux-2.5.63-bk6/Makefile	Mon Mar 31 12:19:33 2003
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 63
-EXTRAVERSION = bk5
+EXTRAVERSION = bk6
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
@@ -159,7 +159,7 @@
 OBJCOPY		= $(CROSS_COMPILE)objcopy
 OBJDUMP		= $(CROSS_COMPILE)objdump
 AWK		= awk
-GENKSYMS	= /sbin/genksyms
+GENKSYMS	= scripts/genksyms/genksyms
 DEPMOD		= /sbin/depmod
 KALLSYMS	= scripts/kallsyms
 PERL		= perl
@@ -190,6 +190,7 @@
 
 # The temporary file to save gcc -MD generated dependencies must not
 # contain a comma
+comma := ,
 depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
 
 noconfig_targets := xconfig menuconfig config oldconfig randconfig \
@@ -319,36 +320,31 @@
 endef
 
 #	set -e makes the rule exit immediately on error
-#	Final awk script makes sure per-cpu vars are in per-cpu section, as
-#	old gcc (eg egcs 2.92.11) ignores section attribute if uninitialized.
 
 define rule_vmlinux__
-	set -e
-	$(if $(filter .tmp_kallsyms%,$^),,
-	  echo '  Generating build number'
-	  . $(src)/scripts/mkversion > .tmp_version
-	  mv -f .tmp_version .version
-	  $(Q)$(MAKE) $(build)=init
+	set -e;								\
+	$(if $(filter .tmp_kallsyms%,$^),,				\
+	  echo '  GEN     .version';					\
+	  . $(srctree)/scripts/mkversion > .tmp_version;		\
+	  mv -f .tmp_version .version;					\
+	  $(MAKE) $(build)=init;					\
 	)
-	$(call cmd,vmlinux__)
+	$(call cmd,vmlinux__);						\
 	echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
 endef
 
-define rule_vmlinux_no_percpu
-	$(rule_vmlinux__)
-	$(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
-endef
-
 ifdef CONFIG_SMP
+#	Final awk script makes sure per-cpu vars are in per-cpu section, as
+#	old gcc (eg egcs 2.92.11) ignores section attribute if uninitialized.
+
+check_per_cpu =	$(AWK) -f $(srctree)/scripts/per-cpu-check.awk < System.map
+endif
+
 define rule_vmlinux
-	$(rule_vmlinux_no_percpu)
-	$(AWK) -f $(srctree)/scripts/per-cpu-check.awk < System.map
-endef
-else
-define rule_vmlinux
-	$(rule_vmlinux_no_percpu)
+	$(rule_vmlinux__)
+	$(NM) $@ | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
+	$(check_per_cpu)
 endef
-endif
 
 LDFLAGS_vmlinux += -T arch/$(ARCH)/vmlinux.lds.s
 
@@ -377,7 +373,7 @@
 	$(call cmd,kallsyms)
 
 .tmp_vmlinux1: $(vmlinux-objs) arch/$(ARCH)/vmlinux.lds.s FORCE
-	$(call if_changed_rule,vmlinux__)
+	+$(call if_changed_rule,vmlinux__)
 
 .tmp_vmlinux2: $(vmlinux-objs) .tmp_kallsyms1.o arch/$(ARCH)/vmlinux.lds.s FORCE
 	$(call if_changed_rule,vmlinux__)
@@ -457,14 +453,14 @@
 # 	Split autoconf.h into include/linux/config/*
 
 include/config/MARKER: scripts/split-include include/linux/autoconf.h
-	@echo '  SPLIT  include/linux/autoconf.h -> include/config/*'
+	@echo '  SPLIT   include/linux/autoconf.h -> include/config/*'
 	@scripts/split-include include/linux/autoconf.h include/config
 	@touch $@
 
 # 	if .config is newer than include/linux/autoconf.h, someone tinkered
 # 	with it and forgot to run make oldconfig
 
-include/linux/autoconf.h: .config
+include/linux/autoconf.h: .config scripts/fixdep
 	$(Q)$(MAKE) $(build)=scripts/kconfig scripts/kconfig/conf
 	./scripts/kconfig/conf -s arch/$(ARCH)/Kconfig
 
@@ -481,7 +477,7 @@
 	  echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2; \
 	  exit 1; \
 	fi;
-	@echo -n '  Generating $@'
+	@echo -n '  GEN     $@'
 	@(echo \#define UTS_RELEASE \"$(KERNELRELEASE)\"; \
 	  echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)`; \
 	 echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))'; \
@@ -506,7 +502,7 @@
 #	Build modules
 
 .PHONY: modules
-modules: $(SUBDIRS) $(if $(CONFIG_MODVERSIONS),vmlinux)
+modules: $(SUBDIRS) $(if $(KBUILD_BUILTIN),vmlinux)
 	@echo '  Building modules, stage 2.';
 	$(Q)$(MAKE) -rR -f scripts/Makefile.modpost
 
@@ -571,6 +567,7 @@
 	 echo "#endif" )
 endef
 
+
 else # ifdef include_config
 
 ifeq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)
@@ -741,10 +738,10 @@
 #	If you do a make spec before packing the tarball you can rpm -ta it
 
 spec:
-	. scripts/mkspec >kernel.spec
+	. $(srctree)/scripts/mkspec >kernel.spec
 
 #	Build a tar ball, generate an rpm from it and pack the result
-#	There arw two bits of magic here
+#	There are two bits of magic here
 #	1) The use of /. to avoid tar packing just the symlink
 #	2) Removing the .dep files as they have source paths in them that
 #	   will become invalid
@@ -784,7 +781,6 @@
 	@echo  ''
 	@echo  'Other generic targets:'
 	@echo  '  all		- Build all targets marked with [*]'
-	@echo  '  dep           - Create module version information'
 	@echo  '* vmlinux	- Build the bare kernel'
 	@echo  '* modules	- Build all modules'
 	@echo  '  dir/file.[ois]- Build specified target only'
@@ -804,7 +800,7 @@
 
 # Documentation targets
 # ---------------------------------------------------------------------------
-sgmldocs psdocs pdfdocs htmldocs: scripts
+sgmldocs psdocs pdfdocs htmldocs: scripts/docproc FORCE
 	$(Q)$(MAKE) $(build)=Documentation/DocBook $@
 
 # Scripts to check various things for consistency
@@ -815,11 +811,6 @@
 		-name '*.[hcS]' -type f -print | sort \
 		| xargs $(PERL) -w scripts/checkconfig.pl
 
-checkhelp:
-	find * $(RCS_FIND_IGNORE) \
-		-name [cC]onfig.in -print | sort \
-		| xargs $(PERL) -w scripts/checkhelp.pl
-
 checkincludes:
 	find * $(RCS_FIND_IGNORE) \
 		-name '*.[hcS]' -type f -print | sort \
diff -urN linux-2.5.63-bk5/arch/alpha/kernel/process.c linux-2.5.63-bk6/arch/alpha/kernel/process.c
--- linux-2.5.63-bk5/arch/alpha/kernel/process.c	Mon Feb 24 11:05:42 2003
+++ linux-2.5.63-bk6/arch/alpha/kernel/process.c	Mon Mar 31 12:19:33 2003
@@ -155,10 +155,7 @@
 	struct halt_info args;
 	args.mode = mode;
 	args.restart_cmd = restart_cmd;
-#ifdef CONFIG_SMP
-	smp_call_function(common_shutdown_1, &args, 1, 0);
-#endif
-	common_shutdown_1(&args);
+	on_each_cpu(common_shutdown_1, &args, 1, 0);
 }
 
 void
diff -urN linux-2.5.63-bk5/arch/alpha/kernel/smp.c linux-2.5.63-bk6/arch/alpha/kernel/smp.c
--- linux-2.5.63-bk5/arch/alpha/kernel/smp.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk6/arch/alpha/kernel/smp.c	Mon Mar 31 12:19:33 2003
@@ -899,10 +899,8 @@
 smp_imb(void)
 {
 	/* Must wait other processors to flush their icache before continue. */
-	if (smp_call_function(ipi_imb, NULL, 1, 1))
+	if (on_each_cpu(ipi_imb, NULL, 1, 1))
 		printk(KERN_CRIT "smp_imb: timed out\n");
-
-	imb();
 }
 
 static void
@@ -916,11 +914,9 @@
 {
 	/* Although we don't have any data to pass, we do want to
 	   synchronize with the other processors.  */
-	if (smp_call_function(ipi_flush_tlb_all, NULL, 1, 1)) {
+	if (on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1)) {
 		printk(KERN_CRIT "flush_tlb_all: timed out\n");
 	}
-
-	tbia();
 }
 
 #define asn_locked() (cpu_data[smp_processor_id()].asn_lock)
@@ -938,6 +934,8 @@
 void
 flush_tlb_mm(struct mm_struct *mm)
 {
+	preempt_disable();
+
 	if (mm == current->active_mm) {
 		flush_tlb_current(mm);
 		if (atomic_read(&mm->mm_users) <= 1) {
@@ -948,6 +946,7 @@
 				if (mm->context[cpu])
 					mm->context[cpu] = 0;
 			}
+			preempt_enable();
 			return;
 		}
 	}
@@ -955,6 +954,8 @@
 	if (smp_call_function(ipi_flush_tlb_mm, mm, 1, 1)) {
 		printk(KERN_CRIT "flush_tlb_mm: timed out\n");
 	}
+
+	preempt_enable();
 }
 
 struct flush_tlb_page_struct {
@@ -981,6 +982,8 @@
 	struct flush_tlb_page_struct data;
 	struct mm_struct *mm = vma->vm_mm;
 
+	preempt_disable();
+
 	if (mm == current->active_mm) {
 		flush_tlb_current_page(mm, vma, addr);
 		if (atomic_read(&mm->mm_users) <= 1) {
@@ -991,6 +994,7 @@
 				if (mm->context[cpu])
 					mm->context[cpu] = 0;
 			}
+			preempt_enable();
 			return;
 		}
 	}
@@ -1002,6 +1006,8 @@
 	if (smp_call_function(ipi_flush_tlb_page, &data, 1, 1)) {
 		printk(KERN_CRIT "flush_tlb_page: timed out\n");
 	}
+
+	preempt_enable();
 }
 
 void
@@ -1030,6 +1036,8 @@
 	if ((vma->vm_flags & VM_EXEC) == 0)
 		return;
 
+	preempt_disable();
+
 	if (mm == current->active_mm) {
 		__load_new_mm_context(mm);
 		if (atomic_read(&mm->mm_users) <= 1) {
@@ -1040,6 +1048,7 @@
 				if (mm->context[cpu])
 					mm->context[cpu] = 0;
 			}
+			preempt_enable();
 			return;
 		}
 	}
@@ -1047,6 +1056,8 @@
 	if (smp_call_function(ipi_flush_icache_page, mm, 1, 1)) {
 		printk(KERN_CRIT "flush_icache_page: timed out\n");
 	}
+
+	preempt_enable();
 }
 
 #ifdef CONFIG_DEBUG_SPINLOCK
diff -urN linux-2.5.63-bk5/arch/i386/Kconfig linux-2.5.63-bk6/arch/i386/Kconfig
--- linux-2.5.63-bk5/arch/i386/Kconfig	Mon Mar 31 12:19:30 2003
+++ linux-2.5.63-bk6/arch/i386/Kconfig	Mon Mar 31 12:19:33 2003
@@ -19,8 +19,13 @@
 	default y
 
 config SWAP
-	bool
+	bool "Support for paging of anonymous memory"
 	default y
+	help
+	  This option allows you to choose whether you want to have support
+	  for socalled swap devices or swap files in your kernel that are
+	  used to provide more virtual memory than the actual RAM present
+	  in your computer.  If unusre say Y.
 
 config SBUS
 	bool
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/Kconfig linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/Kconfig
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/Kconfig	Mon Feb 24 11:05:11 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/Kconfig	Mon Mar 31 12:19:33 2003
@@ -18,20 +18,6 @@
 
 source "drivers/cpufreq/Kconfig"
 
-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 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. 
-
-	  If in doubt, say N.
-
 config CPU_FREQ_TABLE
        tristate "CPU frequency table helpers"
        depends on CPU_FREQ
@@ -56,6 +42,16 @@
 
 	  If in doubt, say N.
 
+config X86_ACPI_CPUFREQ_PROC_INTF
+        bool "/proc/acpi/processor/../performance interface (deprecated)"
+	depends on X86_ACPI_CPUFREQ && PROC_FS
+	help
+	  This enables the deprecated /proc/acpi/processor/../performance 
+	  interface. While it is helpful for debugging, the generic,
+	  cross-architecture cpufreq interfaces should be used.
+
+	  If in doubt, say N.
+
 config ELAN_CPUFREQ
 	tristate "AMD Elan"
 	depends on CPU_FREQ_TABLE && MELAN
@@ -139,7 +135,7 @@
 
 config X86_LONGHAUL
 	tristate "VIA Cyrix III Longhaul"
-	depends on CPU_FREQ
+	depends on CPU_FREQ_TABLE
 	help
 	  This adds the CPUFreq driver for VIA Samuel/CyrixIII, 
 	  VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T 
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/acpi.c linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/acpi.c
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/acpi.c	Mon Feb 24 11:05:07 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/acpi.c	Mon Mar 31 12:19:33 2003
@@ -1,5 +1,5 @@
 /*
- * acpi_processor_perf.c - ACPI Processor P-States Driver ($Revision: 71 $)
+ * acpi_processor_perf.c - ACPI Processor P-States Driver ($Revision: 1.3 $)
  *
  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -50,23 +50,12 @@
 MODULE_LICENSE("GPL");
 
 
-/* Performance Management */
-
 static struct acpi_processor_performance	*performance;
-static struct cpufreq_driver			acpi_cpufreq_driver;
-
-static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_processor_perf_fops = {
-	.open 		= acpi_processor_perf_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
 
 
 static int 
 acpi_processor_get_performance_control (
-	struct acpi_processor	*pr)
+	struct acpi_processor_performance *perf)
 {
 	int			result = 0;
 	acpi_status		status = 0;
@@ -77,7 +66,7 @@
 
 	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_control");
 
-	status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
+	status = acpi_evaluate_object(perf->pr->handle, "_PCT", NULL, &buffer);
 	if(ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PCT\n"));
 		return_VALUE(-ENODEV);
@@ -116,7 +105,7 @@
 		goto end;
 	}
 
-	pr->performance->control_register = (u16) reg->address;
+	perf->control_register = (u16) reg->address;
 
 	/*
 	 * status_register
@@ -143,12 +132,12 @@
 		goto end;
 	}
 
-	pr->performance->status_register = (u16) reg->address;
+	perf->status_register = (u16) reg->address;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"control_register[0x%04x] status_register[0x%04x]\n",
-		pr->performance->control_register,
-		pr->performance->status_register));
+		perf->control_register,
+		perf->status_register));
 
 end:
 	acpi_os_free(buffer.pointer);
@@ -159,7 +148,7 @@
 
 static int 
 acpi_processor_get_performance_states (
-	struct acpi_processor*	pr)
+	struct acpi_processor_performance *	perf)
 {
 	int			result = 0;
 	acpi_status		status = AE_OK;
@@ -171,7 +160,7 @@
 
 	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_states");
 
-	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
+	status = acpi_evaluate_object(perf->pr->handle, "_PSS", NULL, &buffer);
 	if(ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PSS\n"));
 		return_VALUE(-ENODEV);
@@ -188,20 +177,20 @@
 		pss->package.count));
 
 	if (pss->package.count > ACPI_PROCESSOR_MAX_PERFORMANCE) {
-		pr->performance->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE;
+		perf->state_count = ACPI_PROCESSOR_MAX_PERFORMANCE;
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"Limiting number of states to max (%d)\n", 
 			ACPI_PROCESSOR_MAX_PERFORMANCE));
 	}
 	else
-		pr->performance->state_count = pss->package.count;
+		perf->state_count = pss->package.count;
 
-	if (pr->performance->state_count > 1)
-		pr->flags.performance = 1;
+	if (perf->state_count > 1)
+		perf->pr->flags.performance = 1;
 
-	for (i = 0; i < pr->performance->state_count; i++) {
+	for (i = 0; i < perf->state_count; i++) {
 
-		struct acpi_processor_px *px = &(pr->performance->states[i]);
+		struct acpi_processor_px *px = &(perf->states[i]);
 
 		state.length = sizeof(struct acpi_processor_px);
 		state.pointer = px;
@@ -236,7 +225,7 @@
 
 static int
 acpi_processor_set_performance (
-	struct acpi_processor	*pr,
+	struct acpi_processor_performance	*perf,
 	int			state)
 {
 	u16			port = 0;
@@ -246,38 +235,38 @@
 
 	ACPI_FUNCTION_TRACE("acpi_processor_set_performance");
 
-	if (!pr)
+	if (!perf || !perf->pr)
 		return_VALUE(-EINVAL);
 
-	if (!pr->flags.performance)
+	if (!perf->pr->flags.performance)
 		return_VALUE(-ENODEV);
 
-	if (state >= pr->performance->state_count) {
+	if (state >= perf->state_count) {
 		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
 			"Invalid target state (P%d)\n", state));
 		return_VALUE(-ENODEV);
 	}
 
-	if (state < pr->performance_platform_limit) {
+	if (state < perf->pr->performance_platform_limit) {
 		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
 			"Platform limit (P%d) overrides target state (P%d)\n",
-			pr->performance->platform_limit, state));
+			perf->pr->performance_platform_limit, state));
 		return_VALUE(-ENODEV);
 	}
 
-	if (state == pr->performance->state) {
+	if (state == perf->state) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"Already at target state (P%d)\n", state));
 		return_VALUE(0);
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n",
-		pr->performance->state, state));
+		perf->state, state));
 
 	/* cpufreq frequency struct */
-	cpufreq_freqs.cpu = pr->id;
-	cpufreq_freqs.old = pr->performance->states[pr->performance->state].core_frequency;
-	cpufreq_freqs.new = pr->performance->states[state].core_frequency;
+	cpufreq_freqs.cpu = perf->pr->id;
+	cpufreq_freqs.old = perf->states[perf->state].core_frequency;
+	cpufreq_freqs.new = perf->states[state].core_frequency;
 
 	/* notify cpufreq */
 	cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
@@ -287,8 +276,8 @@
 	 * control_register.
 	 */
 
-	port = pr->performance->control_register;
-	value = (u16) pr->performance->states[state].control;
+	port = perf->control_register;
+	value = (u16) perf->states[state].control;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"Writing 0x%02x to port 0x%04x\n", value, port));
@@ -302,15 +291,15 @@
 	 * giving up.
 	 */
 
-	port = pr->performance->status_register;
+	port = perf->status_register;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 		"Looking for 0x%02x from port 0x%04x\n",
-		(u8) pr->performance->states[state].status, port));
+		(u8) perf->states[state].status, port));
 
 	for (i=0; i<100; i++) {
 		value = inb(port);
-		if (value == (u8) pr->performance->states[state].status)
+		if (value == (u8) perf->states[state].status)
 			break;
 		udelay(10);
 	}
@@ -318,7 +307,7 @@
 	/* notify cpufreq */
 	cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
 
-	if (value != pr->performance->states[state].status) {
+	if (value != perf->states[state].status) {
 		unsigned int tmp = cpufreq_freqs.new;
 		cpufreq_freqs.new = cpufreq_freqs.old;
 		cpufreq_freqs.old = tmp;
@@ -332,11 +321,23 @@
 		"Transition successful after %d microseconds\n",
 		i * 10));
 
-	pr->performance->state = state;
+	perf->state = state;
 
 	return_VALUE(0);
 }
 
+
+#ifdef CONFIG_X86_ACPI_CPUFREQ_PROC_INTF
+/* /proc/acpi/processor/../performance interface (DEPRECATED) */
+
+static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file);
+static struct file_operations acpi_processor_perf_fops = {
+	.open 		= acpi_processor_perf_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
 {
 	struct acpi_processor	*pr = (struct acpi_processor *)seq->private;
@@ -347,7 +348,7 @@
 	if (!pr)
 		goto end;
 
-	if (!pr->flags.performance) {
+	if (!pr->flags.performance || !pr->performance) {
 		seq_puts(seq, "<not supported>\n");
 		goto end;
 	}
@@ -379,8 +380,8 @@
 acpi_processor_write_performance (
         struct file		*file,
         const char		*buffer,
-        unsigned long		count,
-        void			*data)
+        size_t			count,
+        loff_t			*data)
 {
 	int			result = 0;
 	struct acpi_processor	*pr = (struct acpi_processor *) data;
@@ -411,24 +412,78 @@
 	return_VALUE(count);
 }
 
+static void
+acpi_cpufreq_add_file (
+	struct acpi_processor *pr)
+{
+	struct proc_dir_entry	*entry = NULL;
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	/* add file 'performance' [R/W] */
+	entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+		  S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
+	if (!entry)
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Unable to create '%s' fs entry\n",
+			ACPI_PROCESSOR_FILE_PERFORMANCE));
+	else {
+		entry->proc_fops = &acpi_processor_perf_fops;
+		entry->proc_fops->write = acpi_processor_write_performance;
+		entry->data = acpi_driver_data(device);
+	}
+	return_VOID;
+}
+
+static void
+acpi_cpufreq_remove_file (
+	struct acpi_processor *pr)
+{
+	struct acpi_device	*device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_addfile");
+
+	if (acpi_bus_get_device(pr->handle, &device))
+		return_VOID;
+
+	/* remove file 'performance' */
+	remove_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
+		  acpi_device_dir(device));
+
+	return_VOID;
+}
+
+#else
+static void acpi_cpufreq_add_file (struct acpi_processor *pr) { return; }
+static void acpi_cpufreq_remove_file (struct acpi_processor *pr) { return; }
+#endif /* CONFIG_X86_ACPI_CPUFREQ_PROC_INTF */
+
 
 static int
-acpi_cpufreq_setpolicy (
-	struct cpufreq_policy   *policy)
+acpi_cpufreq_target (
+	struct cpufreq_policy   *policy,
+	unsigned int target_freq,
+	unsigned int relation)
 {
-	struct acpi_processor *pr = performance[policy->cpu].pr;
+	struct acpi_processor_performance *perf = &performance[policy->cpu];
 	unsigned int next_state = 0;
 	unsigned int result = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_setpolicy");
 
-	result = cpufreq_frequency_table_setpolicy(policy, 
-			&performance[policy->cpu].freq_table[pr->limit.state.px],
+	result = cpufreq_frequency_table_target(policy, 
+			&perf->freq_table[perf->pr->limit.state.px],
+			target_freq,
+			relation,
 			&next_state);
 	if (result)
 		return_VALUE(result);
 
-	result = acpi_processor_set_performance (pr, next_state);
+	result = acpi_processor_set_performance (perf, next_state);
 
 	return_VALUE(result);
 }
@@ -439,18 +494,17 @@
 	struct cpufreq_policy   *policy)
 {
 	unsigned int result = 0;
-	unsigned int cpu = policy->cpu;
-	struct acpi_processor *pr = performance[policy->cpu].pr;
+	struct acpi_processor_performance *perf = &performance[policy->cpu];
 
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_verify");
 
 	result = cpufreq_frequency_table_verify(policy, 
-			&performance[cpu].freq_table[pr->limit.state.px]);
+			&perf->freq_table[perf->pr->limit.state.px]);
 
 	cpufreq_verify_within_limits(
 		policy, 
-		performance[cpu].states[performance[cpu].state_count - 1].core_frequency * 1000,
-		performance[cpu].states[pr->limit.state.px].core_frequency * 1000);
+		perf->states[perf->state_count - 1].core_frequency * 1000,
+		perf->states[perf->pr->limit.state.px].core_frequency * 1000);
 
 	return_VALUE(result);
 }
@@ -458,7 +512,7 @@
 
 static int
 acpi_processor_get_performance_info (
-	struct acpi_processor	*pr)
+	struct acpi_processor_performance	*perf)
 {
 	int			result = 0;
 	acpi_status		status = AE_OK;
@@ -466,31 +520,32 @@
 
 	ACPI_FUNCTION_TRACE("acpi_processor_get_performance_info");
 
-	if (!pr)
+	if (!perf || !perf->pr || !perf->pr->handle)
 		return_VALUE(-EINVAL);
 
-	status = acpi_get_handle(pr->handle, "_PCT", &handle);
+	status = acpi_get_handle(perf->pr->handle, "_PCT", &handle);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"ACPI-based processor performance control unavailable\n"));
 		return_VALUE(-ENODEV);
 	}
 
-	result = acpi_processor_get_performance_control(pr);
+	result = acpi_processor_get_performance_control(perf);
 	if (result)
 		return_VALUE(result);
 
-	result = acpi_processor_get_performance_states(pr);
+	result = acpi_processor_get_performance_states(perf);
 	if (result)
 		return_VALUE(result);
 
-	result = acpi_processor_get_platform_limit(pr);
+	result = acpi_processor_get_platform_limit(perf->pr);
 	if (result)
 		return_VALUE(result);
 
 	return_VALUE(0);
 }
 
+
 static int
 acpi_cpufreq_cpu_init (
 	struct cpufreq_policy   *policy)
@@ -498,22 +553,18 @@
 	unsigned int		i;
 	unsigned int		cpu = policy->cpu;
 	struct acpi_processor  *pr = NULL;
+	struct acpi_processor_performance *perf = &performance[policy->cpu];
 	unsigned int		result = 0;
-	struct proc_dir_entry	*entry = NULL;
-	struct acpi_device	*device = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init");
 
-	acpi_processor_register_performance(&performance[cpu], &pr, cpu);
+	acpi_processor_register_performance(perf, &pr, cpu);
 
 	pr = performance[cpu].pr;
 	if (!pr)
 		return_VALUE(-ENODEV);
 
-	if (acpi_bus_get_device(pr->handle, &device))
-		return_VALUE(-ENODEV);
-
-	result = acpi_processor_get_performance_info(performance[cpu].pr);
+	result = acpi_processor_get_performance_info(perf);
 	if (result)
 		return_VALUE(-ENODEV);
 
@@ -523,52 +574,62 @@
 
 	/* detect transition latency */
 	policy->cpuinfo.transition_latency = 0;
-	for (i=0;i<performance[cpu].state_count;i++) {
-		if (performance[cpu].states[i].transition_latency > policy->cpuinfo.transition_latency)
-			policy->cpuinfo.transition_latency = performance[cpu].states[i].transition_latency;
+	for (i=0;i<perf->state_count;i++) {
+		if (perf->states[i].transition_latency > policy->cpuinfo.transition_latency)
+			policy->cpuinfo.transition_latency = perf->states[i].transition_latency;
 	}
 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cur = perf->states[pr->limit.state.px].core_frequency * 1000;
 
 	/* table init */
-	for (i=0; i<=performance[cpu].state_count; i++)
+	for (i=0; i<=perf->state_count; i++)
 	{
-		performance[cpu].freq_table[i].index = i;
-		if (i<performance[cpu].state_count)
-			performance[cpu].freq_table[i].frequency = performance[cpu].states[i].core_frequency * 1000;
+		perf->freq_table[i].index = i;
+		if (i<perf->state_count)
+			perf->freq_table[i].frequency = perf->states[i].core_frequency * 1000;
 		else
-			performance[cpu].freq_table[i].frequency = CPUFREQ_TABLE_END;
+			perf->freq_table[i].frequency = CPUFREQ_TABLE_END;
 	}
 
-#ifdef CONFIG_CPU_FREQ_24_API
-	acpi_cpufreq_driver.cpu_cur_freq[policy->cpu] = performance[cpu].states[pr->limit.state.px].core_frequency * 1000;
-#endif
+	result = cpufreq_frequency_table_cpuinfo(policy, &perf->freq_table[0]);
 
-	result = cpufreq_frequency_table_cpuinfo(policy, &performance[cpu].freq_table[0]);
-
-	/* add file 'performance' [R/W] */
-	entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE,
-		  S_IFREG|S_IRUGO|S_IWUSR, acpi_device_dir(device));
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_PROCESSOR_FILE_PERFORMANCE));
-	else {
-		entry->proc_fops = &acpi_processor_perf_fops;
-		entry->write_proc = acpi_processor_write_performance;
-		entry->data = acpi_driver_data(device);
-	}
+	acpi_cpufreq_add_file(pr);
 
 	return_VALUE(result);
 }
 
 
+static int
+acpi_cpufreq_cpu_exit (
+	struct cpufreq_policy   *policy)
+{
+	struct acpi_processor  *pr = performance[policy->cpu].pr;
+
+	ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_exit");
+
+	acpi_cpufreq_remove_file(pr);
+
+	return_VALUE(0);
+}
+
+
+static struct cpufreq_driver acpi_cpufreq_driver = {
+	.verify 	= acpi_cpufreq_verify,
+	.target 	= acpi_cpufreq_target,
+	.init		= acpi_cpufreq_cpu_init,
+	.exit		= acpi_cpufreq_cpu_exit,
+	.name		= "acpi-cpufreq",
+};
+
+
 static int __init
 acpi_cpufreq_init (void)
 {
 	int                     result = 0;
 	int                     current_state = 0;
 	int                     i = 0;
-	struct acpi_processor   *pr;
+	struct acpi_processor   *pr = NULL;
+	struct acpi_processor_performance *perf = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_init");
 
@@ -579,10 +640,9 @@
 	performance = kmalloc(NR_CPUS * sizeof(struct acpi_processor_performance), GFP_KERNEL);
 	if (!performance)
 		return_VALUE(-ENOMEM);
-
 	memset(performance, 0, NR_CPUS * sizeof(struct acpi_processor_performance));
 
-	/* register struct acpi_performance performance */
+	/* register struct acpi_processor_performance performance */
 	for (i=0; i<NR_CPUS; i++) {
 		if (cpu_online(i))
 			acpi_processor_register_performance(&performance[i], &pr, i);
@@ -591,11 +651,13 @@
 	/* initialize  */
 	for (i=0; i<NR_CPUS; i++) {
 		if (cpu_online(i) && performance[i].pr)
-			result = acpi_processor_get_performance_info(performance[i].pr);
+			result = acpi_processor_get_performance_info(&performance[i]);
 	}
 
 	/* test it on one CPU */
 	for (i=0; i<NR_CPUS; i++) {
+		if (cpu_online(i))
+			continue;
 		pr = performance[i].pr;
 		if (pr && pr->flags.performance)
 			goto found_capable_cpu;
@@ -604,10 +666,11 @@
 	goto err;
 
  found_capable_cpu:
-	current_state = pr->performance->state;
+	perf = pr->performance;
+	current_state = perf->state;
 
 	if (current_state == pr->limit.state.px) {
-		result = acpi_processor_set_performance(pr, (pr->performance->state_count - 1));
+		result = acpi_processor_set_performance(perf, (perf->state_count - 1));
 		if (result) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
 			result = -ENODEV;
@@ -615,7 +678,7 @@
 		}
 	}
 
-	result = acpi_processor_set_performance(pr, pr->limit.state.px);
+	result = acpi_processor_set_performance(perf, pr->limit.state.px);
 	if (result) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
 		result = -ENODEV;
@@ -623,7 +686,7 @@
 	}
 	
 	if (current_state != 0) {
-		result = acpi_processor_set_performance(pr, current_state);
+		result = acpi_processor_set_performance(perf, current_state);
 		if (result) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Disabled P-States due to failure while switching.\n"));
 			result = -ENODEV;
@@ -639,7 +702,7 @@
 
 	/* error handling */
  err:
-	/* unregister struct acpi_performance performance */
+	/* unregister struct acpi_processor_performance performance */
 	for (i=0; i<NR_CPUS; i++) {
 		if (performance[i].pr) {
 			performance[i].pr->flags.performance = 0;
@@ -647,9 +710,7 @@
 			performance[i].pr = NULL;
 		}
 	}
-
 	kfree(performance);
-
 	return_VALUE(result);
 }
 
@@ -668,7 +729,7 @@
 
 	 cpufreq_unregister_driver(&acpi_cpufreq_driver);
 
-	/* unregister struct acpi_performance performance */
+	/* unregister struct acpi_processor_performance performance */
 	for (i=0; i<NR_CPUS; i++) {
 		if (performance[i].pr) {
 			performance[i].pr->flags.performance = 0;
@@ -682,15 +743,6 @@
 	return_VOID;
 }
 
-static struct cpufreq_driver acpi_cpufreq_driver = {
-	.verify 	= acpi_cpufreq_verify,
-	.setpolicy	= acpi_cpufreq_setpolicy,
-	.init		= acpi_cpufreq_cpu_init,
-	.exit		= NULL,
-	.policy		= NULL,
-	.name		= "acpi-cpufreq",
-};
-
 
 late_initcall(acpi_cpufreq_init);
 module_exit(acpi_cpufreq_exit);
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/elanfreq.c linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/elanfreq.c
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/elanfreq.c	Mon Feb 24 11:05:16 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/elanfreq.c	Mon Mar 31 12:19:33 2003
@@ -31,15 +31,9 @@
 #define REG_CSCIR 0x22 		/* Chip Setup and Control Index Register    */
 #define REG_CSCDR 0x23		/* Chip Setup and Control Data  Register    */
 
-static struct cpufreq_driver *elanfreq_driver;
-
 /* Module parameter */
 static int max_freq;
 
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
-MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
-
 struct s_elan_multiplier {
 	int clock;		/* frequency in kHz                         */
 	int val40h;		/* PMU Force Mode register                  */
@@ -127,11 +121,6 @@
 
 	struct cpufreq_freqs    freqs;
 
-	if (!elanfreq_driver) {
-		printk(KERN_ERR "cpufreq: initialization problem or invalid target frequency\n");
-		return;
-	}
-
 	freqs.old = elanfreq_get_cpu_frequency();
 	freqs.new = elan_multiplier[state].clock;
 	freqs.cpu = 0; /* elanfreq.c is UP only driver */
@@ -187,11 +176,13 @@
 	return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]);
 }
 
-static int elanfreq_setpolicy (struct cpufreq_policy *policy)
+static int elanfreq_target (struct cpufreq_policy *policy, 
+			    unsigned int target_freq, 
+			    unsigned int relation)
 {
 	unsigned int    newstate = 0;
 
-	if (cpufreq_frequency_table_setpolicy(policy, &elanfreq_table[0], &newstate))
+	if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], target_freq, relation, &newstate))
 		return -EINVAL;
 
 	elanfreq_set_cpu_state(newstate);
@@ -204,6 +195,35 @@
  *	Module init and exit code
  */
 
+static int elanfreq_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *c = cpu_data;
+	unsigned int i;
+
+	/* capability check */
+	if ((c->x86_vendor != X86_VENDOR_AMD) ||
+	    (c->x86 != 4) || (c->x86_model!=10))
+		return -ENODEV;
+
+	/* max freq */
+	if (!max_freq)
+		max_freq = elanfreq_get_cpu_frequency();
+
+	/* table init */
+ 	for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+		if (elanfreq_table[i].frequency > max_freq)
+			elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+	}
+
+	/* cpuinfo and default policy values */
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cur = elanfreq_get_cpu_frequency();
+
+	return cpufreq_frequency_table_cpuinfo(policy, &elanfreq_table[0]);;
+}
+
+
 #ifndef MODULE
 /**
  * elanfreq_setup - elanfreq command line parameter parsing
@@ -224,11 +244,18 @@
 __setup("elanfreq=", elanfreq_setup);
 #endif
 
+
+static struct cpufreq_driver elanfreq_driver = {
+	.verify 	= elanfreq_verify,
+	.target 	= elanfreq_target,
+	.init		= elanfreq_cpu_init,
+	.name		= "elanfreq",
+};
+
+
 static int __init elanfreq_init(void) 
 {	
 	struct cpuinfo_x86 *c = cpu_data;
-	struct cpufreq_driver *driver;
-	int ret, i;
 
 	/* Test if we have the right hardware */
 	if ((c->x86_vendor != X86_VENDOR_AMD) ||
@@ -238,63 +265,22 @@
                 return -ENODEV;
 	}
 	
-	driver = kmalloc(sizeof(struct cpufreq_driver) +
-			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
-	if (!driver)
-		return -ENOMEM;
-	memset(driver, 0, sizeof(struct cpufreq_driver) +
-			NR_CPUS * sizeof(struct cpufreq_policy));
-
-	driver->policy = (struct cpufreq_policy *) (driver + 1);
-
-	if (!max_freq)
-		max_freq = elanfreq_get_cpu_frequency();
-
-	/* table init */
- 	for (i=0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if (elanfreq_table[i].frequency > max_freq)
-			elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
-	}
-
-#ifdef CONFIG_CPU_FREQ_24_API
-	driver->cpu_cur_freq[0] = elanfreq_get_cpu_frequency();
-#endif
-
-	driver->verify        = &elanfreq_verify;
-	driver->setpolicy     = &elanfreq_setpolicy;
-	strncpy(driver->name, "elanfreq", CPUFREQ_NAME_LEN);
-
-	driver->policy[0].cpu    = 0;
-	ret = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &elanfreq_table[0]);
-	if (ret) {
-		kfree(driver);
-		return ret;
-	}
-	driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
-	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-
-	elanfreq_driver = driver;
-
-	ret = cpufreq_register(driver);
-	if (ret) {
-		elanfreq_driver = NULL;
-		kfree(driver);
-	}
-
-	return ret;
+	return cpufreq_register_driver(&elanfreq_driver);
 }
 
 
 static void __exit elanfreq_exit(void) 
 {
-	if (elanfreq_driver) {
-		cpufreq_unregister();
-		kfree(elanfreq_driver);
-	}
+	cpufreq_unregister_driver(&elanfreq_driver);
 }
 
-module_init(elanfreq_init);
-module_exit(elanfreq_exit);
 
 MODULE_PARM (max_freq, "i");
 
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
+MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
+
+module_init(elanfreq_init);
+module_exit(elanfreq_exit);
+
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	Mon Feb 24 11:05:32 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	Mon Mar 31 12:19:33 2003
@@ -116,7 +116,6 @@
 	struct pci_dev *cs55x0;
 };
 
-static struct cpufreq_driver *gx_driver;
 static struct gxfreq_params *gx_params;
 static int stock_freq;
 
@@ -345,7 +344,7 @@
 	unsigned int tmp_freq = 0;
 	u8 tmp1, tmp2;
 
-        if (!gx_driver || !stock_freq || !policy)
+        if (!stock_freq || !policy)
                 return -EINVAL;
 
 	policy->cpu = 0;
@@ -375,33 +374,71 @@
 }
 
 /*
- *      cpufreq_gx_setpolicy:  
+ *      cpufreq_gx_target:  
  *
  */
-static int cpufreq_gx_setpolicy(struct cpufreq_policy *policy)
+static int cpufreq_gx_target(struct cpufreq_policy *policy,
+			     unsigned int target_freq,
+			     unsigned int relation)
 {
+	u8 tmp1, tmp2;
+	unsigned int tmp_freq;
 
-        if (!gx_driver || !stock_freq || !policy)
+        if (!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);
+	tmp_freq = gx_validate_speed(target_freq, &tmp1, &tmp2);
+	while (tmp_freq < policy->min) {
+		tmp_freq += stock_freq / max_duration;
+		tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
+	}
+	while (tmp_freq > policy->max) {
+		tmp_freq -= stock_freq / max_duration;
+		tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
+	}
+
+	gx_set_cpuspeed(tmp_freq);
+
+	return 0;
+}
+
+static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
+{
+	int maxfreq, curfreq;
+
+	if (!policy || policy->cpu != 0)
+		return -ENODEV;
+
+	/* determine maximum frequency */
+	if (pci_busclk) {
+		maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
+	} else if (cpu_khz) {
+		maxfreq = cpu_khz;
 	} else {
-		gx_set_cpuspeed(policy->max);
+		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 */
+	policy->cpu = 0;
+
+	if (max_duration < POLICY_MIN_DIV)
+		policy->min = maxfreq / max_duration;
+	else
+		policy->min = maxfreq / POLICY_MIN_DIV;
+	policy->max = maxfreq;
+	policy->cur = curfreq;
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cpuinfo.min_freq = maxfreq / max_duration;
+	policy->cpuinfo.max_freq = maxfreq;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+
 	return 0;
 }
 
@@ -409,11 +446,16 @@
  * cpufreq_gx_init:
  *   MediaGX/Geode GX initilize cpufreq driver
  */
+static struct cpufreq_driver gx_suspmod_driver = {
+	.verify		= cpufreq_gx_verify,
+	.target		= cpufreq_gx_target,
+	.init		= cpufreq_gx_cpu_init,
+	.name		= "gx-suspmod",
+};
 
 static int __init cpufreq_gx_init(void)
 {
-	int maxfreq,ret,curfreq;
- 	struct cpufreq_driver *driver;
+	int ret;
 	struct gxfreq_params *params;
 	struct pci_dev *gx_pci;
 	u32 class_rev;
@@ -428,21 +470,13 @@
 
 	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;
-	memset(driver, 0, sizeof(struct cpufreq_driver) +
-			NR_CPUS * sizeof(struct cpufreq_policy));
-
 	params = kmalloc(sizeof(struct gxfreq_params), GFP_KERNEL);
-	if (params == NULL) {
-		kfree(driver);
+	if (params == NULL)
 		return -ENOMEM;
-	}
 	memset(params, 0, sizeof(struct gxfreq_params));
 
-	driver->policy = (struct cpufreq_policy *)(driver + 1);
 	params->cs55x0 = gx_pci;
+	gx_params = params;
 
 	/* keep cs55x0 configurations */
 	pci_read_config_byte(params->cs55x0, PCI_SUSCFG, &(params->pci_suscfg));
@@ -453,45 +487,7 @@
         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;
-	strncpy(driver->name, "gx-suspmod", CPUFREQ_NAME_LEN);
-
-	gx_driver = driver;
-
-	if ((ret = cpufreq_register(driver))) { 
-		kfree(driver);
+	if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) { 
 		kfree(params);
 		return ret;                   /* register error! */
 	}
@@ -501,13 +497,8 @@
 
 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);
-	}
+	cpufreq_unregister_driver(&gx_suspmod_driver);
+	kfree(gx_params);
 }
 
 MODULE_AUTHOR ("Hiroshi Miura <miura@da-cha.org>");
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/longhaul.c linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/longhaul.c
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/longhaul.c	Mon Feb 24 11:05:06 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/longhaul.c	Mon Mar 31 12:19:33 2003
@@ -1,5 +1,5 @@
 /*
- *  $Id: longhaul.c,v 1.77 2002/10/31 21:17:40 db Exp $
+ *  $Id: longhaul.c,v 1.87 2003/02/22 10:23:46 db Exp $
  *
  *  (C) 2001  Dave Jones. <davej@suse.de>
  *  (C) 2002  Padraig Brady. <padraig@antefacto.com>
@@ -48,6 +48,7 @@
 
 
 /* Module parameters */
+static int prefer_slow_fsb;
 static int dont_scale_voltage;
 static int dont_scale_fsb;
 static int current_fsb;
@@ -237,7 +238,6 @@
 /* fsb values to favour high fsb speed (for e.g. if lowering CPU 
    freq because of heat, but want to maintain highest performance possible) */
 static unsigned int perf_fsb_table[] = { 133, 100, 66, -1 };
-static unsigned int *fsb_search_table;
 
 /* Voltage scales. Div by 1000 to get actual voltage. */
 static int __initdata vrm85scales[32] = {
@@ -260,7 +260,7 @@
 static int voltage_table[32];
 static int highest_speed, lowest_speed; /* kHz */
 static int longhaul; /* version. */
-static struct cpufreq_driver *longhaul_driver;
+static struct cpufreq_frequency_table *longhaul_table;
 
 
 static int longhaul_get_cpu_fsb (void)
@@ -428,7 +428,7 @@
 }
 
 
-static void __init longhaul_get_ranges (void)
+static int __init longhaul_get_ranges (void)
 {
 	unsigned long lo, hi, invalue;
 	unsigned int minmult=0, maxmult=0, minfsb=0, maxfsb=0;
@@ -436,6 +436,9 @@
 		50,30,40,100,55,35,45,95,90,70,80,60,120,75,85,65,
 		-1,110,120,-1,135,115,125,105,130,150,160,140,-1,155,-1,145 };
 	unsigned int fsb_table[4] = { 133, 100, -1, 66 };
+	unsigned int fsbcount = 1;
+	unsigned int i, j, k = 0;
+	static unsigned int *fsb_search_table;
 
 	switch (longhaul) {
 	case 1:
@@ -472,6 +475,11 @@
 
 			dprintk (KERN_INFO "longhaul: Min FSB=%d Max FSB=%d\n",
 				minfsb, maxfsb);
+			fsbcount = 0;
+			for (i=0;i<4;i++) {
+				if((fsb_table[i] >= minfsb) && (fsb_table[i] <= maxfsb))
+					fsbcount++;
+			}
 		} else {
 			minfsb = maxfsb = current_fsb;
 		}
@@ -480,11 +488,37 @@
 
 	highest_speed = maxmult * maxfsb * 100;
 	lowest_speed = minmult * minfsb * 100;
-
 	dprintk (KERN_INFO "longhaul: MinMult(x10)=%d MaxMult(x10)=%d\n",
-		minmult, maxmult);
+		 minmult, maxmult);
 	dprintk (KERN_INFO "longhaul: Lowestspeed=%d Highestspeed=%d\n",
-		lowest_speed, highest_speed);
+		 lowest_speed, highest_speed);
+
+	longhaul_table = kmalloc((numscales * fsbcount + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
+	if(!longhaul_table)
+		return -ENOMEM;
+
+	if (prefer_slow_fsb) 
+		fsb_search_table = perf_fsb_table;   // yep, this is right: the last entry is preferred by cpufreq_frequency_table_* ...
+	else
+		fsb_search_table = power_fsb_table;
+
+	for (i=0; (i<4); i++) {
+		if ((fsb_search_table[i] > maxfsb) || (fsb_search_table[i] < minfsb) || (fsb_search_table[i] == -1))
+			continue;
+		for (j=0; (j<numscales); j++) {
+			if ((clock_ratio[j] > maxmult) || (clock_ratio[j] < minmult) || (clock_ratio[j] == -1))
+				continue;
+			longhaul_table[k].frequency= clock_ratio[j] * fsb_search_table[i] * 100;
+			longhaul_table[k].index	= (j << 8) | (i);
+			k++;
+		}
+	}
+	
+	longhaul_table[k].frequency = CPUFREQ_TABLE_END;
+	if (!k)
+		return -EINVAL;
+	
+	return 0;
 }
 
 
@@ -523,182 +557,34 @@
 }
 
 
-static inline unsigned int longhaul_statecount_fsb(struct cpufreq_policy *policy, unsigned int fsb) {
-	unsigned int i, count = 0;
-
-	for(i=0; i<numscales; i++) {
-		if ((clock_ratio[i] != -1) &&
-		    ((clock_ratio[i] * fsb * 100) <= policy->max) &&
-		    ((clock_ratio[i] * fsb * 100) >= policy->min))
-			count++;
-	}
-
-	return count;
-}
-
-
 static int longhaul_verify(struct cpufreq_policy *policy)
 {
-	unsigned int    number_states = 0;
-	unsigned int    i;
-	unsigned int    fsb_index = 0;
-	unsigned int    tmpfreq = 0;
-	unsigned int    newmax = -1;
-
-	if (!policy || !longhaul_driver)
-		return -EINVAL;
-
-	policy->cpu = 0;
-	cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
-
-	if (can_scale_fsb==1) {
-		for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++)
-			number_states += longhaul_statecount_fsb(policy, fsb_search_table[fsb_index]);
-	} else
-		number_states = longhaul_statecount_fsb(policy, current_fsb);
-
-	if (number_states)
-		return 0;
-
-	/* get frequency closest above current policy->max */
-	if (can_scale_fsb==1) {
-		for (fsb_index=0; fsb_search_table[fsb_index] != -1; fsb_index++)
-			for(i=0; i<numscales; i++) {
-				if (clock_ratio[i] == -1)
-					continue;
-
-				tmpfreq = clock_ratio[i] * fsb_search_table[fsb_index];
-				if ((tmpfreq > policy->max) &&
-				    (tmpfreq < newmax))
-					newmax = tmpfreq;
-			}
-	} else {
-		for(i=0; i<numscales; i++) {
-			if (clock_ratio[i] == -1)
-				continue;
-
-			tmpfreq = clock_ratio[i] * current_fsb;
-			if ((tmpfreq > policy->max) &&
-			    (tmpfreq < newmax))
-				newmax = tmpfreq;
-			}
-	}
-
-	policy->max = newmax;
-
-	cpufreq_verify_within_limits(policy, lowest_speed, highest_speed);
-
-	return 0;
-}
-
-
-static int longhaul_get_best_freq_for_fsb(struct cpufreq_policy *policy, 
-					  unsigned int min_mult, 
-					  unsigned int max_mult, 
-					  unsigned int fsb, 
-					  unsigned int *new_mult)
-{
-	unsigned int optimal = 0;
-	unsigned int found_optimal = 0;
-	unsigned int i;
-
-	switch(policy->policy) {
-	case CPUFREQ_POLICY_POWERSAVE:
-		optimal = max_mult;
-		break;
-	case CPUFREQ_POLICY_PERFORMANCE:
-		optimal = min_mult;
-	}
-
-	for(i=0; i<numscales; i++) {
-		unsigned int freq = fsb * clock_ratio[i] * 100;
-		if ((freq > policy->max) ||
-		    (freq < policy->min))
-			continue;
-		switch(policy->policy) {
-		case CPUFREQ_POLICY_POWERSAVE:
-			if (clock_ratio[i] < clock_ratio[optimal]) {
-				found_optimal = 1;
-				optimal = i;
-			}
-			break;
-		case CPUFREQ_POLICY_PERFORMANCE:
-			if (clock_ratio[i] > clock_ratio[optimal]) {
-				found_optimal = 1;
-				optimal = i;
-			}
-			break;
-		}
-	}
-		
-	if (found_optimal) {
-		*new_mult = optimal;
-		return 1;
-	}
-	return 0;
+	return cpufreq_frequency_table_verify(policy, longhaul_table);
 }
 
 
-static int longhaul_setpolicy (struct cpufreq_policy *policy)
+static int longhaul_target (struct cpufreq_policy *policy,
+			    unsigned int target_freq,
+			    unsigned int relation)
 {
-	unsigned int    i;
-	unsigned int    fsb_index = 0;
-	unsigned int    new_fsb = 0;
-	unsigned int    new_clock_ratio = 0;
-	unsigned int    min_mult = 0;
-	unsigned int    max_mult = 0;
-
+	unsigned int    table_index = 0;
+ 	unsigned int    new_fsb = 0;
+ 	unsigned int    new_clock_ratio = 0;
 
-	if (!longhaul_driver)
+	if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index))
 		return -EINVAL;
 
-	if (policy->policy==CPUFREQ_POLICY_PERFORMANCE)
-		fsb_search_table = perf_fsb_table;
-	else
-		fsb_search_table = power_fsb_table;
-
-	for(i=0;i<numscales;i++) {
-		if (clock_ratio[max_mult] < clock_ratio[i])
-				max_mult = i;
-		else if (clock_ratio[min_mult] > clock_ratio[i])
-				min_mult = i;
-	}
-
-	if (can_scale_fsb==1) {
-		unsigned int found = 0;
-		for (fsb_index=0; fsb_search_table[fsb_index]!=-1; fsb_index++)
-		{
-			if (longhaul_get_best_freq_for_fsb(policy, 
-			              min_mult, max_mult, 
-				      fsb_search_table[fsb_index], 
-				      &new_clock_ratio)) {
-				new_fsb = fsb_search_table[fsb_index];
-				break;
-			}
-		}
-		if (!found)
-			return -EINVAL;
-	} else {
-		new_fsb = current_fsb;
-		if (!longhaul_get_best_freq_for_fsb(policy, min_mult, 
-			     max_mult, new_fsb, &new_clock_ratio))
-			return -EINVAL;
-	}
-
+	new_clock_ratio = longhaul_table[table_index].index & 0xFF;
+	new_fsb = power_fsb_table[(longhaul_table[table_index].index & 0xFF00) >> 8];
+ 
 	longhaul_setstate(new_clock_ratio, new_fsb);
 
 	return 0;
 }
 
-
-static int __init longhaul_init (void)
+static int longhaul_cpu_init (struct cpufreq_policy *policy)
 {
 	struct cpuinfo_x86 *c = cpu_data;
-	unsigned int currentspeed;
-	static int currentmult;
-	unsigned long lo, hi;
-	int ret;
-	struct cpufreq_driver *driver;
 
 	if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) )
 		return -ENODEV;
@@ -733,21 +619,12 @@
 		memcpy (eblcr_table, c5m_eblcr, sizeof(c5m_eblcr));
 		break;
 
-	default:
-		printk (KERN_INFO "longhaul: Unknown VIA CPU. Contact davej@suse.de\n");
-		return -ENODEV;
 	}
 
 	printk (KERN_INFO "longhaul: VIA CPU detected. Longhaul version %d supported\n", longhaul);
 
-	current_fsb = longhaul_get_cpu_fsb();
-	currentmult = longhaul_get_cpu_mult();
-	currentspeed = currentmult * current_fsb * 100;
-
-	dprintk (KERN_INFO "longhaul: CPU currently at %dMHz (%d x %d.%d)\n",
-		(currentspeed/1000), current_fsb, currentmult/10, currentmult%10);
-
 	if (longhaul==2 || longhaul==3) {
+		unsigned long lo, hi;
 		rdmsr (MSR_VIA_LONGHAUL, lo, hi);
 		if ((lo & (1<<0)) && (dont_scale_voltage==0))
 			longhaul_setup_voltagescaling (lo, hi);
@@ -756,57 +633,53 @@
 			can_scale_fsb = 1;
 	}
 
-	longhaul_get_ranges();
-
-	driver = kmalloc(sizeof(struct cpufreq_driver) + 
-			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
-	if (!driver)
+	if (longhaul_get_ranges())
 		return -ENOMEM;
-	memset(driver, 0, sizeof(struct cpufreq_driver) +
-			NR_CPUS * sizeof(struct cpufreq_policy));
 
-	driver->policy = (struct cpufreq_policy *) (driver + 1);
+ 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+ 	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 
-#ifdef CONFIG_CPU_FREQ_24_API
-	driver->cpu_cur_freq[0] = currentspeed;
-#endif
+        policy->cur = (unsigned int) (longhaul_get_cpu_fsb() * longhaul_get_cpu_mult() * 100);
+
+	return cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
+}
+
+static struct cpufreq_driver longhaul_driver = {
+	.verify 	= longhaul_verify,
+	.target 	= longhaul_target,
+	.init		= longhaul_cpu_init,
+	.name		= "longhaul",
+};
 
-	driver->verify    = &longhaul_verify;
-	driver->setpolicy = &longhaul_setpolicy;
+static int __init longhaul_init (void)
+{
+	struct cpuinfo_x86 *c = cpu_data;
 
-	strncpy(driver->name, "longhaul", CPUFREQ_NAME_LEN);
+	if ((c->x86_vendor != X86_VENDOR_CENTAUR) || (c->x86 !=6) )
+		return -ENODEV;
 
-	driver->policy[0].cpu = 0;
-	driver->policy[0].min = (unsigned int) lowest_speed;
-	driver->policy[0].max = (unsigned int) highest_speed;
-	driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
-	driver->policy[0].cpuinfo.min_freq = (unsigned int) lowest_speed;
-	driver->policy[0].cpuinfo.max_freq = (unsigned int) highest_speed;
-	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-
-	longhaul_driver = driver;
-
-	ret = cpufreq_register(driver);
-	if (ret) {
-		longhaul_driver = NULL;
-		kfree(driver);
+	switch (c->x86_model) {
+	case 6 ... 7:
+		return cpufreq_register_driver(&longhaul_driver);
+	case 8:
+		return -ENODEV;
+	default:
+		printk (KERN_INFO "longhaul: Unknown VIA CPU. Contact davej@suse.de\n");
 	}
 
-	return ret;
+	return -ENODEV;
 }
 
-
 static void __exit longhaul_exit (void)
 {
-	if (longhaul_driver) {
-		cpufreq_unregister();
-		kfree(longhaul_driver);
-	}
+	cpufreq_unregister_driver(&longhaul_driver);
+	kfree(longhaul_table);
 }
 
 MODULE_PARM (dont_scale_fsb, "i");
 MODULE_PARM (dont_scale_voltage, "i");
 MODULE_PARM (current_fsb, "i");
+MODULE_PARM (prefer_slow_fsb, "i");
 
 MODULE_AUTHOR ("Dave Jones <davej@suse.de>");
 MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/longrun.c linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/longrun.c
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/longrun.c	Mon Mar 31 12:19:30 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/longrun.c	Mon Mar 31 12:19:33 2003
@@ -1,5 +1,5 @@
 /*
- *  $Id: longrun.c,v 1.22 2003/02/10 17:31:50 db Exp $
+ *  $Id: longrun.c,v 1.25 2003/02/28 16:03:50 db Exp $
  *
  * (C) 2002 - 2003  Dominik Brodowski <linux@brodo.de>
  *
@@ -244,10 +244,6 @@
 	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 	longrun_get_policy(policy);
 	
-#ifdef CONFIG_CPU_FREQ_24_API
-	longrun_driver.cpu_cur_freq[policy->cpu] = longrun_low_freq; /* dummy value */
-#endif
-
 	return 0;
 }
 
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Mon Feb 24 11:05:43 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Mon Mar 31 12:19:33 2003
@@ -49,8 +49,6 @@
 static int has_N44_O17_errata[NR_CPUS];
 static int stock_freq;
 
-static struct cpufreq_driver p4clockmod_driver;
-
 
 static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
 {
@@ -220,9 +218,7 @@
 	/* cpuinfo and default policy values */
 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.transition_latency = 1000;
-#ifdef CONFIG_CPU_FREQ_24_API
-	p4clockmod_driver.cpu_cur_freq[policy->cpu] = stock_freq;
-#endif
+	policy->cur = stock_freq;
 
 	return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]);
 }
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/powernow-k6.c linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Mon Feb 24 11:05:09 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Mon Mar 31 12:19:33 2003
@@ -1,9 +1,9 @@
 /*
- *  $Id: powernow-k6.c,v 1.36 2002/10/31 21:17:40 db Exp $
+ *  $Id: powernow-k6.c,v 1.48 2003/02/22 10:23:46 db Exp $
  *  This file was part of Powertweak Linux (http://powertweak.sf.net)
  *  and is shared with the Linux Kernel module.
  *
- *  (C) 2000-2002  Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
+ *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
  *
  *  Licensed under the terms of the GNU GPL License version 2.
  *
@@ -25,7 +25,6 @@
 #define POWERNOW_IOPORT 0xfff0         /* it doesn't matter where, as long
 					  as it is unused */
 
-static struct cpufreq_driver		*powernow_driver;
 static unsigned int                     busfreq;   /* FSB, in 10 kHz */
 static unsigned int                     max_multiplier;
 
@@ -77,8 +76,8 @@
 	unsigned long           msrval;
 	struct cpufreq_freqs    freqs;
 
-	if (!powernow_driver) {
-		printk(KERN_ERR "cpufreq: initialization problem or invalid target frequency\n");
+	if (clock_ratio[best_i].index > max_multiplier) {
+		printk(KERN_ERR "cpufreq: invalid target frequency\n");
 		return;
 	}
 
@@ -126,11 +125,13 @@
  *
  * sets a new CPUFreq policy
  */
-static int powernow_k6_setpolicy (struct cpufreq_policy *policy)
+static int powernow_k6_target (struct cpufreq_policy *policy,
+			       unsigned int target_freq,
+			       unsigned int relation)
 {
 	unsigned int    newstate = 0;
 
-	if (cpufreq_frequency_table_setpolicy(policy, &clock_ratio[0], &newstate))
+	if (cpufreq_frequency_table_target(policy, &clock_ratio[0], target_freq, relation, &newstate))
 		return -EINVAL;
 
 	powernow_k6_set_state(newstate);
@@ -139,6 +140,59 @@
 }
 
 
+static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *c = cpu_data;
+	unsigned int i;
+
+	/* capability check */
+	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
+	    ((c->x86_model != 12) && (c->x86_model != 13)))
+		return -ENODEV;
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	/* get frequencies */
+	max_multiplier = powernow_k6_get_cpu_multiplier();
+	busfreq = cpu_khz / max_multiplier;
+
+	/* table init */
+ 	for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
+		if (clock_ratio[i].index > max_multiplier)
+			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
+		else
+			clock_ratio[i].frequency = busfreq * clock_ratio[i].index;
+	}
+
+	/* cpuinfo and default policy values */
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cur = busfreq * max_multiplier;
+
+	return cpufreq_frequency_table_cpuinfo(policy, &clock_ratio[0]);
+}
+
+
+static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
+{
+	unsigned int i;
+	for (i=0; i<8; i++) {
+		if (i==max_multiplier)
+			powernow_k6_set_state(i);
+	}
+	return 0;
+}
+
+
+static struct cpufreq_driver powernow_k6_driver = {
+	.verify 	= powernow_k6_verify,
+	.target 	= powernow_k6_target,
+	.init		= powernow_k6_cpu_init,
+	.exit		= powernow_k6_cpu_exit,
+	.name		= "powernow-k6",
+};
+
+
 /**
  * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
  *
@@ -149,68 +203,22 @@
 static int __init powernow_k6_init(void)
 {	
 	struct cpuinfo_x86      *c = cpu_data;
-	struct cpufreq_driver   *driver;
-	unsigned int            result;
-	unsigned int            i;
 
 	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
 		((c->x86_model != 12) && (c->x86_model != 13)))
 		return -ENODEV;
 
-	max_multiplier = powernow_k6_get_cpu_multiplier();
-	busfreq = cpu_khz / max_multiplier;
-
 	if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
 		printk("cpufreq: PowerNow IOPORT region already used.\n");
 		return -EIO;
 	}
 
-	/* initialization of main "cpufreq" code*/
-	driver = kmalloc(sizeof(struct cpufreq_driver) +
-			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
-	if (!driver) {
+	if (cpufreq_register_driver(&powernow_k6_driver)) {
 		release_region (POWERNOW_IOPORT, 16);
-		return -ENOMEM;
-	}
-	memset(driver, 0, sizeof(struct cpufreq_driver) +
-			NR_CPUS * sizeof(struct cpufreq_policy));
-	driver->policy = (struct cpufreq_policy *) (driver + 1);
-
-	/* table init */
- 	for (i=0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if (clock_ratio[i].index > max_multiplier)
-			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
-		else
-			clock_ratio[i].frequency = busfreq * clock_ratio[i].index;
-	}
-
-	driver->verify        = &powernow_k6_verify;
-	driver->setpolicy     = &powernow_k6_setpolicy;
-	strncpy(driver->name, "powernow-k6", CPUFREQ_NAME_LEN);
-
-	/* cpuinfo and default policy values */
-	driver->policy[0].cpu    = 0;
-	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-	driver->policy[0].policy = CPUFREQ_POLICY_PERFORMANCE;
-#ifdef CONFIG_CPU_FREQ_24_API
-	driver->cpu_cur_freq[0]  = busfreq * max_multiplier;
-#endif
-	result = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &clock_ratio[0]);
-	if (result) {
-		kfree(driver);
-		return result;
-	}
-
-	powernow_driver = driver;
-
-	result = cpufreq_register(driver);
-	if (result) {
-		release_region (POWERNOW_IOPORT, 16);
-		powernow_driver = NULL;
-		kfree(driver);
+		return -EINVAL;
 	}
 
-	return result;
+	return 0;
 }
 
 
@@ -221,20 +229,14 @@
  */
 static void __exit powernow_k6_exit(void)
 {
-	unsigned int i;
-
-	if (powernow_driver) {
-		for (i=0;i<8;i++)
-			if (clock_ratio[i].index == max_multiplier)
-				powernow_k6_set_state(i);		
-		cpufreq_unregister();
-		kfree(powernow_driver);
-	}
+	cpufreq_unregister_driver(&powernow_k6_driver);
+	release_region (POWERNOW_IOPORT, 16);
 }
 
 
 MODULE_AUTHOR ("Arjan van de Ven <arjanv@redhat.com>, Dave Jones <davej@suse.de>, Dominik Brodowski <linux@brodo.de>");
 MODULE_DESCRIPTION ("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
 MODULE_LICENSE ("GPL");
+
 module_init(powernow_k6_init);
 module_exit(powernow_k6_exit);
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/powernow-k7.c linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	Mon Mar 31 12:19:33 2003
@@ -1,5 +1,5 @@
 /*
- *  $Id: powernow-k7.c,v 1.31 2003/02/12 21:16:35 davej Exp $
+ *  $Id: powernow-k7.c,v 1.34 2003/02/22 10:23:46 db Exp $
  *
  *  (C) 2003 Dave Jones <davej@suse.de>
  *
@@ -72,8 +72,6 @@
     150, 225, 160, 165, 170, 180, -1, -1,
 };
 
-static struct cpufreq_driver powernow_driver;
-
 static struct cpufreq_frequency_table *powernow_table;
 
 static unsigned int can_scale_bus;
@@ -369,13 +367,18 @@
 
 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.transition_latency = latency;
-#ifdef CONFIG_CPU_FREQ_24_API
-	powernow_driver.cpu_cur_freq[policy->cpu] = maximum_speed;
-#endif
+	policy->cur = maximum_speed;
 
 	return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
 }
 
+static struct cpufreq_driver powernow_driver = {
+	.verify 	= powernow_verify,
+	.target 	= powernow_target,
+	.init		= powernow_cpu_init,
+	.name		= "powernow-k7",
+};
+
 static int __init powernow_init (void)
 {
 	if (check_powernow()==0)
@@ -391,14 +394,6 @@
 		kfree(powernow_table);
 }
 
-static struct cpufreq_driver powernow_driver = {
-	.verify 	= powernow_verify,
-	.target 	= powernow_target,
-	.init		= powernow_cpu_init,
-	.name		= "powernow-k7",
-};
-
-
 MODULE_AUTHOR ("Dave Jones <davej@suse.de>");
 MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
 MODULE_LICENSE ("GPL");
diff -urN linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/speedstep.c linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/speedstep.c
--- linux-2.5.63-bk5/arch/i386/kernel/cpu/cpufreq/speedstep.c	Mon Feb 24 11:05:04 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/cpu/cpufreq/speedstep.c	Mon Mar 31 12:19:33 2003
@@ -1,5 +1,5 @@
 /*
- *  $Id: speedstep.c,v 1.68 2003/01/20 17:31:47 db Exp $
+ *  $Id: speedstep.c,v 1.70 2003/02/22 10:23:46 db Exp $
  *
  * (C) 2001  Dave Jones, Arjan van de ven.
  * (C) 2002 - 2003  Dominik Brodowski <linux@brodo.de>
@@ -30,8 +30,6 @@
 #include <asm/msr.h>
 
 
-static struct cpufreq_driver		speedstep_driver;
-
 /* speedstep_chipset:
  *   It is necessary to know which chipset is used. As accesses to 
  * this device occur at various places in this module, we need a 
@@ -629,9 +627,7 @@
 	policy->policy = (speed == speedstep_low_freq) ? 
 		CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-#ifdef CONFIG_CPU_FREQ_24_API
-	speedstep_driver.cpu_cur_freq[policy->cpu] = speed;
-#endif
+	policy->cur = speed;
 
 	return cpufreq_frequency_table_cpuinfo(policy, &speedstep_freqs[0]);
 }
@@ -686,7 +682,7 @@
 		return -ENODEV;
 	}
 
-	dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.68 $\n");
+	dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.70 $\n");
 
 	/* activate speedstep support */
 	if (speedstep_activate())
diff -urN linux-2.5.63-bk5/arch/i386/kernel/io_apic.c linux-2.5.63-bk6/arch/i386/kernel/io_apic.c
--- linux-2.5.63-bk5/arch/i386/kernel/io_apic.c	Mon Mar 31 12:19:30 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/io_apic.c	Mon Mar 31 12:19:33 2003
@@ -1376,8 +1376,7 @@
 
 void print_all_local_APICs (void)
 {
-	smp_call_function(print_local_APIC, NULL, 1, 1);
-	print_local_APIC(NULL);
+	on_each_cpu(print_local_APIC, NULL, 1, 1);
 }
 
 void /*__init*/ print_PIC(void)
@@ -1843,8 +1842,7 @@
 	 */ 
 	printk(KERN_INFO "activating NMI Watchdog ...");
 
-	smp_call_function(enable_NMI_through_LVT0, NULL, 1, 1);
-	enable_NMI_through_LVT0(NULL);
+	on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1);
 
 	printk(" done.\n");
 }
diff -urN linux-2.5.63-bk5/arch/i386/kernel/ldt.c linux-2.5.63-bk6/arch/i386/kernel/ldt.c
--- linux-2.5.63-bk5/arch/i386/kernel/ldt.c	Mon Feb 24 11:05:38 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/ldt.c	Mon Mar 31 12:19:33 2003
@@ -55,12 +55,14 @@
 	wmb();
 
 	if (reload) {
-		load_LDT(pc);
 #ifdef CONFIG_SMP
 		preempt_disable();
+		load_LDT(pc);
 		if (current->mm->cpu_vm_mask != (1 << smp_processor_id()))
 			smp_call_function(flush_ldt, 0, 1, 1);
 		preempt_enable();
+#else
+		load_LDT(pc);
 #endif
 	}
 	if (oldsize) {
diff -urN linux-2.5.63-bk5/arch/i386/kernel/microcode.c linux-2.5.63-bk6/arch/i386/kernel/microcode.c
--- linux-2.5.63-bk5/arch/i386/kernel/microcode.c	Mon Feb 24 11:05:12 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/microcode.c	Mon Mar 31 12:19:33 2003
@@ -183,11 +183,10 @@
 	int i, error = 0, err;
 	struct microcode *m;
 
-	if (smp_call_function(do_update_one, NULL, 1, 1) != 0) {
+	if (on_each_cpu(do_update_one, NULL, 1, 1) != 0) {
 		printk(KERN_ERR "microcode: IPI timeout, giving up\n");
 		return -EIO;
 	}
-	do_update_one(NULL);
 
 	for (i=0; i<NR_CPUS; i++) {
 		err = update_req[i].err;
diff -urN linux-2.5.63-bk5/arch/i386/kernel/mpparse.c linux-2.5.63-bk6/arch/i386/kernel/mpparse.c
--- linux-2.5.63-bk5/arch/i386/kernel/mpparse.c	Mon Mar 31 12:19:30 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/mpparse.c	Mon Mar 31 12:19:33 2003
@@ -631,7 +631,7 @@
 	else if (acpi_lapic)
 		printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n");
 
-	printk("KERN_INFO Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
+	printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
 	if (mpf->mpf_feature2 & (1<<7)) {
 		printk(KERN_INFO "    IMCR and PIC compatibility mode.\n");
 		pic_mode = 1;
diff -urN linux-2.5.63-bk5/arch/i386/kernel/smp.c linux-2.5.63-bk6/arch/i386/kernel/smp.c
--- linux-2.5.63-bk5/arch/i386/kernel/smp.c	Mon Feb 24 11:05:06 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/smp.c	Mon Mar 31 12:19:33 2003
@@ -436,7 +436,7 @@
 	preempt_enable();
 }
 
-static inline void do_flush_tlb_all_local(void)
+static void do_flush_tlb_all(void* info)
 {
 	unsigned long cpu = smp_processor_id();
 
@@ -445,18 +445,9 @@
 		leave_mm(cpu);
 }
 
-static void flush_tlb_all_ipi(void* info)
-{
-	do_flush_tlb_all_local();
-}
-
 void flush_tlb_all(void)
 {
-	preempt_disable();
-	smp_call_function (flush_tlb_all_ipi,0,1,1);
-
-	do_flush_tlb_all_local();
-	preempt_enable();
+	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
 }
 
 /*
diff -urN linux-2.5.63-bk5/arch/i386/kernel/sysenter.c linux-2.5.63-bk6/arch/i386/kernel/sysenter.c
--- linux-2.5.63-bk5/arch/i386/kernel/sysenter.c	Mon Feb 24 11:06:02 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/sysenter.c	Mon Mar 31 12:19:33 2003
@@ -95,8 +95,7 @@
 		return 0;
 
 	memcpy((void *) page, sysent, sizeof(sysent));
-	enable_sep_cpu(NULL);
-	smp_call_function(enable_sep_cpu, NULL, 1, 1);
+	on_each_cpu(enable_sep_cpu, NULL, 1, 1);
 	return 0;
 }
 
diff -urN linux-2.5.63-bk5/arch/i386/kernel/timers/timer_tsc.c linux-2.5.63-bk6/arch/i386/kernel/timers/timer_tsc.c
--- linux-2.5.63-bk5/arch/i386/kernel/timers/timer_tsc.c	Mon Mar 31 12:19:30 2003
+++ linux-2.5.63-bk6/arch/i386/kernel/timers/timer_tsc.c	Mon Mar 31 12:19:33 2003
@@ -299,6 +299,7 @@
 	return -ENODEV;
 }
 
+#ifndef CONFIG_X86_TSC
 /* disable flag for tsc.  Takes effect by clearing the TSC cpu flag
  * in cpu/common.c */
 static int __init tsc_setup(char *str)
@@ -306,7 +307,14 @@
 	tsc_disable = 1;
 	return 1;
 }
-
+#else
+static int __init tsc_setup(char *str)
+{
+	printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, "
+				"cannot disable TSC.\n");
+	return 1;
+}
+#endif
 __setup("notsc", tsc_setup);
 
 
diff -urN linux-2.5.63-bk5/arch/i386/mach-voyager/voyager_smp.c linux-2.5.63-bk6/arch/i386/mach-voyager/voyager_smp.c
--- linux-2.5.63-bk5/arch/i386/mach-voyager/voyager_smp.c	Mon Mar 31 12:19:30 2003
+++ linux-2.5.63-bk6/arch/i386/mach-voyager/voyager_smp.c	Mon Mar 31 12:19:33 2003
@@ -1209,8 +1209,8 @@
 		smp_call_function_interrupt();
 }
 
-static inline void
-do_flush_tlb_all_local(void)
+static void
+do_flush_tlb_all(void* info)
 {
 	unsigned long cpu = smp_processor_id();
 
@@ -1220,20 +1220,11 @@
 }
 
 
-static void
-flush_tlb_all_function(void* info)
-{
-	do_flush_tlb_all_local();
-}
-
 /* flush the TLB of every active CPU in the system */
 void
 flush_tlb_all(void)
 {
-	preempt_disable();
-	smp_call_function (flush_tlb_all_function, 0, 1, 1);
-	do_flush_tlb_all_local();
-	preempt_enable();
+	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
 }
 
 /* used to set up the trampoline for other CPUs when the memory manager
diff -urN linux-2.5.63-bk5/arch/i386/mm/pageattr.c linux-2.5.63-bk6/arch/i386/mm/pageattr.c
--- linux-2.5.63-bk5/arch/i386/mm/pageattr.c	Mon Feb 24 11:05:29 2003
+++ linux-2.5.63-bk6/arch/i386/mm/pageattr.c	Mon Mar 31 12:19:33 2003
@@ -130,11 +130,8 @@
 } 
 
 static inline void flush_map(void)
-{	
-#ifdef CONFIG_SMP 
-	smp_call_function(flush_kernel_map, NULL, 1, 1);
-#endif	
-	flush_kernel_map(NULL);
+{
+	on_each_cpu(flush_kernel_map, NULL, 1, 1);
 }
 
 struct deferred_page { 
diff -urN linux-2.5.63-bk5/arch/i386/mm/pgtable.c linux-2.5.63-bk6/arch/i386/mm/pgtable.c
--- linux-2.5.63-bk5/arch/i386/mm/pgtable.c	Mon Feb 24 11:06:03 2003
+++ linux-2.5.63-bk6/arch/i386/mm/pgtable.c	Mon Mar 31 12:19:33 2003
@@ -11,6 +11,7 @@
 #include <linux/smp.h>
 #include <linux/highmem.h>
 #include <linux/slab.h>
+#include <linux/pagemap.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
diff -urN linux-2.5.63-bk5/arch/i386/oprofile/nmi_int.c linux-2.5.63-bk6/arch/i386/oprofile/nmi_int.c
--- linux-2.5.63-bk5/arch/i386/oprofile/nmi_int.c	Mon Feb 24 11:05:44 2003
+++ linux-2.5.63-bk6/arch/i386/oprofile/nmi_int.c	Mon Mar 31 12:19:33 2003
@@ -95,8 +95,7 @@
 	 * without actually triggering any NMIs as this will
 	 * break the core code horrifically.
 	 */
-	smp_call_function(nmi_cpu_setup, NULL, 0, 1);
-	nmi_cpu_setup(0);
+	on_each_cpu(nmi_cpu_setup, NULL, 0, 1);
 	set_nmi_callback(nmi_callback);
 	oprofile_pmdev = set_nmi_pm_callback(oprofile_pm_callback);
 	return 0;
@@ -148,8 +147,7 @@
 {
 	unset_nmi_pm_callback(oprofile_pmdev);
 	unset_nmi_callback();
-	smp_call_function(nmi_cpu_shutdown, NULL, 0, 1);
-	nmi_cpu_shutdown(0);
+	on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
 }
 
  
@@ -162,8 +160,7 @@
 
 static int nmi_start(void)
 {
-	smp_call_function(nmi_cpu_start, NULL, 0, 1);
-	nmi_cpu_start(0);
+	on_each_cpu(nmi_cpu_start, NULL, 0, 1);
 	return 0;
 }
  
@@ -177,8 +174,7 @@
  
 static void nmi_stop(void)
 {
-	smp_call_function(nmi_cpu_stop, NULL, 0, 1);
-	nmi_cpu_stop(0);
+	on_each_cpu(nmi_cpu_stop, NULL, 0, 1);
 }
 
 
diff -urN linux-2.5.63-bk5/arch/ia64/kernel/smp.c linux-2.5.63-bk6/arch/ia64/kernel/smp.c
--- linux-2.5.63-bk5/arch/ia64/kernel/smp.c	Mon Feb 24 11:06:01 2003
+++ linux-2.5.63-bk6/arch/ia64/kernel/smp.c	Mon Mar 31 12:19:33 2003
@@ -206,18 +206,18 @@
 void
 smp_flush_tlb_all (void)
 {
-	smp_call_function((void (*)(void *))local_flush_tlb_all, 0, 1, 1);
-	local_flush_tlb_all();
+	on_each_cpu((void (*)(void *))local_flush_tlb_all, 0, 1, 1);
 }
 
 void
 smp_flush_tlb_mm (struct mm_struct *mm)
 {
-	local_finish_flush_tlb_mm(mm);
-
 	/* this happens for the common case of a single-threaded fork():  */
 	if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1))
+	{
+		local_finish_flush_tlb_mm(mm);
 		return;
+	}
 
 	/*
 	 * We could optimize this further by using mm->cpu_vm_mask to track which CPUs
@@ -226,7 +226,7 @@
 	 * anyhow, and once a CPU is interrupted, the cost of local_flush_tlb_all() is
 	 * rather trivial.
 	 */
-	smp_call_function((void (*)(void *))local_finish_flush_tlb_mm, mm, 1, 1);
+	on_each_cpu((void (*)(void *))local_finish_flush_tlb_mm, mm, 1, 1);
 }
 
 /*
diff -urN linux-2.5.63-bk5/arch/mips64/kernel/smp.c linux-2.5.63-bk6/arch/mips64/kernel/smp.c
--- linux-2.5.63-bk5/arch/mips64/kernel/smp.c	Mon Feb 24 11:05:38 2003
+++ linux-2.5.63-bk6/arch/mips64/kernel/smp.c	Mon Mar 31 12:19:33 2003
@@ -195,8 +195,7 @@
 
 void flush_tlb_all(void)
 {
-	smp_call_function(flush_tlb_all_ipi, 0, 1, 1);
-	_flush_tlb_all();
+	on_each_cpu(flush_tlb_all_ipi, 0, 1, 1);
 }
 
 static void flush_tlb_mm_ipi(void *mm)
@@ -219,6 +218,8 @@
 
 void flush_tlb_mm(struct mm_struct *mm)
 {
+	preempt_disable();
+
 	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
 		smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1);
 	} else {
@@ -228,6 +229,8 @@
 				CPU_CONTEXT(i, mm) = 0;
 	}
 	_flush_tlb_mm(mm);
+
+	preempt_enable();
 }
 
 struct flush_tlb_data {
@@ -246,6 +249,8 @@
 
 void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
+	preempt_disable();
+
 	if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) {
 		struct flush_tlb_data fd;
 
@@ -260,6 +265,8 @@
 				CPU_CONTEXT(i, mm) = 0;
 	}
 	_flush_tlb_range(mm, start, end);
+
+	preempt_enable();
 }
 
 static void flush_tlb_page_ipi(void *info)
@@ -271,6 +278,8 @@
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
+	preempt_disable();
+
 	if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) {
 		struct flush_tlb_data fd;
 
@@ -284,5 +293,7 @@
 				CPU_CONTEXT(i, vma->vm_mm) = 0;
 	}
 	_flush_tlb_page(vma, page);
+
+	preempt_enable();
 }
 
diff -urN linux-2.5.63-bk5/arch/parisc/kernel/cache.c linux-2.5.63-bk6/arch/parisc/kernel/cache.c
--- linux-2.5.63-bk5/arch/parisc/kernel/cache.c	Mon Feb 24 11:05:29 2003
+++ linux-2.5.63-bk6/arch/parisc/kernel/cache.c	Mon Mar 31 12:19:33 2003
@@ -39,8 +39,7 @@
 void
 flush_data_cache(void)
 {
-	smp_call_function((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
-	flush_data_cache_local();
+	on_each_cpu((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
 }
 #endif
 
diff -urN linux-2.5.63-bk5/arch/parisc/kernel/irq.c linux-2.5.63-bk6/arch/parisc/kernel/irq.c
--- linux-2.5.63-bk5/arch/parisc/kernel/irq.c	Mon Mar 31 12:19:30 2003
+++ linux-2.5.63-bk6/arch/parisc/kernel/irq.c	Mon Mar 31 12:19:33 2003
@@ -61,20 +61,17 @@
 
 static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;  /* protect IRQ regions */
 
-#ifdef CONFIG_SMP
 static void cpu_set_eiem(void *info)
 {
 	set_eiem((unsigned long) info);
 }
-#endif
 
 static inline void disable_cpu_irq(void *unused, int irq)
 {
 	unsigned long eirr_bit = EIEM_MASK(irq);
 
 	cpu_eiem &= ~eirr_bit;
-	set_eiem(cpu_eiem);
-        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
 static void enable_cpu_irq(void *unused, int irq)
@@ -83,8 +80,7 @@
 
 	mtctl(eirr_bit, 23);	/* clear EIRR bit before unmasking */
 	cpu_eiem |= eirr_bit;
-        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
-	set_eiem(cpu_eiem);
+        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
 /* mask and disable are the same at the CPU level
@@ -100,8 +96,7 @@
 	** handle *any* unmasked pending interrupts.
 	** ie We don't need to check for pending interrupts here.
 	*/
-        smp_call_function(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
-	set_eiem(cpu_eiem);
+        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
 }
 
 /*
diff -urN linux-2.5.63-bk5/arch/parisc/kernel/smp.c linux-2.5.63-bk6/arch/parisc/kernel/smp.c
--- linux-2.5.63-bk5/arch/parisc/kernel/smp.c	Mon Feb 24 11:06:01 2003
+++ linux-2.5.63-bk6/arch/parisc/kernel/smp.c	Mon Mar 31 12:19:33 2003
@@ -401,7 +401,7 @@
 __setup("maxcpus=", maxcpus);
 
 /*
- * Flush all other CPU's tlb and then mine.  Do this with smp_call_function()
+ * Flush all other CPU's tlb and then mine.  Do this with on_each_cpu()
  * as we want to ensure all TLB's flushed before proceeding.
  */
 
@@ -410,8 +410,7 @@
 void
 smp_flush_tlb_all(void)
 {
-	smp_call_function((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
-	flush_tlb_all_local();
+	on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
 }
 
 
diff -urN linux-2.5.63-bk5/arch/parisc/mm/init.c linux-2.5.63-bk6/arch/parisc/mm/init.c
--- linux-2.5.63-bk5/arch/parisc/mm/init.c	Mon Feb 24 11:05:32 2003
+++ linux-2.5.63-bk6/arch/parisc/mm/init.c	Mon Mar 31 12:19:33 2003
@@ -974,8 +974,7 @@
 	    do_recycle++;
 	}
 	spin_unlock(&sid_lock);
-	smp_call_function((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
-	flush_tlb_all_local();
+	on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
 	if (do_recycle) {
 	    spin_lock(&sid_lock);
 	    recycle_sids(recycle_ndirty,recycle_dirty_array);
diff -urN linux-2.5.63-bk5/arch/ppc/kernel/temp.c linux-2.5.63-bk6/arch/ppc/kernel/temp.c
--- linux-2.5.63-bk5/arch/ppc/kernel/temp.c	Mon Feb 24 11:05:33 2003
+++ linux-2.5.63-bk6/arch/ppc/kernel/temp.c	Mon Mar 31 12:19:33 2003
@@ -194,10 +194,7 @@
 
 	/* schedule ourselves to be run again */
 	mod_timer(&tau_timer, jiffies + shrink_timer) ;
-#ifdef CONFIG_SMP
-	smp_call_function(tau_timeout, NULL, 1, 0);
-#endif
-	tau_timeout(NULL);
+	on_each_cpu(tau_timeout, NULL, 1, 0);
 }
 
 /*
@@ -239,10 +236,7 @@
 	tau_timer.expires = jiffies + shrink_timer;
 	add_timer(&tau_timer);
 	
-#ifdef CONFIG_SMP
-	smp_call_function(TAU_init_smp, NULL, 1, 0);
-#endif
-	TAU_init_smp(NULL);
+	on_each_cpu(TAU_init_smp, NULL, 1, 0);
 	
 	printk("Thermal assist unit ");
 #ifdef CONFIG_TAU_INT
diff -urN linux-2.5.63-bk5/arch/s390/kernel/smp.c linux-2.5.63-bk6/arch/s390/kernel/smp.c
--- linux-2.5.63-bk5/arch/s390/kernel/smp.c	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk6/arch/s390/kernel/smp.c	Mon Mar 31 12:19:33 2003
@@ -228,8 +228,7 @@
 void machine_restart_smp(char * __unused) 
 {
 	cpu_restart_map = cpu_online_map;
-        smp_call_function(do_machine_restart, NULL, 0, 0);
-	do_machine_restart(NULL);
+        on_each_cpu(do_machine_restart, NULL, 0, 0);
 }
 
 static void do_machine_halt(void * __unused)
@@ -247,8 +246,7 @@
 
 void machine_halt_smp(void)
 {
-        smp_call_function(do_machine_halt, NULL, 0, 0);
-	do_machine_halt(NULL);
+        on_each_cpu(do_machine_halt, NULL, 0, 0);
 }
 
 static void do_machine_power_off(void * __unused)
@@ -266,8 +264,7 @@
 
 void machine_power_off_smp(void)
 {
-        smp_call_function(do_machine_power_off, NULL, 0, 0);
-	do_machine_power_off(NULL);
+        on_each_cpu(do_machine_power_off, NULL, 0, 0);
 }
 
 /*
@@ -339,8 +336,7 @@
 
 void smp_ptlb_all(void)
 {
-        smp_call_function(smp_ptlb_callback, NULL, 0, 1);
-	local_flush_tlb();
+        on_each_cpu(smp_ptlb_callback, NULL, 0, 1);
 }
 
 /*
@@ -400,8 +396,10 @@
 	parms.end_ctl = cr;
 	parms.orvals[cr] = 1 << bit;
 	parms.andvals[cr] = 0xFFFFFFFF;
+	preempt_disable();
 	smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         __ctl_set_bit(cr, bit);
+	preempt_enable();
 }
 
 /*
@@ -414,8 +412,10 @@
 	parms.end_ctl = cr;
 	parms.orvals[cr] = 0x00000000;
 	parms.andvals[cr] = ~(1 << bit);
+	preempt_disable();
 	smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         __ctl_clear_bit(cr, bit);
+	preempt_enable();
 }
 
 /*
diff -urN linux-2.5.63-bk5/arch/s390x/kernel/exec32.c linux-2.5.63-bk6/arch/s390x/kernel/exec32.c
--- linux-2.5.63-bk5/arch/s390x/kernel/exec32.c	Mon Feb 24 11:05:04 2003
+++ linux-2.5.63-bk6/arch/s390x/kernel/exec32.c	Mon Mar 31 12:19:33 2003
@@ -4,7 +4,7 @@
  * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  * Author(s): Gerhard Tonn (ton@de.ibm.com)
  *
- * Seperated from binfmt_elf32.c to reduce exports for module enablement.
+ * Separated from binfmt_elf32.c to reduce exports for module enablement.
  *
  */
 
diff -urN linux-2.5.63-bk5/arch/s390x/kernel/smp.c linux-2.5.63-bk6/arch/s390x/kernel/smp.c
--- linux-2.5.63-bk5/arch/s390x/kernel/smp.c	Mon Feb 24 11:05:32 2003
+++ linux-2.5.63-bk6/arch/s390x/kernel/smp.c	Mon Mar 31 12:19:33 2003
@@ -227,8 +227,7 @@
 void machine_restart_smp(char * __unused) 
 {
 	cpu_restart_map = cpu_online_map;
-        smp_call_function(do_machine_restart, NULL, 0, 0);
-	do_machine_restart(NULL);
+        on_each_cpu(do_machine_restart, NULL, 0, 0);
 }
 
 static void do_machine_halt(void * __unused)
@@ -246,8 +245,7 @@
 
 void machine_halt_smp(void)
 {
-        smp_call_function(do_machine_halt, NULL, 0, 0);
-	do_machine_halt(NULL);
+        on_each_cpu(do_machine_halt, NULL, 0, 0);
 }
 
 static void do_machine_power_off(void * __unused)
@@ -265,8 +263,7 @@
 
 void machine_power_off_smp(void)
 {
-        smp_call_function(do_machine_power_off, NULL, 0, 0);
-	do_machine_power_off(NULL);
+        on_each_cpu(do_machine_power_off, NULL, 0, 0);
 }
 
 /*
@@ -383,8 +380,10 @@
 	parms.end_ctl = cr;
 	parms.orvals[cr] = 1 << bit;
 	parms.andvals[cr] = -1L;
+	preempt_disable();
 	smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         __ctl_set_bit(cr, bit);
+	preempt_enable();
 }
 
 /*
@@ -397,8 +396,10 @@
 	parms.end_ctl = cr;
 	parms.orvals[cr] = 0;
 	parms.andvals[cr] = ~(1L << bit);
+	preempt_disable();
 	smp_call_function(smp_ctl_bit_callback, &parms, 0, 1);
         __ctl_clear_bit(cr, bit);
+	preempt_enable();
 }
 
 
diff -urN linux-2.5.63-bk5/arch/x86_64/kernel/bluesmoke.c linux-2.5.63-bk6/arch/x86_64/kernel/bluesmoke.c
--- linux-2.5.63-bk5/arch/x86_64/kernel/bluesmoke.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/arch/x86_64/kernel/bluesmoke.c	Mon Mar 31 12:19:33 2003
@@ -111,11 +111,7 @@
 {
 	u32 low, high;
 	int i;
-	unsigned int *cpu = info;
 
-	BUG_ON (*cpu != smp_processor_id());
-
-	preempt_disable();
 	for (i=0; i<banks; i++) {
 		rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
 
@@ -130,20 +126,12 @@
 			wmb();
 		}
 	}
-	preempt_enable();
 }
 
 
 static void mce_timerfunc (unsigned long data)
 {
-	unsigned int i;
-
-	for (i=0; i<smp_num_cpus; i++) {
-		if (i == smp_processor_id())
-			mce_checkregs(&i);
-		else
-			smp_call_function (mce_checkregs, &i, 1, 1);
-	}
+	on_each_cpu (mce_checkregs, NULL, 1, 1);
 
 	/* Refresh the timer. */
 	mce_timer.expires = jiffies + MCE_RATE;
diff -urN linux-2.5.63-bk5/arch/x86_64/kernel/io_apic.c linux-2.5.63-bk6/arch/x86_64/kernel/io_apic.c
--- linux-2.5.63-bk5/arch/x86_64/kernel/io_apic.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/arch/x86_64/kernel/io_apic.c	Mon Mar 31 12:19:33 2003
@@ -928,8 +928,7 @@
 
 void print_all_local_APICs (void)
 {
-	smp_call_function(print_local_APIC, NULL, 1, 1);
-	print_local_APIC(NULL);
+	on_each_cpu(print_local_APIC, NULL, 1, 1);
 }
 
 void /*__init*/ print_PIC(void)
diff -urN linux-2.5.63-bk5/arch/x86_64/kernel/ldt.c linux-2.5.63-bk6/arch/x86_64/kernel/ldt.c
--- linux-2.5.63-bk5/arch/x86_64/kernel/ldt.c	Mon Feb 24 11:05:44 2003
+++ linux-2.5.63-bk6/arch/x86_64/kernel/ldt.c	Mon Mar 31 12:19:33 2003
@@ -60,12 +60,14 @@
 	pc->size = mincount;
 	wmb();
 	if (reload) {
-		load_LDT(pc);
 #ifdef CONFIG_SMP
 		preempt_disable();
+		load_LDT(pc);
 		if (current->mm->cpu_vm_mask != (1<<smp_processor_id()))
 			smp_call_function(flush_ldt, 0, 1, 1);
 		preempt_enable();
+#else
+		load_LDT(pc);
 #endif
 	}
 	if (oldsize) {
diff -urN linux-2.5.63-bk5/arch/x86_64/kernel/smp.c linux-2.5.63-bk6/arch/x86_64/kernel/smp.c
--- linux-2.5.63-bk5/arch/x86_64/kernel/smp.c	Mon Feb 24 11:05:13 2003
+++ linux-2.5.63-bk6/arch/x86_64/kernel/smp.c	Mon Mar 31 12:19:33 2003
@@ -328,7 +328,7 @@
 	preempt_enable();
 }
 
-static inline void do_flush_tlb_all_local(void)
+static void do_flush_tlb_all(void* info)
 {
 	unsigned long cpu = smp_processor_id();
 
@@ -337,18 +337,9 @@
 		leave_mm(cpu);
 }
 
-static void flush_tlb_all_ipi(void* info)
-{
-	do_flush_tlb_all_local();
-}
-
 void flush_tlb_all(void)
 {
-	preempt_disable();
-	smp_call_function (flush_tlb_all_ipi,0,1,1);
-
-	do_flush_tlb_all_local();
-	preempt_enable();
+	on_each_cpu(do_flush_tlb_all, 0, 1, 1);
 }
 
 void smp_kdb_stop(void)
diff -urN linux-2.5.63-bk5/arch/x86_64/mm/pageattr.c linux-2.5.63-bk6/arch/x86_64/mm/pageattr.c
--- linux-2.5.63-bk5/arch/x86_64/mm/pageattr.c	Mon Feb 24 11:05:32 2003
+++ linux-2.5.63-bk6/arch/x86_64/mm/pageattr.c	Mon Mar 31 12:19:33 2003
@@ -123,12 +123,7 @@
 
 static inline void flush_map(unsigned long address)
 {	
-	preempt_disable();
-#ifdef CONFIG_SMP 
-	smp_call_function(flush_kernel_map, (void *)address, 1, 1);
-#endif	
-	flush_kernel_map((void *)address);
-	preempt_enable();
+	on_each_cpu(flush_kernel_map, (void *)address, 1, 1);
 }
 
 struct deferred_page { 
diff -urN linux-2.5.63-bk5/drivers/block/cciss.c linux-2.5.63-bk6/drivers/block/cciss.c
--- linux-2.5.63-bk5/drivers/block/cciss.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/block/cciss.c	Mon Mar 31 12:19:33 2003
@@ -87,7 +87,11 @@
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
-#define MAX_CONFIG_WAIT 1000 
+#define MAX_CONFIG_WAIT 30000 
+#define MAX_IOCTL_CONFIG_WAIT 1000
+
+/*define how many times we will try a command because of bus resets */
+#define MAX_CMD_RETRIES 3
 
 #define READ_AHEAD 	 128
 #define NR_CMDS		 384 /* #commands that can be outstanding */
@@ -116,7 +120,7 @@
 static void start_io( ctlr_info_t *h);
 static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
 	unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
-	unsigned char *scsi3addr);
+	unsigned char *scsi3addr, int cmd_type);
 
 #ifdef CONFIG_PROC_FS
 static int cciss_proc_get_info(char *buffer, char **start, off_t offset, 
@@ -467,8 +471,7 @@
                         &(c->cfgtable->HostWrite.CoalIntCount));
 		writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
-		for(i=0;i<MAX_CONFIG_WAIT;i++)
-		{
+		for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
 			if (!(readl(c->vaddr + SA5_DOORBELL) 
 					& CFGTBL_ChangeReq))
 				break;
@@ -476,8 +479,8 @@
 			udelay(1000);
 		}	
 		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-		if (i >= MAX_CONFIG_WAIT)
-			return( -EFAULT);
+		if (i >= MAX_IOCTL_CONFIG_WAIT)
+			return -EAGAIN;
                 return(0);
         }
 	case CCISS_GETNODENAME:
@@ -514,8 +517,7 @@
 			
 		writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
-		for(i=0;i<MAX_CONFIG_WAIT;i++)
-		{
+		for(i=0;i<MAX_IOCTL_CONFIG_WAIT;i++) {
 			if (!(readl(c->vaddr + SA5_DOORBELL) 
 					& CFGTBL_ChangeReq))
 				break;
@@ -523,8 +525,8 @@
 			udelay(1000);
 		}	
 		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-		if (i >= MAX_CONFIG_WAIT)
-			return( -EFAULT);
+		if (i >= MAX_IOCTL_CONFIG_WAIT)
+			return -EAGAIN;
                 return(0);
         }
 
@@ -575,6 +577,24 @@
 	case CCISS_REVALIDVOLS:
                 return( revalidate_allvol(inode->i_rdev));
 
+ 	case CCISS_GETLUNINFO: {
+ 		LogvolInfo_struct luninfo;
+ 		struct gendisk *disk = hba[ctlr]->gendisk[dsk];
+ 		drive_info_struct *drv = &hba[ctlr]->drv[dsk];
+ 		int i;
+ 		
+ 		luninfo.LunID = drv->LunID;
+ 		luninfo.num_opens = drv->usage_count;
+ 		luninfo.num_parts = 0;
+ 		/* count partitions 1 to 15 with sizes > 0 */
+ 		for(i=1; i <MAX_PART; i++)
+ 			if (disk->part[i].nr_sects != 0)
+ 				luninfo.num_parts++;
+ 		if (copy_to_user((void *) arg, &luninfo,
+ 				sizeof(LogvolInfo_struct)))
+ 			return -EFAULT;
+ 		return(0);
+ 	}
 	case CCISS_DEREGDISK:
 		return( deregister_disk(ctlr,dsk));
 
@@ -696,7 +716,153 @@
 		cmd_free(h, c, 0);
                 return(0);
 	} 
+	case CCISS_BIG_PASSTHRU: {
+		BIG_IOCTL_Command_struct *ioc;
+		ctlr_info_t *h = hba[ctlr];
+		CommandList_struct *c;
+		unsigned char **buff = NULL;
+		int	*buff_size = NULL;
+		u64bit	temp64;
+		unsigned long flags;
+		BYTE sg_used = 0;
+		int status = 0;
+		int i;
+		DECLARE_COMPLETION(wait);
+		__u32   left;
+		__u32	sz;
+		BYTE    *data_ptr;
 
+		if (!arg)
+			return -EINVAL;
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		ioc = (BIG_IOCTL_Command_struct *) 
+			kmalloc(sizeof(*ioc), GFP_KERNEL);
+		if (!ioc) {
+			status = -ENOMEM;
+			goto cleanup1;
+		}
+		if (copy_from_user(ioc, (void *) arg, sizeof(*ioc)))
+			return -EFAULT;
+		if ((ioc->buf_size < 1) &&
+			(ioc->Request.Type.Direction != XFER_NONE))
+				return -EINVAL;
+		/* Check kmalloc limits  using all SGs */
+		if (ioc->malloc_size > MAX_KMALLOC_SIZE)
+			return -EINVAL;
+		if (ioc->buf_size > ioc->malloc_size * MAXSGENTRIES)
+			return -EINVAL;
+		buff = (unsigned char **) kmalloc(MAXSGENTRIES * 
+				sizeof(char *), GFP_KERNEL);
+		if (!buff) {
+			status = -ENOMEM;
+			goto cleanup1;
+		}
+		memset(buff, 0, MAXSGENTRIES);
+		buff_size = (int *) kmalloc(MAXSGENTRIES * sizeof(int), 
+					GFP_KERNEL);
+		if (!buff_size) {
+			status = -ENOMEM;
+			goto cleanup1;
+		}
+		left = ioc->buf_size;
+		data_ptr = (BYTE *) ioc->buf;
+		while (left) {
+			sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
+			buff_size[sg_used] = sz;
+			buff[sg_used] = kmalloc(sz, GFP_KERNEL);
+			if (buff[sg_used] == NULL) {
+				status = -ENOMEM;
+				goto cleanup1;
+			}
+			if (ioc->Request.Type.Direction == XFER_WRITE &&
+				copy_from_user(buff[sg_used], data_ptr, sz)) {
+					status = -ENOMEM;
+					goto cleanup1;			
+			}
+			left -= sz;
+			data_ptr += sz;
+			sg_used++;
+		}
+		if ((c = cmd_alloc(h , 0)) == NULL) {
+			status = -ENOMEM;
+			goto cleanup1;	
+		}
+		c->cmd_type = CMD_IOCTL_PEND;
+		c->Header.ReplyQueue = 0;
+		
+		if( ioc->buf_size > 0) {
+			c->Header.SGList = sg_used;
+			c->Header.SGTotal= sg_used;
+		} else { 
+			c->Header.SGList = 0;
+			c->Header.SGTotal= 0;
+		}
+		c->Header.LUN = ioc->LUN_info;
+		c->Header.Tag.lower = c->busaddr;
+		
+		c->Request = ioc->Request;
+		if (ioc->buf_size > 0 ) {
+			int i;
+			for(i=0; i<sg_used; i++) {
+				temp64.val = pci_map_single( h->pdev, buff[i],
+					buff_size[i],
+					PCI_DMA_BIDIRECTIONAL);
+				c->SG[i].Addr.lower = temp64.val32.lower;
+				c->SG[i].Addr.upper = temp64.val32.upper;
+				c->SG[i].Len = buff_size[i];
+				c->SG[i].Ext = 0;  /* we are not chaining */
+			}
+		}
+		c->waiting = &wait;
+		/* Put the request on the tail of the request queue */
+		spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
+		addQ(&h->reqQ, c);
+		h->Qdepth++;
+		start_io(h);
+		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
+		wait_for_completion(&wait);
+		/* unlock the buffers from DMA */
+		for(i=0; i<sg_used; i++) {
+			temp64.val32.lower = c->SG[i].Addr.lower;
+			temp64.val32.upper = c->SG[i].Addr.upper;
+			pci_unmap_single( h->pdev, (dma_addr_t) temp64.val,
+				buff_size[i], PCI_DMA_BIDIRECTIONAL);
+		}
+		/* Copy the error information out */
+		ioc->error_info = *(c->err_info);
+		if (copy_to_user((void *) arg, ioc, sizeof(*ioc))) {
+			cmd_free(h, c, 0);
+			status = -EFAULT;
+			goto cleanup1;
+		}
+		if (ioc->Request.Type.Direction == XFER_READ) {
+			/* Copy the data out of the buffer we created */
+			BYTE *ptr = (BYTE  *) ioc->buf;
+	        	for(i=0; i< sg_used; i++) {
+				if (copy_to_user(ptr, buff[i], buff_size[i])) {
+					cmd_free(h, c, 0);
+					status = -EFAULT;
+					goto cleanup1;
+				}
+				ptr += buff_size[i];
+			}
+		}
+		cmd_free(h, c, 0);
+		status = 0;
+cleanup1:
+		if (buff) {
+			for(i=0; i<sg_used; i++)
+				if(buff[i] != NULL)
+					kfree(buff[i]);
+			kfree(buff);
+		}
+		if (buff_size)
+			kfree(buff_size);
+		if (ioc)
+			kfree(ioc);
+		return(status);
+	}
 	default:
 		return -EBADRQC;
 	}
@@ -816,113 +982,154 @@
 	h->drv[logvol].LunID = 0;
 	return(0);
 }
-static int sendcmd_withirq(__u8	cmd,
-	int	ctlr,
-	void	*buff,
-	size_t	size,
-	unsigned int use_unit_num,
-	unsigned int log_unit,
-	__u8	page_code )
+static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
+	size_t size,
+	unsigned int use_unit_num, /* 0: address the controller,
+				      1: address logical volume log_unit,
+				      2: periph device address is scsi3addr */
+	unsigned int log_unit, __u8 page_code, unsigned char *scsi3addr,
+	int cmd_type)
 {
-	ctlr_info_t *h = hba[ctlr];
-	CommandList_struct *c;
-	u64bit	buff_dma_handle;
-	unsigned long flags;
-	int return_status = IO_OK;
-	DECLARE_COMPLETION(wait);
-	
-	if ((c = cmd_alloc(h , 0)) == NULL)
-	{
-		return -ENOMEM;
-	}
-	// Fill in the command type 
+	ctlr_info_t *h= hba[ctlr];
+	u64bit buff_dma_handle;
+	int status = IO_OK;
+
 	c->cmd_type = CMD_IOCTL_PEND;
-	// Fill in Command Header 
-	c->Header.ReplyQueue = 0;  // unused in simple mode
-	if( buff != NULL) 	// buffer to fill 
-	{
+	c->Header.ReplyQueue = 0;
+	if( buff != NULL) {
 		c->Header.SGList = 1;
 		c->Header.SGTotal= 1;
-	} else	// no buffers to fill  
-	{
+	} else {
 		c->Header.SGList = 0;
                 c->Header.SGTotal= 0;
 	}
-	c->Header.Tag.lower = c->busaddr;  // use the kernel address the cmd block for tag
-	// Fill in Request block 	
-	switch(cmd)
-	{
+	c->Header.Tag.lower = c->busaddr;
+
+	c->Request.Type.Type = cmd_type;
+	if (cmd_type == TYPE_CMD) {
+		switch(cmd) {
 		case  CISS_INQUIRY:
 			/* If the logical unit number is 0 then, this is going
-				to controller so It's a physical command
-				mode = 0 target = 0.
-				So we have nothing to write. 
-				Otherwise 
-				mode = 1  target = LUNID
-			*/
-			if(use_unit_num != 0)
-			{
+			to controller so It's a physical command
+			mode = 0 target = 0.  So we have nothing to write.
+			otherwise, if use_unit_num == 1,
+			mode = 1(volume set addressing) target = LUNID
+			otherwise, if use_unit_num == 2,
+			mode = 0(periph dev addr) target = scsi3addr */
+			if (use_unit_num == 1) {
 				c->Header.LUN.LogDev.VolId=
-                                	hba[ctlr]->drv[log_unit].LunID;
+					h->drv[log_unit].LunID;
                         	c->Header.LUN.LogDev.Mode = 1;
+			} else if (use_unit_num == 2) {
+				memcpy(c->Header.LUN.LunAddrBytes,scsi3addr,8);
+				c->Header.LUN.LogDev.Mode = 0;
 			}
-			if(page_code != 0)
-			{
+			/* are we trying to read a vital product page */
+			if(page_code != 0) {
 				c->Request.CDB[1] = 0x01;
 				c->Request.CDB[2] = page_code;
 			}
 			c->Request.CDBLen = 6;
-			c->Request.Type.Type =  TYPE_CMD; // It is a command. 
 			c->Request.Type.Attribute = ATTR_SIMPLE;  
-			c->Request.Type.Direction = XFER_READ; // Read 
-			c->Request.Timeout = 0; // Don't time out 
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
 			c->Request.CDB[0] =  CISS_INQUIRY;
 			c->Request.CDB[4] = size  & 0xFF;  
 		break;
-	case CISS_REPORT_LOG:
+		case CISS_REPORT_LOG:
+		case CISS_REPORT_PHYS:
                         /* Talking to controller so It's a physical command
-                                mode = 00 target = 0.
-                                So we have nothing to write.
+			   mode = 00 target = 0.  Nothing to write.
                         */
-                        c->Request.CDBLen = 12;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE; 
-                        c->Request.Type.Direction = XFER_READ; // Read
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = CISS_REPORT_LOG;
-                        c->Request.CDB[6] = (size >> 24) & 0xFF;  //MSB
-                        c->Request.CDB[7] = (size >> 16) & 0xFF;
-                        c->Request.CDB[8] = (size >> 8) & 0xFF;
-                        c->Request.CDB[9] = size & 0xFF;
-                break;
-	case CCISS_READ_CAPACITY:
-			c->Header.LUN.LogDev.VolId= 
-				hba[ctlr]->drv[log_unit].LunID;
+			c->Request.CDBLen = 12;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = cmd;
+			c->Request.CDB[6] = (size >> 24) & 0xFF;  //MSB
+			c->Request.CDB[7] = (size >> 16) & 0xFF;
+			c->Request.CDB[8] = (size >> 8) & 0xFF;
+			c->Request.CDB[9] = size & 0xFF;
+			break;
+
+		case CCISS_READ_CAPACITY:
+			c->Header.LUN.LogDev.VolId = h->drv[log_unit].LunID;
 			c->Header.LUN.LogDev.Mode = 1;
 			c->Request.CDBLen = 10;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE; 
-                        c->Request.Type.Direction = XFER_READ; // Read
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = CCISS_READ_CAPACITY;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_READ;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = cmd;
+		break;
+		case CCISS_CACHE_FLUSH:
+			c->Request.CDBLen = 12;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_WRITE;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = BMIC_WRITE;
+			c->Request.CDB[6] = BMIC_CACHE_FLUSH;
 		break;
 		default:
 			printk(KERN_WARNING
-				"cciss:  Unknown Command 0x%c sent attempted\n", cmd);
-			cmd_free(h, c, 1);
+				"cciss%d:  Unknown Command 0x%c\n", ctlr, cmd);
 			return(IO_ERROR);
-	};
-
-	// Fill in the scatter gather information
-	if (size > 0 ) 
-	{
-		buff_dma_handle.val = (__u64) pci_map_single( h->pdev, 
+		}
+	} else if (cmd_type == TYPE_MSG) {
+		switch (cmd) {
+		case 3:	/* No-Op message */
+			c->Request.CDBLen = 1;
+			c->Request.Type.Attribute = ATTR_SIMPLE;
+			c->Request.Type.Direction = XFER_WRITE;
+			c->Request.Timeout = 0;
+			c->Request.CDB[0] = cmd;
+			break;
+		default:
+			printk(KERN_WARNING
+				"cciss%d: unknown message type %d\n",
+				ctlr, cmd);
+			return IO_ERROR;
+		}
+	} else {
+		printk(KERN_WARNING
+			"cciss%d: unknown command type %d\n", ctlr, cmd_type);
+		return IO_ERROR;
+	}
+	/* Fill in the scatter gather information */
+	if (size > 0) {
+		buff_dma_handle.val = (__u64) pci_map_single(h->pdev,
 			buff, size, PCI_DMA_BIDIRECTIONAL);
 		c->SG[0].Addr.lower = buff_dma_handle.val32.lower;
 		c->SG[0].Addr.upper = buff_dma_handle.val32.upper;
 		c->SG[0].Len = size;
-		c->SG[0].Ext = 0;  // we are not chaining
+		c->SG[0].Ext = 0;  /* we are not chaining */
+	}
+	return status;
+}
+static int sendcmd_withirq(__u8	cmd,
+	int	ctlr,
+	void	*buff,
+	size_t	size,
+	unsigned int use_unit_num,
+	unsigned int log_unit,
+	__u8	page_code,
+	int cmd_type)
+{
+	ctlr_info_t *h = hba[ctlr];
+	CommandList_struct *c;
+	u64bit	buff_dma_handle;
+	unsigned long flags;
+	int return_status;
+	DECLARE_COMPLETION(wait);
+	
+	if ((c = cmd_alloc(h , 0)) == NULL)
+		return -ENOMEM;
+	return_status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
+		log_unit, page_code, NULL, cmd_type);
+	if (return_status != IO_OK) {
+		cmd_free(h, c, 0);
+		return return_status;
 	}
+resend_cmd2:
 	c->waiting = &wait;
 	
 	/* Put the request on the tail of the queue and send it */
@@ -934,10 +1141,6 @@
 	
 	wait_for_completion(&wait);
 
-	/* unlock the buffers from DMA */
-        pci_unmap_single( h->pdev, (dma_addr_t) buff_dma_handle.val,
-                	size, PCI_DMA_BIDIRECTIONAL);
-
 	if(c->err_info->CommandStatus != 0) 
 	{ /* an error has occurred */ 
 		switch(c->err_info->CommandStatus)
@@ -989,11 +1192,22 @@
 				return_status = IO_ERROR;
 			break;
 			case CMD_UNSOLICITED_ABORT:
-				printk(KERN_WARNING "cciss: cmd %p aborted "
-					"do to an unsolicited abort\n", c);
+				printk(KERN_WARNING 
+					"cciss%d: unsolicited abort %p\n",
+					ctlr, c);
+				if (c->retry_count < MAX_CMD_RETRIES) {
+					printk(KERN_WARNING 
+						"cciss%d: retrying %p\n", 
+						ctlr, c);
+					c->retry_count++;
+					/* erase the old error information */
+					memset(c->err_info, 0,
+						sizeof(ErrorInfo_struct));
+					return_status = IO_OK;
+					INIT_COMPLETION(wait);
+					goto resend_cmd2;
+				}
 				return_status = IO_ERROR;
-
-
 			break;
 			default:
 				printk(KERN_WARNING "cciss: cmd %p returned "
@@ -1002,6 +1216,9 @@
 				return_status = IO_ERROR;
 		}
 	}	
+	/* unlock the buffers from DMA */
+	pci_unmap_single( h->pdev, (dma_addr_t) buff_dma_handle.val,
+			size, PCI_DMA_BIDIRECTIONAL);
 	cmd_free(h, c, 0);
         return(return_status);
 
@@ -1015,10 +1232,10 @@
 	memset(inq_buff, 0, sizeof(InquiryData_struct));
 	if (withirq)
 		return_code = sendcmd_withirq(CISS_INQUIRY, ctlr,
-			inq_buff, sizeof(*inq_buff), 1, logvol ,0xC1);
+			inq_buff, sizeof(*inq_buff), 1, logvol ,0xC1, TYPE_CMD);
 	else
 		return_code = sendcmd(CISS_INQUIRY, ctlr, inq_buff,
-			sizeof(*inq_buff), 1, logvol ,0xC1, NULL);
+			sizeof(*inq_buff), 1, logvol ,0xC1, NULL, TYPE_CMD);
 	if (return_code == IO_OK) {
 		if(inq_buff->data_byte[8] == 0xFF) {
 			printk(KERN_WARNING
@@ -1057,10 +1274,10 @@
 	memset(buf, 0, sizeof(*buf));
 	if (withirq)
 		return_code = sendcmd_withirq(CCISS_READ_CAPACITY,
-			ctlr, buf, sizeof(*buf), 1, logvol, 0 );
+			ctlr, buf, sizeof(*buf), 1, logvol, 0, TYPE_CMD);
 	else
 		return_code = sendcmd(CCISS_READ_CAPACITY,
-			ctlr, buf, sizeof(*buf), 1, logvol, 0, NULL );
+			ctlr, buf, sizeof(*buf), 1, logvol, 0, NULL, TYPE_CMD);
 	if (return_code == IO_OK) {
 		*total_size = be32_to_cpu(*((__u32 *) &buf->total_size[0]))+1;
 		*block_size = be32_to_cpu(*((__u32 *) &buf->block_size[0]));
@@ -1111,7 +1328,7 @@
 		goto mem_msg;
 	
 	return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, 
-			sizeof(ReportLunData_struct), 0, 0, 0 );
+			sizeof(ReportLunData_struct), 0, 0, 0, TYPE_CMD);
 
 	if( return_code == IO_OK)
 	{
@@ -1265,126 +1482,27 @@
 				      2: periph device address is scsi3addr */
 	unsigned int log_unit,
 	__u8	page_code,
-	unsigned char *scsi3addr)
+	unsigned char *scsi3addr,
+	int cmd_type)
 {
 	CommandList_struct *c;
 	int i;
 	unsigned long complete;
 	ctlr_info_t *info_p= hba[ctlr];
 	u64bit buff_dma_handle;
+	int status;
 
-	c = cmd_alloc(info_p, 1);
-	if (c == NULL)
-	{
+	if ((c = cmd_alloc(info_p, 1)) == NULL) {
 		printk(KERN_WARNING "cciss: unable to get memory");
 		return(IO_ERROR);
 	}
-	// Fill in Command Header 
-	c->Header.ReplyQueue = 0;  // unused in simple mode
-	if( buff != NULL) 	// buffer to fill 
-	{
-		c->Header.SGList = 1;
-		c->Header.SGTotal= 1;
-	} else	// no buffers to fill  
-	{
-		c->Header.SGList = 0;
-                c->Header.SGTotal= 0;
-	}
-	c->Header.Tag.lower = c->busaddr;  // use the kernel address the cmd block for tag
-	// Fill in Request block 	
-	switch(cmd)
-	{
-		case  CISS_INQUIRY:
-			/* If the logical unit number is 0 then, this is going
-				to controller so It's a physical command
-				mode = 0 target = 0.
-				So we have nothing to write. 
-				otherwise, if use_unit_num == 1, 
-				mode = 1(volume set addressing) target = LUNID
-				otherwise, if use_unit_num == 2,
-				mode = 0(periph dev addr) target = scsi3addr 
-			*/
-			if(use_unit_num == 1)
-			{
-				c->Header.LUN.LogDev.VolId=
-                                	hba[ctlr]->drv[log_unit].LunID;
-                        	c->Header.LUN.LogDev.Mode = 1;
-			}
-			else if (use_unit_num == 2)
-			{
-				memcpy(c->Header.LUN.LunAddrBytes,scsi3addr,8);
-                        	c->Header.LUN.LogDev.Mode = 0; // phys dev addr 
-			}
-
-			/* are we trying to read a vital product page */
-			if(page_code != 0)
-			{
-				c->Request.CDB[1] = 0x01;
-				c->Request.CDB[2] = page_code;
-			}
-			c->Request.CDBLen = 6;
-			c->Request.Type.Type =  TYPE_CMD; // It is a command. 
-			c->Request.Type.Attribute = ATTR_SIMPLE;  
-			c->Request.Type.Direction = XFER_READ; // Read 
-			c->Request.Timeout = 0; // Don't time out 
-			c->Request.CDB[0] =  CISS_INQUIRY;
-			c->Request.CDB[4] = size  & 0xFF;  
-		break;
-		case CISS_REPORT_LOG:
-		case CISS_REPORT_PHYS:
-                        /* Talking to controller so It's a physical command
-                                mode = 00 target = 0.
-                                So we have nothing to write.
-                        */
-                        c->Request.CDBLen = 12;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE; 
-                        c->Request.Type.Direction = XFER_READ; // Read
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = cmd;
-                        c->Request.CDB[6] = (size >> 24) & 0xFF;  //MSB
-                        c->Request.CDB[7] = (size >> 16) & 0xFF;
-                        c->Request.CDB[8] = (size >> 8) & 0xFF;
-                        c->Request.CDB[9] = size & 0xFF;
-                break;
-
-		case CCISS_READ_CAPACITY:
-			c->Header.LUN.LogDev.VolId= 
-				hba[ctlr]->drv[log_unit].LunID;
-			c->Header.LUN.LogDev.Mode = 1;
-			c->Request.CDBLen = 10;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE; 
-                        c->Request.Type.Direction = XFER_READ; // Read
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = CCISS_READ_CAPACITY;
-		break;
-		case CCISS_CACHE_FLUSH:
-			c->Request.CDBLen = 12;
-                        c->Request.Type.Type =  TYPE_CMD; // It is a command.
-                        c->Request.Type.Attribute = ATTR_SIMPLE;
-                        c->Request.Type.Direction = XFER_WRITE; // No data
-                        c->Request.Timeout = 0; // Don't time out
-                        c->Request.CDB[0] = BMIC_WRITE;  // BMIC Passthru
-                        c->Request.CDB[6] = BMIC_CACHE_FLUSH;
-		break;
-		default:
-			printk(KERN_WARNING
-				"cciss:  Unknown Command 0x%c sent attempted\n",
-				  cmd);
-			cmd_free(info_p, c, 1);
-			return(IO_ERROR);
-	};
-	// Fill in the scatter gather information
-	if (size > 0 ) 
-	{
-		buff_dma_handle.val = (__u64) pci_map_single( info_p->pdev, 
-			buff, size, PCI_DMA_BIDIRECTIONAL);
-		c->SG[0].Addr.lower = buff_dma_handle.val32.lower;
-		c->SG[0].Addr.upper = buff_dma_handle.val32.upper;
-		c->SG[0].Len = size;
-		c->SG[0].Ext = 0;  // we are not chaining
+	status = fill_cmd(c, cmd, ctlr, buff, size, use_unit_num,
+		log_unit, page_code, scsi3addr, cmd_type);
+	if (status != IO_OK) {
+		cmd_free(info_p, c, 1);
+		return status;
 	}
+resend_cmd1:
 	/*
          * Disable interrupt
          */
@@ -1417,9 +1535,6 @@
 	printk(KERN_DEBUG "cciss: command completed\n");
 #endif /* CCISS_DEBUG */
 
-	/* unlock the data buffer from DMA */
-	pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
-                                size, PCI_DMA_BIDIRECTIONAL);
 	if (complete != 1) {
 		if ( (complete & CISS_ERROR_BIT)
 		     && (complete & ~CISS_ERROR_BIT) == c->busaddr)
@@ -1437,8 +1552,30 @@
 			 	))
 			{
 				complete = c->busaddr;
-			} else
-			{
+			} else {
+				if (c->err_info->CommandStatus ==
+						CMD_UNSOLICITED_ABORT) {
+					printk(KERN_WARNING "cciss%d: "
+						"unsolicited abort %p\n",
+						ctlr, c);
+					if (c->retry_count < MAX_CMD_RETRIES) {
+						printk(KERN_WARNING
+						   "cciss%d: retrying %p\n",
+						   ctlr, c);
+						c->retry_count++;
+						/* erase the old error */
+						/* information */
+						memset(c->err_info, 0,
+						   sizeof(ErrorInfo_struct));
+						goto resend_cmd1;
+					} else {
+						printk(KERN_WARNING
+						   "cciss%d: retried %p too "
+						   "many times\n", ctlr, c);
+						status = IO_ERROR;
+						goto cleanup1;
+					}
+				}
 				printk(KERN_WARNING "ciss ciss%d: sendcmd"
 				" Error %x \n", ctlr, 
 					c->err_info->CommandStatus); 
@@ -1448,27 +1585,31 @@
 				  c->err_info->MoreErrInfo.Invalid_Cmd.offense_size,
 				  c->err_info->MoreErrInfo.Invalid_Cmd.offense_num,
 				  c->err_info->MoreErrInfo.Invalid_Cmd.offense_value);
-				cmd_free(info_p,c, 1);
-				return(IO_ERROR);
+				status = IO_ERROR;
+				goto cleanup1;
 			}
 		}
                 if (complete != c->busaddr) {
                         printk( KERN_WARNING "cciss cciss%d: SendCmd "
                       "Invalid command list address returned! (%lx)\n",
                                 ctlr, complete);
-                        cmd_free(info_p, c, 1);
-                        return (IO_ERROR);
+			status = IO_ERROR;
+			goto cleanup1;
                 }
         } else {
                 printk( KERN_WARNING
                         "cciss cciss%d: SendCmd Timeout out, "
                         "No command list address returned!\n",
                         ctlr);
-                cmd_free(info_p, c, 1);
-                return (IO_ERROR);
+		status = IO_ERROR;
         }
+		
+cleanup1:	
+	/* unlock the data buffer from DMA */
+	pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
+				size, PCI_DMA_BIDIRECTIONAL);
 	cmd_free(info_p, c, 1);
-        return (IO_OK);
+	return (status);
 } 
 /*
  * Map (physical) PCI mem into (virtual) kernel space
@@ -1552,27 +1693,35 @@
 	}
 
 } 
+/* Assumes that CCISS_LOCK(h->ctlr) is held. */
+/* Zeros out the error record and then resends the command back */
+/* to the controller */
+static inline void resend_cciss_cmd( ctlr_info_t *h, CommandList_struct *c)
+{
+	/* erase the old error information */
+	memset(c->err_info, 0, sizeof(ErrorInfo_struct));
+
+	/* add it to software queue and then send it to the controller */
+	addQ(&(h->reqQ),c);
+	h->Qdepth++;
+	if(h->Qdepth > h->maxQsinceinit)
+		h->maxQsinceinit = h->Qdepth;
+
+	start_io(h);
+}
 /* checks the status of the job and calls complete buffers to mark all 
  * buffers for the completed job. 
  */ 
-static inline void complete_command( CommandList_struct *cmd, int timeout)
+static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd,
+		int timeout)
 {
 	int status = 1;
 	int i;
+	int retry_cmd = 0;
 	u64bit temp64;
 		
 	if (timeout)
 		status = 0; 
-	/* unmap the DMA mapping for all the scatter gather elements */
-	for(i=0; i<cmd->Header.SGList; i++)
-	{
-		temp64.val32.lower = cmd->SG[i].Addr.lower;
-		temp64.val32.upper = cmd->SG[i].Addr.upper;
-		pci_unmap_page(hba[cmd->ctlr]->pdev,
-			temp64.val, cmd->SG[i].Len, 
-			(cmd->Request.Type.Direction == XFER_READ) ? 
-				PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
-	}
 
 	if(cmd->err_info->CommandStatus != 0) 
 	{ /* an error has occurred */ 
@@ -1646,8 +1795,18 @@
 				status=0;
 			break;
 			case CMD_UNSOLICITED_ABORT:
-				printk(KERN_WARNING "cciss: cmd %p aborted "
-					"do to an unsolicited abort\n", cmd);
+				printk(KERN_WARNING "cciss%d: unsolicited "
+					"abort %p\n", h->ctlr, cmd);
+				if (cmd->retry_count < MAX_CMD_RETRIES) {
+					retry_cmd=1;
+					printk(KERN_WARNING
+						"cciss%d: retrying %p\n",
+						h->ctlr, cmd);
+					cmd->retry_count++;
+				} else
+					printk(KERN_WARNING
+						"cciss%d: %p retried too "
+						"many times\n", h->ctlr, cmd);
 				status=0;
 			break;
 			case CMD_TIMEOUT:
@@ -1662,7 +1821,21 @@
 				status=0;
 		}
 	}
-
+	/* We need to return this command */
+	if(retry_cmd) {
+		resend_cciss_cmd(h,cmd);
+		return;
+	}	
+	/* command did not need to be retried */
+	/* unmap the DMA mapping for all the scatter gather elements */
+	for(i=0; i<cmd->Header.SGList; i++) {
+		temp64.val32.lower = cmd->SG[i].Addr.lower;
+		temp64.val32.upper = cmd->SG[i].Addr.upper;
+		pci_unmap_page(hba[cmd->ctlr]->pdev,
+			temp64.val, cmd->SG[i].Len,
+			(cmd->Request.Type.Direction == XFER_READ) ?
+				PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+	}
 	complete_buffers(cmd->rq->bio, status);
 
 #ifdef CCISS_DEBUG
@@ -1670,6 +1843,7 @@
 #endif /* CCISS_DEBUG */ 
 
 	end_that_request_last(cmd->rq);
+	cmd_free(h,cmd,1);
 }
 
 /* 
@@ -1816,8 +1990,7 @@
 			 if (c->busaddr == a) {
 				removeQ(&h->cmpQ, c);
 				if (c->cmd_type == CMD_RWREQ) {
-					complete_command(c, 0);
-					cmd_free(h, c, 1);
+					complete_command(h, c, 0);
 				} else if (c->cmd_type == CMD_IOCTL_PEND) {
 					complete(c->waiting);
 				}
@@ -2038,12 +2211,15 @@
 		&(c->cfgtable->HostWrite.TransportRequest));
 	writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
 
-	for(i=0;i<MAX_CONFIG_WAIT;i++)
-	{
+	/* under certain very rare conditions, this can take awhile.
+	 * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right
+	 * as we enter this code.) */
+	for(i=0;i<MAX_CONFIG_WAIT;i++) {
 		if (!(readl(c->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
 			break;
 		/* delay and try again */
-		udelay(1000);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(10);
 	}	
 
 #ifdef CCISS_DEBUG
@@ -2102,7 +2278,7 @@
         }
 	/* Get the firmware version */ 
 	return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, 
-		sizeof(InquiryData_struct), 0, 0 ,0, NULL );
+		sizeof(InquiryData_struct), 0, 0 ,0, NULL, TYPE_CMD);
 	if (return_code == IO_OK)
 	{
 		hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32];
@@ -2116,7 +2292,7 @@
 	}
 	/* Get the number of logical volumes */ 
 	return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, 
-			sizeof(ReportLunData_struct), 0, 0, 0, NULL );
+			sizeof(ReportLunData_struct), 0, 0, 0, NULL, TYPE_CMD);
 
 	if( return_code == IO_OK)
 	{
@@ -2390,7 +2566,8 @@
 	/* sendcmd will turn off interrupt, and send the flush...
 	* To write all data in the battery backed cache to disks */
 	memset(flush_buf, 0, 4);
-	return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL);
+	return_code = sendcmd(CCISS_CACHE_FLUSH, i, flush_buf, 4, 0, 0, 0, NULL,
+				TYPE_CMD);
 	if(return_code != IO_OK)
 	{
 		printk(KERN_WARNING "Error Flushing cache on controller %d\n", 
diff -urN linux-2.5.63-bk5/drivers/block/cciss_cmd.h linux-2.5.63-bk6/drivers/block/cciss_cmd.h
--- linux-2.5.63-bk5/drivers/block/cciss_cmd.h	Mon Feb 24 11:05:11 2003
+++ linux-2.5.63-bk6/drivers/block/cciss_cmd.h	Mon Mar 31 12:19:33 2003
@@ -240,6 +240,7 @@
   struct _CommandList_struct *next;
   struct request *	   rq;
   struct completion *waiting;
+  int	 retry_count;
 #ifdef CONFIG_CISS_SCSI_TAPE
   void * scsi_cmd;
 #endif
diff -urN linux-2.5.63-bk5/drivers/block/cciss_scsi.c linux-2.5.63-bk6/drivers/block/cciss_scsi.c
--- linux-2.5.63-bk5/drivers/block/cciss_scsi.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/block/cciss_scsi.c	Mon Mar 31 12:19:33 2003
@@ -47,7 +47,8 @@
 				      2: address is in scsi3addr */
 	unsigned int log_unit,
 	__u8	page_code,
-	unsigned char *scsi3addr );
+	unsigned char *scsi3addr,
+	int cmd_type);
 
 
 int __init cciss_scsi_detect(Scsi_Host_Template *tpnt);
diff -urN linux-2.5.63-bk5/drivers/block/deadline-iosched.c linux-2.5.63-bk6/drivers/block/deadline-iosched.c
--- linux-2.5.63-bk5/drivers/block/deadline-iosched.c	Mon Feb 24 11:05:40 2003
+++ linux-2.5.63-bk6/drivers/block/deadline-iosched.c	Mon Mar 31 12:19:33 2003
@@ -98,7 +98,7 @@
 	unsigned long expires;
 };
 
-static inline void deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq);
+static void deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq);
 
 static kmem_cache_t *drq_pool;
 
@@ -205,7 +205,7 @@
 		return;
 	}
 
-	deadline_move_to_dispatch(dd, __alias);
+	deadline_move_request(dd, __alias);
 	goto retry;
 }
 
diff -urN linux-2.5.63-bk5/drivers/block/loop.c linux-2.5.63-bk6/drivers/block/loop.c
--- linux-2.5.63-bk5/drivers/block/loop.c	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk6/drivers/block/loop.c	Mon Mar 31 12:19:33 2003
@@ -447,7 +447,22 @@
 		goto out_bh;
 	}
 
-	bio = bio_copy(rbh, GFP_NOIO, rbh->bi_rw & WRITE);
+	/*
+	 * When called on the page reclaim -> writepage path, this code can
+	 * trivially consume all memory.  So we drop PF_MEMALLOC to avoid
+	 * stealing all the page reserves and throttle to the writeout rate.
+	 * pdflush will have been woken by page reclaim.  Let it do its work.
+	 */
+	do {
+		int flags = current->flags;
+
+		current->flags &= ~PF_MEMALLOC;
+		bio = bio_copy(rbh, (GFP_ATOMIC & ~__GFP_HIGH) | __GFP_NOWARN,
+					rbh->bi_rw & WRITE);
+		current->flags = flags;
+		if (bio == NULL)
+			blk_congestion_wait(WRITE, HZ/10);
+	} while (bio == NULL);
 
 	bio->bi_end_io = loop_end_io_transfer;
 	bio->bi_private = rbh;
diff -urN linux-2.5.63-bk5/drivers/char/Makefile linux-2.5.63-bk6/drivers/char/Makefile
--- linux-2.5.63-bk5/drivers/char/Makefile	Mon Feb 24 11:05:46 2003
+++ linux-2.5.63-bk6/drivers/char/Makefile	Mon Mar 31 12:19:33 2003
@@ -83,7 +83,7 @@
 clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
 
 $(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE)
-	$(call do_cmd,CONMK  $@,$(objtree)/scripts/conmakehash $< > $@)
+	$(call do_cmd,CONMK   $@,$(objtree)/scripts/conmakehash $< > $@)
 
 $(obj)/defkeymap.o:  $(obj)/defkeymap.c
 
diff -urN linux-2.5.63-bk5/drivers/char/agp/agp.h linux-2.5.63-bk6/drivers/char/agp/agp.h
--- linux-2.5.63-bk5/drivers/char/agp/agp.h	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/char/agp/agp.h	Mon Mar 31 12:19:33 2003
@@ -42,9 +42,8 @@
 
 static void __attribute__((unused)) global_cache_flush(void)
 {
-	if (smp_call_function(ipi_handler, NULL, 1, 1) != 0)
+	if (on_each_cpu(ipi_handler, NULL, 1, 1) != 0)
 		panic(PFX "timed out waiting for the other CPUs!\n");
-	flush_agp_cache();
 }
 #else
 static inline void global_cache_flush(void)
diff -urN linux-2.5.63-bk5/drivers/cpufreq/Kconfig linux-2.5.63-bk6/drivers/cpufreq/Kconfig
--- linux-2.5.63-bk5/drivers/cpufreq/Kconfig	Mon Feb 24 11:05:43 2003
+++ linux-2.5.63-bk6/drivers/cpufreq/Kconfig	Mon Mar 31 12:19:33 2003
@@ -9,3 +9,30 @@
 	  For details, take a look at linux/Documentation/cpufreq. 
 	  
 	  If in doubt, say N.
+
+config CPU_FREQ_GOV_USERSPACE
+       tristate "'userspace' governor for userspace frequency scaling"
+       depends on CPU_FREQ
+       help
+	  Enable this cpufreq governor when you either want to set the
+	  CPU frequency manually or when an userspace programm shall
+          be able to set the CPU dynamically, like on LART 
+	  ( http://www.lart.tudelft.nl/ )
+
+	  For details, take a look at linux/Documentation/cpufreq. 
+
+	  If in doubt, say Y.
+
+config CPU_FREQ_24_API
+	bool "/proc/sys/cpu/ interface (2.4. / OLD)"
+	depends on CPU_FREQ && SYSCTL && CPU_FREQ_GOV_USERSPACE
+	help
+	  This enables the /proc/sys/cpu/ sysctl interface for controlling
+	  the CPUFreq,"userspace" governor. This is the same interface
+	  as known from the.4.-kernel patches for CPUFreq, and offers
+	  the same functionality as long as "userspace" is the
+	  selected governor for the specified CPU.
+	
+	  For details, take a look at linux/Documentation/cpufreq. 
+
+	  If in doubt, say N.
diff -urN linux-2.5.63-bk5/drivers/cpufreq/Makefile linux-2.5.63-bk6/drivers/cpufreq/Makefile
--- linux-2.5.63-bk5/drivers/cpufreq/Makefile	Mon Feb 24 11:06:03 2003
+++ linux-2.5.63-bk6/drivers/cpufreq/Makefile	Mon Mar 31 12:19:33 2003
@@ -1,3 +1,4 @@
 #CPUfreq governors and cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o
 obj-$(CONFIG_CPU_FREQ_PROC_INTF)	+= proc_intf.o
+obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)	+= userspace.o
diff -urN linux-2.5.63-bk5/drivers/cpufreq/userspace.c linux-2.5.63-bk6/drivers/cpufreq/userspace.c
--- linux-2.5.63-bk5/drivers/cpufreq/userspace.c	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/drivers/cpufreq/userspace.c	Mon Mar 31 12:19:33 2003
@@ -0,0 +1,596 @@
+/*
+ *  drivers/cpufreq/userspace.c
+ *
+ *  Copyright (C)  2001 Russell King
+ *            (C)  2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *
+ * $Id:$
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ctype.h>
+#include <linux/cpufreq.h>
+#include <linux/sysctl.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+
+#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
+                .ctl_name	= CPU_NR_FREQ_MAX, \
+                .data		= &cpu_max_freq[cpunr], \
+                .procname	= "speed-max", \
+                .maxlen		= sizeof(cpu_max_freq[cpunr]),\
+                .mode		= 0444, \
+                .proc_handler	= proc_dointvec, }
+
+#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
+                .ctl_name	= CPU_NR_FREQ_MIN, \
+                .data		= &cpu_min_freq[cpunr], \
+                .procname	= "speed-min", \
+                .maxlen		= sizeof(cpu_min_freq[cpunr]),\
+                .mode		= 0444, \
+                .proc_handler	= proc_dointvec, }
+
+#define CTL_CPU_VARS_SPEED(cpunr) { \
+                .ctl_name	= CPU_NR_FREQ, \
+                .procname	= "speed", \
+                .mode		= 0644, \
+                .proc_handler	= cpufreq_procctl, \
+                .strategy	= cpufreq_sysctl, \
+                .extra1		= (void*) (cpunr), }
+
+#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
+                CTL_CPU_VARS_SPEED_MAX(cpunr), \
+                CTL_CPU_VARS_SPEED_MIN(cpunr), \
+                CTL_CPU_VARS_SPEED(cpunr),  \
+                { .ctl_name = 0, }, }
+
+/* the ctl_table entry for each CPU */
+#define CPU_ENUM(s) { \
+                .ctl_name	= (CPU_NR + s), \
+                .procname	= #s, \
+                .mode		= 0555, \
+                .child		= ctl_cpu_vars_##s }
+
+/**
+ * A few values needed by the userspace governor
+ */
+static unsigned int	cpu_max_freq[NR_CPUS];
+static unsigned int	cpu_min_freq[NR_CPUS];
+static unsigned int	cpu_cur_freq[NR_CPUS];
+static unsigned int	cpu_is_managed[NR_CPUS];
+static struct cpufreq_policy current_policy[NR_CPUS];
+
+static DECLARE_MUTEX	(userspace_sem); 
+
+
+/* keep track of frequency transitions */
+static int 
+userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
+                       void *data)
+{
+        struct cpufreq_freqs *freq = data;
+
+	cpu_cur_freq[freq->cpu] = freq->new;
+
+        return 0;
+}
+
+static struct notifier_block userspace_cpufreq_notifier_block = {
+        .notifier_call  = userspace_cpufreq_notifier
+};
+
+
+/** 
+ * cpufreq_set - set the CPU frequency
+ * @freq: target frequency in kHz
+ * @cpu: CPU for which the frequency is to be set
+ *
+ * Sets the CPU frequency to freq.
+ */
+int cpufreq_set(unsigned int freq, unsigned int cpu)
+{
+	int ret = -EINVAL;
+
+	down(&userspace_sem);
+	if (!cpu_is_managed[cpu])
+		goto err;
+
+	if (freq < cpu_min_freq[cpu])
+		freq = cpu_min_freq[cpu];
+	if (freq > cpu_max_freq[cpu])
+		freq = cpu_max_freq[cpu];
+
+	ret = cpufreq_driver_target_l(&current_policy[cpu], freq, 
+	      CPUFREQ_RELATION_L);
+
+ err:
+	up(&userspace_sem);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cpufreq_set);
+
+
+/** 
+ * cpufreq_setmax - set the CPU to the maximum frequency
+ * @cpu - affected cpu;
+ *
+ * Sets the CPU frequency to the maximum frequency supported by
+ * this CPU.
+ */
+int cpufreq_setmax(unsigned int cpu)
+{
+	if (!cpu_is_managed[cpu] || !cpu_online(cpu))
+		return -EINVAL;
+	return cpufreq_set(cpu_max_freq[cpu], cpu);
+}
+EXPORT_SYMBOL_GPL(cpufreq_setmax);
+
+
+/** 
+ * cpufreq_get - get the current CPU frequency (in kHz)
+ * @cpu: CPU number
+ *
+ * Get the CPU current (static) CPU frequency
+ */
+unsigned int cpufreq_get(unsigned int cpu)
+{
+	return cpu_cur_freq[cpu];
+}
+EXPORT_SYMBOL(cpufreq_get);
+
+
+#ifdef CONFIG_CPU_FREQ_24_API
+
+
+/*********************** cpufreq_sysctl interface ********************/
+static int
+cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
+		void *buffer, size_t *lenp)
+{
+	char buf[16], *p;
+	int cpu = (int) ctl->extra1;
+	int len, left = *lenp;
+
+	if (!left || (filp->f_pos && !write) || !cpu_online(cpu)) {
+		*lenp = 0;
+		return 0;
+	}
+
+	if (write) {
+		unsigned int freq;
+
+		len = left;
+		if (left > sizeof(buf))
+			left = sizeof(buf);
+		if (copy_from_user(buf, buffer, left))
+			return -EFAULT;
+		buf[sizeof(buf) - 1] = '\0';
+
+		freq = simple_strtoul(buf, &p, 0);
+		cpufreq_set(freq, cpu);
+	} else {
+		len = sprintf(buf, "%d\n", cpufreq_get(cpu));
+		if (len > left)
+			len = left;
+		if (copy_to_user(buffer, buf, len))
+			return -EFAULT;
+	}
+
+	*lenp = len;
+	filp->f_pos += len;
+	return 0;
+}
+
+static int
+cpufreq_sysctl(ctl_table *table, int *name, int nlen,
+	       void *oldval, size_t *oldlenp,
+	       void *newval, size_t newlen, void **context)
+{
+	int cpu = (int) table->extra1;
+
+	if (!cpu_online(cpu))
+		return -EINVAL;
+
+	if (oldval && oldlenp) {
+		size_t oldlen;
+
+		if (get_user(oldlen, oldlenp))
+			return -EFAULT;
+
+		if (oldlen != sizeof(unsigned int))
+			return -EINVAL;
+
+		if (put_user(cpufreq_get(cpu), (unsigned int *)oldval) ||
+		    put_user(sizeof(unsigned int), oldlenp))
+			return -EFAULT;
+	}
+	if (newval && newlen) {
+		unsigned int freq;
+
+		if (newlen != sizeof(unsigned int))
+			return -EINVAL;
+
+		if (get_user(freq, (unsigned int *)newval))
+			return -EFAULT;
+
+		cpufreq_set(freq, cpu);
+	}
+	return 1;
+}
+
+/* ctl_table ctl_cpu_vars_{0,1,...,(NR_CPUS-1)} */
+/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
+        CTL_TABLE_CPU_VARS(0);
+#if NR_CPUS > 1
+	CTL_TABLE_CPU_VARS(1);
+#endif
+#if NR_CPUS > 2
+	CTL_TABLE_CPU_VARS(2);
+#endif
+#if NR_CPUS > 3
+	CTL_TABLE_CPU_VARS(3);
+#endif
+#if NR_CPUS > 4
+	CTL_TABLE_CPU_VARS(4);
+#endif
+#if NR_CPUS > 5
+	CTL_TABLE_CPU_VARS(5);
+#endif
+#if NR_CPUS > 6
+	CTL_TABLE_CPU_VARS(6);
+#endif
+#if NR_CPUS > 7
+	CTL_TABLE_CPU_VARS(7);
+#endif
+#if NR_CPUS > 8
+	CTL_TABLE_CPU_VARS(8);
+#endif
+#if NR_CPUS > 9
+	CTL_TABLE_CPU_VARS(9);
+#endif
+#if NR_CPUS > 10
+	CTL_TABLE_CPU_VARS(10);
+#endif
+#if NR_CPUS > 11
+	CTL_TABLE_CPU_VARS(11);
+#endif
+#if NR_CPUS > 12
+	CTL_TABLE_CPU_VARS(12);
+#endif
+#if NR_CPUS > 13
+	CTL_TABLE_CPU_VARS(13);
+#endif
+#if NR_CPUS > 14
+	CTL_TABLE_CPU_VARS(14);
+#endif
+#if NR_CPUS > 15
+	CTL_TABLE_CPU_VARS(15);
+#endif
+#if NR_CPUS > 16
+	CTL_TABLE_CPU_VARS(16);
+#endif
+#if NR_CPUS > 17
+	CTL_TABLE_CPU_VARS(17);
+#endif
+#if NR_CPUS > 18
+	CTL_TABLE_CPU_VARS(18);
+#endif
+#if NR_CPUS > 19
+	CTL_TABLE_CPU_VARS(19);
+#endif
+#if NR_CPUS > 20
+	CTL_TABLE_CPU_VARS(20);
+#endif
+#if NR_CPUS > 21
+	CTL_TABLE_CPU_VARS(21);
+#endif
+#if NR_CPUS > 22
+	CTL_TABLE_CPU_VARS(22);
+#endif
+#if NR_CPUS > 23
+	CTL_TABLE_CPU_VARS(23);
+#endif
+#if NR_CPUS > 24
+	CTL_TABLE_CPU_VARS(24);
+#endif
+#if NR_CPUS > 25
+	CTL_TABLE_CPU_VARS(25);
+#endif
+#if NR_CPUS > 26
+	CTL_TABLE_CPU_VARS(26);
+#endif
+#if NR_CPUS > 27
+	CTL_TABLE_CPU_VARS(27);
+#endif
+#if NR_CPUS > 28
+	CTL_TABLE_CPU_VARS(28);
+#endif
+#if NR_CPUS > 29
+	CTL_TABLE_CPU_VARS(29);
+#endif
+#if NR_CPUS > 30
+	CTL_TABLE_CPU_VARS(30);
+#endif
+#if NR_CPUS > 31
+	CTL_TABLE_CPU_VARS(31);
+#endif
+#if NR_CPUS > 32
+#error please extend CPU enumeration
+#endif
+
+/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
+static ctl_table ctl_cpu_table[NR_CPUS + 1] = {
+	CPU_ENUM(0),
+#if NR_CPUS > 1
+	CPU_ENUM(1),
+#endif
+#if NR_CPUS > 2
+	CPU_ENUM(2),
+#endif
+#if NR_CPUS > 3
+	CPU_ENUM(3),
+#endif
+#if NR_CPUS > 4
+	CPU_ENUM(4),
+#endif
+#if NR_CPUS > 5
+	CPU_ENUM(5),
+#endif
+#if NR_CPUS > 6
+	CPU_ENUM(6),
+#endif
+#if NR_CPUS > 7
+	CPU_ENUM(7),
+#endif
+#if NR_CPUS > 8
+	CPU_ENUM(8),
+#endif
+#if NR_CPUS > 9
+	CPU_ENUM(9),
+#endif
+#if NR_CPUS > 10
+	CPU_ENUM(10),
+#endif
+#if NR_CPUS > 11
+	CPU_ENUM(11),
+#endif
+#if NR_CPUS > 12
+	CPU_ENUM(12),
+#endif
+#if NR_CPUS > 13
+	CPU_ENUM(13),
+#endif
+#if NR_CPUS > 14
+	CPU_ENUM(14),
+#endif
+#if NR_CPUS > 15
+	CPU_ENUM(15),
+#endif
+#if NR_CPUS > 16
+	CPU_ENUM(16),
+#endif
+#if NR_CPUS > 17
+	CPU_ENUM(17),
+#endif
+#if NR_CPUS > 18
+	CPU_ENUM(18),
+#endif
+#if NR_CPUS > 19
+	CPU_ENUM(19),
+#endif
+#if NR_CPUS > 20
+	CPU_ENUM(20),
+#endif
+#if NR_CPUS > 21
+	CPU_ENUM(21),
+#endif
+#if NR_CPUS > 22
+	CPU_ENUM(22),
+#endif
+#if NR_CPUS > 23
+	CPU_ENUM(23),
+#endif
+#if NR_CPUS > 24
+	CPU_ENUM(24),
+#endif
+#if NR_CPUS > 25
+	CPU_ENUM(25),
+#endif
+#if NR_CPUS > 26
+	CPU_ENUM(26),
+#endif
+#if NR_CPUS > 27
+	CPU_ENUM(27),
+#endif
+#if NR_CPUS > 28
+	CPU_ENUM(28),
+#endif
+#if NR_CPUS > 29
+	CPU_ENUM(29),
+#endif
+#if NR_CPUS > 30
+	CPU_ENUM(30),
+#endif
+#if NR_CPUS > 31
+	CPU_ENUM(31),
+#endif
+#if NR_CPUS > 32
+#error please extend CPU enumeration
+#endif
+	{
+		.ctl_name	= 0,
+	}
+};
+
+static ctl_table ctl_cpu[2] = {
+	{
+		.ctl_name	= CTL_CPU,
+		.procname	= "cpu",
+		.mode		= 0555,
+		.child		= ctl_cpu_table,
+	},
+	{
+		.ctl_name	= 0,
+	}
+};
+
+struct ctl_table_header *cpufreq_sysctl_table;
+
+static inline void cpufreq_sysctl_init(void)
+{
+	cpufreq_sysctl_table = register_sysctl_table(ctl_cpu, 0);
+}
+
+static inline void cpufreq_sysctl_exit(void)
+{
+	unregister_sysctl_table(cpufreq_sysctl_table);
+}
+
+#else
+#define cpufreq_sysctl_init() do {} while(0)
+#define cpufreq_sysctl_exit() do {} while(0)
+#endif /* CONFIG_CPU_FREQ_24API */
+
+
+/************************** sysfs interface ************************/
+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);
+}
+
+static ssize_t show_speed (struct device *dev, char *buf)
+{
+	unsigned int cpu = to_cpu_nr(dev);
+
+	return sprintf (buf, "%u\n", cpu_cur_freq[cpu]);
+}
+
+static ssize_t 
+store_speed (struct device *dev, const char *buf, size_t count) 
+{
+	unsigned int cpu = to_cpu_nr(dev);
+	unsigned int freq = 0;
+	unsigned int ret;
+
+	ret = sscanf (buf, "%u", &freq);
+	if (ret != 1)
+		return -EINVAL;
+
+	cpufreq_set(freq, cpu);
+
+	return count;
+}
+
+static DEVICE_ATTR(scaling_setspeed, (S_IRUGO | S_IWUSR), show_speed, store_speed);
+
+
+static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
+				   unsigned int event)
+{
+	unsigned int cpu = policy->cpu;
+	switch (event) {
+	case CPUFREQ_GOV_START:
+		if ((!cpu_online(cpu)) || (!try_module_get(THIS_MODULE)) ||
+		    !policy->cur)
+			return -EINVAL;
+		down(&userspace_sem);
+		cpu_is_managed[cpu] = 1;		
+		cpu_min_freq[cpu] = policy->min;
+		cpu_max_freq[cpu] = policy->max;
+		cpu_cur_freq[cpu] = policy->cur;
+		device_create_file (policy->intf.dev, &dev_attr_scaling_setspeed);
+		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
+		up(&userspace_sem);
+		break;
+	case CPUFREQ_GOV_STOP:
+		down(&userspace_sem);
+		cpu_is_managed[cpu] = 0;
+		cpu_min_freq[cpu] = 0;
+		cpu_max_freq[cpu] = 0;
+		device_remove_file (policy->intf.dev, &dev_attr_scaling_setspeed);
+		up(&userspace_sem);
+		module_put(THIS_MODULE);
+		break;
+	case CPUFREQ_GOV_LIMITS:
+		down(&userspace_sem);
+		cpu_min_freq[cpu] = policy->min;
+		cpu_max_freq[cpu] = policy->max;
+		if (policy->max < cpu_cur_freq[cpu])
+			cpufreq_driver_target(&current_policy[cpu], policy->max, 
+			      CPUFREQ_RELATION_H);
+		else if (policy->min > cpu_cur_freq[cpu])
+			cpufreq_driver_target(&current_policy[cpu], policy->min, 
+			      CPUFREQ_RELATION_L);
+		memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
+		up(&userspace_sem);
+		break;
+	}
+	return 0;
+}
+
+/* on ARM SA1100 we need to rely on the values of cpufreq_get() - because 
+ * of this, cpu_cur_freq[] needs to be set early.
+ */
+#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_SA1100)
+extern unsigned int sa11x0_getspeed(void);
+
+static void cpufreq_sa11x0_compat(void)
+{
+	cpu_cur_freq[0] = sa11x0_getspeed();
+}
+#else
+#define cpufreq_sa11x0_compat() do {} while(0)
+#endif
+
+
+static struct cpufreq_governor cpufreq_gov_userspace = {
+	.name		= "userspace",
+	.governor	= cpufreq_governor_userspace,
+	.owner		= THIS_MODULE,
+};
+EXPORT_SYMBOL(cpufreq_gov_userspace);
+
+static int already_init = 0;
+
+int cpufreq_gov_userspace_init(void)
+{
+	if (!already_init) {
+		down(&userspace_sem);
+		cpufreq_sa11x0_compat();
+		cpufreq_sysctl_init();
+		cpufreq_register_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+		already_init = 1;
+		up(&userspace_sem);
+	}
+	return cpufreq_register_governor(&cpufreq_gov_userspace);
+}
+EXPORT_SYMBOL(cpufreq_gov_userspace_init);
+
+
+static void __exit cpufreq_gov_userspace_exit(void)
+{
+	cpufreq_unregister_governor(&cpufreq_gov_userspace);
+        cpufreq_unregister_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+	cpufreq_sysctl_exit();
+}
+
+
+MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>, Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION ("CPUfreq policy governor 'userspace'");
+MODULE_LICENSE ("GPL");
+
+module_init(cpufreq_gov_userspace_init);
+module_exit(cpufreq_gov_userspace_exit);
diff -urN linux-2.5.63-bk5/drivers/hotplug/Makefile linux-2.5.63-bk6/drivers/hotplug/Makefile
--- linux-2.5.63-bk5/drivers/hotplug/Makefile	Mon Feb 24 11:05:38 2003
+++ linux-2.5.63-bk6/drivers/hotplug/Makefile	Mon Mar 31 12:19:33 2003
@@ -18,7 +18,7 @@
 
 cpqphp-objs		:=	cpqphp_core.o	\
 				cpqphp_ctrl.o	\
-				cpqphp_proc.o	\
+				cpqphp_sysfs.o	\
 				cpqphp_pci.o
 
 ibmphp-objs		:=	ibmphp_core.o	\
diff -urN linux-2.5.63-bk5/drivers/hotplug/acpiphp_pci.c linux-2.5.63-bk6/drivers/hotplug/acpiphp_pci.c
--- linux-2.5.63-bk5/drivers/hotplug/acpiphp_pci.c	Mon Feb 24 11:05:04 2003
+++ linux-2.5.63-bk6/drivers/hotplug/acpiphp_pci.c	Mon Mar 31 12:19:33 2003
@@ -194,133 +194,6 @@
 	return 0;
 }
 
-
-/* enable pci_dev */
-static int configure_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct acpiphp_func *func;
-	struct acpiphp_bridge *bridge;
-	struct pci_dev *dev;
-
-	func = (struct acpiphp_func *)wrapped_dev->data;
-	bridge = (struct acpiphp_bridge *)wrapped_bus->data;
-	dev = wrapped_dev->dev;
-
-	/* TBD: support PCI-to-PCI bridge case */
-	if (!func || !bridge)
-		return 0;
-
-	//pci_proc_attach_device(dev);
-	//pci_announce_device_to_drivers(dev);
-	info("Device %s configured\n", dev->slot_name);
-
-	return 0;
-}
-
-
-static int is_pci_dev_in_use (struct pci_dev* dev)
-{
-	/*
-	 * dev->driver will be set if the device is in use by a new-style
-	 * driver -- otherwise, check the device's regions to see if any
-	 * driver has claimed them
-	 */
-
-	int i, inuse=0;
-
-	if (dev->driver) return 1; //assume driver feels responsible
-
-	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
-		if (!pci_resource_start(dev, i))
-			continue;
-
-		if (pci_resource_flags(dev, i) & IORESOURCE_IO)
-			inuse = check_region(pci_resource_start(dev, i),
-					     pci_resource_len(dev, i));
-		else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
-			inuse = check_mem_region(pci_resource_start(dev, i),
-						 pci_resource_len(dev, i));
-	}
-
-	return inuse;
-}
-
-
-static int pci_hp_remove_device (struct pci_dev *dev)
-{
-	if (is_pci_dev_in_use(dev)) {
-		err("***Cannot safely power down device -- "
-		       "it appears to be in use***\n");
-		return -EBUSY;
-	}
-	pci_remove_device(dev);
-	return 0;
-}
-
-
-/* remove device driver */
-static int unconfigure_pci_dev_driver (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	dbg("attempting removal of driver for device %s\n", dev->slot_name);
-
-	/* Now, remove the Linux Driver Representation */
-	if (dev->driver) {
-		if (dev->driver->remove) {
-			dev->driver->remove(dev);
-			dbg("driver was properly removed\n");
-		}
-		dev->driver = NULL;
-	}
-
-	return is_pci_dev_in_use(dev);
-}
-
-
-/* remove pci_dev itself from system */
-static int unconfigure_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	/* Now, remove the Linux Representation */
-	if (dev) {
-		if (pci_hp_remove_device(dev) == 0) {
-			info("Device %s removed\n", dev->slot_name);
-			kfree(dev); /* Now, remove */
-		} else {
-			return -1; /* problems while freeing, abort visitation */
-		}
-	}
-
-	return 0;
-}
-
-
-/* remove pci_bus itself from system */
-static int unconfigure_pci_bus (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
-{
-	struct pci_bus *bus = wrapped_bus->bus;
-
-#ifdef CONFIG_PROC_FS
-	/* Now, remove the Linux Representation */
-	if (bus->procdir) {
-		pci_proc_detach_bus(bus);
-	}
-#endif
-	/* the cleanup code should live in the kernel ... */
-	bus->self->subordinate = NULL;
-	/* unlink from parent bus */
-	list_del(&bus->node);
-
-	/* Now, remove */
-	if (bus)
-		kfree(bus);
-
-	return 0;
-}
-
-
 /* detect_used_resource - subtract resource under dev from bridge */
 static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
 {
@@ -592,22 +465,6 @@
 	return retval;
 }
 
-
-/* for pci_visit_dev() */
-static struct pci_visit configure_functions = {
-	.post_visit_pci_dev =	configure_pci_dev
-};
-
-static struct pci_visit unconfigure_functions_phase1 = {
-	.post_visit_pci_dev =	unconfigure_pci_dev_driver
-};
-
-static struct pci_visit unconfigure_functions_phase2 = {
-	.post_visit_pci_bus =	unconfigure_pci_bus,
-	.post_visit_pci_dev =	unconfigure_pci_dev
-};
-
-
 /**
  * acpiphp_configure_function - configure PCI function
  * @func: function to be configured
@@ -618,33 +475,10 @@
  */
 int acpiphp_configure_function (struct acpiphp_func *func)
 {
-	int retval = 0;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-	struct acpiphp_bridge *bridge;
-
-	/* if pci_dev is NULL, ignore it */
-	if (!func->pci_dev)
-		goto err_exit;
-
-	bridge = func->slot->bridge;
-
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-	wrapped_dev.dev = func->pci_dev;
-	wrapped_dev.data = func;
-	wrapped_bus.bus = bridge->pci_bus;
-	wrapped_bus.data = bridge;
-
-	retval = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
-	if (retval)
-		goto err_exit;
-
- err_exit:
-	return retval;
+	/* all handled by the pci core now */
+	return 0;
 }
 
-
 /**
  * acpiphp_unconfigure_function - unconfigure PCI function
  * @func: function to be unconfigured
@@ -653,28 +487,13 @@
 int acpiphp_unconfigure_function (struct acpiphp_func *func)
 {
 	struct acpiphp_bridge *bridge;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
 	int retval = 0;
 
 	/* if pci_dev is NULL, ignore it */
 	if (!func->pci_dev)
 		goto err_exit;
 
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-	wrapped_dev.dev = func->pci_dev;
-	//wrapped_dev.data = func;
-	wrapped_bus.bus = func->slot->bridge->pci_bus;
-	//wrapped_bus.data = func->slot->bridge;
-
-	retval = pci_visit_dev(&unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
-	if (retval)
-		goto err_exit;
-
-	retval = pci_visit_dev(&unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
-	if (retval)
-		goto err_exit;
+	pci_remove_bus_device(func->pci_dev);
 
 	/* free all resources */
 	bridge = func->slot->bridge;
diff -urN linux-2.5.63-bk5/drivers/hotplug/cpci_hotplug_pci.c linux-2.5.63-bk6/drivers/hotplug/cpci_hotplug_pci.c
--- linux-2.5.63-bk5/drivers/hotplug/cpci_hotplug_pci.c	Mon Feb 24 11:05:36 2003
+++ linux-2.5.63-bk6/drivers/hotplug/cpci_hotplug_pci.c	Mon Mar 31 12:19:33 2003
@@ -483,29 +483,6 @@
 	return 0;
 }
 
-static int unconfigure_visit_pci_dev_phase1(struct pci_dev_wrapped *wrapped_dev,
-				 struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	dbg("%s - enter", __FUNCTION__);
-
-	dbg("attempting removal of driver for device %02x:%02x.%x",
-	    dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-
-	/* Now, remove the Linux Driver representation */
-	if(dev->driver) {
-		dbg("device is attached to a driver");
-		if(dev->driver->remove) {
-			dev->driver->remove(dev);
-			dbg("driver was removed");
-		}
-		dev->driver = NULL;
-	}
-	dbg("%s - exit", __FUNCTION__);
-	return pci_is_dev_in_use(dev);
-}
-
 static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
 					    struct pci_bus_wrapped *wrapped_bus)
 {
@@ -577,10 +554,6 @@
 	.visit_pci_dev = configure_visit_pci_dev,
 };
 
-static struct pci_visit unconfigure_functions_phase1 = {
-	.post_visit_pci_dev = unconfigure_visit_pci_dev_phase1
-};
-
 static struct pci_visit unconfigure_functions_phase2 = {
 	.post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
 	.post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
@@ -668,13 +641,6 @@
 		if(dev) {
 			wrapped_dev.dev = dev;
 			wrapped_bus.bus = dev->bus;
-			dbg("%s - unconfigure phase 1", __FUNCTION__);
-			rc = pci_visit_dev(&unconfigure_functions_phase1,
-					   &wrapped_dev, &wrapped_bus);
-			if(rc) {
-				break;
-			}
-
 			dbg("%s - unconfigure phase 2", __FUNCTION__);
 			rc = pci_visit_dev(&unconfigure_functions_phase2,
 					   &wrapped_dev, &wrapped_bus);
diff -urN linux-2.5.63-bk5/drivers/hotplug/cpqphp.h linux-2.5.63-bk6/drivers/hotplug/cpqphp.h
--- linux-2.5.63-bk5/drivers/hotplug/cpqphp.h	Mon Feb 24 11:05:40 2003
+++ linux-2.5.63-bk6/drivers/hotplug/cpqphp.h	Mon Mar 31 12:19:33 2003
@@ -403,31 +403,8 @@
 #define msg_button_ignore	"PCI slot #%d - button press ignored.  (action in progress...)\n"
 
 
-/* Proc functions for the hotplug controller info */
-#ifdef CONFIG_PROC_FS
-extern int cpqhp_proc_init_ctrl		(void);
-extern int cpqhp_proc_destroy_ctrl	(void);
-extern int cpqhp_proc_create_ctrl	(struct controller *ctrl);
-extern int cpqhp_proc_remove_ctrl	(struct controller *ctrl);
-#else
-static inline int cpqhp_proc_init_ctrl (void)
-{
-	return 0;
-}
-static inline int cpqhp_proc_destroy_ctrl (void)
-{
-	return 0;
-}
-static inline int cpqhp_proc_create_ctrl (struct controller *ctrl)
-{
-	return 0;
-}
-static inline int cpqhp_proc_remove_ctrl (struct controller *ctrl)
-{
-	return 0;
-}
-#endif
-
+/* sysfs functions for the hotplug controller info */
+extern void cpqhp_create_ctrl_files		(struct controller *ctrl);
 
 /* controller functions */
 extern void	cpqhp_pushbutton_thread		(unsigned long event_pointer);
diff -urN linux-2.5.63-bk5/drivers/hotplug/cpqphp_core.c linux-2.5.63-bk6/drivers/hotplug/cpqphp_core.c
--- linux-2.5.63-bk5/drivers/hotplug/cpqphp_core.c	Mon Feb 24 11:05:04 2003
+++ linux-2.5.63-bk6/drivers/hotplug/cpqphp_core.c	Mon Mar 31 12:19:33 2003
@@ -1038,6 +1038,7 @@
 	dbg ("    pcix_support           %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported");
 
 	ctrl->pci_dev = pdev;
+	pci_set_drvdata(pdev, ctrl);
 
 	/* make our own copy of the pci bus structure, as we like tweaking it a lot */
 	ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
@@ -1231,11 +1232,7 @@
 	// Done with exclusive hardware access
 	up(&ctrl->crit_sect);
 
-	rc = cpqhp_proc_create_ctrl (ctrl);
-	if (rc) {
-		err("cpqhp_proc_create_ctrl failed\n");
-		goto err_free_irq;
-	}
+	cpqhp_create_ctrl_files (ctrl);
 
 	return 0;
 
@@ -1309,10 +1306,6 @@
 		goto error;
 	}
 
-	retval = cpqhp_proc_init_ctrl();
-	if (retval)
-		goto error;
-
 	initialized = 1;
 
 	return retval;
@@ -1343,8 +1336,6 @@
 	ctrl = cpqhp_ctrl_list;
 
 	while (ctrl) {
-		cpqhp_proc_remove_ctrl (ctrl);
-
 		if (ctrl->hpc_reg) {
 			u16 misc;
 			rc = read_slot_enable (ctrl);
@@ -1431,8 +1422,6 @@
 		}
 	}
 
-	remove_proc_entry("hpc", 0);
-
 	// Stop the notification mechanism
 	cpqhp_event_stop_thread();
 
@@ -1490,9 +1479,6 @@
 
 static void __exit cpqhpc_cleanup(void)
 {
-	dbg("cleaning up proc entries\n");
-	cpqhp_proc_destroy_ctrl();
-
 	dbg("unload_cpqphpd()\n");
 	unload_cpqphpd();
 
diff -urN linux-2.5.63-bk5/drivers/hotplug/cpqphp_pci.c linux-2.5.63-bk6/drivers/hotplug/cpqphp_pci.c
--- linux-2.5.63-bk5/drivers/hotplug/cpqphp_pci.c	Mon Feb 24 11:05:44 2003
+++ linux-2.5.63-bk6/drivers/hotplug/cpqphp_pci.c	Mon Mar 31 12:19:33 2003
@@ -44,48 +44,6 @@
 
 static u16 unused_IRQ;
 
-
-static int is_pci_dev_in_use(struct pci_dev* dev) 
-{
-	/* 
-	 * dev->driver will be set if the device is in use by a new-style 
-	 * driver -- otherwise, check the device's regions to see if any
-	 * driver has claimed them
-	 */
-
-	int i, inuse=0;
-
-	if (dev->driver) return 1; //assume driver feels responsible
-
-	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
-		if (!pci_resource_start(dev, i))
-			continue;
-
-		if (pci_resource_flags(dev, i) & IORESOURCE_IO)
-			inuse = check_region(pci_resource_start(dev, i),
-					     pci_resource_len(dev, i));
-		else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
-			inuse = check_mem_region(pci_resource_start(dev, i),
-						 pci_resource_len(dev, i));
-	}
-
-	return inuse;
-
-}
-
-
-static int pci_hp_remove_device(struct pci_dev *dev)
-{
-	if (is_pci_dev_in_use(dev)) {
-		err("***Cannot safely power down device -- "
-		       "it appears to be in use***\n");
-		return -EBUSY;
-	}
-	pci_remove_device(dev);
-	return 0;
-}
-
-
 /*
  * detect_HRT_floating_pointer
  *
@@ -122,144 +80,14 @@
 	return fp;
 }
 
-static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
-{
-	struct pci_bus* bus = wrapped_bus->bus;
-	struct pci_dev* dev = wrapped_dev->dev;
-	struct pci_func *temp_func;
-	int i=0;
-
-	//We need to fix up the hotplug function representation with the linux representation
-	do {
-		temp_func = cpqhp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	if (temp_func) {
-		temp_func->pci_dev = dev;
-	} else {
-		//We did not even find a hotplug rep of the function, create it
-		//This code might be taken out if we can guarantee the creation of functions
-		//in parallel (hotplug and Linux at the same time).
-		dbg("@@@@@@@@@@@ cpqhp_slot_create in %s\n", __FUNCTION__);
-		temp_func = cpqhp_slot_create(bus->number);
-		if (temp_func == NULL)
-			return -ENOMEM;
-		temp_func->pci_dev = dev;
-	}
-
-	//Create /proc/bus/pci proc entry for this device and bus device is on
-	//Notify the drivers of the change
-	if (temp_func->pci_dev) {
-//		pci_insert_device (temp_func->pci_dev, bus);
-//		pci_proc_attach_device(temp_func->pci_dev);
-//		pci_announce_device_to_drivers(temp_func->pci_dev);
-	}
-
-	return 0;
-}
-
-
-static int unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
-{
-	struct pci_dev* dev = wrapped_dev->dev;
-
-	struct pci_func *temp_func;
-	int i=0;
-
-	//We need to remove the hotplug function representation with the linux representation
-	do {
-		temp_func = cpqhp_slot_find(dev->bus->number, dev->devfn >> 3, i++);
-		if (temp_func) {
-			dbg("temp_func->function = %d\n", temp_func->function);
-		}
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	//Now, remove the Linux Representation
-	if (dev) {
-		if (pci_hp_remove_device(dev) == 0) {
-			kfree(dev); //Now, remove
-		} else {
-			return -1; // problems while freeing, abort visitation
-		}
-	}
-
-	if (temp_func) {
-		temp_func->pci_dev = NULL;
-	} else {
-		dbg("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
-	}
-
-	return 0;
-}
-
-
-static int unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev) 
-{
-	struct pci_bus* bus = wrapped_bus->bus;
-
-	//The cleanup code for proc entries regarding buses should be in the kernel...
-	if (bus->procdir)
-		dbg("detach_pci_bus %s\n", bus->procdir->name);
-	pci_proc_detach_bus(bus);
-	// The cleanup code should live in the kernel...
-	bus->self->subordinate = NULL;
-	// unlink from parent bus
-	list_del(&bus->node);
-
-	// Now, remove
-	if (bus)
-		kfree(bus);
-
-	return 0;
-}
-
-
-static int unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus) 
-{
-	struct pci_dev* dev = wrapped_dev->dev;
-
-	dbg("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	//Now, remove the Linux Driver Representation 
-	if (dev->driver) {
-		if (dev->driver->remove) {
-			dev->driver->remove(dev);
-			dbg("driver was properly removed\n");
-		}
-		dev->driver = NULL;
-	}
-
-	return is_pci_dev_in_use(dev);
-}
-
-
-static struct pci_visit configure_functions = {
-	.visit_pci_dev =	configure_visit_pci_dev,
-};
-
-
-static struct pci_visit unconfigure_functions_phase1 = {
-	.post_visit_pci_dev =	unconfigure_visit_pci_dev_phase1
-};
-
-static struct pci_visit unconfigure_functions_phase2 = {
-	.post_visit_pci_bus =	unconfigure_visit_pci_bus_phase2,               
-	.post_visit_pci_dev =	unconfigure_visit_pci_dev_phase2
-};
-
 
 int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)  
 {
 	unsigned char bus;
 	struct pci_dev dev0;
 	struct pci_bus *child;
-	struct pci_dev* temp;
 	int rc = 0;
 
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-
 	memset(&dev0, 0, sizeof(struct pci_dev));
 
 	if (func->pci_dev == NULL)
@@ -287,44 +115,22 @@
 
 	}
 
-	temp = func->pci_dev;
-
-	if (temp) {
-		wrapped_dev.dev = temp;
-		wrapped_bus.bus = temp->bus;
-		rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
-	}
 	return rc;
 }
 
 
 int cpqhp_unconfigure_device(struct pci_func* func) 
 {
-	int rc = 0;
 	int j;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
 	
-	memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
-	memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
-
 	dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
 
 	for (j=0; j<8 ; j++) {
 		struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
-		if (temp) {
-			wrapped_dev.dev = temp;
-			wrapped_bus.bus = temp->bus;
-			rc = pci_visit_dev(&unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-
-			rc = pci_visit_dev(&unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-		}
+		if (temp)
+			pci_remove_bus_device(temp);
 	}
-	return rc;
+	return 0;
 }
 
 static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
diff -urN linux-2.5.63-bk5/drivers/hotplug/cpqphp_proc.c linux-2.5.63-bk6/drivers/hotplug/cpqphp_proc.c
--- linux-2.5.63-bk5/drivers/hotplug/cpqphp_proc.c	Mon Feb 24 11:05:45 2003
+++ linux-2.5.63-bk6/drivers/hotplug/cpqphp_proc.c	Wed Dec 31 16:00:00 1969
@@ -1,197 +0,0 @@
-/*
- * Compaq Hot Plug Controller Driver
- *
- * Copyright (c) 1995,2001 Compaq Computer Corporation
- * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (c) 2001 IBM Corp.
- *
- * 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 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, GOOD TITLE or
- * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to <greg@kroah.com>
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/workqueue.h>
-#include <linux/pci.h>
-#include "cpqphp.h"
-
-
-
-static struct proc_dir_entry *ctrl_proc_root;
-
-/* A few routines that create proc entries for the hot plug controller */
-
-static int read_ctrl (char *buf, char **start, off_t offset, int len, int *eof, void *data)
-{
-	struct controller *ctrl = (struct controller *)data;
-	char * out = buf;
-	int index;
-	struct pci_resource *res;
-
-	if (offset > 0)	return 0; /* no partial requests */
-	len  = 0;
-	*eof = 1;
-
-	out += sprintf(out, "hot plug ctrl Info Page\n");
-	out += sprintf(out, "bus = %d, device = %d, function = %d\n",
-		       ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
-		       PCI_FUNC(ctrl->pci_dev->devfn));
-	out += sprintf(out, "Free resources: memory\n");
-	index = 11;
-	res = ctrl->mem_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-	out += sprintf(out, "Free resources: prefetchable memory\n");
-	index = 11;
-	res = ctrl->p_mem_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-	out += sprintf(out, "Free resources: IO\n");
-	index = 11;
-	res = ctrl->io_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-	out += sprintf(out, "Free resources: bus numbers\n");
-	index = 11;
-	res = ctrl->bus_head;
-	while (res && index--) {
-		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-		res = res->next;
-	}
-
-	*start = buf;
-	len = out-buf;
-
-	return len;
-}
-
-static int read_dev (char *buf, char **start, off_t offset, int len, int *eof, void *data)
-{
-	struct controller *ctrl = (struct controller *)data;
-	char * out = buf;
-	int index;
-	struct pci_resource *res;
-	struct pci_func *new_slot;
-	struct slot *slot;
-
-	if (offset > 0)	return 0; /* no partial requests */
-	len  = 0;
-	*eof = 1;
-
-	out += sprintf(out, "hot plug ctrl Info Page\n");
-	out += sprintf(out, "bus = %d, device = %d, function = %d\n",
-		       ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
-		       PCI_FUNC(ctrl->pci_dev->devfn));
-
-	slot=ctrl->slot;
-
-	while (slot) {
-		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
-		if (!new_slot)
-			break;
-		out += sprintf(out, "assigned resources: memory\n");
-		index = 11;
-		res = new_slot->mem_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		out += sprintf(out, "assigned resources: prefetchable memory\n");
-		index = 11;
-		res = new_slot->p_mem_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		out += sprintf(out, "assigned resources: IO\n");
-		index = 11;
-		res = new_slot->io_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		out += sprintf(out, "assigned resources: bus numbers\n");
-		index = 11;
-		res = new_slot->bus_head;
-		while (res && index--) {
-			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
-			res = res->next;
-		}
-		slot=slot->next;
-	}
-
-	*start = buf;
-	len = out-buf;
-
-	return len;
-}
-
-int cpqhp_proc_create_ctrl (struct controller *ctrl)
-{
-	strcpy(ctrl->proc_name, "hpca");
-	ctrl->proc_name[3] = 'a' + ctrl->bus;
-
-	ctrl->proc_entry = create_proc_entry(ctrl->proc_name, S_IFREG | S_IRUGO, ctrl_proc_root);
-	ctrl->proc_entry->data = ctrl;
-	ctrl->proc_entry->read_proc = &read_ctrl;
-
-	strcpy(ctrl->proc_name2, "slot_a");
-	ctrl->proc_name2[5] = 'a' + ctrl->bus;
-	ctrl->proc_entry2 = create_proc_entry(ctrl->proc_name2, S_IFREG | S_IRUGO, ctrl_proc_root);
-	ctrl->proc_entry2->data = ctrl;
-	ctrl->proc_entry2->read_proc = &read_dev;
-
-	return 0;
-}
-
-int cpqhp_proc_remove_ctrl (struct controller *ctrl)
-{
-	if (ctrl->proc_entry)
-		remove_proc_entry(ctrl->proc_name, ctrl_proc_root);
-	if (ctrl->proc_entry2)
-		remove_proc_entry(ctrl->proc_name2, ctrl_proc_root);
-
-	return 0;
-}
-	
-int cpqhp_proc_init_ctrl (void)
-{
-	ctrl_proc_root = proc_mkdir("hpc", proc_root_driver);
-	if (!ctrl_proc_root)
-		return -ENOMEM;
-	ctrl_proc_root->owner = THIS_MODULE;
-	return 0;
-}
-
-int cpqhp_proc_destroy_ctrl (void)
-{
-	remove_proc_entry("hpc", proc_root_driver);
-	return 0;
-}
-
diff -urN linux-2.5.63-bk5/drivers/hotplug/cpqphp_sysfs.c linux-2.5.63-bk6/drivers/hotplug/cpqphp_sysfs.c
--- linux-2.5.63-bk5/drivers/hotplug/cpqphp_sysfs.c	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/drivers/hotplug/cpqphp_sysfs.c	Mon Mar 31 12:19:33 2003
@@ -0,0 +1,143 @@
+/*
+ * Compaq Hot Plug Controller Driver
+ *
+ * Copyright (c) 1995,2001 Compaq Computer Corporation
+ * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (c) 2001 IBM Corp.
+ *
+ * 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 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Send feedback to <greg@kroah.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/workqueue.h>
+#include <linux/pci.h>
+#include "cpqphp.h"
+
+
+/* A few routines that create sysfs entries for the hot plug controller */
+
+static int show_ctrl (struct device *dev, char *buf)
+{
+	struct pci_dev *pci_dev;
+	struct controller *ctrl;
+	char * out = buf;
+	int index;
+	struct pci_resource *res;
+
+	pci_dev = container_of (dev, struct pci_dev, dev);
+	ctrl = pci_get_drvdata(pci_dev);
+
+	out += sprintf(buf, "Free resources: memory\n");
+	index = 11;
+	res = ctrl->mem_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+	out += sprintf(out, "Free resources: prefetchable memory\n");
+	index = 11;
+	res = ctrl->p_mem_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+	out += sprintf(out, "Free resources: IO\n");
+	index = 11;
+	res = ctrl->io_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+	out += sprintf(out, "Free resources: bus numbers\n");
+	index = 11;
+	res = ctrl->bus_head;
+	while (res && index--) {
+		out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+		res = res->next;
+	}
+
+	return out - buf;
+}
+static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
+
+static int show_dev (struct device *dev, char *buf)
+{
+	struct pci_dev *pci_dev;
+	struct controller *ctrl;
+	char * out = buf;
+	int index;
+	struct pci_resource *res;
+	struct pci_func *new_slot;
+	struct slot *slot;
+
+	pci_dev = container_of (dev, struct pci_dev, dev);
+	ctrl = pci_get_drvdata(pci_dev);
+
+	slot=ctrl->slot;
+
+	while (slot) {
+		new_slot = cpqhp_slot_find(slot->bus, slot->device, 0);
+		if (!new_slot)
+			break;
+		out += sprintf(out, "assigned resources: memory\n");
+		index = 11;
+		res = new_slot->mem_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		out += sprintf(out, "assigned resources: prefetchable memory\n");
+		index = 11;
+		res = new_slot->p_mem_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		out += sprintf(out, "assigned resources: IO\n");
+		index = 11;
+		res = new_slot->io_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		out += sprintf(out, "assigned resources: bus numbers\n");
+		index = 11;
+		res = new_slot->bus_head;
+		while (res && index--) {
+			out += sprintf(out, "start = %8.8x, length = %8.8x\n", res->base, res->length);
+			res = res->next;
+		}
+		slot=slot->next;
+	}
+
+	return out - buf;
+}
+static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL);
+
+void cpqhp_create_ctrl_files (struct controller *ctrl)
+{
+	device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl);
+	device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev);
+}
diff -urN linux-2.5.63-bk5/drivers/hotplug/ibmphp.h linux-2.5.63-bk6/drivers/hotplug/ibmphp.h
--- linux-2.5.63-bk5/drivers/hotplug/ibmphp.h	Mon Feb 24 11:05:08 2003
+++ linux-2.5.63-bk6/drivers/hotplug/ibmphp.h	Mon Mar 31 12:19:33 2003
@@ -683,11 +683,6 @@
 #define ENABLE		1
 #define DISABLE		0
 
-#define ADD		0
-#define REMOVE		1
-#define DETAIL		2
-
-#define MAX_OPS		3
 #define CARD_INFO	0x07
 #define PCIX133		0x07
 #define PCIX66		0x05
@@ -761,6 +756,7 @@
 
 extern int ibmphp_init_devno (struct slot **);	/* This function is called from EBDA, so we need it not be static */
 extern int ibmphp_disable_slot (struct hotplug_slot *);	/* This function is called from HPC, so we need it to not be static */
+extern int ibmphp_do_disable_slot (struct slot *slot_cur);
 extern int ibmphp_update_slot_info (struct slot *);	/* This function is called from HPC, so we need it to not be be static */
 extern int ibmphp_configure_card (struct pci_func *, u8);
 extern int ibmphp_unconfigure_card (struct slot **, int);
diff -urN linux-2.5.63-bk5/drivers/hotplug/ibmphp_core.c linux-2.5.63-bk6/drivers/hotplug/ibmphp_core.c
--- linux-2.5.63-bk5/drivers/hotplug/ibmphp_core.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/hotplug/ibmphp_core.c	Mon Mar 31 12:19:33 2003
@@ -55,7 +55,6 @@
 MODULE_LICENSE ("GPL");
 MODULE_DESCRIPTION (DRIVER_DESC);
 
-static int *ops[MAX_OPS + 1];
 struct pci_bus *ibmphp_pci_bus;
 static int max_slots;
 
@@ -550,20 +549,6 @@
 	struct list_head *tmp;
 	int retval;
 	int rc;
-	int j;
-
-	for (j = 0; j < MAX_OPS; j++) {
-		ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL);
-		memset (ops[j], 0, (max_slots + 1) * sizeof (int));
-		if (!ops[j]) {
-			err ("out of system memory \n");
-			return -ENOMEM;
-		}
-	}
-
-	ops[ADD][0] = 0;
-	ops[REMOVE][0] = 0;
-	ops[DETAIL][0] = 0;
 
 	list_for_each (tmp, &ibmphp_slot_head) {
 		slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
@@ -588,24 +573,15 @@
 		if (retval)
 			return retval;
 
-		debug ("status = %x, ext_status = %x\n", slot_cur->status, slot_cur->ext_status);
-		debug ("SLOT_POWER = %x, SLOT_PRESENT = %x, SLOT_LATCH = %x\n", SLOT_POWER (slot_cur->status), SLOT_PRESENT (slot_cur->status), SLOT_LATCH (slot_cur->status));
-
-		if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
-			/* No power, adapter, and latch closed */
-			ops[ADD][slot_cur->number] = 1;
-		else
-			ops[ADD][slot_cur->number] = 0;
-
-		ops[DETAIL][slot_cur->number] = 1;
-
-		if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
-			/*Power,adapter,latch closed */
-			ops[REMOVE][slot_cur->number] = 1;
-		else
-			ops[REMOVE][slot_cur->number] = 0;
-
-		if ((SLOT_PWRGD (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) {
+		debug ("status = %x\n", slot_cur->status);
+		debug ("ext_status = %x\n", slot_cur->ext_status);
+		debug ("SLOT_POWER = %x\n", SLOT_POWER (slot_cur->status));
+		debug ("SLOT_PRESENT = %x\n", SLOT_PRESENT (slot_cur->status));
+		debug ("SLOT_LATCH = %x\n", SLOT_LATCH (slot_cur->status));
+
+		if ((SLOT_PWRGD (slot_cur->status)) && 
+		    !(SLOT_PRESENT (slot_cur->status)) && 
+		    !(SLOT_LATCH (slot_cur->status))) {
 			debug ("BEFORE POWER OFF COMMAND\n");
 				rc = power_off (slot_cur);
 				if (rc)
@@ -643,35 +619,20 @@
 	if (retval)
 		return retval;
 
-	if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
-	    && !(SLOT_LATCH (slot_cur->status)))
-		ops[ADD][number] = 1;
-	else
-		ops[ADD][number] = 0;
-
-	ops[DETAIL][number] = 1;
-
-	if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
-	    && !(SLOT_LATCH (slot_cur->status)))
-		ops[REMOVE][number] = 1;
-	else
-		ops[REMOVE][number] = 0;
-
 	switch (opn) {
 		case ENABLE:
-			if (ops[ADD][number])
+			if (!(SLOT_PWRGD (slot_cur->status)) && 
+			     (SLOT_PRESENT (slot_cur->status)) && 
+			     !(SLOT_LATCH (slot_cur->status)))
 				return 0;
 			break;
 		case DISABLE:
-			if (ops[REMOVE][number])
-				return 0;
-			break;
-		case DETAIL:
-			if (ops[DETAIL][number])
+			if ((SLOT_PWRGD (slot_cur->status)) && 
+			    (SLOT_PRESENT (slot_cur->status)) &&
+			    !(SLOT_LATCH (slot_cur->status)))
 				return 0;
 			break;
 		default:
-			return -EINVAL;
 			break;
 	}
 	err ("validate failed....\n");
@@ -820,174 +781,23 @@
 	debug ("%s -- exit\n", __FUNCTION__);
 }
 
-static int ibm_is_pci_dev_in_use (struct pci_dev *dev)
-{
-	int i = 0;
-	int inuse = 0;
-
-	if (dev->driver)
-		return 1;
-
-	for (i = 0; !dev->driver && !inuse && (i < 6); i++) {
-
-		if (!pci_resource_start (dev, i))
-			continue;
-
-		if (pci_resource_flags (dev, i) & IORESOURCE_IO)
-			inuse = check_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
-
-		else if (pci_resource_flags (dev, i) & IORESOURCE_MEM)
-			inuse = check_mem_region (pci_resource_start (dev, i), pci_resource_len (dev, i));
-	}
-
-	return inuse;
-}
-
-static int ibm_pci_hp_remove_device (struct pci_dev *dev)
-{
-	if (ibm_is_pci_dev_in_use (dev)) {
-		err ("***Cannot safely power down device -- it appears to be in use***\n");
-		return -EBUSY;
-	}
-	pci_remove_device (dev);
-	return 0;
-}
-
-static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-	struct pci_func *temp_func;
-	int i = 0;
-
-	do {
-		temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	if (dev) {
-		if (ibm_pci_hp_remove_device (dev) == 0)
-			kfree (dev);    /* Now, remove */
-		else
-			return -1;
-	}
-
-	if (temp_func)
-		temp_func->dev = NULL;
-	else
-		debug ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
-
-	return 0;
-}
-
-static int ibm_unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
-{
-	struct pci_bus *bus = wrapped_bus->bus;
-
-	pci_proc_detach_bus (bus);
-	/* The cleanup code should live in the kernel... */
-	bus->self->subordinate = NULL;
-	/* unlink from parent bus */
-	list_del (&bus->node);
-
-	/* Now, remove */
-	if (bus)
-		kfree (bus);
-
-	return 0;
-}
-
-static int ibm_unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	struct pci_dev *dev = wrapped_dev->dev;
-
-	debug ("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT (dev->devfn), PCI_FUNC (dev->devfn));
-
-	/* Now, remove the Linux Driver Representation */
-	if (dev->driver) {
-		debug ("is there a driver?\n");
-		if (dev->driver->remove) {
-			dev->driver->remove (dev);
-			debug ("driver was properly removed\n");
-		}
-		dev->driver = NULL;
-	}
-
-	return ibm_is_pci_dev_in_use (dev);
-}
-
-static struct pci_visit ibm_unconfigure_functions_phase1 = {
-	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase1,
-};
-
-static struct pci_visit ibm_unconfigure_functions_phase2 = {
-	.post_visit_pci_bus =	ibm_unconfigure_visit_pci_bus_phase2,
-	.post_visit_pci_dev =	ibm_unconfigure_visit_pci_dev_phase2,
-};
-
 static int ibm_unconfigure_device (struct pci_func *func)
 {
-	int rc = 0;
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
 	struct pci_dev *temp;
 	u8 j;
 
-	memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-	memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
-
-	debug ("inside ibm_unconfigure_device\n");
+	debug ("inside %s\n", __FUNCTION__);
 	debug ("func->device = %x, func->function = %x\n", func->device, func->function);
 	debug ("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0);
 
 	for (j = 0; j < 0x08; j++) {
 		temp = pci_find_slot (func->busno, (func->device << 3) | j);
-		if (temp) {
-			wrapped_dev.dev = temp;
-			wrapped_bus.bus = temp->bus;
-			rc = pci_visit_dev (&ibm_unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-
-			rc = pci_visit_dev (&ibm_unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
-			if (rc)
-				break;
-		}
+		if (temp)
+			pci_remove_bus_device(temp);
 	}
-	debug ("rc in ibm_unconfigure_device b4 returning is %d \n", rc);
-	return rc;
-}
-
-static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
-{
-	//      struct pci_bus *bus = wrapped_bus->bus; /* We don't need this, since we don't create in the else statement */
-	struct pci_dev *dev = wrapped_dev->dev;
-	struct pci_func *temp_func;
-	int i = 0;
-
-	do {
-		temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
-	} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
-
-	if (temp_func)
-		temp_func->dev = dev;
-	else {
-		/* This should not really happen, since we create functions
-		   first and then call to configure */
-		debug (" We shouldn't come here \n");
-	}
-
-	if (temp_func->dev) {
-//		pci_proc_attach_device (temp_func->dev);
-//		pci_announce_device_to_drivers (temp_func->dev);
-	}
-
 	return 0;
 }
 
-static struct pci_visit configure_functions = {
-	.visit_pci_dev =configure_visit_pci_dev,
-};
-
-
 /*
  * The following function is to fix kernel bug regarding 
  * getting bus entries, here we manually add those primary 
@@ -1037,15 +847,9 @@
 	unsigned char bus;
 	struct pci_dev dev0;
 	struct pci_bus *child;
-	struct pci_dev *temp;
 	int rc = 0;
 	int flag = 0;	/* this is to make sure we don't double scan the bus, for bridged devices primarily */
 
-	struct pci_dev_wrapped wrapped_dev;
-	struct pci_bus_wrapped wrapped_bus;
-
-	memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
-	memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
 	memset (&dev0, 0, sizeof (struct pci_dev));
 
 	if (!(bus_structure_fixup (func->busno)))
@@ -1073,12 +877,6 @@
 		pci_do_scan_bus (child);
 	}
 
-	temp = func->dev;
-	if (temp) {
-		wrapped_dev.dev = temp;
-		wrapped_bus.bus = temp->bus;
-		rc = pci_visit_dev (&configure_functions, &wrapped_dev, &wrapped_bus);
-	}
 	return rc;
 }
 
@@ -1274,7 +1072,6 @@
 	int rc, i, rcpr;
 	struct slot *slot_cur;
 	u8 function;
-	u8 faulted = 0;
 	struct pci_func *tmp_func;
 
 	ibmphp_lock_operations ();
@@ -1284,16 +1081,7 @@
 
 	if ((rc = validate (slot_cur, ENABLE))) {
 		err ("validate function failed \n");
-		attn_off (slot_cur);	/* need to turn off if was blinking b4 */
-		attn_on (slot_cur);
-		rc = slot_update (&slot_cur);
-		if (rc) {
-			ibmphp_unlock_operations();
-			return rc;
-		}
-		ibmphp_update_slot_info (slot_cur);
-                ibmphp_unlock_operations ();
-		return rc;
+		goto error_nopower;
 	}
 
 	attn_LED_blink (slot_cur);
@@ -1301,10 +1089,7 @@
 	rc = set_bus (slot_cur);
 	if (rc) {
 		err ("was not able to set the bus \n");
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		ibmphp_unlock_operations ();
-		return -ENODEV;
+		goto error_nopower;
 	}
 
 	/*-----------------debugging------------------------------*/
@@ -1314,18 +1099,12 @@
 
 	rc = check_limitations (slot_cur);
 	if (rc) {
-		err ("Adding this card exceeds the limitations of this bus. \n");
-		err ("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus \n. Try hot-adding into another bus \n");
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-
-		if (slot_update (&slot_cur)) {
-			ibmphp_unlock_operations ();
-			return -ENODEV;
-		}
-		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return -EINVAL;
+		err ("Adding this card exceeds the limitations of this bus.\n");
+		err ("(i.e., >1 133MHz cards running on same bus, or "
+		     ">2 66 PCI cards running on same bus\n.");
+		err ("Try hot-adding into another bus \n");
+		rc = -EINVAL;
+		goto error_nopower;
 	}
 
 	rc = power_on (slot_cur);
@@ -1338,8 +1117,8 @@
 		if (slot_update (&slot_cur)) {
 			attn_off (slot_cur);
 			attn_on (slot_cur);
-			ibmphp_unlock_operations ();
-			return -ENODEV;
+			rc = -ENODEV;
+			goto exit;
 		}
 		/* Check to see the error of why it failed */
 		if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PWRGD (slot_cur->status)))
@@ -1352,8 +1131,7 @@
 			print_card_capability (slot_cur);
 		}
 		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return rc;
+		goto exit;
 	}
 	debug ("after power_on\n");
 	/*-----------------------debugging---------------------------*/
@@ -1362,61 +1140,32 @@
 	/*----------------------------------------------------------*/
 
 	rc = slot_update (&slot_cur);
-	if (rc) {
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		rcpr = power_off (slot_cur);
-		if (rcpr) {
-			ibmphp_unlock_operations ();
-			return rcpr;
-		}
-		ibmphp_unlock_operations ();
-		return rc;
-	}
+	if (rc)
+		goto error_power;
 	
+	rc = -EINVAL;
 	if (SLOT_POWER (slot_cur->status) && !(SLOT_PWRGD (slot_cur->status))) {
-		faulted = 1;
 		err ("power fault occurred trying to power up... \n");
-	} else if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) {
-		faulted = 1;
+		goto error_power;
+	}
+	if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) {
 		err ("bus speed mismatch occurred.  please check current bus speed and card capability \n");
 		print_card_capability (slot_cur);
+		goto error_power;
 	} 
 	/* Don't think this case will happen after above checks... but just in case, for paranoia sake */
-	else if (!(SLOT_POWER (slot_cur->status))) {
+	if (!(SLOT_POWER (slot_cur->status))) {
 		err ("power on failed... \n");
-		faulted = 1;
-	}
-	if (faulted) {
-		attn_off (slot_cur);	/* need to turn off b4 on */
-		attn_on (slot_cur);
-		rcpr = power_off (slot_cur);
-		if (rcpr) {
-			ibmphp_unlock_operations ();
-			return rcpr;
-		}
-			
-		if (slot_update (&slot_cur)) {                      
-			ibmphp_unlock_operations ();	
-			return -ENODEV;
-		}
-		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return -EINVAL;
+		goto error_power;
 	}
 
 	slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
-	if (!slot_cur->func) { /* We cannot do update_slot_info here, since no memory for kmalloc n.e.ways, and update_slot_info allocates some */
+	if (!slot_cur->func) {
+		/* We cannot do update_slot_info here, since no memory for
+		 * kmalloc n.e.ways, and update_slot_info allocates some */
 		err ("out of system memory \n");
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		rcpr = power_off (slot_cur);
-		if (rcpr) {
-			ibmphp_unlock_operations ();
-			return rcpr;
-		}
-		ibmphp_unlock_operations ();
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto error_power;
 	}
 	memset (slot_cur->func, 0, sizeof (struct pci_func));
 	slot_cur->func->busno = slot_cur->bus;
@@ -1431,21 +1180,10 @@
 		ibmphp_unconfigure_card (&slot_cur, 1); /* true because don't need to actually deallocate resources, just remove references */
 		debug ("after unconfigure_card\n");
 		slot_cur->func = NULL;
-		attn_off (slot_cur);	/* need to turn off in case was blinking */
-		attn_on (slot_cur);
-		rcpr = power_off (slot_cur);
-		if (rcpr) {
-			ibmphp_unlock_operations ();
-			return rcpr;
-		}
-		if (slot_update (&slot_cur)) {
-			ibmphp_unlock_operations();
-			return -ENODEV;
-		}
-		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto error_power;
 	}
+
 	function = 0x00;
 	do {
 		tmp_func = ibm_slot_find (slot_cur->bus, slot_cur->func->device, function++);
@@ -1455,13 +1193,36 @@
 
 	attn_off (slot_cur);
 	if (slot_update (&slot_cur)) {
-		ibmphp_unlock_operations ();
-		return -EFAULT;
+		rc = -EFAULT;
+		goto exit;
 	}
 	ibmphp_print_test ();
 	rc = ibmphp_update_slot_info (slot_cur);
+exit:
 	ibmphp_unlock_operations(); 
 	return rc;
+
+error_nopower:
+	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
+	attn_on (slot_cur);
+error_cont:
+	rcpr = slot_update (&slot_cur);
+	if (rcpr) {
+		rc = rcpr;
+		goto exit;
+	}
+	ibmphp_update_slot_info (slot_cur);
+	goto exit;
+
+error_power:
+	attn_off (slot_cur);	/* need to turn off if was blinking b4 */
+	attn_on (slot_cur);
+	rcpr = power_off (slot_cur);
+	if (rcpr) {
+		rc = rcpr;
+		goto exit;
+	}
+	goto error_cont;
 }
 
 /**************************************************************
@@ -1472,45 +1233,34 @@
 **************************************************************/
 int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
 {
+	struct slot *slot = hotplug_slot->private;
+	int rc;
+	
+	ibmphp_lock_operations();
+	rc = ibmphp_do_disable_slot(slot);
+	ibmphp_unlock_operations();
+	return rc;
+}
+
+int ibmphp_do_disable_slot (struct slot *slot_cur)
+{
 	int rc;
-	struct slot *slot_cur = (struct slot *) hotplug_slot->private;
 	u8 flag;
 	int parm = 0;
 
 	debug ("DISABLING SLOT... \n"); 
 		
-	if (slot_cur == NULL) {
-		ibmphp_unlock_operations (); 
-		return -ENODEV;
-	}
-	
-	if (slot_cur->ctrl == NULL) {
-		ibmphp_unlock_operations ();
+	if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {
 		return -ENODEV;
 	}
 	
-	flag = slot_cur->flag;	/* to see if got here from polling */
-	
-	if (flag)
-		ibmphp_lock_operations ();
-	
+	flag = slot_cur->flag;
 	slot_cur->flag = TRUE;
 
 	if (flag == TRUE) {
 		rc = validate (slot_cur, DISABLE);	/* checking if powered off already & valid slot # */
-		if (rc) {
-			/*  Need to turn off if was blinking b4 */
-			attn_off (slot_cur);
-			attn_on (slot_cur);
-			if (slot_update (&slot_cur)) {
-				ibmphp_unlock_operations ();
-				return -EFAULT;
-			}
-		
-			ibmphp_update_slot_info (slot_cur);
-			ibmphp_unlock_operations ();
-			return rc;
-		}
+		if (rc)
+			goto error;
 	}
 	attn_LED_blink (slot_cur);
 
@@ -1519,10 +1269,8 @@
 		slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL);
 		if (!slot_cur->func) {
 			err ("out of system memory \n");
-			attn_off (slot_cur);
-			attn_on (slot_cur);
-			ibmphp_unlock_operations ();
-			return -ENOMEM;
+			rc = -ENOMEM;
+			goto error;
 		}
 		memset (slot_cur->func, 0, sizeof (struct pci_func));
 		slot_cur->func->busno = slot_cur->bus;
@@ -1531,11 +1279,9 @@
 
 	if ((rc = ibm_unconfigure_device (slot_cur->func))) {
 		err ("removing from kernel failed... \n");
-		err ("Please check to see if it was statically linked or is in use otherwise. (perhaps the driver is not 'hot-removable')\n");
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		ibmphp_unlock_operations ();
-		return rc;
+		err ("Please check to see if it was statically linked or is "
+		     "in use otherwise. (perhaps the driver is not 'hot-removable')\n");
+		goto error;
 	}
         
 	/* If we got here from latch suddenly opening on operating card or 
@@ -1554,43 +1300,34 @@
 	debug ("in disable_slot. after unconfigure_card\n");
 	if (rc) {
 		err ("could not unconfigure card.\n");
-		attn_off (slot_cur);	/* need to turn off if was blinking b4 */
-		attn_on (slot_cur);
-
-		if (slot_update (&slot_cur)) {
-			ibmphp_unlock_operations ();
-			return -EFAULT;
-		}
-
-		if (flag)
-			ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return -EFAULT;
+		goto error;
 	}
 
-	rc = ibmphp_hpc_writeslot (hotplug_slot->private, HPC_SLOT_OFF);
-	if (rc) {
-		attn_off (slot_cur);
-		attn_on (slot_cur);
-		if (slot_update (&slot_cur)) {
-			ibmphp_unlock_operations ();
-			return -EFAULT;
-		}
-
-		ibmphp_update_slot_info (slot_cur);
-		ibmphp_unlock_operations ();
-		return rc;
-	}
+	rc = ibmphp_hpc_writeslot (slot_cur, HPC_SLOT_OFF);
+	if (rc)
+		goto error;
 
 	attn_off (slot_cur);
-	if (slot_update (&slot_cur)) {
-		ibmphp_unlock_operations ();
-		return -EFAULT;
-	}
+	rc = slot_update (&slot_cur);
+	if (rc)
+		goto exit;
+
 	rc = ibmphp_update_slot_info (slot_cur);
 	ibmphp_print_test ();
-	ibmphp_unlock_operations();
+exit:
 	return rc;
+
+error:
+	/*  Need to turn off if was blinking b4 */
+	attn_off (slot_cur);
+	attn_on (slot_cur);
+	if (slot_update (&slot_cur)) {
+		rc = -EFAULT;
+		goto exit;
+	}
+	if (flag)		
+		ibmphp_update_slot_info (slot_cur);
+	goto exit;
 }
 
 struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
@@ -1622,6 +1359,7 @@
 	debug ("after ebda hpc \n");
 	ibmphp_free_ebda_pci_rsrc_queue ();
 	debug ("after ebda pci rsrc \n");
+	kfree (ibmphp_pci_bus);
 }
 
 static int __init ibmphp_init (void)
@@ -1637,13 +1375,15 @@
 	ibmphp_pci_bus = kmalloc (sizeof (*ibmphp_pci_bus), GFP_KERNEL);
 	if (!ibmphp_pci_bus) {
 		err ("out of memory\n");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto exit;
 	}
 
 	bus = ibmphp_find_bus (0);
 	if (!bus) {
 		err ("Can't find the root pci bus, can not continue\n");
-		return -ENODEV;
+		rc = -ENODEV;
+		goto error;
 	}
 	memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus));
 
@@ -1654,39 +1394,39 @@
 	for (i = 0; i < 16; i++)
 		irqs[i] = 0;
 
-	if ((rc = ibmphp_access_ebda ())) {
-		ibmphp_unload ();
-		return rc;
-	}
+	if ((rc = ibmphp_access_ebda ()))
+		goto error;
 	debug ("after ibmphp_access_ebda ()\n");
 
-	if ((rc = ibmphp_rsrc_init ())) {
-		ibmphp_unload ();
-		return rc;
-	}
+	if ((rc = ibmphp_rsrc_init ()))
+		goto error;
 	debug ("AFTER Resource & EBDA INITIALIZATIONS\n");
 
 	max_slots = get_max_slots ();
 	
-	if ((rc = ibmphp_register_pci ())) {
-		ibmphp_unload ();
-		return rc;
-	}
+	if ((rc = ibmphp_register_pci ()))
+		goto error;
 
 	if (init_ops ()) {
-		ibmphp_unload ();
-		return -ENODEV;
+		rc = -ENODEV;
+		goto error;
 	}
+
 	ibmphp_print_test ();
 	if ((rc = ibmphp_hpc_start_poll_thread ())) {
-		ibmphp_unload ();
-		return -ENODEV;
+		goto error;
 	}
 
-	/* if no NVRAM module selected, lock ourselves into memory with a 
-	 * module count of -1 so that no one can unload us. */
+	/* lock ourselves into memory with a module 
+	 * count of -1 so that no one can unload us. */
 	MOD_DEC_USE_COUNT;
-	return 0;
+
+exit:
+	return rc;
+
+error:
+	ibmphp_unload ();
+	goto exit;
 }
 
 static void __exit ibmphp_exit (void)
diff -urN linux-2.5.63-bk5/drivers/hotplug/ibmphp_hpc.c linux-2.5.63-bk6/drivers/hotplug/ibmphp_hpc.c
--- linux-2.5.63-bk5/drivers/hotplug/ibmphp_hpc.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk6/drivers/hotplug/ibmphp_hpc.c	Mon Mar 31 12:19:33 2003
@@ -1063,7 +1063,7 @@
 	if (disable) {
 		debug ("process_changeinstatus - disable slot\n");
 		pslot->flag = FALSE;
-		rc = ibmphp_disable_slot (pslot->hotplug_slot);
+		rc = ibmphp_do_disable_slot (pslot);
 	}
 
 	if (update || disable) {
diff -urN linux-2.5.63-bk5/drivers/hotplug/pci_hotplug_core.c linux-2.5.63-bk6/drivers/hotplug/pci_hotplug_core.c
--- linux-2.5.63-bk5/drivers/hotplug/pci_hotplug_core.c	Mon Feb 24 11:05:40 2003
+++ linux-2.5.63-bk6/drivers/hotplug/pci_hotplug_core.c	Mon Mar 31 12:19:33 2003
@@ -67,8 +67,6 @@
 
 //////////////////////////////////////////////////////////////////
 
-static spinlock_t list_lock;
-
 static LIST_HEAD(pci_hotplug_slot_list);
 
 static struct subsystem hotplug_slots_subsys;
@@ -531,23 +529,16 @@
 	if ((slot->info == NULL) || (slot->ops == NULL))
 		return -EINVAL;
 
-	/* make sure we have not already registered this slot */
-	spin_lock (&list_lock);
-	if (get_slot_from_name (slot->name) != NULL) {
-		spin_unlock (&list_lock);
-		return -EINVAL;
-	}
-
 	strncpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
 	kobj_set_kset_s(slot, hotplug_slots_subsys);
 
+	/* this can fail if we have already registered a slot with the same name */
 	if (kobject_register(&slot->kobj)) {
 		err("Unable to register kobject");
 		return -EINVAL;
 	}
 		
 	list_add (&slot->slot_list, &pci_hotplug_slot_list);
-	spin_unlock (&list_lock);
 
 	result = fs_add_slot (slot);
 	dbg ("Added slot %s to the list\n", slot->name);
@@ -570,16 +561,11 @@
 	if (slot == NULL)
 		return -ENODEV;
 
-	/* make sure we have this slot in our list before trying to delete it */
-	spin_lock (&list_lock);
 	temp = get_slot_from_name (slot->name);
 	if (temp != slot) {
-		spin_unlock (&list_lock);
 		return -ENODEV;
 	}
-
 	list_del (&slot->slot_list);
-	spin_unlock (&list_lock);
 
 	fs_remove_slot (slot);
 	dbg ("Removed slot %s from the list\n", slot->name);
@@ -639,8 +625,6 @@
 {
 	int result;
 
-	spin_lock_init(&list_lock);
-
 	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
 	result = subsystem_register(&hotplug_slots_subsys);
 	if (result) {
diff -urN linux-2.5.63-bk5/drivers/media/radio/radio-aimslab.c linux-2.5.63-bk6/drivers/media/radio/radio-aimslab.c
--- linux-2.5.63-bk5/drivers/media/radio/radio-aimslab.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk6/drivers/media/radio/radio-aimslab.c	Mon Mar 31 12:19:33 2003
@@ -1,6 +1,6 @@
 /* radiotrack (radioreveal) driver for Linux radio support
  * (c) 1997 M. Kirkwood
- * Coverted to new API by Alan Cox <Alan.Cox@linux.org>
+ * Converted to new API by Alan Cox <Alan.Cox@linux.org>
  * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
  *
  * History:
diff -urN linux-2.5.63-bk5/drivers/media/radio/radio-gemtek.c linux-2.5.63-bk6/drivers/media/radio/radio-gemtek.c
--- linux-2.5.63-bk5/drivers/media/radio/radio-gemtek.c	Mon Feb 24 11:05:04 2003
+++ linux-2.5.63-bk6/drivers/media/radio/radio-gemtek.c	Mon Mar 31 12:19:33 2003
@@ -8,7 +8,7 @@
  *    RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
  * 
  *    Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
- *    Coverted to new API by Alan Cox <Alan.Cox@linux.org>
+ *    Converted to new API by Alan Cox <Alan.Cox@linux.org>
  *    Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
  *
  * TODO: Allow for more than one of these foolish entities :-)
diff -urN linux-2.5.63-bk5/drivers/media/radio/radio-rtrack2.c linux-2.5.63-bk6/drivers/media/radio/radio-rtrack2.c
--- linux-2.5.63-bk5/drivers/media/radio/radio-rtrack2.c	Mon Feb 24 11:05:37 2003
+++ linux-2.5.63-bk6/drivers/media/radio/radio-rtrack2.c	Mon Mar 31 12:19:33 2003
@@ -1,7 +1,7 @@
 /* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
  * 
  * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
- * Coverted to new API by Alan Cox <Alan.Cox@linux.org>
+ * Converted to new API by Alan Cox <Alan.Cox@linux.org>
  * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
  *
  * TODO: Allow for more than one of these foolish entities :-)
diff -urN linux-2.5.63-bk5/drivers/net/e100/e100.h linux-2.5.63-bk6/drivers/net/e100/e100.h
--- linux-2.5.63-bk5/drivers/net/e100/e100.h	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk6/drivers/net/e100/e100.h	Mon Mar 31 12:19:33 2003
@@ -706,8 +706,6 @@
 #define IPCB_INSERTVLAN_ENABLE 		BIT_1
 #define IPCB_IP_ACTIVATION_DEFAULT      IPCB_HARDWAREPARSING_ENABLE
 
-#define FOLD_CSUM(_XSUM)  ((((_XSUM << 16) | (_XSUM >> 16)) + _XSUM) >> 16)
-
 /* Transmit Buffer Descriptor (TBD)*/
 typedef struct _tbd_t {
 	u32 tbd_buf_addr;	/* Physical Transmit Buffer Address */
diff -urN linux-2.5.63-bk5/drivers/net/e100/e100_main.c linux-2.5.63-bk6/drivers/net/e100/e100_main.c
--- linux-2.5.63-bk5/drivers/net/e100/e100_main.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/net/e100/e100_main.c	Mon Mar 31 12:19:33 2003
@@ -2071,32 +2071,6 @@
 }
 
 /**
- * e100_pseudo_hdr_csum - compute IP pseudo-header checksum
- * @ip: points to the header of the IP packet
- *
- * Return the 16 bit checksum of the IP pseudo-header.,which is computed
- * on the fields: IP src, IP dst, next protocol, payload length.
- * The checksum vaule is returned in network byte order.
- */
-static inline u16
-e100_pseudo_hdr_csum(const struct iphdr *ip)
-{
-	u32 pseudo = 0;
-	u32 payload_len = 0;
-
-	payload_len = ntohs(ip->tot_len) - (ip->ihl * 4);
-
-	pseudo += htons(payload_len);
-	pseudo += (ip->protocol << 8);
-	pseudo += ip->saddr & 0x0000ffff;
-	pseudo += (ip->saddr & 0xffff0000) >> 16;
-	pseudo += ip->daddr & 0x0000ffff;
-	pseudo += (ip->daddr & 0xffff0000) >> 16;
-
-	return FOLD_CSUM(pseudo);
-}
-
-/**
  * e100_prepare_xmit_buff - prepare a buffer for transmission
  * @bdp: atapter's private data struct
  * @skb: skb to send
@@ -2140,27 +2114,13 @@
 
 		if ((ip->protocol == IPPROTO_TCP) ||
 		    (ip->protocol == IPPROTO_UDP)) {
-			u16 *chksum;
-
 			tcb->tcbu.ipcb.ip_activation_high =
 				IPCB_HARDWAREPARSING_ENABLE;
 			tcb->tcbu.ipcb.ip_schedule |=
 				IPCB_TCPUDP_CHECKSUM_ENABLE;
 
-			if (ip->protocol == IPPROTO_TCP) {
-				struct tcphdr *tcp;
-
-				tcp = (struct tcphdr *) ((u32 *) ip + ip->ihl);
-				chksum = &(tcp->check);
+			if (ip->protocol == IPPROTO_TCP)
 				tcb->tcbu.ipcb.ip_schedule |= IPCB_TCP_PACKET;
-			} else {
-				struct udphdr *udp;
-
-				udp = (struct udphdr *) ((u32 *) ip + ip->ihl);
-				chksum = &(udp->check);
-			}
-
-			*chksum = e100_pseudo_hdr_csum(ip);
 		}
 	}
 
diff -urN linux-2.5.63-bk5/drivers/net/via-rhine.c linux-2.5.63-bk6/drivers/net/via-rhine.c
--- linux-2.5.63-bk5/drivers/net/via-rhine.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/net/via-rhine.c	Mon Mar 31 12:19:34 2003
@@ -108,11 +108,18 @@
 	- New reset code uses "force reset" cmd on Rhine-II
 	- Various clean ups
 
+	LK1.1.17 (Roger Luethi)
+	- Fix race in via_rhine_start_tx()
+	- On errors, wait for Tx engine to turn off before scavenging
+	- Handle Tx descriptor write-back race on Rhine-II
+	- Force flushing for PCI posted writes
+	- More reset code changes
+
 */
 
 #define DRV_NAME	"via-rhine"
-#define DRV_VERSION	"1.1.16"
-#define DRV_RELDATE	"February-15-2003"
+#define DRV_VERSION	"1.1.17"
+#define DRV_RELDATE	"March-1-2003"
 
 
 /* A few user-configurable values.
@@ -562,7 +569,7 @@
 
 		/* VT86C100A may need long delay after reset (dlink) */
 		/* Seen on Rhine-II as well (rl) */
-		while ((readw(ioaddr + ChipCmd) & CmdReset) && --boguscnt);
+		while ((readw(ioaddr + ChipCmd) & CmdReset) && --boguscnt)
 			udelay(5);
 
 	}
diff -urN linux-2.5.63-bk5/drivers/net/wireless/airo.c linux-2.5.63-bk6/drivers/net/wireless/airo.c
--- linux-2.5.63-bk5/drivers/net/wireless/airo.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/net/wireless/airo.c	Mon Mar 31 12:19:34 2003
@@ -5816,7 +5816,7 @@
 			break;
 		}
 
-		/* Seperate R/W functions bracket legality here
+		/* Separate R/W functions bracket legality here
 		 */
 		if ( com.command <= AIROGMICSTATS )
 			rc = readrids(dev,&com);
diff -urN linux-2.5.63-bk5/drivers/pci/hotplug.c linux-2.5.63-bk6/drivers/pci/hotplug.c
--- linux-2.5.63-bk5/drivers/pci/hotplug.c	Mon Feb 24 11:05:44 2003
+++ linux-2.5.63-bk6/drivers/pci/hotplug.c	Mon Mar 31 12:19:34 2003
@@ -10,6 +10,7 @@
 #define DBG(x...)
 #endif
 
+static void pci_free_resources(struct pci_dev *dev);
 
 #ifdef CONFIG_HOTPLUG
 int pci_hotplug (struct device *dev, char **envp, int num_envp,
@@ -185,7 +186,13 @@
 {
 	if (pci_dev_driver(dev))
 		return -EBUSY;
-	pci_remove_device(dev);
+	device_unregister(&dev->dev);
+	list_del(&dev->bus_list);
+	list_del(&dev->global_list);
+	pci_free_resources(dev);
+#ifdef CONFIG_PROC_FS
+	pci_proc_detach_device(dev);
+#endif
 	return 0;
 }
 EXPORT_SYMBOL(pci_remove_device_safe);
@@ -233,15 +240,33 @@
 }
 
 /**
- * pci_remove_device - remove a pci device
+ * pci_remove_bus_device - remove a PCI device and any children
  * @dev: the device to remove
  *
- * Delete the device structure from the device lists,
- * remove the /proc entry, and notify userspace (/sbin/hotplug).
+ * Remove a PCI device from the device lists, informing the drivers
+ * that the device has been removed.  We also remove any subordinate
+ * buses and children in a depth-first manner.
+ *
+ * For each device we remove, delete the device structure from the
+ * device lists, remove the /proc entry, and notify userspace
+ * (/sbin/hotplug).
  */
-void
-pci_remove_device(struct pci_dev *dev)
+void pci_remove_bus_device(struct pci_dev *dev)
 {
+	if (dev->subordinate) {
+		struct pci_bus *b = dev->subordinate;
+
+		pci_remove_behind_bridge(dev);
+
+#ifdef CONFIG_PROC_FS
+		pci_proc_detach_bus(b);
+#endif
+
+		list_del(&b->node);
+		kfree(b);
+		dev->subordinate = NULL;
+	}
+
 	device_unregister(&dev->dev);
 	list_del(&dev->bus_list);
 	list_del(&dev->global_list);
@@ -249,9 +274,33 @@
 #ifdef CONFIG_PROC_FS
 	pci_proc_detach_device(dev);
 #endif
+
+	kfree(dev);
+}
+
+/**
+ * pci_remove_behind_bridge - remove all devices behind a PCI bridge
+ * @dev: PCI bridge device
+ *
+ * Remove all devices on the bus, except for the parent bridge.
+ * This also removes any child buses, and any devices they may
+ * contain in a depth-first manner.
+ */
+void pci_remove_behind_bridge(struct pci_dev *dev)
+{
+	struct list_head *l, *n;
+
+	if (dev->subordinate) {
+		list_for_each_safe(l, n, &dev->subordinate->devices) {
+			struct pci_dev *dev = pci_dev_b(l);
+
+			pci_remove_bus_device(dev);
+		}
+	}
 }
 
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pci_insert_device);
-EXPORT_SYMBOL(pci_remove_device);
+EXPORT_SYMBOL(pci_remove_bus_device);
+EXPORT_SYMBOL(pci_remove_behind_bridge);
 #endif
diff -urN linux-2.5.63-bk5/drivers/pci/probe.c linux-2.5.63-bk6/drivers/pci/probe.c
--- linux-2.5.63-bk5/drivers/pci/probe.c	Mon Feb 24 11:05:38 2003
+++ linux-2.5.63-bk6/drivers/pci/probe.c	Mon Mar 31 12:19:34 2003
@@ -609,6 +609,7 @@
 	}
 	return b;
 }
+EXPORT_SYMBOL(pci_scan_bus_parented);
 
 EXPORT_SYMBOL(pci_devices);
 EXPORT_SYMBOL(pci_root_buses);
diff -urN linux-2.5.63-bk5/drivers/pcmcia/cardbus.c linux-2.5.63-bk6/drivers/pcmcia/cardbus.c
--- linux-2.5.63-bk5/drivers/pcmcia/cardbus.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/cardbus.c	Mon Mar 31 12:19:34 2003
@@ -90,7 +90,7 @@
 #define PCDATA_INDICATOR	0x0015
 
 typedef struct cb_config_t {
-	struct pci_dev dev;
+	struct pci_dev *dev[8];
 } cb_config_t;
 
 /*=====================================================================
@@ -178,7 +178,7 @@
 	if (!s->cb_config)
 		goto fail;
 
-	dev = &s->cb_config[0].dev;
+	dev = s->cb_config->dev[0];
 
 	/* Config space? */
 	if (space == 0) {
@@ -248,14 +248,25 @@
 	}
 	s->functions = fn;
 
-	c = kmalloc(fn * sizeof(struct cb_config_t), GFP_ATOMIC);
+	c = kmalloc(sizeof(struct cb_config_t), GFP_ATOMIC);
 	if (!c)
 		return CS_OUT_OF_RESOURCE;
-	memset(c, 0, fn * sizeof(struct cb_config_t));
+ 	memset(c, 0, sizeof(struct cb_config_t));
+
+	for (i = 0; i < fn; i++) {
+		c->dev[i] = kmalloc(sizeof(struct pci_dev), GFP_ATOMIC);
+		if (!c->dev[i]) {
+			for (; i--; )
+				kfree(c->dev[i]);
+			kfree(c);
+			return CS_OUT_OF_RESOURCE;
+		}
+		memset(c->dev[i], 0, sizeof(struct pci_dev));
+	}
 
 	irq = s->cap.pci_irq;
 	for (i = 0; i < fn; i++) {
-		struct pci_dev *dev = &c[i].dev;
+		struct pci_dev *dev = c->dev[i];
 		u8 irq_pin;
 		int r;
 
@@ -309,11 +320,8 @@
 	cb_config_t *c = s->cb_config;
 
 	if (c) {
-		int i;
-
 		s->cb_config = NULL;
-		for (i = 0 ; i < s->functions ; i++)
-			pci_remove_device(&c[i].dev);
+		pci_remove_behind_bridge(s->cap.cb_dev);
 
 		kfree(c);
 		printk(KERN_INFO "cs: cb_free(bus %d)\n", s->cap.cb_dev->subordinate->number);
@@ -347,7 +355,7 @@
 
 	/* Set up PCI interrupt and command registers */
 	for (i = 0; i < s->functions; i++) {
-		dev = &s->cb_config[i].dev;
+		dev = s->cb_config->dev[i];
 		pci_write_config_byte(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
 				      PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
 		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
@@ -356,7 +364,7 @@
 
 	if (s->irq.AssignedIRQ) {
 		for (i = 0; i < s->functions; i++) {
-			dev = &s->cb_config[i].dev;
+			dev = s->cb_config->dev[i];
 			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
 					      s->irq.AssignedIRQ);
 		}
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100.h linux-2.5.63-bk6/drivers/pcmcia/sa1100.h
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100.h	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100.h	Mon Mar 31 12:19:34 2003
@@ -150,6 +150,7 @@
  */
 #define SA1100_PCMCIA_POLL_PERIOD    (2*HZ)
 
+struct pcmcia_low_level;
 
 /* This structure encapsulates per-socket state which we might need to
  * use when responding to a Card Services query of some kind.
@@ -158,6 +159,8 @@
   /*
    * Core PCMCIA state
    */
+  int			nr;
+  struct resource	res;
   socket_state_t        cs_state;
   pccard_io_map         io_map[MAX_IO_WIN];
   pccard_mem_map        pc_mem_map[MAX_WIN];
@@ -173,6 +176,9 @@
    * Info from low level handler
    */
   unsigned int          irq;
+  unsigned int		irq_state;
+
+  struct pcmcia_low_level *ops;
 };
 
 
@@ -189,61 +195,55 @@
 /*
  * Declaration for all machine specific init/exit functions.
  */
-extern int pcmcia_adsbitsy_init(void);
-extern void pcmcia_adsbitsy_exit(void);
-
-extern int pcmcia_assabet_init(void);
-extern void pcmcia_assabet_exit(void);
-
-extern int pcmcia_badge4_init(void);
-extern void pcmcia_badge4_exit(void);
+extern int pcmcia_adsbitsy_init(struct device *);
+extern void pcmcia_adsbitsy_exit(struct device *);
 
-extern int pcmcia_cerf_init(void);
-extern void pcmcia_cerf_exit(void);
+extern int pcmcia_assabet_init(struct device *);
+extern void pcmcia_assabet_exit(struct device *);
 
-extern int pcmcia_flexanet_init(void);
-extern void pcmcia_flexanet_exit(void);
+extern int pcmcia_badge4_init(struct device *);
+extern void pcmcia_badge4_exit(struct device *);
 
-extern int pcmcia_freebird_init(void);
-extern void pcmcia_freebird_exit(void);
+extern int pcmcia_cerf_init(struct device *);
+extern void pcmcia_cerf_exit(struct device *);
 
-extern int pcmcia_gcplus_init(void);
-extern void pcmcia_gcplus_exit(void);
+extern int pcmcia_flexanet_init(struct device *);
+extern void pcmcia_flexanet_exit(struct device *);
 
-extern int pcmcia_graphicsmaster_init(void);
-extern void pcmcia_graphicsmaster_exit(void);
+extern int pcmcia_freebird_init(struct device *);
+extern void pcmcia_freebird_exit(struct device *);
 
-extern int pcmcia_jornada720_init(void);
-extern void pcmcia_jornada720_exit(void);
+extern int pcmcia_gcplus_init(struct device *);
+extern void pcmcia_gcplus_exit(struct device *);
 
-extern int pcmcia_neponset_init(void);
-extern void pcmcia_neponset_exit(void);
+extern int pcmcia_graphicsmaster_init(struct device *);
+extern void pcmcia_graphicsmaster_exit(struct device *);
 
-extern int pcmcia_pangolin_init(void);
-extern void pcmcia_pangolin_exit(void);
+extern int pcmcia_pangolin_init(struct device *);
+extern void pcmcia_pangolin_exit(struct device *);
 
-extern int pcmcia_pfs168_init(void);
-extern void pcmcia_pfs168_exit(void);
+extern int pcmcia_pfs168_init(struct device *);
+extern void pcmcia_pfs168_exit(struct device *);
 
-extern int pcmcia_shannon_init(void);
-extern void pcmcia_shannon_exit(void);
+extern int pcmcia_shannon_init(struct device *);
+extern void pcmcia_shannon_exit(struct device *);
 
-extern int pcmcia_simpad_init(void);
-extern void pcmcia_simpad_exit(void);
+extern int pcmcia_simpad_init(struct device *);
+extern void pcmcia_simpad_exit(struct device *);
 
-extern int pcmcia_stork_init(void);
-extern void pcmcia_stork_exit(void);
+extern int pcmcia_stork_init(struct device *);
+extern void pcmcia_stork_exit(struct device *);
 
-extern int pcmcia_system3_init(void);
-extern void pcmcia_system3_exit(void);
+extern int pcmcia_system3_init(struct device *);
+extern void pcmcia_system3_exit(struct device *);
 
-extern int pcmcia_trizeps_init(void);
-extern void pcmcia_trizeps_exit(void);
+extern int pcmcia_trizeps_init(struct device *);
+extern void pcmcia_trizeps_exit(struct device *);
 
-extern int pcmcia_xp860_init(void);
-extern void pcmcia_xp860_exit(void);
+extern int pcmcia_xp860_init(struct device *);
+extern void pcmcia_xp860_exit(struct device *);
 
-extern int pcmcia_yopy_init(void);
-extern void pcmcia_yopy_exit(void);
+extern int pcmcia_yopy_init(struct device *);
+extern void pcmcia_yopy_exit(struct device *);
 
 #endif  /* !defined(_PCMCIA_SA1100_H) */
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_adsbitsy.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_adsbitsy.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_adsbitsy.c	Mon Feb 24 11:06:02 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_adsbitsy.c	Mon Mar 31 12:19:34 2003
@@ -9,8 +9,10 @@
  * 7/5/01 Woojung Huh <whuh@applieddata.net>
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -34,12 +36,12 @@
 }
 
 static int
-adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+adsbitsy_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int pa_dwr_mask, pa_dwr_set;
   int ret;
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
 
@@ -71,7 +73,7 @@
     return -1;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -84,25 +86,25 @@
 }
 
 static struct pcmcia_low_level adsbitsy_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= adsbitsy_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= adsbitsy_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_adsbitsy_init(void)
+int __init pcmcia_adsbitsy_init(struct device *dev)
 {
 	int ret = -ENODEV;
 	if (machine_is_adsbitsy())
-		ret = sa1100_register_pcmcia(&adsbitsy_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&adsbitsy_pcmcia_ops, dev);
 	return ret;
 }
 
-void __exit pcmcia_adsbitsy_exit(void)
+void __exit pcmcia_adsbitsy_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&adsbitsy_pcmcia_ops);
+	sa1100_unregister_pcmcia(&adsbitsy_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_assabet.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_assabet.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_assabet.c	Mon Feb 24 11:05:40 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_assabet.c	Mon Mar 31 12:19:34 2003
@@ -5,9 +5,11 @@
  *
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -31,18 +33,18 @@
 {
 	int i, res;
 
-	/* Set transition detect */
-	set_irq_type(ASSABET_IRQ_GPIO_CF_IRQ, IRQT_FALLING);
-
 	/* Register interrupts */
 	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			goto irq_err;
+		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
 	}
 
+	init->socket_irq[0] = NO_IRQ;
+	init->socket_irq[1] = ASSABET_IRQ_GPIO_CF_IRQ;
+
 	/* There's only one slot, but it's "Slot 1": */
 	return 2;
 
@@ -69,47 +71,31 @@
 	return 0;
 }
 
-static int
-assabet_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+static void
+assabet_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long levels;
+	unsigned long levels = GPLR;
 
-	if (state_array->size < 2)
-		return -1;
-
-	levels = GPLR;
-
-	state_array->state[1].detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
-	state_array->state[1].ready  = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
-	state_array->state[1].bvd1   = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
-	state_array->state[1].bvd2   = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
-	state_array->state[1].wrprot = 0; /* Not available on Assabet. */
-	state_array->state[1].vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
-	state_array->state[1].vs_Xv  = 0;
-
-	return 1;
-}
-
-static int assabet_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-	if (info->sock > 1)
-		return -1;
-
-	if (info->sock == 1)
-		info->irq = ASSABET_IRQ_GPIO_CF_IRQ;
-
-	return 0;
+	if (sock == 1) {
+		state->detect = (levels & ASSABET_GPIO_CF_CD) ? 0 : 1;
+		state->ready  = (levels & ASSABET_GPIO_CF_IRQ) ? 1 : 0;
+		state->bvd1   = (levels & ASSABET_GPIO_CF_BVD1) ? 1 : 0;
+		state->bvd2   = (levels & ASSABET_GPIO_CF_BVD2) ? 1 : 0;
+		state->wrprot = 0; /* Not available on Assabet. */
+		state->vs_3v  = 1; /* Can only apply 3.3V on Assabet. */
+		state->vs_Xv  = 0;
+	}
 }
 
 static int
-assabet_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+assabet_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
 	unsigned int mask;
 
-	if (configure->sock > 1)
+	if (sock > 1)
 		return -1;
 
-	if (configure->sock == 0)
+	if (sock == 0)
 		return 0;
 
 	switch (configure->vcc) {
@@ -138,15 +124,6 @@
 
 	ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR, mask);
 
-	/*
-	 * Handle suspend mode properly.  This prevents a
-	 * flood of IRQs from the CF device.
-	 */
-	if (configure->irq)
-		enable_irq(ASSABET_IRQ_GPIO_CF_IRQ);
-	else
-		disable_irq(ASSABET_IRQ_GPIO_CF_IRQ);
-
 	return 0;
 }
 
@@ -194,23 +171,23 @@
 }
 
 static struct pcmcia_low_level assabet_pcmcia_ops = { 
+	.owner			= THIS_MODULE,
 	.init			= assabet_pcmcia_init,
 	.shutdown		= assabet_pcmcia_shutdown,
 	.socket_state		= assabet_pcmcia_socket_state,
-	.get_irq_info		= assabet_pcmcia_get_irq_info,
 	.configure_socket	= assabet_pcmcia_configure_socket,
 
 	.socket_init		= assabet_pcmcia_socket_init,
 	.socket_suspend		= assabet_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_assabet_init(void)
+int __init pcmcia_assabet_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_assabet()) {
 		if (!machine_has_neponset())
-			ret = sa1100_register_pcmcia(&assabet_pcmcia_ops);
+			ret = sa1100_register_pcmcia(&assabet_pcmcia_ops, dev);
 #ifndef CONFIG_ASSABET_NEPONSET
 		else
 			printk(KERN_ERR "Card Services disabled: missing "
@@ -220,8 +197,8 @@
 	return ret;
 }
 
-void __exit pcmcia_assabet_exit(void)
+void __exit pcmcia_assabet_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&assabet_pcmcia_ops);
+	sa1100_unregister_pcmcia(&assabet_pcmcia_ops, dev);
 }
 
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_badge4.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_badge4.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_badge4.c	Mon Feb 24 11:05:11 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_badge4.c	Mon Mar 31 12:19:34 2003
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/device.h>
@@ -96,11 +97,11 @@
 }
 
 static int
-badge4_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+badge4_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
 	int ret;
 
-	switch (conf->sock) {
+	switch (sock) {
 	case 0:
 		if ((conf->vcc != 0) &&
 		    (conf->vcc != badge4_pcmvcc)) {
@@ -130,7 +131,7 @@
 		return -1;
 	}
 
-	ret = sa1111_pcmcia_configure_socket(conf);
+	ret = sa1111_pcmcia_configure_socket(sock, conf);
 	if (ret == 0) {
 		unsigned long flags;
 		int need5V;
@@ -148,29 +149,29 @@
 }
 
 static struct pcmcia_low_level badge4_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= badge4_pcmcia_init,
 	.shutdown		= badge4_pcmcia_shutdown,
 	.socket_state		= sa1111_pcmcia_socket_state,
-	.get_irq_info		= sa1111_pcmcia_get_irq_info,
 	.configure_socket	= badge4_pcmcia_configure_socket,
 
 	.socket_init		= sa1111_pcmcia_socket_init,
 	.socket_suspend		= sa1111_pcmcia_socket_suspend,
 };
 
-int pcmcia_badge4_init(void)
+int pcmcia_badge4_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_badge4())
-		ret = sa1100_register_pcmcia(&badge4_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&badge4_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __devexit pcmcia_badge4_exit(void)
+void __devexit pcmcia_badge4_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&badge4_pcmcia_ops);
+	sa1100_unregister_pcmcia(&badge4_pcmcia_ops, dev);
 }
 
 static int __init pcmv_setup(char *s)
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_cerf.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_cerf.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_cerf.c	Mon Feb 24 11:05:44 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_cerf.c	Mon Mar 31 12:19:34 2003
@@ -6,8 +6,10 @@
  *
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -34,16 +36,16 @@
 {
   int i, res;
 
-  set_irq_type(IRQ_GPIO_CF_IRQ, IRQT_FALLING);
-
   for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-    res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+    res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt, SA_INTERRUPT,
 		      irqs[i].str, NULL);
     if (res)
       goto irq_err;
+    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
   }
 
+  init->socket_irq[CERF_SOCKET] = IRQ_GPIO_CF_IRQ;
+
   return 2;
 
  irq_err:
@@ -66,43 +68,28 @@
   return 0;
 }
 
-static int cerf_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-  int i = CERF_SOCKET;
-
-  if(state_array->size<2) return -1;
-
-  levels=GPLR;
-
-  state_array->state[i].detect=((levels & GPIO_CF_CD)==0)?1:0;
-  state_array->state[i].ready=(levels & GPIO_CF_IRQ)?1:0;
-  state_array->state[i].bvd1=(levels & GPIO_CF_BVD1)?1:0;
-  state_array->state[i].bvd2=(levels & GPIO_CF_BVD2)?1:0;
-  state_array->state[i].wrprot=0;
-  state_array->state[i].vs_3v=1;
-  state_array->state[i].vs_Xv=0;
-
-  return 1;
-}
-
-static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  if(info->sock>1) return -1;
-
-  if (info->sock == CERF_SOCKET)
-    info->irq=IRQ_GPIO_CF_IRQ;
+static void cerf_pcmcia_socket_state(int sock, struct pcmcia_state *state)
+{
+  unsigned long levels=GPLR;
 
-  return 0;
+  if (sock == CERF_SOCKET) {
+    state->detect=((levels & GPIO_CF_CD)==0)?1:0;
+    state->ready=(levels & GPIO_CF_IRQ)?1:0;
+    state->bvd1=(levels & GPIO_CF_BVD1)?1:0;
+    state->bvd2=(levels & GPIO_CF_BVD2)?1:0;
+    state->wrprot=0;
+    state->vs_3v=1;
+    state->vs_Xv=0;
+  }
 }
 
-static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
+static int cerf_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
-  if(configure->sock>1)
+  if (sock>1)
     return -1;
 
-  if (configure->sock != CERF_SOCKET)
+  if (sock != CERF_SOCKET)
     return 0;
 
   switch(configure->vcc){
@@ -161,27 +148,27 @@
 }
 
 static struct pcmcia_low_level cerf_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= cerf_pcmcia_init,
   .shutdown		= cerf_pcmcia_shutdown,
   .socket_state		= cerf_pcmcia_socket_state,
-  .get_irq_info		= cerf_pcmcia_get_irq_info,
   .configure_socket	= cerf_pcmcia_configure_socket,
 
   .socket_init		= cerf_pcmcia_socket_init,
   .socket_suspend	= cerf_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_cerf_init(void)
+int __init pcmcia_cerf_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_cerf())
-		ret = sa1100_register_pcmcia(&cerf_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&cerf_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_cerf_exit(void)
+void __exit pcmcia_cerf_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&cerf_pcmcia_ops);
+	sa1100_unregister_pcmcia(&cerf_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_flexanet.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_flexanet.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_flexanet.c	Mon Feb 24 11:05:32 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_flexanet.c	Mon Mar 31 12:19:34 2003
@@ -5,9 +5,10 @@
  * by Jordi Colomer, 09/05/2001
  *
  */
-
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -40,19 +41,18 @@
   GPDR &= ~(GPIO_CF1_NCD | GPIO_CF1_BVD1 | GPIO_CF1_IRQ |
             GPIO_CF2_NCD | GPIO_CF2_BVD1 | GPIO_CF2_IRQ );
 
-  /* Set IRQ edge */
-  set_irq_type(IRQ_GPIO_CF1_IRQ, IRQT_FALLING);
-  set_irq_type(IRQ_GPIO_CF2_IRQ, IRQT_FALLING);
-
   /* Register the socket interrupts (not the card interrupts) */
   for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-    res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+    res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt, SA_INTERRUPT,
 		      irqs[i].name, NULL);
     if (res < 0)
       break;
+    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
   }
 
+  init->socket_irq[0] = IRQ_GPIO_CF1_IRQ;
+  init->socket_irq[1] = IRQ_GPIO_CF2_IRQ;
+
   /* If we failed, then free all interrupts requested thus far. */
   if (res < 0) {
     printk(KERN_ERR "%s: request for IRQ%d failed: %d\n",
@@ -88,67 +88,43 @@
  *  Sockets in Flexanet are 3.3V only, without BVD2.
  *
  */
-static int flexanet_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-
-  if (state_array->size < 2)
-    return -1;
-
-  /* Sense the GPIOs, asynchronously */
-  levels = GPLR;
-
-  /* Socket 0 */
-  state_array->state[0].detect = ((levels & GPIO_CF1_NCD)==0)?1:0;
-  state_array->state[0].ready  = (levels & GPIO_CF1_IRQ)?1:0;
-  state_array->state[0].bvd1   = (levels & GPIO_CF1_BVD1)?1:0;
-  state_array->state[0].bvd2   = 1;
-  state_array->state[0].wrprot = 0;
-  state_array->state[0].vs_3v  = 1;
-  state_array->state[0].vs_Xv  = 0;
-
-  /* Socket 1 */
-  state_array->state[1].detect = ((levels & GPIO_CF2_NCD)==0)?1:0;
-  state_array->state[1].ready  = (levels & GPIO_CF2_IRQ)?1:0;
-  state_array->state[1].bvd1   = (levels & GPIO_CF2_BVD1)?1:0;
-  state_array->state[1].bvd2   = 1;
-  state_array->state[1].wrprot = 0;
-  state_array->state[1].vs_3v  = 1;
-  state_array->state[1].vs_Xv  = 0;
-
-  return 1;
-}
-
-
-/*
- * Return the IRQ information for a given socket number (the IRQ number)
- *
- */
-static int flexanet_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  /* check the socket index */
-  if (info->sock > 1)
-    return -1;
+static void flexanet_pcmcia_socket_state(int sock, struct pcmcia_state *state)
+{
+  unsigned long levels = GPLR; /* Sense the GPIOs, asynchronously */
 
-  if (info->sock == 0)
-    info->irq = IRQ_GPIO_CF1_IRQ;
-  else if (info->sock == 1)
-    info->irq = IRQ_GPIO_CF2_IRQ;
+  switch (sock) {
+  case 0: /* Socket 0 */
+    state->detect = ((levels & GPIO_CF1_NCD)==0)?1:0;
+    state->ready  = (levels & GPIO_CF1_IRQ)?1:0;
+    state->bvd1   = (levels & GPIO_CF1_BVD1)?1:0;
+    state->bvd2   = 1;
+    state->wrprot = 0;
+    state->vs_3v  = 1;
+    state->vs_Xv  = 0;
+    break;
 
-  return 0;
+  case 1: /* Socket 1 */
+    state->detect = ((levels & GPIO_CF2_NCD)==0)?1:0;
+    state->ready  = (levels & GPIO_CF2_IRQ)?1:0;
+    state->bvd1   = (levels & GPIO_CF2_BVD1)?1:0;
+    state->bvd2   = 1;
+    state->wrprot = 0;
+    state->vs_3v  = 1;
+    state->vs_Xv  = 0;
+    break;
+  }
 }
 
 
 /*
  *
  */
-static int flexanet_pcmcia_configure_socket(const struct pcmcia_configure
+static int flexanet_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long value, flags, mask;
 
-
-  if (configure->sock > 1)
+  if (sock > 1)
     return -1;
 
   /* Ignore the VCC level since it is 3.3V and always on */
@@ -174,7 +150,7 @@
   /* Reset the slot(s) using the controls in the BCR */
   mask = 0;
 
-  switch (configure->sock)
+  switch (sock)
   {
     case 0 : mask = FHH_BCR_CF1_RST; break;
     case 1 : mask = FHH_BCR_CF2_RST; break;
@@ -222,28 +198,28 @@
  *
  */
 static struct pcmcia_low_level flexanet_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= flexanet_pcmcia_init,
   .shutdown		= flexanet_pcmcia_shutdown,
   .socket_state		= flexanet_pcmcia_socket_state,
-  .get_irq_info		= flexanet_pcmcia_get_irq_info,
   .configure_socket	= flexanet_pcmcia_configure_socket,
 
   .socket_init		= flexanet_pcmcia_socket_init,
   .socket_suspend	= flexanet_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_flexanet_init(void)
+int __init pcmcia_flexanet_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_flexanet())
-		ret = sa1100_register_pcmcia(&flexanet_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&flexanet_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_flexanet_exit(void)
+void __exit pcmcia_flexanet_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&flexanet_pcmcia_ops);
+	sa1100_unregister_pcmcia(&flexanet_pcmcia_ops, dev);
 }
 
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_freebird.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_freebird.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_freebird.c	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_freebird.c	Mon Mar 31 12:19:34 2003
@@ -4,8 +4,10 @@
  * Created by Eric Peng <ericpeng@coventive.com>
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -35,18 +37,17 @@
   mdelay(100);
   LINKUP_PRC = 0xc0;
 
-  /* Set transition detect */
-  set_irq_type(IRQ_GPIO_FREEBIRD_CF_IRQ, IRQT_FALLING);
-
   /* Register interrupts */
   for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-    res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
+    res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt, SA_INTERRUPT,
     		      irqs[i].str, NULL);
     if (res)
       goto irq_err;
+    set_irq_type(irqs[i].irq, IRQT_NOEDGE);
   }
 
+  init->socket_irq[0] = IRQ_GPIO_FREEBIRD_CF_IRQ;
+
   /* There's only one slot, but it's "Slot 1": */
   return 2;
 
@@ -75,54 +76,30 @@
   return 0;
 }
 
-static int freebird_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0,
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  levels = LINKUP_PRS;
+static void freebird_pcmcia_socket_state(int sock, struct pcmcia_state *state)
+{
+  unsigned long levels = LINKUP_PRS;
 //printk("LINKUP_PRS=%x\n",levels);
 
-  state_array->state[0].detect=
-    ((levels & (LINKUP_CD1 | LINKUP_CD2))==0)?1:0;
-
-  state_array->state[0].ready=(levels & LINKUP_RDY)?1:0;
-
-  state_array->state[0].bvd1=(levels & LINKUP_BVD1)?1:0;
-
-  state_array->state[0].bvd2=(levels & LINKUP_BVD2)?1:0;
-
-  state_array->state[0].wrprot=0; /* Not available on Assabet. */
-
-  state_array->state[0].vs_3v=1;  /* Can only apply 3.3V on Assabet. */
-
-  state_array->state[0].vs_Xv=0;
-
-  return 1;
-}
-
-static int freebird_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  if(info->sock>1) return -1;
-
-  if(info->sock==0)
-    info->irq=IRQ_GPIO_FREEBIRD_CF_IRQ;
-
-  return 0;
+  if (sock == 0) {
+    state->detect = ((levels & (LINKUP_CD1 | LINKUP_CD2))==0)?1:0;
+    state->ready  = (levels & LINKUP_RDY)?1:0;
+    state->bvd1   = (levels & LINKUP_BVD1)?1:0;
+    state->bvd2   = (levels & LINKUP_BVD2)?1:0;
+    state->wrprot = 0; /* Not available on Assabet. */
+    state->vs_3v  = 1;  /* Can only apply 3.3V on Assabet. */
+    state->vs_Xv  = 0;
+  }
 }
 
-static int freebird_pcmcia_configure_socket(const struct pcmcia_configure
+static int freebird_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long value, flags;
 
-  if(configure->sock>1) return -1;
+  if(sock>1) return -1;
 
-  if(configure->sock==1) return 0;
+  if(sock==1) return 0;
 
   local_irq_save(flags);
 
@@ -179,27 +156,27 @@
 }
 
 static struct pcmcia_low_level freebird_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= freebird_pcmcia_init,
   .shutdown		= freebird_pcmcia_shutdown,
   .socket_state		= freebird_pcmcia_socket_state,
-  .get_irq_info		= freebird_pcmcia_get_irq_info,
   .configure_socket	= freebird_pcmcia_configure_socket,
 
   .socket_init		= freebird_pcmcia_socket_init,
   .socket_suspend	= freebird_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_freebird_init(void)
+int __init pcmcia_freebird_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_freebird())
-		ret = sa1100_register_pcmcia(&freebird_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&freebird_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_freebird_exit(void)
+void __exit pcmcia_freebird_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&freebird_pcmcia_ops);
+	sa1100_unregister_pcmcia(&freebird_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_generic.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_generic.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_generic.c	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_generic.c	Mon Mar 31 12:19:34 2003
@@ -110,59 +110,74 @@
  * Call board specific BS value calculation to allow boards
  * to tweak the BS values.
  */
-static int sa1100_pcmcia_set_mecr(int sock, unsigned int cpu_clock)
+static int
+sa1100_pcmcia_set_mecr(struct sa1100_pcmcia_socket *skt, unsigned int cpu_clock)
 {
-	struct sa1100_pcmcia_socket *skt;
 	u32 mecr;
 	unsigned long flags;
 	unsigned int bs;
 
-	if (sock < 0 || sock > SA1100_PCMCIA_MAX_SOCK)
-		return -1;
-
-	skt = PCMCIA_SOCKET(sock);
-
 	local_irq_save(flags);
 
-	bs = pcmcia_low_level->socket_get_timing(sock, cpu_clock, skt->speed_io);
+	bs = skt->ops->socket_get_timing(skt->nr, cpu_clock, skt->speed_io);
 
 	mecr = MECR;
-	MECR_FAST_SET(mecr, sock, 0);
-	MECR_BSIO_SET(mecr, sock, bs );
-	MECR_BSA_SET(mecr, sock, bs );
-	MECR_BSM_SET(mecr, sock, bs );
+	MECR_FAST_SET(mecr, skt->nr, 0);
+	MECR_BSIO_SET(mecr, skt->nr, bs );
+	MECR_BSA_SET(mecr, skt->nr, bs );
+	MECR_BSM_SET(mecr, skt->nr, bs );
 	MECR = mecr;
 
 	local_irq_restore(flags);
 
-	DEBUG(4, "%s(): FAST%u %X  BSM%u %X  BSA%u %X  BSIO%u %X\n",
-	      __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
-	      MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
-	      sock, MECR_BSIO_GET(mecr, sock));
+	DEBUG(4, "%s(): sock %u FAST %X  BSM %X  BSA %X  BSIO %X\n",
+	      __FUNCTION__, skt->nr, MECR_FAST_GET(mecr, skt->nr),
+	      MECR_BSM_GET(mecr, skt->nr), MECR_BSA_GET(mecr, skt->nr),
+	      MECR_BSIO_GET(mecr, skt->nr));
 
 	return 0;
 }
 
 /*
- * sa1100_pcmcia_state_to_config
- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ * sa1100_pcmcia_config_skt
+ * ^^^^^^^^^^^^^^^^^^^^^^^^
  *
  * Convert PCMCIA socket state to our socket configure structure.
  */
-static struct pcmcia_configure
-sa1100_pcmcia_state_to_config(unsigned int sock, socket_state_t *state)
+static int
+sa1100_pcmcia_config_skt(struct sa1100_pcmcia_socket *skt, socket_state_t *state)
 {
-  struct pcmcia_configure conf;
+	struct pcmcia_configure conf;
+	int ret;
+
+	conf.vcc     = state->Vcc;
+	conf.vpp     = state->Vpp;
+	conf.output  = state->flags & SS_OUTPUT_ENA ? 1 : 0;
+	conf.speaker = state->flags & SS_SPKR_ENA ? 1 : 0;
+	conf.reset   = state->flags & SS_RESET ? 1 : 0;
+
+	ret = skt->ops->configure_socket(skt->nr, &conf);
+	if (ret == 0) {
+		/*
+		 * This really needs a better solution.  The IRQ
+		 * may or may not be claimed by the driver.
+		 */
+		if (skt->irq_state != 1 && state->io_irq) {
+			skt->irq_state = 1;
+			set_irq_type(skt->irq, IRQT_FALLING);
+		} else if (skt->irq_state == 1 && state->io_irq == 0) {
+		  	skt->irq_state = 0;
+			set_irq_type(skt->irq, IRQT_NOEDGE);
+		}
+
+		skt->cs_state = *state;
+	}
 
-  conf.sock    = sock;
-  conf.vcc     = state->Vcc;
-  conf.vpp     = state->Vpp;
-  conf.output  = state->flags & SS_OUTPUT_ENA ? 1 : 0;
-  conf.speaker = state->flags & SS_SPKR_ENA ? 1 : 0;
-  conf.reset   = state->flags & SS_RESET ? 1 : 0;
-  conf.irq     = state->io_irq != 0;
+	if (ret < 0)
+		printk(KERN_ERR "sa1100_pcmcia: unable to configure "
+		       "socket %d\n", skt->nr);
 
-  return conf;
+	return ret;
 }
 
 /* sa1100_pcmcia_sock_init()
@@ -177,17 +192,12 @@
 static int sa1100_pcmcia_sock_init(unsigned int sock)
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
-  struct pcmcia_configure conf;
 
   DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, sock);
 
-  skt->cs_state = dead_socket;
-
-  conf = sa1100_pcmcia_state_to_config(sock, &dead_socket);
-
-  pcmcia_low_level->configure_socket(&conf);
+  sa1100_pcmcia_config_skt(skt, &dead_socket);
 
-  return pcmcia_low_level->socket_init(sock);
+  return skt->ops->socket_init(skt->nr);
 }
 
 
@@ -203,19 +213,14 @@
 static int sa1100_pcmcia_suspend(unsigned int sock)
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
-  struct pcmcia_configure conf;
   int ret;
 
-  DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, skt->nr);
 
-  conf = sa1100_pcmcia_state_to_config(sock, &dead_socket);
+  ret = sa1100_pcmcia_config_skt(skt, &dead_socket);
 
-  ret = pcmcia_low_level->configure_socket(&conf);
-
-  if (ret == 0) {
-    skt->cs_state = dead_socket;
-    ret = pcmcia_low_level->socket_suspend(sock);
-  }
+  if (ret == 0)
+    ret = skt->ops->socket_suspend(skt->nr);
 
   return ret;
 }
@@ -286,40 +291,33 @@
  */
 static void sa1100_pcmcia_task_handler(void *data)
 {
-  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
-  struct pcmcia_state_array state_array;
+  struct pcmcia_state state;
   unsigned int all_events;
 
   DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
 
-  state_array.size = sa1100_pcmcia_socket_count;
-  state_array.state = state;
-
   do {
     unsigned int events;
-    int ret, i;
-
-    memset(state, 0, sizeof(state));
+    int i;
 
     DEBUG(4, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);
 
-    ret = pcmcia_low_level->socket_state(&state_array);
-    if (ret < 0) {
-      printk(KERN_ERR "sa1100_pcmcia: unable to read socket status\n");
-      break;
-    }
-
     all_events = 0;
 
-    for (i = 0; i < state_array.size; i++, all_events |= events) {
+    for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
       struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
 
-      events = sa1100_pcmcia_events(&state[i], &skt->k_state,
+      memset(&state, 0, sizeof(state));
+
+      skt->ops->socket_state(skt->nr, &state);
+
+      events = sa1100_pcmcia_events(&state, &skt->k_state,
 				    skt->cs_state.csc_mask,
 				    skt->cs_state.flags);
 
-      if (events && sa1100_pcmcia_socket[i].handler != NULL)
+      if (events && skt->handler != NULL)
 	skt->handler(skt->handler_info, events);
+      all_events |= events;
     }
   } while(all_events);
 }  /* sa1100_pcmcia_task_handler() */
@@ -351,7 +349,7 @@
  * handling code performs scheduling operations which cannot be
  * executed from within an interrupt context.
  */
-static void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
+void sa1100_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
 {
   DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
   schedule_work(&sa1100_pcmcia_task);
@@ -378,12 +376,16 @@
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
 
+  if (handler && !try_module_get(skt->ops->owner))
+  	return -ENODEV;
   if (handler == NULL) {
     skt->handler = NULL;
   } else {
     skt->handler_info = info;
     skt->handler = handler;
   }
+  if (!handler)
+  	module_put(skt->ops->owner);
 
   return 0;
 }
@@ -427,7 +429,7 @@
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
   int ret = -1;
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   if (sock < sa1100_pcmcia_socket_count) {
     cap->features  = SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
@@ -463,28 +465,20 @@
 sa1100_pcmcia_get_status(unsigned int sock, unsigned int *status)
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
-  struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
-  struct pcmcia_state_array state_array;
+  struct pcmcia_state state;
   unsigned int stat;
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
-
-  state_array.size = sa1100_pcmcia_socket_count;
-  state_array.state = state;
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
-  memset(state, 0, sizeof(state));
+  memset(&state, 0, sizeof(state));
 
-  if ((pcmcia_low_level->socket_state(&state_array)) < 0) {
-    printk(KERN_ERR "sa1100_pcmcia: unable to get socket status\n");
-    return -1;
-  }
-
-  skt->k_state = state[sock];
+  skt->ops->socket_state(skt->nr, &state);
+  skt->k_state = state;
 
-  stat = state[sock].detect ? SS_DETECT : 0;
-  stat |= state[sock].ready ? SS_READY  : 0;
-  stat |= state[sock].vs_3v ? SS_3VCARD : 0;
-  stat |= state[sock].vs_Xv ? SS_XVCARD : 0;
+  stat = state.detect ? SS_DETECT : 0;
+  stat |= state.ready ? SS_READY  : 0;
+  stat |= state.vs_3v ? SS_3VCARD : 0;
+  stat |= state.vs_Xv ? SS_XVCARD : 0;
 
   /* The power status of individual sockets is not available
    * explicitly from the hardware, so we just remember the state
@@ -493,11 +487,11 @@
   stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
 
   if (skt->cs_state.flags & SS_IOCARD)
-    stat |= state[sock].bvd1 ? SS_STSCHG : 0;
+    stat |= state.bvd1 ? SS_STSCHG : 0;
   else {
-    if (state[sock].bvd1 == 0)
+    if (state.bvd1 == 0)
       stat |= SS_BATDEAD;
-    else if (state[sock].bvd2 == 0)
+    else if (state.bvd2 == 0)
       stat |= SS_BATWARN;
   }
 
@@ -530,7 +524,7 @@
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   *state = skt->cs_state;
 
@@ -551,9 +545,8 @@
 sa1100_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
-  struct pcmcia_configure conf;
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   DEBUG(3, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n",
 	(state->csc_mask==0)?"<NONE>":"",
@@ -571,16 +564,7 @@
   DEBUG(3, "\tVcc %d  Vpp %d  irq %d\n",
 	state->Vcc, state->Vpp, state->io_irq);
 
-  conf = sa1100_pcmcia_state_to_config(sock, state);
-
-  if (pcmcia_low_level->configure_socket(&conf) < 0) {
-    printk(KERN_ERR "sa1100_pcmcia: unable to configure socket %d\n", sock);
-    return -1;
-  }
-
-  skt->cs_state = *state;
-  
-  return 0;
+  return sa1100_pcmcia_config_skt(skt, state);
 }  /* sa1100_pcmcia_set_socket() */
 
 
@@ -623,7 +607,7 @@
 {
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   DEBUG(3, "\tmap %u  speed %u\n\tstart 0x%08x  stop 0x%08x\n",
 	map->map, map->speed, map->start, map->stop);
@@ -647,7 +631,7 @@
     if ( map->speed == 0)
        map->speed = SA1100_PCMCIA_IO_ACCESS;
 
-	sa1100_pcmcia_set_mecr(sock, cpufreq_get(0));
+	sa1100_pcmcia_set_mecr(skt, cpufreq_get(0));
   }
 
   if (map->stop == 1)
@@ -704,7 +688,7 @@
   struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
   unsigned long start;
 
-  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock);
+  DEBUG(2, "%s() for sock %u\n", __FUNCTION__, skt->nr);
 
   DEBUG(3, "\tmap %u speed %u sys_start %08lx sys_stop %08lx card_start %08x\n",
 	map->map, map->speed, map->sys_start, map->sys_stop, map->card_start);
@@ -736,18 +720,17 @@
 			  map->speed = SA1100_PCMCIA_5V_MEM_ACCESS;
 	  }
 
-	  sa1100_pcmcia_set_mecr(sock, cpufreq_get(0));
+	  sa1100_pcmcia_set_mecr(skt, cpufreq_get(0));
 
   }
 
-  start = (map->flags & MAP_ATTRIB) ? skt->phys_attr : skt->phys_mem;
-
   if (map->sys_stop == 0)
     map->sys_stop = PAGE_SIZE-1;
 
+  start = (map->flags & MAP_ATTRIB) ? skt->phys_attr : skt->phys_mem;
   map->sys_stop -= map->sys_start;
-  map->sys_stop += start;
-  map->sys_start = start;
+  map->sys_stop += start + map->card_start;
+  map->sys_start = start + map->card_start;
 
   skt->pc_mem_map[map->map] = *map;
 
@@ -767,9 +750,8 @@
 sa1100_pcmcia_proc_status(char *buf, char **start, off_t pos,
 			  int count, int *eof, void *data)
 {
-  unsigned int sock = (unsigned int)data;
+  struct sa1100_pcmcia_socket *skt = data;
   unsigned int clock = cpufreq_get(0);
-  struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
   unsigned long mecr = MECR;
   char *p = buf;
 
@@ -815,13 +797,13 @@
   p+=sprintf(p, "IRQ      : %d\n", skt->cs_state.io_irq);
 
   p+=sprintf(p, "I/O      : %u (%u)\n", skt->speed_io,
-	     sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, sock)));
+	     sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, skt->nr)));
 
   p+=sprintf(p, "attribute: %u (%u)\n", skt->speed_attr,
-	     sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, sock)));
+	     sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, skt->nr)));
 
   p+=sprintf(p, "common   : %u (%u)\n", skt->speed_mem,
-	     sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, sock)));
+	     sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, skt->nr)));
 
   return p-buf;
 }
@@ -846,7 +828,7 @@
   }
 
   entry->read_proc = sa1100_pcmcia_proc_status;
-  entry->data = (void *)sock;
+  entry->data = PCMCIA_SOCKET(sock);
 }
 
 #endif  /* defined(CONFIG_PROC_FS) */
@@ -881,8 +863,10 @@
 {
 	unsigned int sock;
 
-	for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock)
-		sa1100_pcmcia_set_mecr(sock, clock);
+	for (sock = 0; sock < SA1100_PCMCIA_MAX_SOCK; ++sock) {
+		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(sock);
+		sa1100_pcmcia_set_mecr(skt, clock);
+	}
 }
 
 /* sa1100_pcmcia_notifier()
@@ -936,11 +920,10 @@
  *
  * Register an SA1100 PCMCIA low level driver with the SA1100 core.
  */
-int sa1100_register_pcmcia(struct pcmcia_low_level *ops)
+int sa1100_register_pcmcia(struct pcmcia_low_level *ops, struct device *dev)
 {
 	struct pcmcia_init pcmcia_init;
-	struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
-	struct pcmcia_state_array state_array;
+	struct pcmcia_socket_class_data *cls;
 	unsigned int i, cpu_clock;
 	int ret;
 
@@ -956,54 +939,46 @@
 	 * set default MECR calculation if the board specific
 	 * code did not specify one...
 	 */
-	if (!pcmcia_low_level->socket_get_timing)
-		pcmcia_low_level->socket_get_timing = sa1100_pcmcia_default_mecr_timing;
+	if (!ops->socket_get_timing)
+		ops->socket_get_timing = sa1100_pcmcia_default_mecr_timing;
 
-	pcmcia_init.handler = sa1100_pcmcia_interrupt;
+	pcmcia_init.socket_irq[0] = NO_IRQ;
+	pcmcia_init.socket_irq[1] = NO_IRQ;
 	ret = ops->init(&pcmcia_init);
 	if (ret < 0) {
 		printk(KERN_ERR "Unable to initialize kernel PCMCIA service (%d).\n", ret);
-		if (ret == -1)
-			ret = -EIO;
 		goto out;
 	}
 
 	sa1100_pcmcia_socket_count = ret;
 
-	state_array.size  = ret;
-	state_array.state = state;
-
-	memset(state, 0, sizeof(state));
+	cpu_clock = cpufreq_get(0);
 
-	if (ops->socket_state(&state_array) < 0) {
-		printk(KERN_ERR "Unable to get PCMCIA status driver.\n");
-		ret = -EIO;
-		goto shutdown;
+	for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
+		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+		memset(skt, 0, sizeof(*skt));
 	}
 
-	cpu_clock = cpufreq_get(0);
-
 	/*
 	 * We initialize the MECR to default values here, because we are
 	 * not guaranteed to see a SetIOMap operation at runtime.
 	 */
 	for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
 		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
-		struct pcmcia_irq_info irq_info;
 
-		if (!request_mem_region(_PCMCIA(i), PCMCIASp, "PCMCIA")) {
-			ret = -EBUSY;
-			goto out_err;
-		}
+		skt->res.start	= _PCMCIA(i);
+		skt->res.end	= _PCMCIA(i) + PCMCIASp - 1;
+		skt->res.name	= "PCMCIA";
+		skt->res.flags	= IORESOURCE_MEM;
 
-		irq_info.sock = i;
-		irq_info.irq  = -1;
-		ret = ops->get_irq_info(&irq_info);
-		if (ret < 0)
-			printk(KERN_ERR "Unable to get IRQ for socket %u (%d)\n", i, ret);
+		ret = request_resource(&iomem_resource, &skt->res);
+		if (ret)
+			goto out_err;
 
-		skt->irq        = irq_info.irq;
-		skt->k_state    = state[i];
+		skt->nr		= i;
+		skt->ops	= ops;
+		skt->irq	= pcmcia_init.socket_irq[i];
+		skt->irq_state	= 0;
 		skt->speed_io   = SA1100_PCMCIA_IO_ACCESS;
 		skt->speed_attr = SA1100_PCMCIA_5V_MEM_ACCESS;
 		skt->speed_mem  = SA1100_PCMCIA_5V_MEM_ACCESS;
@@ -1016,18 +991,22 @@
 			goto out_err;
 		}
 
-		sa1100_pcmcia_set_mecr(i, cpu_clock);
+		ops->socket_state(skt->nr, &skt->k_state);
+		sa1100_pcmcia_set_mecr(skt, cpu_clock);
 	}
 
-
-	/* Only advertise as many sockets as we can detect */
-	ret = register_ss_entry(sa1100_pcmcia_socket_count,
-				&sa1100_pcmcia_operations);
-	if (ret < 0) {
-		printk(KERN_ERR "Unable to register sockets\n");
+	cls = kmalloc(sizeof(struct pcmcia_socket_class_data), GFP_KERNEL);
+	if (!cls) {
+		ret = -ENOMEM;
 		goto out_err;
 	}
 
+	memset(cls, 0, sizeof(struct pcmcia_socket_class_data));
+
+	cls->ops	= &sa1100_pcmcia_operations;
+	cls->nsock	= sa1100_pcmcia_socket_count;
+	dev->class_data = cls;
+
 	/*
 	 * Start the event poll timer.  It will reschedule by itself afterwards.
 	 */
@@ -1039,10 +1018,10 @@
 		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
 		iounmap(skt->virt_io);
 		skt->virt_io = NULL;
-		release_mem_region(_PCMCIA(i), PCMCIASp);
+		if (skt->res.start)
+			release_resource(&skt->res);
 	}
 
- shutdown:
 	ops->shutdown();
 
  out:
@@ -1056,7 +1035,7 @@
  *
  * Unregister a previously registered pcmcia driver
  */
-void sa1100_unregister_pcmcia(struct pcmcia_low_level *ops)
+void sa1100_unregister_pcmcia(struct pcmcia_low_level *ops, struct device *dev)
 {
 	int i;
 
@@ -1072,25 +1051,84 @@
 
 	del_timer_sync(&poll_timer);
 
-	unregister_ss_entry(&sa1100_pcmcia_operations);
-
 	for (i = 0; i < sa1100_pcmcia_socket_count; i++) {
 		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
 
 		iounmap(skt->virt_io);
 		skt->virt_io = NULL;
 		
-		release_mem_region(_PCMCIA(i), PCMCIASp);
+		release_resource(&skt->res);
 	}
 
 	ops->shutdown();
 
 	flush_scheduled_work();
 
+	kfree(dev->class_data);
+	dev->class_data = NULL;
+
 	pcmcia_low_level = NULL;
 }
 EXPORT_SYMBOL(sa1100_unregister_pcmcia);
 
+static struct device_driver sa1100_pcmcia_driver = {
+	.name		= "sa11x0-pcmcia",
+	.bus		= &platform_bus_type,
+	.devclass	= &pcmcia_socket_class,
+};
+
+static struct platform_device sa1100_pcmcia_device = {
+	.name		= "sa11x0-pcmcia",
+	.id		= 0,
+	.dev		= {
+		.name	= "Intel Corporation SA11x0 [PCMCIA]",
+	},
+};
+
+struct ll_fns {
+	int (*init)(struct device *dev);
+	void (*exit)(struct device *dev);
+};
+
+static struct ll_fns sa1100_ll_fns[] = {
+#ifdef CONFIG_SA1100_ASSABET
+	{ .init = pcmcia_assabet_init,	.exit = pcmcia_assabet_exit,	},
+#endif
+#ifdef CONFIG_SA1100_CERF
+	{ .init = pcmcia_cerf_init,	.exit = pcmcia_cerf_exit,	},
+#endif
+#ifdef CONFIG_SA1100_FLEXANET
+	{ .init = pcmcia_flexanet_init,	.exit = pcmcia_flexanet_exit,	},
+#endif
+#ifdef CONFIG_SA1100_FREEBIRD
+	{ .init = pcmcia_freebird_init,	.exit = pcmcia_freebird_exit,	},
+#endif
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+	{ .init = pcmcia_gcplus_init,	.exit = pcmcia_gcplus_exit,	},
+#endif
+#ifdef CONFIG_SA1100_H3600
+	{ .init = pcmcia_h3600_init,	.exit = pcmcia_h3600_exit,	},
+#endif
+#ifdef CONFIG_SA1100_PANGOLIN
+	{ .init = pcmcia_pangolin_init,	.exit = pcmcia_pangolin_exit,	},
+#endif
+#ifdef CONFIG_SA1100_SHANNON
+	{ .init = pcmcia_shannon_init,	.exit = pcmcia_shannon_exit,	},
+#endif
+#ifdef CONFIG_SA1100_SIMPAD
+	{ .init = pcmcia_simpad_init,	.exit = pcmcia_simpad_exit,	},
+#endif
+#ifdef CONFIG_SA1100_STORK
+	{ .init = pcmcia_stork_init,	.exit = pcmcia_stork_exit,	},
+#endif
+#ifdef CONFIG_SA1100_TRIZEPS
+	{ .init = pcmcia_trizeps_init,	.exit = pcmcia_trizeps_exit,	},
+#endif
+#ifdef CONFIG_SA1100_YOPY
+	{ .init = pcmcia_yopy_init,	.exit = pcmcia_yopy_exit,	},
+#endif
+};
+
 /* sa1100_pcmcia_init()
  * ^^^^^^^^^^^^^^^^^^^^
  *
@@ -1115,61 +1153,34 @@
 		return -EINVAL;
 	}
 
-	for (i = 0; i < SA1100_PCMCIA_MAX_SOCK; i++) {
-		struct sa1100_pcmcia_socket *skt = PCMCIA_SOCKET(i);
-
-		skt->speed_io   = SA1100_PCMCIA_IO_ACCESS;
-		skt->speed_attr = SA1100_PCMCIA_5V_MEM_ACCESS;
-		skt->speed_mem  = SA1100_PCMCIA_5V_MEM_ACCESS;
-	}
-
 #ifdef CONFIG_CPU_FREQ
 	ret = cpufreq_register_notifier(&sa1100_pcmcia_notifier_block,
 					CPUFREQ_TRANSITION_NOTIFIER);
 	if (ret < 0) {
 		printk(KERN_ERR "Unable to register CPU frequency change "
 			"notifier (%d)\n", ret);
+		driver_unregister(&sa1100_pcmcia_driver);
 		return ret;
 	}
 #endif
 
-#ifdef CONFIG_SA1100_ASSABET
-	pcmcia_assabet_init();
-#endif
-#ifdef CONFIG_SA1100_CERF
-	pcmcia_cerf_init();
-#endif
-#ifdef CONFIG_SA1100_FLEXANET
-	pcmcia_flexanet_init();
-#endif
-#ifdef CONFIG_SA1100_FREEBIRD
-	pcmcia_freebird_init();
-#endif
-#ifdef CONFIG_SA1100_GRAPHICSCLIENT
-	pcmcia_gcplus_init();
-#endif
-#ifdef CONFIG_SA1100_H3600
-	pcmcia_h3600_init();
-#endif
-#ifdef CONFIG_SA1100_PANGOLIN
-	pcmcia_pangolin_init();
-#endif
-#ifdef CONFIG_SA1100_SHANNON
-	pcmcia_shannon_init();
-#endif
-#ifdef CONFIG_SA1100_SIMPAD
-	pcmcia_simpad_init();
-#endif
-#ifdef CONFIG_SA1100_STORK
-	pcmcia_stork_init();
-#endif
-#ifdef CONFIG_SA1100_TRIZEPS
-	pcmcia_trizeps_init();
-#endif
-#ifdef CONFIG_SA1100_YOPY
-	pcmcia_yopy_init();
-#endif
+	driver_register(&sa1100_pcmcia_driver);
+
+	/*
+	 * Initialise any "on-board" PCMCIA sockets.
+	 */
+	for (i = 0; i < ARRAY_SIZE(sa1100_ll_fns); i++) {
+		ret = sa1100_ll_fns[i].init(&sa1100_pcmcia_device.dev);
+		if (ret == 0)
+			break;
+	}
 
+	if (ret == 0)
+		platform_device_register(&sa1100_pcmcia_device);
+
+	/*
+	 * Don't fail if we don't find any on-board sockets.
+	 */
 	return 0;
 }
 
@@ -1180,48 +1191,14 @@
  */
 static void __exit sa1100_pcmcia_exit(void)
 {
-#ifdef CONFIG_SA1100_ASSABET
-	pcmcia_assabet_exit();
-#endif
-#ifdef CONFIG_SA1100_CERF
-	pcmcia_cerf_exit();
-#endif
-#ifdef CONFIG_SA1100_FLEXANET
-	pcmcia_flexanet_exit();
-#endif
-#ifdef CONFIG_SA1100_FREEBIRD
-	pcmcia_freebird_exit();
-#endif
-#ifdef CONFIG_SA1100_GRAPHICSCLIENT
-	pcmcia_gcplus_exit();
-#endif
-#ifdef CONFIG_SA1100_H3600
-	pcmcia_h3600_exit();
-#endif
-#ifdef CONFIG_SA1100_PANGOLIN
-	pcmcia_pangolin_exit();
-#endif
-#ifdef CONFIG_SA1100_SHANNON
-	pcmcia_shannon_exit();
-#endif
-#ifdef CONFIG_SA1100_SIMPAD
-	pcmcia_simpad_exit();
-#endif
-#ifdef CONFIG_SA1100_STORK
-	pcmcia_stork_exit();
-#endif
-#ifdef CONFIG_SA1100_YOPY
-	pcmcia_yopy_exit();
-#endif
+	platform_device_unregister(&sa1100_pcmcia_device);
 
-	if (pcmcia_low_level) {
-		printk(KERN_ERR "PCMCIA: low level driver still registered\n");
-		sa1100_unregister_pcmcia(pcmcia_low_level);
-	}
 
 #ifdef CONFIG_CPU_FREQ
 	cpufreq_unregister_notifier(&sa1100_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 #endif
+
+	driver_unregister(&sa1100_pcmcia_driver);
 }
 
 MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_generic.h linux-2.5.63-bk6/drivers/pcmcia/sa1100_generic.h
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_generic.h	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_generic.h	Mon Mar 31 12:19:34 2003
@@ -18,7 +18,7 @@
 #define SA1100_PCMCIA_MAX_SOCK   (2)
 
 struct pcmcia_init {
-  void (*handler)(int irq, void *dev, struct pt_regs *regs);
+	int	socket_irq[SA1100_PCMCIA_MAX_SOCK];
 };
 
 struct pcmcia_state {
@@ -31,14 +31,8 @@
             vs_Xv: 1;
 };
 
-struct pcmcia_state_array {
-  unsigned int size;
-  struct pcmcia_state *state;
-};
-
 struct pcmcia_configure {
-  unsigned sock: 8,
-            vcc: 8,
+  unsigned  vcc: 8,
             vpp: 8,
          output: 1,
         speaker: 1,
@@ -46,17 +40,13 @@
             irq: 1;
 };
 
-struct pcmcia_irq_info {
-  unsigned int sock;
-  unsigned int irq;
-};
-
 struct pcmcia_low_level {
+  struct module *owner;
+
   int (*init)(struct pcmcia_init *);
   int (*shutdown)(void);
-  int (*socket_state)(struct pcmcia_state_array *);
-  int (*get_irq_info)(struct pcmcia_irq_info *);
-  int (*configure_socket)(const struct pcmcia_configure *);
+  void (*socket_state)(int sock, struct pcmcia_state *);
+  int (*configure_socket)(int sock, const struct pcmcia_configure *);
 
   /*
    * Enable card status IRQs on (re-)initialisation.  This can
@@ -77,7 +67,8 @@
 		unsigned int cpu_speed, unsigned int cmd_time);
 };
 
-extern int sa1100_register_pcmcia(struct pcmcia_low_level *);
-extern void sa1100_unregister_pcmcia(struct pcmcia_low_level *);
+extern int sa1100_register_pcmcia(struct pcmcia_low_level *, struct device *);
+extern void sa1100_unregister_pcmcia(struct pcmcia_low_level *, struct device *);
+extern void sa1100_pcmcia_interrupt(int, void *, struct pt_regs *);
 
 #endif
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_graphicsclient.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_graphicsclient.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_graphicsclient.c	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_graphicsclient.c	Mon Mar 31 12:19:34 2003
@@ -11,9 +11,11 @@
  *    Fix
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -49,13 +51,15 @@
 
   /* Register interrupts */
   irq = S0_CD_IRQ;
-  res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA 0 CD", NULL);
+  res = request_irq(irq, sa1100_pcmcia_interrupt, SA_INTERRUPT, "PCMCIA 0 CD", NULL);
   if (res < 0) {
     printk(KERN_ERR "%s: request for IRQ%d failed (%d)\n",
 	   __FUNCTION__, irq, res);
     return res;
   }
 
+  init->socket_irq[0] = S0_STS_IRQ;
+
   return 1;			// 1 PCMCIA Slot
 }
 
@@ -71,45 +75,27 @@
   return 0;
 }
 
-static int gcplus_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-
-  if(state_array->size<1) return -1;
-
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  levels=*PCMCIA_Status;
-
-  state_array->state[0].detect=(levels & ADS_CS_ST_A_CD)?1:0;
-  state_array->state[0].ready=(levels & ADS_CS_ST_A_READY)?1:0;
-  state_array->state[0].bvd1= 0;
-  state_array->state[0].bvd2= 0;
-  state_array->state[0].wrprot=0;
-  state_array->state[0].vs_3v=0;
-  state_array->state[0].vs_Xv=0;
-
-  return 1;
-}
-
-static int gcplus_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+static void gcplus_pcmcia_socket_state(int sock, struct pcmcia_state *state_array)
 {
-	if (info->sock > 1)
-		return -1;
+  unsigned long levels = *PCMCIA_Status;
 
-	if (info->sock == 0)
-		info->irq = S0_STS_IRQ;
-
-  	return 0;
+  if (sock == 0) {
+    state->detect=(levels & ADS_CS_ST_A_CD)?1:0;
+    state->ready=(levels & ADS_CS_ST_A_READY)?1:0;
+    state->bvd1= 0;
+    state->bvd2= 0;
+    state->wrprot=0;
+    state->vs_3v=0;
+    state->vs_Xv=0;
+  }
 }
 
-static int gcplus_pcmcia_configure_socket(const struct pcmcia_configure
+static int gcplus_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long flags;
 
-  if(configure->sock>1) return -1;
+  if(sock>1) return -1;
 
   local_irq_save(flags);
 
@@ -160,28 +146,28 @@
 }
 
 static struct pcmcia_low_level gcplus_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= gcplus_pcmcia_init,
   .shutdown		= gcplus_pcmcia_shutdown,
   .socket_state		= gcplus_pcmcia_socket_state,
-  .get_irq_info		= gcplus_pcmcia_get_irq_info,
   .configure_socket	= gcplus_pcmcia_configure_socket,
 
   .socket_init		= gcplus_pcmcia_socket_init,
   .socket_suspend	= gcplus_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_gcplus_init(void)
+int __init pcmcia_gcplus_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_gcplus())
-		ret = sa1100_register_pcmcia(&gcplus_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&gcplus_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_gcplus_exit(void)
+void __exit pcmcia_gcplus_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&gcplus_pcmcia_ops);
+	sa1100_unregister_pcmcia(&gcplus_pcmcia_ops, dev);
 }
 
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_graphicsmaster.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_graphicsmaster.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_graphicsmaster.c	Mon Feb 24 11:05:38 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_graphicsmaster.c	Mon Mar 31 12:19:34 2003
@@ -8,8 +8,10 @@
  * 7/5/01 Woojung Huh <whuh@applieddata.net>
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -35,12 +37,12 @@
 }
 
 static int
-graphicsmaster_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+graphicsmaster_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int pa_dwr_mask, pa_dwr_set;
   int ret;
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
 
@@ -69,7 +71,7 @@
     return -1;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -82,28 +84,28 @@
 }
 
 static struct pcmcia_low_level graphicsmaster_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= graphicsmaster_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= graphicsmaster_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_graphicsmaster_init(void)
+int __init pcmcia_graphicsmaster_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_graphicsmaster())
-		ret = sa1100_register_pcmcia(&graphicsmaster_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&graphicsmaster_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_graphicsmaster_exit(void)
+void __exit pcmcia_graphicsmaster_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&graphicsmaster_pcmcia_ops);
+	sa1100_unregister_pcmcia(&graphicsmaster_pcmcia_ops, dev);
 }
 
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_h3600.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_h3600.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_h3600.c	Mon Feb 24 11:05:38 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_h3600.c	Mon Mar 31 12:19:34 2003
@@ -4,8 +4,10 @@
  * PCMCIA implementation routines for H3600
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -28,17 +30,11 @@
 	int i, res;
 
 	/*
-	 * Set transition detect
-	 */
-	set_irq_type(IRQ_GPIO_H3600_PCMCIA_IRQ0, IRQT_FALLING);
-	set_irq_type(IRQ_GPIO_H3600_PCMCIA_IRQ1, IRQT_FALLING);
-
-	/*
 	 * Register interrupts
 	 */
 	for (i = res = 0; i < ARRAY_SIZE(irqs); i++) {
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			break;
 	}
@@ -51,6 +47,9 @@
 			free_irq(irqs[i].irq, NULL);
 	}
 
+	init->socket_irq[0] = IRQ_GPIO_H3600_PCMCIA_IRQ0;
+	init->socket_irq[1] = IRQ_GPIO_H3600_PCMCIA_IRQ1;
+
 	return res ? res : 2;
 }
 
@@ -72,54 +71,37 @@
 	return 0;
 }
 
-static int
-h3600_pcmcia_socket_state(struct pcmcia_state_array *state)
+static void h3600_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long levels;
-
-	if (state->size < 2)
-		return -1;
-
-	levels = GPLR;
+	unsigned long levels = GPLR;
 
-	state->state[0].detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
-	state->state[0].ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
-	state->state[0].bvd1 = 0;
-	state->state[0].bvd2 = 0;
-	state->state[0].wrprot = 0; /* Not available on H3600. */
-	state->state[0].vs_3v = 0;
-	state->state[0].vs_Xv = 0;
-
-	state->state[1].detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
-	state->state[1].ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
-	state->state[1].bvd1 = 0;
-	state->state[1].bvd2 = 0;
-	state->state[1].wrprot = 0; /* Not available on H3600. */
-	state->state[1].vs_3v = 0;
-	state->state[1].vs_Xv = 0;
-
-	return 1;
-}
-
-static int h3600_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-	switch (info->sock) {
+	switch (sock) {
 	case 0:
-		info->irq = IRQ_GPIO_H3600_PCMCIA_IRQ0;
+		state->detect = levels & GPIO_H3600_PCMCIA_CD0 ? 0 : 1;
+		state->ready = levels & GPIO_H3600_PCMCIA_IRQ0 ? 1 : 0;
+		state->bvd1 = 0;
+		state->bvd2 = 0;
+		state->wrprot = 0; /* Not available on H3600. */
+		state->vs_3v = 0;
+		state->vs_Xv = 0;
 		break;
+
 	case 1:
-		info->irq = IRQ_GPIO_H3600_PCMCIA_IRQ1;
+		state->detect = levels & GPIO_H3600_PCMCIA_CD1 ? 0 : 1;
+		state->ready = levels & GPIO_H3600_PCMCIA_IRQ1 ? 1 : 0;
+		state->bvd1 = 0;
+		state->bvd2 = 0;
+		state->wrprot = 0; /* Not available on H3600. */
+		state->vs_3v = 0;
+		state->vs_Xv = 0;
 		break;
-	default:
-		return -1;
 	}
-	return 0;
 }
 
 static int
-h3600_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+h3600_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
-	if (conf->sock > 1)
+	if (sock > 1)
 		return -1;
 
 	if (conf->vcc != 0 && conf->vcc != 33 && conf->vcc != 50) {
@@ -188,27 +170,27 @@
 }
 
 struct pcmcia_low_level h3600_pcmcia_ops = { 
+	.owner			= THIS_MODULE,
 	.init			= h3600_pcmcia_init,
 	.shutdown		= h3600_pcmcia_shutdown,
 	.socket_state		= h3600_pcmcia_socket_state,
-	.get_irq_info		= h3600_pcmcia_get_irq_info,
 	.configure_socket	= h3600_pcmcia_configure_socket,
 
 	.socket_init		= h3600_pcmcia_socket_init,
 	.socket_suspend		= h3600_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_h3600_init(void)
+int __init pcmcia_h3600_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_h3600())
-		ret = sa1100_register_pcmcia(&h3600_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&h3600_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_h3600_exit(void)
+void __exit pcmcia_h3600_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&h3600_pcmcia_ops);
+	sa1100_unregister_pcmcia(&h3600_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_jornada720.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_jornada720.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_jornada720.c	Mon Feb 24 11:05:29 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_jornada720.c	Mon Mar 31 12:19:34 2003
@@ -4,6 +4,7 @@
  * Jornada720 PCMCIA specific routines
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/device.h>
@@ -49,15 +50,15 @@
 }
 
 static int
-jornada720_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+jornada720_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int pa_dwr_mask, pa_dwr_set;
   int ret;
 
 printk("%s(): config socket %d vcc %d vpp %d\n", __FUNCTION__,
-	       conf->sock, conf->vcc, conf->vpp);
+	       sock, conf->vcc, conf->vpp);
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = SOCKET0_POWER | SOCKET0_3V;
 
@@ -90,7 +91,7 @@
     return -1;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -103,27 +104,27 @@
 }
 
 static struct pcmcia_low_level jornada720_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= jornada720_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= jornada720_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_jornada720_init(void)
+int __init pcmcia_jornada720_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_jornada720())
-		ret = sa1100_register_pcmcia(&jornada720_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&jornada720_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __devexit pcmcia_jornada720_exit(void)
+void __devexit pcmcia_jornada720_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&jornada720_pcmcia_ops);
+	sa1100_unregister_pcmcia(&jornada720_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_neponset.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_neponset.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_neponset.c	Mon Feb 24 11:05:44 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_neponset.c	Mon Mar 31 12:19:34 2003
@@ -3,6 +3,7 @@
  *
  * Neponset PCMCIA specific routines
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/device.h>
@@ -58,13 +59,13 @@
 }
 
 static int
-neponset_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+neponset_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
 	unsigned int ncr_mask, pa_dwr_mask;
 	unsigned int ncr_set, pa_dwr_set;
 	int ret;
 
-	switch (conf->sock) {
+	switch (sock) {
 	case 0:
 		pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
 		ncr_mask = NCR_A0VPP | NCR_A1VPP;
@@ -113,7 +114,7 @@
 		return -1;
 	}
 
-	ret = sa1111_pcmcia_configure_socket(conf);
+	ret = sa1111_pcmcia_configure_socket(sock, conf);
 	if (ret == 0) {
 		unsigned long flags;
 
@@ -127,27 +128,27 @@
 }
 
 static struct pcmcia_low_level neponset_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= neponset_pcmcia_init,
 	.shutdown		= sa1111_pcmcia_shutdown,
 	.socket_state		= sa1111_pcmcia_socket_state,
-	.get_irq_info		= sa1111_pcmcia_get_irq_info,
 	.configure_socket	= neponset_pcmcia_configure_socket,
 
 	.socket_init		= sa1111_pcmcia_socket_init,
 	.socket_suspend		= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_neponset_init(void)
+int __init pcmcia_neponset_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_assabet())
-		ret = sa1100_register_pcmcia(&neponset_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&neponset_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __devexit pcmcia_neponset_exit(void)
+void __devexit pcmcia_neponset_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&neponset_pcmcia_ops);
+	sa1100_unregister_pcmcia(&neponset_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_pangolin.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_pangolin.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_pangolin.c	Mon Feb 24 11:05:06 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_pangolin.c	Mon Mar 31 12:19:34 2003
@@ -5,8 +5,10 @@
  *
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -14,6 +16,12 @@
 #include <asm/irq.h>
 #include "sa1100_generic.h"
 
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+#define PANGOLIN_SOCK	1
+#else
+#define PANGOLIN_SOCK	0
+#endif
+
 static int pangolin_pcmcia_init(struct pcmcia_init *init){
   int res;
 
@@ -22,12 +30,14 @@
   GPCR = GPIO_PCMCIA_BUS_ON;
 #endif
 
+  init->socket_irq[PANGOLIN_SOCK] = IRQ_PCMCIA_IRQ;
+
   /* Set transition detect */
   set_irq_type(IRQ_PCMCIA_CD, IRQT_NOEDGE);
   set_irq_type(IRQ_PCMCIA_IRQ, IRQT_FALLING);
 
   /* Register interrupts */
-  res = request_irq(IRQ_PCMCIA_CD, init->handler, SA_INTERRUPT,
+  res = request_irq(IRQ_PCMCIA_CD, sa1100_pcmcia_interrupt, SA_INTERRUPT,
 		    "PCMCIA_CD", NULL);
   if (res >= 0)
     /* There's only one slot, but it's "Slot 1": */
@@ -51,57 +61,29 @@
   return 0;
 }
 
-static int pangolin_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-  unsigned long levels;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  levels=GPLR;
-#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
-  state_array->state[1].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
-  state_array->state[1].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
-  state_array->state[1].bvd1=1; /* Not available on Pangolin. */
-  state_array->state[1].bvd2=1; /* Not available on Pangolin. */
-  state_array->state[1].wrprot=0; /* Not available on Pangolin. */
-  state_array->state[1].vs_3v=1;  /* Can only apply 3.3V on Pangolin. */
-  state_array->state[1].vs_Xv=0;
-#else
-  state_array->state[0].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
-  state_array->state[0].ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
-  state_array->state[0].bvd1=1; /* Not available on Pangolin. */
-  state_array->state[0].bvd2=1; /* Not available on Pangolin. */
-  state_array->state[0].wrprot=0; /* Not available on Pangolin. */
-  state_array->state[0].vs_3v=0;  /* voltage level is determined by jumper setting */
-  state_array->state[0].vs_Xv=0;
-#endif
-  return 1;
-}
-
-static int pangolin_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+static void pangolin_pcmcia_socket_state(int sock, struct pcmcia_state *state)
+{
+  unsigned long levels = GPLR;;
 
-  if(info->sock>1) return -1;
-#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
-  if(info->sock==1)
-	info->irq=IRQ_PCMCIA_IRQ;
-#else
-  if(info->sock==0)
-        info->irq=IRQ_PCMCIA_IRQ;
-#endif
-  return 0;
+  if (sock == PANGOLIN_SOCK) {
+    state->detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
+    state->ready=(levels & GPIO_PCMCIA_IRQ)?1:0;
+    state->bvd1=1; /* Not available on Pangolin. */
+    state->bvd2=1; /* Not available on Pangolin. */
+    state->wrprot=0; /* Not available on Pangolin. */
+    state->vs_3v=1;  /* Can only apply 3.3V on Pangolin. */
+    state->vs_Xv=0;
+  }
 }
 
-static int pangolin_pcmcia_configure_socket(const struct pcmcia_configure
+static int pangolin_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long value, flags;
 
-  if(configure->sock>1) return -1;
+  if(sock>1) return -1;
 #ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
-  if(configure->sock==0) return 0;
+  if(sock==0) return 0;
 #endif
   local_irq_save(flags);
 
@@ -132,7 +114,7 @@
   }
 #ifdef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
   /* reset & unreset request */
-  if(configure->sock==0) {
+  if(sock==0) {
 	if(configure->reset) {
 		GPSR |= GPIO_PCMCIA_RESET;
 	} else {
@@ -148,40 +130,40 @@
 static int pangolin_pcmcia_socket_init(int sock)
 {
   if (sock == 1)
-    set_irq_type(IRQ_PCmCIA_CD, IRQT_BOTHEDGE);
+    set_irq_type(IRQ_PCMCIA_CD, IRQT_BOTHEDGE);
   return 0;
 }
 
 static int pangolin_pcmcia_socket_suspend(int sock)
 {
   if (sock == 1)
-    set_irq_type(IRQ_PCmCIA_CD, IRQT_NOEDGE);
+    set_irq_type(IRQ_PCMCIA_CD, IRQT_NOEDGE);
   return 0;
 }
 
 static struct pcmcia_low_level pangolin_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= pangolin_pcmcia_init,
   .shutdown		= pangolin_pcmcia_shutdown,
   .socket_state		= pangolin_pcmcia_socket_state,
-  .get_irq_info		= pangolin_pcmcia_get_irq_info,
   .configure_socket	= pangolin_pcmcia_configure_socket,
 
   .socket_init		= pangolin_pcmcia_socket_init,
-  socket_suspend,	pangolin_pcmcia_socket_suspend,
+  .socket_suspend	= pangolin_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_pangolin_init(void)
+int __init pcmcia_pangolin_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_pangolin())
-		ret = sa1100_register_pcmcia(&pangolin_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&pangolin_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_pangolin_exit(void)
+void __exit pcmcia_pangolin_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&pangolin_pcmcia_ops);
+	sa1100_unregister_pcmcia(&pangolin_pcmcia_ops, dev);
 }
 
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_pfs168.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_pfs168.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_pfs168.c	Mon Feb 24 11:05:16 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_pfs168.c	Mon Mar 31 12:19:34 2003
@@ -5,9 +5,11 @@
  * PFS168 PCMCIA specific routines
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -29,7 +31,7 @@
 }
 
 static int
-pfs168_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+pfs168_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int pa_dwr_mask = 0, pa_dwr_set = 0;
   int ret;
@@ -46,7 +48,7 @@
    *
    */
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
 
@@ -106,7 +108,7 @@
     break;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -119,27 +121,27 @@
 }
 
 static struct pcmcia_low_level pfs168_pcmcia_ops = {
+  .owner		= THIS_MODULE,
   .init			= pfs168_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= pfs168_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_pfs168_init(void)
+int __init pcmcia_pfs168_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_pfs168())
-		ret = sa1100_register_pcmcia(&pfs168_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&pfs168_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_pfs168_exit(void)
+void __exit pcmcia_pfs168_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&pfs168_pcmcia_ops);
+	sa1100_unregister_pcmcia(&pfs168_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_shannon.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_shannon.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_shannon.c	Mon Feb 24 11:05:44 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_shannon.c	Mon Mar 31 12:19:34 2003
@@ -4,8 +4,10 @@
  * PCMCIA implementation routines for Shannon
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -32,17 +34,16 @@
 	GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
 		  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
 
-	/* Set transition detect */
-	set_irq_type(SHANNON_IRQ_GPIO_RDY_0, IRQT_FALLING);
-	set_irq_type(SHANNON_IRQ_GPIO_RDY_1, IRQT_FALLING);
+	init->socket_irq[0] = SHANNON_IRQ_GPIO_RDY_0;
+	init->socket_irq[1] = SHANNON_IRQ_GPIO_RDY_1;
 
 	/* Register interrupts */
 	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			goto irq_err;
+		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
 	}
 
 	return 2;
@@ -68,48 +69,35 @@
 	return 0;
 }
 
-static int shannon_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+static void shannon_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long levels;
-
-	memset(state_array->state, 0,
-	       state_array->size * sizeof(struct pcmcia_state));
-
-	levels = GPLR;
+	unsigned long levels = GPLR;
 
-	state_array->state[0].detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
-	state_array->state[0].ready  = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
-	state_array->state[0].wrprot = 0; /* Not available on Shannon. */
-	state_array->state[0].bvd1 = 1; 
-	state_array->state[0].bvd2 = 1; 
-	state_array->state[0].vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
-	state_array->state[0].vs_Xv  = 0;
-
-	state_array->state[1].detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
-	state_array->state[1].ready  = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
-	state_array->state[1].wrprot = 0; /* Not available on Shannon. */
-	state_array->state[1].bvd1 = 1; 
-	state_array->state[1].bvd2 = 1; 
-	state_array->state[1].vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
-	state_array->state[1].vs_Xv  = 0;
-
-	return 1;
-}
+	switch (sock) {
+	case 0:
+		state->detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
+		state->ready  = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
+		state->wrprot = 0; /* Not available on Shannon. */
+		state->bvd1   = 1; 
+		state->bvd2   = 1; 
+		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
+		state->vs_Xv  = 0;
+		break;
 
-static int shannon_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-	if (info->sock == 0)
-		info->irq = SHANNON_IRQ_GPIO_RDY_0;
-	else if (info->sock == 1)
-		info->irq = SHANNON_IRQ_GPIO_RDY_1;
-	else return -1;
-	
-	return 0;
+	case 1:
+		state->detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
+		state->ready  = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
+		state->wrprot = 0; /* Not available on Shannon. */
+		state->bvd1   = 1; 
+		state->bvd2   = 1; 
+		state->vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
+		state->vs_Xv  = 0;
+		break;
+	}
 }
 
-static int shannon_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int shannon_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
-
 	switch (configure->vcc) {
 	case 0:	/* power off */
 		printk(KERN_WARNING __FUNCTION__"(): CS asked for 0V, still applying 3.3V..\n");
@@ -152,27 +140,27 @@
 }
 
 static struct pcmcia_low_level shannon_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= shannon_pcmcia_init,
 	.shutdown		= shannon_pcmcia_shutdown,
 	.socket_state		= shannon_pcmcia_socket_state,
-	.get_irq_info		= shannon_pcmcia_get_irq_info,
 	.configure_socket	= shannon_pcmcia_configure_socket,
 
 	.socket_init		= shannon_pcmcia_socket_init,
 	.socket_suspend		= shannon_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_shannon_init(void)
+int __init pcmcia_shannon_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_shannon())
-		ret = sa1100_register_pcmcia(&shannon_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&shannon_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_shannon_exit(void)
+void __exit pcmcia_shannon_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&shannon_pcmcia_ops);
+	sa1100_unregister_pcmcia(&shannon_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_simpad.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_simpad.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_simpad.c	Mon Feb 24 11:06:01 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_simpad.c	Mon Mar 31 12:19:34 2003
@@ -4,8 +4,10 @@
  * PCMCIA implementation routines for simpad
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -27,15 +29,16 @@
 
   clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
-  /* Set transition detect */
-  set_irq_type( IRQ_GPIO_CF_CD, IRQT_NOEDGE );
-  set_irq_type( IRQ_GPIO_CF_IRQ, IRQT_FALLING );
+  init->socket_irq[1] = IRQ_GPIO_CF_IRQ;
 
   /* Register interrupts */
   irq = IRQ_GPIO_CF_CD;
-  res = request_irq( irq, init->handler, SA_INTERRUPT, "CF_CD", NULL );
+  res = request_irq(irq, sa1100_pcmcia_interrupt, SA_INTERRUPT,
+		    "CF_CD", NULL );
   if( res < 0 ) goto irq_err;
 
+  set_irq_type( IRQ_GPIO_CF_CD, IRQT_NOEDGE );
+
   /* There's only one slot, but it's "Slot 1": */
   return 2;
 
@@ -58,59 +61,36 @@
   return 0;
 }
 
-static int simpad_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array)
+static void simpad_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-  unsigned long levels;
-  unsigned long *cs3reg = CS3_BASE;
-
-  if(state_array->size<2) return -1;
-
-  memset(state_array->state, 0, 
-	 (state_array->size)*sizeof(struct pcmcia_state));
-
-  levels=GPLR;
-
-  state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
-
-  state_array->state[1].ready=(levels & GPIO_CF_IRQ)?1:0;
-
-  state_array->state[1].bvd1=1; /* Not available on Simpad. */
-
-  state_array->state[1].bvd2=1; /* Not available on Simpad. */
-
-  state_array->state[1].wrprot=0; /* Not available on Simpad. */
-
+  if (sock == 1) {
+    unsigned long levels = GPLR;
+    unsigned long *cs3reg = CS3_BASE;
+
+    state->detect=((levels & GPIO_CF_CD)==0)?1:0;
+    state->ready=(levels & GPIO_CF_IRQ)?1:0;
+    state->bvd1=1; /* Not available on Simpad. */
+    state->bvd2=1; /* Not available on Simpad. */
+    state->wrprot=0; /* Not available on Simpad. */
   
-  if((*cs3reg & 0x0c) == 0x0c) {
-    state_array->state[1].vs_3v=0;
-    state_array->state[1].vs_Xv=0;
-  } else
-  {
-    state_array->state[1].vs_3v=1;
-    state_array->state[1].vs_Xv=0;
+    if((*cs3reg & 0x0c) == 0x0c) {
+      state->vs_3v=0;
+      state->vs_Xv=0;
+    } else {
+      state->vs_3v=1;
+      state->vs_Xv=0;
+    }
   }
-  return 1;
-}
-
-static int simpad_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-  if(info->sock>1) return -1;
-
-  if(info->sock==1)
-    info->irq=IRQ_GPIO_CF_IRQ;
-
-  return 0;
 }
 
-static int simpad_pcmcia_configure_socket(const struct pcmcia_configure
+static int simpad_pcmcia_configure_socket(int sock, const struct pcmcia_configure
 					   *configure)
 {
   unsigned long value, flags;
 
-  if(configure->sock>1) return -1;
+  if(sock>1) return -1;
 
-  if(configure->sock==0) return 0;
+  if(sock==0) return 0;
 
   local_irq_save(flags);
 
@@ -159,27 +139,27 @@
 }
 
 static struct pcmcia_low_level simpad_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= simpad_pcmcia_init,
   .shutdown		= simpad_pcmcia_shutdown,
   .socket_state		= simpad_pcmcia_socket_state,
-  .get_irq_info		= simpad_pcmcia_get_irq_info,
   .configure_socket	= simpad_pcmcia_configure_socket,
 
   .socket_init		= simpad_pcmcia_socket_init,
   .socket_suspend	= simpad_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_simpad_init(void)
+int __init pcmcia_simpad_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_simpad())
-		ret = sa1100_register_pcmcia(&simpad_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&simpad_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_simpad_exit(void)
+void __exit pcmcia_simpad_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&simpad_pcmcia_ops);
+	sa1100_unregister_pcmcia(&simpad_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_stork.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_stork.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_stork.c	Mon Feb 24 11:05:32 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_stork.c	Mon Mar 31 12:19:34 2003
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/i2c.h>
 
 #include <asm/hardware.h>
@@ -45,17 +46,16 @@
 
 	printk("in stork_pcmcia_init\n");
 
-	/* Set transition detect */
-	set_irq_type(IRQ_GPIO_STORK_PCMCIA_A_RDY, IRQT_FALLING);
-	set_irq_type(IRQ_GPIO_STORK_PCMCIA_B_RDY, IRQT_FALLING);
+	init->socket_irq[0] = IRQ_GPIO_STORK_PCMCIA_A_RDY;
+	init->socket_irq[1] = IRQ_GPIO_STORK_PCMCIA_B_RDY;
 
 	/* Register interrupts */
 	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			goto irq_err;
+		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
 	}
 
         return 2;
@@ -87,69 +87,51 @@
         return 0;
 }
 
-static int stork_pcmcia_socket_state(struct pcmcia_state_array *state_array)
+static void stork_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-        unsigned long levels;
-
-        if(state_array->size<2) return -1;
+        unsigned long levels = GPLR;
 
-        memset(state_array->state, 0, 
-               (state_array->size)*sizeof(struct pcmcia_state));
+	if (debug > 1)
+		printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", levels,
+			(levels & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
 
-        levels=GPLR;
+	switch (sock) {
+	case 0:
+		state->detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
+		state->ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
+		state->bvd1= 1;
+		state->bvd2= 1;
+		state->wrprot=0;
+		state->vs_3v=1;
+		state->vs_Xv=0;
+		break;
 
-	if (debug > 1)
-		printk(__FUNCTION__ " GPLR=%x IRQ[1:0]=%x\n", GPLR, (GPLR & (GPIO_STORK_PCMCIA_A_RDY|GPIO_STORK_PCMCIA_B_RDY)));
-	state_array->state[0].detect=((levels & GPIO_STORK_PCMCIA_A_CARD_DETECT)==0)?1:0;
-	state_array->state[0].ready=(levels & GPIO_STORK_PCMCIA_A_RDY)?1:0;
-	state_array->state[0].bvd1= 1;
-	state_array->state[0].bvd2= 1;
-	state_array->state[0].wrprot=0;
-	state_array->state[0].vs_3v=1;
-	state_array->state[0].vs_Xv=0;
-
-	state_array->state[1].detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
-	state_array->state[1].ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
-	state_array->state[1].bvd1=1;
-	state_array->state[1].bvd2=1;
-	state_array->state[1].wrprot=0;
-	state_array->state[1].vs_3v=1;
-	state_array->state[1].vs_Xv=0;
-
-        return 1;
-}
-
-static int stork_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-
-        switch (info->sock) {
-        case 0:
-                info->irq=IRQ_GPIO_STORK_PCMCIA_A_RDY;
-                break;
-        case 1:
-                info->irq=IRQ_GPIO_STORK_PCMCIA_B_RDY;
-                break;
-        default:
-                return -1;
-        }
-        return 0;
+	case 1:
+		state->detect=((levels & GPIO_STORK_PCMCIA_B_CARD_DETECT)==0)?1:0;
+		state->ready=(levels & GPIO_STORK_PCMCIA_B_RDY)?1:0;
+		state->bvd1=1;
+		state->bvd2=1;
+		state->wrprot=0;
+		state->vs_3v=1;
+		state->vs_Xv=0;
+		break;
+	}
 }
 
-static int stork_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int stork_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
-        int card = configure->sock;
 	unsigned long flags;
 
         int DETECT, RDY, POWER, RESET;
 
-        if (card > 1) return -1;
+        if (sock > 1) return -1;
 
 	printk(__FUNCTION__ ": socket=%d vcc=%d vpp=%d reset=%d\n", 
-                       card, configure->vcc, configure->vpp, configure->reset);
+                       sock, configure->vcc, configure->vpp, configure->reset);
 
 	local_irq_save(flags);
 
-        if (card == 0) {
+        if (sock == 0) {
     	    DETECT = GPIO_STORK_PCMCIA_A_CARD_DETECT;
     	    RDY = GPIO_STORK_PCMCIA_A_RDY;
     	    POWER = STORK_PCMCIA_A_POWER_ON;
@@ -228,28 +210,28 @@
 }
 
 static struct pcmcia_low_level stork_pcmcia_ops = { 
+	.owner			= THIS_MODULE,
 	.init			= stork_pcmcia_init,
 	.shutdown		= stork_pcmcia_shutdown,
 	.socket_state		= stork_pcmcia_socket_state,
-	.get_irq_info		= stork_pcmcia_get_irq_info,
 	.configure_socket	= stork_pcmcia_configure_socket,
 
 	.socket_init		= stork_pcmcia_socket_init,
 	.socket_suspend		= stork_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_stork_init(void)
+int __init pcmcia_stork_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_stork())
-		ret = sa1100_register_pcmcia(&stork_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&stork_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_stork_exit(void)
+void __exit pcmcia_stork_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&stork_pcmcia_ops);
+	sa1100_unregister_pcmcia(&stork_pcmcia_ops, dev);
 }
 
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_system3.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_system3.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_system3.c	Mon Feb 24 11:06:02 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_system3.c	Mon Mar 31 12:19:34 2003
@@ -25,9 +25,11 @@
  *
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/device.h>
 #include <linux/ioport.h>
 
 #include <asm/hardware.h>
@@ -48,6 +50,9 @@
 
 int system3_pcmcia_init(struct pcmcia_init *init)
 {
+	init->socket_irq[0] = IRQ_S0_READY_NINT;
+	init->socket_irq[1] = IRQ_S1_READY_NINT;
+
 	/* Don't need no CD and BVD* interrupts */
 	return 2;
 }
@@ -57,76 +62,69 @@
 	return 0;
 }
 
-int system3_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+int system3_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
-	if (!conf)
-		return -1;
-
 	/* only CF ATM */
-	if (conf->sock == 0)
+	if (sock == 0)
 		return -1;
 
-	return sa1111_pcmcia_configure_socket( conf );
+	return sa1111_pcmcia_configure_socket(sock, conf);
 }
 
-static int system3_pcmcia_socket_state(struct pcmcia_state_array
-		*state)
+static void system3_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long	status		= 0;
-
-	if(state->size<2) return -1;
-
-	memset(state->state, 0,
-			(state->size)*sizeof(struct pcmcia_state));
-
-	status=PCSR;
+	unsigned long status = PCSR;
 
+	switch (sock) {
 #if 0 /* PCMCIA socket not yet connected */
-	state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1;
-	state->state[0].ready  = status & PCSR_S0_READY  ? 1 : 0;
-	state->state[0].bvd1   = status & PCSR_S0_BVD1   ? 1 : 0;
-	state->state[0].bvd2   = 1;
-	state->state[0].wrprot = status & PCSR_S0_WP     ? 1 : 0;
-	state->state[0].vs_3v  = 1;
-	state->state[0].vs_Xv  = 0;
+	case 0:
+		state->detect = status & PCSR_S0_DETECT ? 0 : 1;
+		state->ready  = status & PCSR_S0_READY  ? 1 : 0;
+		state->bvd1   = status & PCSR_S0_BVD1   ? 1 : 0;
+		state->bvd2   = 1;
+		state->wrprot = status & PCSR_S0_WP     ? 1 : 0;
+		state->vs_3v  = 1;
+		state->vs_Xv  = 0;
+		break;
 #endif
 
-	state->state[1].detect = status & PCSR_S1_DETECT ? 0 : 1;
-	state->state[1].ready  = status & PCSR_S1_READY  ? 1 : 0;
-	state->state[1].bvd1   = status & PCSR_S1_BVD1   ? 1 : 0;
-	state->state[1].bvd2   = 1;
-	state->state[1].wrprot = status & PCSR_S1_WP     ? 1 : 0;
-	state->state[1].vs_3v  = 1;
-	state->state[1].vs_Xv  = 0;
-
-	DPRINTK( "PCSR=0x%08lx, S1_RDY_nIREQ=%d\n", status,
-			state->state[1].ready );
+	case 1:
+		state->detect = status & PCSR_S1_DETECT ? 0 : 1;
+		state->ready  = status & PCSR_S1_READY  ? 1 : 0;
+		state->bvd1   = status & PCSR_S1_BVD1   ? 1 : 0;
+		state->bvd2   = 1;
+		state->wrprot = status & PCSR_S1_WP     ? 1 : 0;
+		state->vs_3v  = 1;
+		state->vs_Xv  = 0;
+		break;
+	}
 
-	return 1;
+	DPRINTK("Sock %d PCSR=0x%08lx, Sx_RDY_nIREQ=%d\n",
+		sock, status, state->ready);
 }
 
 struct pcmcia_low_level system3_pcmcia_ops = {
-	.init				= system3_pcmcia_init,
-	.shutdown			= system3_pcmcia_shutdown,
+	.owner			= THIS_MODULE,
+	.init			= system3_pcmcia_init,
+	.shutdown		= system3_pcmcia_shutdown,
 	.socket_state		= system3_pcmcia_socket_state,
-	.get_irq_info		= sa1111_pcmcia_get_irq_info,
 	.configure_socket	= system3_pcmcia_configure_socket,
 
 	.socket_init		= sa1111_pcmcia_socket_init,
 	.socket_suspend		= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_system3_init(void)
+int __init pcmcia_system3_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_pt_system3())
-		ret = sa1100_register_pcmcia(&system3_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&system3_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_system3_exit(void)
+void __exit pcmcia_system3_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&system3_pcmcia_ops);
+	sa1100_unregister_pcmcia(&system3_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_trizeps.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_trizeps.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_trizeps.c	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_trizeps.c	Mon Mar 31 12:19:34 2003
@@ -9,8 +9,10 @@
  * Guennadi Liakhovetski <gl@dsa-ac.de>
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -29,6 +31,8 @@
 {
 	int res;
 
+	init->socket_irq[0] = TRIZEPS_IRQ_PCMCIA_IRQ0;
+
 	/* Enable CF bus: */
 	TRIZEPS_BCR_clear(TRIZEPS_BCR1, TRIZEPS_nPCM_ENA_REG);
 
@@ -36,15 +40,12 @@
 	GPDR &= ~((GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0))
 		    | (GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)));
 
-	/* Set transition detect */
-//	set_irq_type(SA1100_GPIO_TO_IRQ(GPIO_TRIZEPS_PCMCIA_CD0), IRQT_BOTHEDGE);
-	set_irq_type(TRIZEPS_IRQ_PCMCIA_IRQ0, IRQT_FALLING);
-
 	/* Register SOCKET interrupts */
 	/* WHY? */
-	set_irq_type(TRIZEPS_IRQ_PCMCIA_CD0, IRQT_NOEDGE);
-	res = request_irq( TRIZEPS_IRQ_PCMCIA_CD0, init->handler, SA_INTERRUPT, "PCMCIA_CD0", NULL );
+	res = request_irq(TRIZEPS_IRQ_PCMCIA_CD0, sa1100_pcmcia_interrupt,
+			  SA_INTERRUPT, "PCMCIA_CD0", NULL );
 	if( res < 0 ) goto irq_err;
+	set_irq_type(TRIZEPS_IRQ_PCMCIA_CD0, IRQT_NOEDGE);
 
 	//MECR = 0x00060006; // Initialised on trizeps init
 
@@ -79,55 +80,30 @@
  *
 
  ******************************************************/
-static int trizeps_pcmcia_socket_state(struct pcmcia_state_array
-				       *state_array){
-	unsigned long levels;
-
-	if (state_array->size < NUMBER_OF_TRIZEPS_PCMCIA_SLOTS) return -1;
-
-	memset(state_array->state, 0,
-	       (state_array->size)*sizeof(struct pcmcia_state));
-
-	levels = GPLR;
-
-	state_array->state[0].detect = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0)) == 0) ? 1 : 0;
-	state_array->state[0].ready  = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)) != 0) ? 1 : 0;
-	state_array->state[0].bvd1   = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD1) !=0 ) ? 1 : 0;
-	state_array->state[0].bvd2   = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD2) != 0) ? 1 : 0;
-	state_array->state[0].wrprot = 0; // not write protected
-	state_array->state[0].vs_3v  = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS1) == 0) ? 1 : 0; //VS1=0 -> vs_3v=1
-	state_array->state[0].vs_Xv  = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS2) == 0) ? 1 : 0; //VS2=0 -> vs_Xv=1
-
-	return 1;  // success
-}
-
-/**
- *
- *
- ******************************************************/
-static int trizeps_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
+static void trizeps_pcmcia_socket_state(int sock, struct pcmcia_state *state_array)
+{
+	unsigned long levels = GPLR;
 
-	switch (info->sock) {
-	case 0:
-		info->irq=TRIZEPS_IRQ_PCMCIA_IRQ0;
-		break;
-	case 1:
-		// MFTB2 use only one Slot
-	default:
-		return -1;
+	if (sock == 0) {
+		state->detect = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0)) == 0) ? 1 : 0;
+		state->ready  = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)) != 0) ? 1 : 0;
+		state->bvd1   = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD1) !=0 ) ? 1 : 0;
+		state->bvd2   = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD2) != 0) ? 1 : 0;
+		state->wrprot = 0; // not write protected
+		state->vs_3v  = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS1) == 0) ? 1 : 0; //VS1=0 -> vs_3v=1
+		state->vs_Xv  = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS2) == 0) ? 1 : 0; //VS2=0 -> vs_Xv=1
 	}
-	return 0;
 }
 
 /**
  *
  *
  ******************************************************/
-static int trizeps_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int trizeps_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
 	unsigned long flags;
 
-	if(configure->sock>1) return -1;
+	if(sock>1) return -1;
 
 	local_irq_save(flags);
 
@@ -167,24 +143,18 @@
 	*/
 	local_irq_restore(flags);
 
-	if (configure->irq) {
-		enable_irq(TRIZEPS_IRQ_PCMCIA_CD0);
-		enable_irq(TRIZEPS_IRQ_PCMCIA_IRQ0);
-	} else {
-		disable_irq(TRIZEPS_IRQ_PCMCIA_IRQ0);
-		disable_irq(TRIZEPS_IRQ_PCMCIA_CD0);
-	}
-
 	return 0;
 }
 
 static int trizeps_pcmcia_socket_init(int sock)
 {
+	set_irq_type(TRIZEPS_IRQ_PCMCIA_CD0, IRQT_BOTHEDGE);
 	return 0;
 }
 
 static int trizeps_pcmcia_socket_suspend(int sock)
 {
+	set_irq_type(TRIZEPS_IRQ_PCMCIA_CD0, IRQT_NOEDGE);
 	return 0;
 }
 
@@ -193,24 +163,24 @@
  *
  ******************************************************/
 struct pcmcia_low_level trizeps_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= trizeps_pcmcia_init,
 	.shutdown		= trizeps_pcmcia_shutdown,
 	.socket_state		= trizeps_pcmcia_socket_state,
-	.get_irq_info		= trizeps_pcmcia_get_irq_info,
 	.configure_socket	= trizeps_pcmcia_configure_socket,
 	.socket_init		= trizeps_pcmcia_socket_init,
 	.socket_suspend		= trizeps_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_trizeps_init(void)
+int __init pcmcia_trizeps_init(struct device *dev)
 {
 	if (machine_is_trizeps()) {
-		return sa1100_register_pcmcia(&trizeps_pcmcia_ops);
+		return sa1100_register_pcmcia(&trizeps_pcmcia_ops, dev);
 	}
 	return -ENODEV;
 }
 
-void __exit pcmcia_trizeps_exit(void)
+void __exit pcmcia_trizeps_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&trizeps_pcmcia_ops);
+	sa1100_unregister_pcmcia(&trizeps_pcmcia_ops, dev);
 }
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_xp860.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_xp860.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_xp860.c	Mon Feb 24 11:05:16 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_xp860.c	Mon Mar 31 12:19:34 2003
@@ -4,9 +4,11 @@
  * XP860 PCMCIA specific routines
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -40,7 +42,7 @@
 }
 
 static int
-xp860_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+xp860_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
   unsigned int gpio_mask, pa_dwr_mask;
   unsigned int gpio_set, pa_dwr_set;
@@ -70,7 +72,7 @@
    * the corresponding truth table.
    */
 
-  switch (conf->sock) {
+  switch (sock) {
   case 0:
     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
     gpio_mask = NCR_A0VPP | NCR_A1VPP;
@@ -117,7 +119,7 @@
     break;
   }
 
-  ret = sa1111_pcmcia_configure_socket(conf);
+  ret = sa1111_pcmcia_configure_socket(sock, conf);
   if (ret == 0) {
     unsigned long flags;
 
@@ -132,28 +134,28 @@
 }
 
 static struct pcmcia_low_level xp860_pcmcia_ops = { 
+  .owner		= THIS_MODULE,
   .init			= xp860_pcmcia_init,
   .shutdown		= sa1111_pcmcia_shutdown,
   .socket_state		= sa1111_pcmcia_socket_state,
-  .get_irq_info		= sa1111_pcmcia_get_irq_info,
   .configure_socket	= xp860_pcmcia_configure_socket,
 
   .socket_init		= sa1111_pcmcia_socket_init,
   .socket_suspend	= sa1111_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_xp860_init(void)
+int __init pcmcia_xp860_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_xp860())
-		ret = sa1100_register_pcmcia(&xp860_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&xp860_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_xp860_exit(void)
+void __exit pcmcia_xp860_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&xp860_pcmcia_ops);
+	sa1100_unregister_pcmcia(&xp860_pcmcia_ops, dev);
 }
 
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1100_yopy.c linux-2.5.63-bk6/drivers/pcmcia/sa1100_yopy.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1100_yopy.c	Mon Feb 24 11:05:39 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1100_yopy.c	Mon Mar 31 12:19:34 2003
@@ -4,8 +4,10 @@
  * PCMCIA implementation routines for Yopy
  *
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/device.h>
 #include <linux/init.h>
 
 #include <asm/hardware.h>
@@ -38,19 +40,18 @@
 {
 	int i, res;
 
+	init->socket_irq[0] = IRQ_CF_IREQ;
+
 	pcmcia_power(0);
 	pcmcia_reset(1);
 
-	/* Set transition detect */
-	set_irq_type(IRQ_CF_IREQ, IRQT_FALLING);
-
 	/* Register interrupts */
 	for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
-		res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		res = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (res)
 			goto irq_err;
+		set_irq_type(irqs[i].irq, IRQT_NOEDGE);
 	}
 
 	return 1;
@@ -80,42 +81,24 @@
 	return 0;
 }
 
-static int yopy_pcmcia_socket_state(struct pcmcia_state_array *state_array)
-{
-	unsigned long levels;
-
-	if (state_array->size != 1)
-		return -1;
-
-	memset(state_array->state, 0,
-	       state_array->size * sizeof(struct pcmcia_state));
-
-	levels = GPLR;
-
-	state_array->state[0].detect = (levels & GPIO_CF_CD)    ? 0 : 1;
-	state_array->state[0].ready  = (levels & GPIO_CF_READY) ? 1 : 0;
-	state_array->state[0].bvd1   = (levels & GPIO_CF_BVD1)  ? 1 : 0;
-	state_array->state[0].bvd2   = (levels & GPIO_CF_BVD2)  ? 1 : 0;
-	state_array->state[0].wrprot = 0; /* Not available on Yopy. */
-	state_array->state[0].vs_3v  = 0; /* FIXME Can only apply 3.3V on Yopy. */
-	state_array->state[0].vs_Xv  = 0;
-
-	return 1;
-}
-
-static int yopy_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+static void yopy_pcmcia_socket_state(int sock, struct pcmcia_state_array *state)
 {
-	if (info->sock != 0)
-		return -1;
-
-	info->irq = IRQ_CF_IREQ;
+	unsigned long levels = GPLR;
 
-	return 0;
+	if (sock == 0) {
+		state->detect = (levels & GPIO_CF_CD)    ? 0 : 1;
+		state->ready  = (levels & GPIO_CF_READY) ? 1 : 0;
+		state->bvd1   = (levels & GPIO_CF_BVD1)  ? 1 : 0;
+		state->bvd2   = (levels & GPIO_CF_BVD2)  ? 1 : 0;
+		state->wrprot = 0; /* Not available on Yopy. */
+		state->vs_3v  = 0; /* FIXME Can only apply 3.3V on Yopy. */
+		state->vs_Xv  = 0;
+	}
 }
 
-static int yopy_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+static int yopy_pcmcia_configure_socket(int sock, const struct pcmcia_configure *configure)
 {
-	if (configure->sock != 0)
+	if (sock != 0)
 		return -1;
 
 	switch (configure->vcc) {
@@ -161,28 +144,28 @@
 }
 
 static struct pcmcia_low_level yopy_pcmcia_ops = {
+	.owner			= THIS_MODULE,
 	.init			= yopy_pcmcia_init,
 	.shutdown		= yopy_pcmcia_shutdown,
 	.socket_state		= yopy_pcmcia_socket_state,
-	.get_irq_info		= yopy_pcmcia_get_irq_info,
 	.configure_socket	= yopy_pcmcia_configure_socket,
 
 	.socket_init		= yopy_pcmcia_socket_init,
 	.socket_suspend		= yopy_pcmcia_socket_suspend,
 };
 
-int __init pcmcia_yopy_init(void)
+int __init pcmcia_yopy_init(struct device *dev)
 {
 	int ret = -ENODEV;
 
 	if (machine_is_yopy())
-		ret = sa1100_register_pcmcia(&yopy_pcmcia_ops);
+		ret = sa1100_register_pcmcia(&yopy_pcmcia_ops, dev);
 
 	return ret;
 }
 
-void __exit pcmcia_yopy_exit(void)
+void __exit pcmcia_yopy_exit(struct device *dev)
 {
-	sa1100_unregister_pcmcia(&yopy_pcmcia_ops);
+	sa1100_unregister_pcmcia(&yopy_pcmcia_ops, dev);
 }
 
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1111_generic.c linux-2.5.63-bk6/drivers/pcmcia/sa1111_generic.c
--- linux-2.5.63-bk5/drivers/pcmcia/sa1111_generic.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1111_generic.c	Mon Mar 31 12:19:34 2003
@@ -12,6 +12,9 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
+#include <linux/proc_fs.h>
+#include <pcmcia/ss.h>
+
 #include <asm/hardware.h>
 #include <asm/hardware/sa1111.h>
 #include <asm/irq.h>
@@ -35,9 +38,14 @@
 {
 	int i, ret;
 
+	if (init->socket_irq[0] == NO_IRQ)
+		init->socket_irq[0] = IRQ_S0_READY_NINT;
+	if (init->socket_irq[1] == NO_IRQ)
+		init->socket_irq[1] = IRQ_S1_READY_NINT;
+
 	for (i = ret = 0; i < ARRAY_SIZE(irqs); i++) {
-		ret = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-				  irqs[i].str, NULL);
+		ret = request_irq(irqs[i].irq, sa1100_pcmcia_interrupt,
+				  SA_INTERRUPT, irqs[i].str, NULL);
 		if (ret)
 			break;
 		set_irq_type(irqs[i].irq, IRQT_FALLING);
@@ -63,53 +71,39 @@
 	return 0;
 }
 
-int sa1111_pcmcia_socket_state(struct pcmcia_state_array *state)
+void sa1111_pcmcia_socket_state(int sock, struct pcmcia_state *state)
 {
-	unsigned long status;
-
-	if (state->size < 2)
-		return -1;
-
-	status = sa1111_readl(pcmcia->mapbase + SA1111_PCSR);
-
-	state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1;
-	state->state[0].ready  = status & PCSR_S0_READY  ? 1 : 0;
-	state->state[0].bvd1   = status & PCSR_S0_BVD1   ? 1 : 0;
-	state->state[0].bvd2   = status & PCSR_S0_BVD2   ? 1 : 0;
-	state->state[0].wrprot = status & PCSR_S0_WP     ? 1 : 0;
-	state->state[0].vs_3v  = status & PCSR_S0_VS1    ? 0 : 1;
-	state->state[0].vs_Xv  = status & PCSR_S0_VS2    ? 0 : 1;
-
-	state->state[1].detect = status & PCSR_S1_DETECT ? 0 : 1;
-	state->state[1].ready  = status & PCSR_S1_READY  ? 1 : 0;
-	state->state[1].bvd1   = status & PCSR_S1_BVD1   ? 1 : 0;
-	state->state[1].bvd2   = status & PCSR_S1_BVD2   ? 1 : 0;
-	state->state[1].wrprot = status & PCSR_S1_WP     ? 1 : 0;
-	state->state[1].vs_3v  = status & PCSR_S1_VS1    ? 0 : 1;
-	state->state[1].vs_Xv  = status & PCSR_S1_VS2    ? 0 : 1;
-
-	return 1;
-}
+	unsigned long status = sa1111_readl(pcmcia->mapbase + SA1111_PCSR);
 
-int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-	int ret = 0;
+	switch (sock) {
+	case 0:
+		state->detect = status & PCSR_S0_DETECT ? 0 : 1;
+		state->ready  = status & PCSR_S0_READY  ? 1 : 0;
+		state->bvd1   = status & PCSR_S0_BVD1   ? 1 : 0;
+		state->bvd2   = status & PCSR_S0_BVD2   ? 1 : 0;
+		state->wrprot = status & PCSR_S0_WP     ? 1 : 0;
+		state->vs_3v  = status & PCSR_S0_VS1    ? 0 : 1;
+		state->vs_Xv  = status & PCSR_S0_VS2    ? 0 : 1;
+		break;
 
-	switch (info->sock) {
-	case 0:	info->irq = IRQ_S0_READY_NINT;	break;
-	case 1: info->irq = IRQ_S1_READY_NINT;	break;
-	default: ret = 1;
+	case 1:
+		state->detect = status & PCSR_S1_DETECT ? 0 : 1;
+		state->ready  = status & PCSR_S1_READY  ? 1 : 0;
+		state->bvd1   = status & PCSR_S1_BVD1   ? 1 : 0;
+		state->bvd2   = status & PCSR_S1_BVD2   ? 1 : 0;
+		state->wrprot = status & PCSR_S1_WP     ? 1 : 0;
+		state->vs_3v  = status & PCSR_S1_VS1    ? 0 : 1;
+		state->vs_Xv  = status & PCSR_S1_VS2    ? 0 : 1;
+		break;
 	}
-
-	return ret;
 }
 
-int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *conf)
+int sa1111_pcmcia_configure_socket(int sock, const struct pcmcia_configure *conf)
 {
 	unsigned int rst, flt, wait, pse, irq, pccr_mask, val;
 	unsigned long flags;
 
-	switch (conf->sock) {
+	switch (sock) {
 	case 0:
 		rst = PCCR_S0_RST;
 		flt = PCCR_S0_FLT;
@@ -161,11 +155,6 @@
 	sa1111_writel(val, pcmcia->mapbase + SA1111_PCCR);
 	local_irq_restore(flags);
 
-	if (conf->irq)
-		enable_irq(irq);
-	else
-		disable_irq(irq);
-
 	return 0;
 }
 
@@ -207,28 +196,28 @@
 	sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR);
 
 #ifdef CONFIG_SA1100_ADSBITSY
-	pcmcia_adsbitsy_init();
+	pcmcia_adsbitsy_init(dev);
 #endif
 #ifdef CONFIG_SA1100_BADGE4
-	pcmcia_badge4_init();
+	pcmcia_badge4_init(dev);
 #endif
 #ifdef CONFIG_SA1100_GRAPHICSMASTER
-	pcmcia_graphicsmaster_init();
+	pcmcia_graphicsmaster_init(dev);
 #endif
 #ifdef CONFIG_SA1100_JORNADA720
-	pcmcia_jornada720_init();
+	pcmcia_jornada720_init(dev);
 #endif
 #ifdef CONFIG_ASSABET_NEPONSET
-	pcmcia_neponset_init();
+	pcmcia_neponset_init(dev);
 #endif
 #ifdef CONFIG_SA1100_PFS168
-	pcmcia_pfs_init();
+	pcmcia_pfs_init(dev);
 #endif
 #ifdef CONFIG_SA1100_PT_SYSTEM3
-	pcmcia_system3_init();
+	pcmcia_system3_init(dev);
 #endif
 #ifdef CONFIG_SA1100_XP860
-	pcmcia_xp860_init();
+	pcmcia_xp860_init(dev);
 #endif
 	return 0;
 }
@@ -238,28 +227,28 @@
 	struct sa1111_dev *sadev = SA1111_DEV(dev);
 
 #ifdef CONFIG_SA1100_ADSBITSY
-	pcmcia_adsbitsy_exit();
+	pcmcia_adsbitsy_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_BADGE4
-	pcmcia_badge4_exit();
+	pcmcia_badge4_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_GRAPHICSMASTER
-	pcmcia_graphicsmaster_exit();
+	pcmcia_graphicsmaster_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_JORNADA720
-	pcmcia_jornada720_exit();
+	pcmcia_jornada720_exit(dev);
 #endif
 #ifdef CONFIG_ASSABET_NEPONSET
-	pcmcia_neponset_exit();
+	pcmcia_neponset_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_PFS168
-	pcmcia_pfs_exit();
+	pcmcia_pfs_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_PT_SYSTEM3
-	pcmcia_system3_exit();
+	pcmcia_system3_exit(dev);
 #endif
 #ifdef CONFIG_SA1100_XP860
-	pcmcia_xp860_exit();
+	pcmcia_xp860_exit(dev);
 #endif
 
 	release_mem_region(sadev->res.start, 512);
@@ -282,6 +271,7 @@
 	.drv = {
 		.name		= "sa1111-pcmcia",
 		.bus		= &sa1111_bus_type,
+		.devclass	= &pcmcia_socket_class,
 		.probe		= pcmcia_probe,
 		.remove		= __devexit_p(pcmcia_remove),
 		.suspend	= pcmcia_suspend,
diff -urN linux-2.5.63-bk5/drivers/pcmcia/sa1111_generic.h linux-2.5.63-bk6/drivers/pcmcia/sa1111_generic.h
--- linux-2.5.63-bk5/drivers/pcmcia/sa1111_generic.h	Mon Feb 24 11:05:46 2003
+++ linux-2.5.63-bk6/drivers/pcmcia/sa1111_generic.h	Mon Mar 31 12:19:34 2003
@@ -1,7 +1,14 @@
 extern int sa1111_pcmcia_init(struct pcmcia_init *);
 extern int sa1111_pcmcia_shutdown(void);
-extern int sa1111_pcmcia_socket_state(struct pcmcia_state_array *);
-extern int sa1111_pcmcia_get_irq_info(struct pcmcia_irq_info *);
-extern int sa1111_pcmcia_configure_socket(const struct pcmcia_configure *);
+extern void sa1111_pcmcia_socket_state(int sock, struct pcmcia_state *);
+extern int sa1111_pcmcia_configure_socket(int sock, const struct pcmcia_configure *);
 extern int sa1111_pcmcia_socket_init(int);
 extern int sa1111_pcmcia_socket_suspend(int);
+
+
+extern int pcmcia_jornada720_init(struct device *);
+extern void pcmcia_jornada720_exit(struct device *);
+
+extern int pcmcia_neponset_init(struct device *);
+extern void pcmcia_neponset_exit(struct device *);
+
diff -urN linux-2.5.63-bk5/drivers/s390/char/sclp.c linux-2.5.63-bk6/drivers/s390/char/sclp.c
--- linux-2.5.63-bk5/drivers/s390/char/sclp.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/s390/char/sclp.c	Mon Mar 31 12:19:34 2003
@@ -481,8 +481,7 @@
 do_machine_quiesce(void)
 {
 	cpu_quiesce_map = cpu_online_map;
-	smp_call_function(do_load_quiesce_psw, NULL, 0, 0);
-	do_load_quiesce_psw(NULL);
+	on_each_cpu(do_load_quiesce_psw, NULL, 0, 0);
 }
 #else
 static void
diff -urN linux-2.5.63-bk5/drivers/scsi/ibmmca.c linux-2.5.63-bk6/drivers/scsi/ibmmca.c
--- linux-2.5.63-bk5/drivers/scsi/ibmmca.c	Mon Feb 24 11:05:07 2003
+++ linux-2.5.63-bk6/drivers/scsi/ibmmca.c	Mon Mar 31 12:19:34 2003
@@ -1157,7 +1157,7 @@
 	if (adaptertype == IBM_SCSI2_FW) {	/* F/W SCSI adapter: */
 		/* F/W adapter PUN-space extension evaluation: */
 		if (num_bus) {
-			printk(KERN_INFO "IBM MCA SCSI: Seperate bus mode (wide-addressing enabled)\n");
+			printk(KERN_INFO "IBM MCA SCSI: Separate bus mode (wide-addressing enabled)\n");
 			subsystem_maxid(host_index) = 16;
 		} else {
 			printk(KERN_INFO "IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n");
diff -urN linux-2.5.63-bk5/drivers/serial/sunsu.c linux-2.5.63-bk6/drivers/serial/sunsu.c
--- linux-2.5.63-bk5/drivers/serial/sunsu.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/serial/sunsu.c	Mon Mar 31 12:19:34 2003
@@ -478,7 +478,7 @@
 	spin_unlock_irqrestore(&up->port.lock, flags);
 }
 
-/* Seperate interrupt handling path for keyboard/mouse ports.  */
+/* Separate interrupt handling path for keyboard/mouse ports.  */
 
 static void
 sunsu_change_speed(struct uart_port *port, unsigned int cflag,
diff -urN linux-2.5.63-bk5/drivers/usb/core/hcd.h linux-2.5.63-bk6/drivers/usb/core/hcd.h
--- linux-2.5.63-bk5/drivers/usb/core/hcd.h	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/drivers/usb/core/hcd.h	Mon Mar 31 12:19:34 2003
@@ -255,8 +255,8 @@
 extern int usb_set_address(struct usb_device *dev);
 
 /* use these only before the device's address has been set */
-#define usb_snddefctrl(dev)		((PIPE_CONTROL << 30) | __create_pipe(dev,0))
-#define usb_rcvdefctrl(dev)		((PIPE_CONTROL << 30) | __create_pipe(dev,0) | USB_DIR_IN)
+#define usb_snddefctrl(dev)		((PIPE_CONTROL << 30))
+#define usb_rcvdefctrl(dev)		((PIPE_CONTROL << 30) | USB_DIR_IN)
 
 /*-------------------------------------------------------------------------*/
 
diff -urN linux-2.5.63-bk5/drivers/video/virgefb.c linux-2.5.63-bk6/drivers/video/virgefb.c
--- linux-2.5.63-bk5/drivers/video/virgefb.c	Mon Feb 24 11:05:14 2003
+++ linux-2.5.63-bk6/drivers/video/virgefb.c	Mon Mar 31 12:19:34 2003
@@ -1752,7 +1752,7 @@
 
 	} else {
 
-		/* board running in Z3 space. Seperate video memory (3 apertures)
+		/* board running in Z3 space. Separate video memory (3 apertures)
 		   and S3 register set */
 
 		on_zorro2 = 0;
diff -urN linux-2.5.63-bk5/fs/buffer.c linux-2.5.63-bk6/fs/buffer.c
--- linux-2.5.63-bk5/fs/buffer.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/fs/buffer.c	Mon Mar 31 12:19:34 2003
@@ -1403,10 +1403,7 @@
 	
 static void invalidate_bh_lrus(void)
 {
-	preempt_disable();
-	invalidate_bh_lru(NULL);
-	smp_call_function(invalidate_bh_lru, NULL, 1, 1);
-	preempt_enable();
+	on_each_cpu(invalidate_bh_lru, NULL, 1, 1);
 }
 
 void set_bh_page(struct buffer_head *bh,
diff -urN linux-2.5.63-bk5/fs/ext2/dir.c linux-2.5.63-bk6/fs/ext2/dir.c
--- linux-2.5.63-bk5/fs/ext2/dir.c	Mon Feb 24 11:05:33 2003
+++ linux-2.5.63-bk6/fs/ext2/dir.c	Mon Mar 31 12:19:34 2003
@@ -420,6 +420,7 @@
 	err = ext2_commit_chunk(page, from, to);
 	ext2_put_page(page);
 	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(dir);
 }
 
@@ -509,6 +510,7 @@
 	ext2_set_de_type (de, inode);
 	err = ext2_commit_chunk(page, from, to);
 	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(dir);
 	/* OFFSET_CACHE */
 out_put:
@@ -556,6 +558,7 @@
 	dir->inode = 0;
 	err = ext2_commit_chunk(page, from, to);
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(inode);
 out:
 	ext2_put_page(page);
diff -urN linux-2.5.63-bk5/fs/ext2/ialloc.c linux-2.5.63-bk6/fs/ext2/ialloc.c
--- linux-2.5.63-bk5/fs/ext2/ialloc.c	Mon Feb 24 11:05:32 2003
+++ linux-2.5.63-bk6/fs/ext2/ialloc.c	Mon Mar 31 12:19:34 2003
@@ -526,7 +526,7 @@
 	inode->i_blocks = 0;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	memset(ei->i_data, 0, sizeof(ei->i_data));
-	ei->i_flags = EXT2_I(dir)->i_flags;
+	ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;
 	if (S_ISLNK(mode))
 		ei->i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);
 	/* dirsync is only applied to directories */
diff -urN linux-2.5.63-bk5/fs/intermezzo/super.c linux-2.5.63-bk6/fs/intermezzo/super.c
--- linux-2.5.63-bk5/fs/intermezzo/super.c	Mon Feb 24 11:06:01 2003
+++ linux-2.5.63-bk6/fs/intermezzo/super.c	Mon Mar 31 12:19:34 2003
@@ -318,7 +318,7 @@
 
         CDEBUG(D_MALLOC, "mount error exit: kmem %ld, vmem %ld\n",
                presto_kmemory, presto_vmemory);
-        return NULL;
+        return ERR_PTR(-EINVAL);
 }
 
 
diff -urN linux-2.5.63-bk5/include/asm-ia64/page.h linux-2.5.63-bk6/include/asm-ia64/page.h
--- linux-2.5.63-bk5/include/asm-ia64/page.h	Mon Feb 24 11:05:09 2003
+++ linux-2.5.63-bk6/include/asm-ia64/page.h	Mon Mar 31 12:19:34 2003
@@ -57,6 +57,16 @@
 # define REGION_SHIFT	61
 # define HPAGE_SIZE	(__IA64_UL_CONST(1) << HPAGE_SHIFT)
 # define HPAGE_MASK	(~(HPAGE_SIZE - 1))
+static inline int
+check_valid_hugepage_range(unsigned long addr, unsigned long len)
+{
+	if (REGION_NUMBER(addr) == REGION_HPAGE)
+		return -EINVAL;
+	if (REGION_NUMBER(addr+len) == REGION_HPAGE)
+		return -EINVAL;
+	return 0;
+}
+#define ARCH_HAS_VALID_HUGEPAGE_RANGE
 #endif /* CONFIG_HUGETLB_PAGE */
 
 #ifdef __ASSEMBLY__
diff -urN linux-2.5.63-bk5/include/asm-parisc/cacheflush.h linux-2.5.63-bk6/include/asm-parisc/cacheflush.h
--- linux-2.5.63-bk5/include/asm-parisc/cacheflush.h	Mon Feb 24 11:05:47 2003
+++ linux-2.5.63-bk6/include/asm-parisc/cacheflush.h	Mon Mar 31 12:19:34 2003
@@ -25,16 +25,10 @@
 
 extern void flush_cache_all_local(void);
 
-#ifdef CONFIG_SMP
 static inline void flush_cache_all(void)
 {
-	smp_call_function((void (*)(void *))flush_cache_all_local, NULL, 1, 1);
-	flush_cache_all_local();
+	on_each_cpu((void (*)(void *))flush_cache_all_local, NULL, 1, 1);
 }
-#else
-#define flush_cache_all flush_cache_all_local
-#endif
-
 
 /* The following value needs to be tuned and probably scaled with the
  * cache size.
diff -urN linux-2.5.63-bk5/include/linux/cciss_ioctl.h linux-2.5.63-bk6/include/linux/cciss_ioctl.h
--- linux-2.5.63-bk5/include/linux/cciss_ioctl.h	Mon Feb 24 11:05:29 2003
+++ linux-2.5.63-bk6/include/linux/cciss_ioctl.h	Mon Mar 31 12:19:34 2003
@@ -33,6 +33,18 @@
 typedef char FirmwareVer_type[4];
 typedef __u32 DriverVer_type;
 
+#define MAX_KMALLOC_SIZE 128000
+
+typedef struct _BIG_IOCTL_Command_struct {
+  LUNAddr_struct	   LUN_info;
+  RequestBlock_struct      Request;
+  ErrorInfo_struct  	   error_info; 
+  DWORD			   malloc_size; /* < MAX_KMALLOC_SIZE in cciss.c */
+  DWORD			   buf_size;    /* size in bytes of the buf */
+  				        /* < malloc_size * MAXSGENTRIES */
+  BYTE			   *buf;
+} BIG_IOCTL_Command_struct;
+
 
 #ifndef CCISS_CMD_H
 // This defines are duplicated in cciss_cmd.h in the driver directory 
@@ -169,6 +181,11 @@
   BYTE			   *buf;
 } IOCTL_Command_struct;
 
+typedef struct _LogvolInfo_struct{
+	__u32	LunID;
+	int	num_opens;  /* number of opens on the logical volume */
+	int	num_parts;  /* number of partitions configured on logvol */
+} LogvolInfo_struct;
 
 #define CCISS_GETPCIINFO _IOR(CCISS_IOC_MAGIC, 1, cciss_pci_info_struct)
 
@@ -190,5 +207,7 @@
 #define CCISS_REGNEWDISK  _IOW(CCISS_IOC_MAGIC, 13, int)
 
 #define CCISS_REGNEWD	   _IO(CCISS_IOC_MAGIC, 14)
+#define CCISS_GETLUNINFO   _IOR(CCISS_IOC_MAGIC, 17, LogvolInfo_struct)
+#define CCISS_BIG_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 18, BIG_IOCTL_Command_struct)
 
 #endif  
diff -urN linux-2.5.63-bk5/include/linux/cpufreq.h linux-2.5.63-bk6/include/linux/cpufreq.h
--- linux-2.5.63-bk5/include/linux/cpufreq.h	Mon Feb 24 11:05:34 2003
+++ linux-2.5.63-bk6/include/linux/cpufreq.h	Mon Mar 31 12:19:34 2003
@@ -62,6 +62,8 @@
 	unsigned int            cpu;    /* cpu nr or CPUFREQ_ALL_CPUS */
 	unsigned int            min;    /* in kHz */
 	unsigned int            max;    /* in kHz */
+	unsigned int            cur;    /* in kHz, only needed if cpufreq
+					 * governors are used */
         unsigned int            policy; /* see above */
 	struct cpufreq_governor *governor; /* see below */
 	struct cpufreq_cpuinfo  cpuinfo;     /* see above */
@@ -164,10 +166,6 @@
 	/* 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_driver(struct cpufreq_driver *driver_data);
@@ -208,14 +206,19 @@
 /* the proc_intf.c needs this */
 int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
 
-#ifdef CONFIG_CPU_FREQ_24_API
+#if defined(CONFIG_CPU_FREQ_GOV_USERSPACE) || defined(CONFIG_CPU_FREQ_GOV_USERSPACE_MODULE)
 /*********************************************************************
- *                        CPUFREQ 2.4. INTERFACE                     *
+ *                      CPUFREQ USERSPACE GOVERNOR                   *
  *********************************************************************/
+extern struct cpufreq_governor cpufreq_gov_userspace;
+int cpufreq_gov_userspace_init(void);
+
 int cpufreq_setmax(unsigned int cpu);
 int cpufreq_set(unsigned int kHz, unsigned int cpu);
 unsigned int cpufreq_get(unsigned int cpu);
 
+#ifdef CONFIG_CPU_FREQ_24_API
+
 /* /proc/sys/cpu */
 enum {
 	CPU_NR   = 1,           /* compatibilty reasons */
@@ -260,45 +263,10 @@
 	CPU_NR_FREQ = 3,
 };
 
-#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MAX, \
-                .data		= &cpu_max_freq[cpunr], \
-                .procname	= "speed-max", \
-                .maxlen		= sizeof(cpu_max_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ_MIN, \
-                .data		= &cpu_min_freq[cpunr], \
-                .procname	= "speed-min", \
-                .maxlen		= sizeof(cpu_min_freq[cpunr]),\
-                .mode		= 0444, \
-                .proc_handler	= proc_dointvec, }
-
-#define CTL_CPU_VARS_SPEED(cpunr) { \
-                .ctl_name	= CPU_NR_FREQ, \
-                .procname	= "speed", \
-                .mode		= 0644, \
-                .proc_handler	= cpufreq_procctl, \
-                .strategy	= cpufreq_sysctl, \
-                .extra1		= (void*) (cpunr), }
-
-#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
-                CTL_CPU_VARS_SPEED_MAX(cpunr), \
-                CTL_CPU_VARS_SPEED_MIN(cpunr), \
-                CTL_CPU_VARS_SPEED(cpunr),  \
-                { .ctl_name = 0, }, }
-
-/* the ctl_table entry for each CPU */
-#define CPU_ENUM(s) { \
-                .ctl_name	= (CPU_NR + s), \
-                .procname	= #s, \
-                .mode		= 0555, \
-                .child		= ctl_cpu_vars_##s }
-
 #endif /* CONFIG_CPU_FREQ_24_API */
 
+#endif /* CONFIG_CPU_FREQ_GOV_USERSPACE */
+
 
 /*********************************************************************
  *                     FREQUENCY TABLE HELPERS                       *
diff -urN linux-2.5.63-bk5/include/linux/gfp.h linux-2.5.63-bk6/include/linux/gfp.h
--- linux-2.5.63-bk5/include/linux/gfp.h	Mon Feb 24 11:05:13 2003
+++ linux-2.5.63-bk6/include/linux/gfp.h	Mon Mar 31 12:19:34 2003
@@ -49,24 +49,16 @@
 extern struct page * FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *));
 static inline struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order)
 {
-	struct pglist_data *pgdat = NODE_DATA(nid);
-	unsigned int idx = (gfp_mask & GFP_ZONEMASK);
-
 	if (unlikely(order >= MAX_ORDER))
 		return NULL;
-	return __alloc_pages(gfp_mask, order, pgdat->node_zonelists + idx);
-}
-static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
-{
-	struct pglist_data *pgdat = NODE_DATA(numa_node_id());
-	unsigned int idx = (gfp_mask & GFP_ZONEMASK);
 
-	if (unlikely(order >= MAX_ORDER))
-		return NULL;
-	return __alloc_pages(gfp_mask, order, pgdat->node_zonelists + idx);
+	return __alloc_pages(gfp_mask, order, NODE_DATA(nid)->node_zonelists + (gfp_mask & GFP_ZONEMASK));
 }
 
-#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
+#define alloc_pages(gfp_mask, order) \
+		alloc_pages_node(numa_node_id(), gfp_mask, order)
+#define alloc_page(gfp_mask) \
+		alloc_pages_node(numa_node_id(), gfp_mask, 0)
 
 extern unsigned long FASTCALL(__get_free_pages(unsigned int gfp_mask, unsigned int order));
 extern unsigned long FASTCALL(get_zeroed_page(unsigned int gfp_mask));
diff -urN linux-2.5.63-bk5/include/linux/hugetlb.h linux-2.5.63-bk6/include/linux/hugetlb.h
--- linux-2.5.63-bk5/include/linux/hugetlb.h	Mon Feb 24 11:05:32 2003
+++ linux-2.5.63-bk6/include/linux/hugetlb.h	Mon Mar 31 12:19:34 2003
@@ -4,7 +4,6 @@
 #ifdef CONFIG_HUGETLB_PAGE
 
 struct ctl_table;
-struct hugetlb_key;
 
 static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
 {
@@ -38,6 +37,10 @@
 		mm->used_hugetlb = 1;
 }
 
+#ifndef ARCH_HAS_VALID_HUGEPAGE_RANGE
+#define check_valid_hugepage_range(addr, len)	0
+#endif
+
 #else /* !CONFIG_HUGETLB_PAGE */
 
 static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
@@ -59,6 +62,7 @@
 #define follow_huge_pmd(mm, addr, pmd, write)	0
 #define is_aligned_hugepage_range(addr, len)	0
 #define pmd_huge(x)	0
+#define check_valid_hugepage_range(addr, len)	0
 
 #ifndef HPAGE_MASK
 #define HPAGE_MASK	0		/* Keep the compiler happy */
diff -urN linux-2.5.63-bk5/include/linux/module.h linux-2.5.63-bk6/include/linux/module.h
--- linux-2.5.63-bk5/include/linux/module.h	Mon Feb 24 11:05:39 2003
+++ linux-2.5.63-bk6/include/linux/module.h	Mon Mar 31 12:19:34 2003
@@ -150,13 +150,7 @@
 void *__symbol_get_gpl(const char *symbol);
 #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
 
-#ifdef __GENKSYMS__
-
-/* genksyms doesn't handle GPL-only symbols yet */
-#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
-	
-#else
-
+#ifndef __GENKSYMS__
 #ifdef CONFIG_MODVERSIONS
 /* Mark the CRC weak since genksyms apparently decides not to
  * generate a checksums for some symbols */
@@ -188,7 +182,7 @@
 #endif
 
 /* We don't mangle the actual symbol anymore, so no need for
- * special casing EXPORT_SYMBOL_NOVERS */
+ * special casing EXPORT_SYMBOL_NOVERS.  FIXME: Deprecated */
 #define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
 
 struct module_ref
diff -urN linux-2.5.63-bk5/include/linux/pci.h linux-2.5.63-bk6/include/linux/pci.h
--- linux-2.5.63-bk5/include/linux/pci.h	Mon Feb 24 11:05:31 2003
+++ linux-2.5.63-bk6/include/linux/pci.h	Mon Mar 31 12:19:34 2003
@@ -645,7 +645,8 @@
 int pci_register_driver(struct pci_driver *);
 void pci_unregister_driver(struct pci_driver *);
 void pci_insert_device(struct pci_dev *, struct pci_bus *);
-void pci_remove_device(struct pci_dev *);
+void pci_remove_bus_device(struct pci_dev *);
+void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
 const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
 unsigned int pci_do_scan_bus(struct pci_bus *bus);
@@ -692,7 +693,6 @@
 extern int pci_visit_dev(struct pci_visit *fn,
 			 struct pci_dev_wrapped *wrapped_dev,
 			 struct pci_bus_wrapped *wrapped_parent);
-extern int pci_is_dev_in_use(struct pci_dev *dev);
 extern int pci_remove_device_safe(struct pci_dev *dev);
 
 #endif /* CONFIG_PCI */
diff -urN linux-2.5.63-bk5/include/linux/smp.h linux-2.5.63-bk6/include/linux/smp.h
--- linux-2.5.63-bk5/include/linux/smp.h	Mon Feb 24 11:05:33 2003
+++ linux-2.5.63-bk6/include/linux/smp.h	Mon Mar 31 12:19:34 2003
@@ -10,9 +10,10 @@
 
 #ifdef CONFIG_SMP
 
+#include <linux/preempt.h>
 #include <linux/kernel.h>
 #include <linux/compiler.h>
-#include <linux/threads.h>
+#include <linux/thread_info.h>
 #include <asm/smp.h>
 #include <asm/bug.h>
 
@@ -54,6 +55,21 @@
 			      int retry, int wait);
 
 /*
+ * Call a function on all processors
+ */
+static inline int on_each_cpu(void (*func) (void *info), void *info,
+			      int retry, int wait)
+{
+	int ret = 0;
+
+	preempt_disable();
+	ret = smp_call_function(func, info, retry, wait);
+	func(info);
+	preempt_enable();
+	return ret;
+}
+
+/*
  * True once the per process idle is forked
  */
 extern int smp_threads_ready;
@@ -96,6 +112,7 @@
 #define hard_smp_processor_id()			0
 #define smp_threads_ready			1
 #define smp_call_function(func,info,retry,wait)	({ 0; })
+#define on_each_cpu(func,info,retry,wait)	({ func(info); 0; })
 static inline void smp_send_reschedule(int cpu) { }
 static inline void smp_send_reschedule_all(void) { }
 #define cpu_online_map				1
diff -urN linux-2.5.63-bk5/include/linux/swap.h linux-2.5.63-bk6/include/linux/swap.h
--- linux-2.5.63-bk5/include/linux/swap.h	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk6/include/linux/swap.h	Mon Mar 31 12:19:34 2003
@@ -68,10 +68,11 @@
 
 #ifdef __KERNEL__
 
-struct sysinfo;
 struct address_space;
-struct zone;
+struct pte_chain;
+struct sysinfo;
 struct writeback_control;
+struct zone;
 
 /*
  * A swap extent maps a range of a swapfile's PAGE_SIZE pages onto a range of
@@ -140,6 +141,9 @@
 /* Swap 50% full? Release swapcache more aggressively.. */
 #define vm_swap_full() (nr_swap_pages*2 < total_swap_pages)
 
+/* linux/mm/oom_kill.c */
+extern void out_of_memory(void);
+
 /* linux/mm/page_alloc.c */
 extern unsigned long totalram_pages;
 extern unsigned long totalhigh_pages;
@@ -149,13 +153,11 @@
 extern unsigned int nr_free_buffer_pages(void);
 extern unsigned int nr_free_pagecache_pages(void);
 
-/* linux/mm/filemap.c */
-extern void FASTCALL(mark_page_accessed(struct page *));
-
 /* linux/mm/swap.c */
 extern void FASTCALL(lru_cache_add(struct page *));
 extern void FASTCALL(lru_cache_add_active(struct page *));
 extern void FASTCALL(activate_page(struct page *));
+extern void FASTCALL(mark_page_accessed(struct page *));
 extern void lru_add_drain(void);
 extern int rotate_reclaimable_page(struct page *page);
 extern void swap_setup(void);
@@ -165,11 +167,8 @@
 extern int shrink_all_memory(int);
 extern int vm_swappiness;
 
-/* linux/mm/oom_kill.c */
-extern void out_of_memory(void);
-
 /* linux/mm/rmap.c */
-struct pte_chain;
+#ifdef CONFIG_MMU
 int FASTCALL(page_referenced(struct page *));
 struct pte_chain *FASTCALL(page_add_rmap(struct page *, pte_t *,
 					struct pte_chain *));
@@ -186,6 +185,11 @@
 /* linux/mm/shmem.c */
 extern int shmem_unuse(swp_entry_t entry, struct page *page);
 
+#else
+#define page_referenced(page) \
+	TestClearPageReferenced(page)
+#endif /* CONFIG_MMU */
+
 #ifdef CONFIG_SWAP
 /* linux/mm/page_io.c */
 extern int swap_readpage(struct file *, struct page *);
@@ -242,8 +246,6 @@
 	page_cache_release(page)
 #define free_pages_and_swap_cache(pages, nr) \
 	release_pages((pages), (nr), 0);
-#define page_referenced(page) \
-	TestClearPageReferenced(page)
 
 #define show_swap_cache_info()			/*NOTHING*/
 #define free_swap_and_cache(swp)		/*NOTHING*/
diff -urN linux-2.5.63-bk5/init/Makefile linux-2.5.63-bk6/init/Makefile
--- linux-2.5.63-bk5/init/Makefile	Mon Feb 24 11:05:16 2003
+++ linux-2.5.63-bk6/init/Makefile	Mon Mar 31 12:19:34 2003
@@ -2,7 +2,11 @@
 # Makefile for the linux kernel.
 #
 
-obj-y			:= main.o version.o do_mounts.o initramfs.o
+obj-y				:= main.o version.o mounts.o initramfs.o
+mounts-y			:= do_mounts.o
+mounts-$(CONFIG_DEVFS_FS)	+= do_mounts_devfs.o
+mounts-$(CONFIG_BLK_DEV_RAM)	+= do_mounts_rd.o
+mounts-$(CONFIG_BLK_DEV_MD)	+= do_mounts_md.o
 
 # files to be removed upon make clean
 clean-files := ../include/linux/compile.h
@@ -17,5 +21,5 @@
 # actual file if its content has changed.
 
 include/linux/compile.h: FORCE
-	@echo -n '  Generating $@'
+	@echo -n '  GEN     $@'
 	@sh $(srctree)/scripts/mkcompile_h $@ "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CC) $(CFLAGS)"
diff -urN linux-2.5.63-bk5/init/do_mounts.c linux-2.5.63-bk6/init/do_mounts.c
--- linux-2.5.63-bk5/init/do_mounts.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/init/do_mounts.c	Mon Mar 31 12:19:34 2003
@@ -1,77 +1,28 @@
-#define __KERNEL_SYSCALLS__
-#include <linux/config.h>
-#include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/unistd.h>
 #include <linux/ctype.h>
-#include <linux/blk.h>
 #include <linux/fd.h>
 #include <linux/tty.h>
-#include <linux/init.h>
 #include <linux/suspend.h>
 #include <linux/root_dev.h>
-#include <linux/mount.h>
-#include <linux/dirent.h>
 #include <linux/security.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_mount.h>
-#include <linux/minix_fs.h>
-#include <linux/ext2_fs.h>
-#include <linux/romfs_fs.h>
 
-#include <linux/raid/md.h>
-
-#define BUILD_CRAMDISK
+#include "do_mounts.h"
 
 extern int get_filesystem_list(char * buf);
 
-extern asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
-	 unsigned long flags, void *data);
-extern asmlinkage long sys_mkdir(const char *name, int mode);
-extern asmlinkage long sys_rmdir(const char *name);
-extern asmlinkage long sys_chdir(const char *name);
-extern asmlinkage long sys_fchdir(int fd);
-extern asmlinkage long sys_chroot(const char *name);
-extern asmlinkage long sys_unlink(const char *name);
-extern asmlinkage long sys_symlink(const char *old, const char *new);
-extern asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
-extern asmlinkage long sys_umount(char *name, int flags);
-extern asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
-extern asmlinkage long sys_access(const char * filename, int mode);
-extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
-extern asmlinkage long sys_getdents64(unsigned int fd, void * dirent,
-	unsigned int count);
-
-#ifdef CONFIG_BLK_DEV_INITRD
-unsigned int real_root_dev;	/* do_proc_dointvec cannot handle kdev_t */
-static int __initdata mount_initrd = 1;
-
-static int __init no_initrd(char *str)
-{
-	mount_initrd = 0;
-	return 1;
-}
-
-__setup("noinitrd", no_initrd);
-#else
-static int __initdata mount_initrd = 0;
-#endif
-
 int __initdata rd_doload;	/* 1 = load RAM disk, 0 = don't load */
 
 int root_mountflags = MS_RDONLY | MS_VERBOSE;
-static char root_device_name[64];
-static char saved_root_name[64];
+static char * __initdata root_device_name;
+static char __initdata saved_root_name[64];
 
 /* this is initialized in init/main.c */
 dev_t ROOT_DEV;
 
-static int do_devfs = 0;
-
 static int __init load_ramdisk(char *str)
 {
 	rd_doload = simple_strtol(str,NULL,0) & 3;
@@ -98,7 +49,7 @@
 __setup("ro", readonly);
 __setup("rw", readwrite);
 
-static __init dev_t try_name(char *name, int part)
+static dev_t __init try_name(char *name, int part)
 {
 	char path[64];
 	char buf[32];
@@ -167,7 +118,7 @@
  *	is mounted on rootfs /sys.
  */
 
-__init dev_t name_to_dev_t(char *name)
+dev_t name_to_dev_t(char *name)
 {
 	char s[32];
 	char *p;
@@ -225,8 +176,7 @@
 
 static int __init root_dev_setup(char *line)
 {
-	strncpy(saved_root_name, line, 64);
-	saved_root_name[63] = '\0';
+	strncpy(saved_root_name, line, 63);
 	return 1;
 }
 
@@ -275,7 +225,23 @@
 	}
 	*s = '\0';
 }
-static void __init mount_block_root(char *name, int flags)
+
+static int __init do_mount_root(char *name, char *fs, int flags, void *data)
+{
+	int err = sys_mount(name, "/root", fs, flags, data);
+	if (err)
+		return err;
+
+	sys_chdir("/root");
+	ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
+	printk("VFS: Mounted root (%s filesystem)%s.\n",
+	       current->fs->pwdmnt->mnt_sb->s_type->name,
+	       current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? 
+	       " readonly" : "");
+	return 0;
+}
+
+void __init mount_block_root(char *name, int flags)
 {
 	char *fs_names = __getname();
 	char *p;
@@ -283,7 +249,7 @@
 	get_fs_names(fs_names);
 retry:
 	for (p = fs_names; *p; p += strlen(p)+1) {
-		int err = sys_mount(name, "/root", p, flags, root_mount_data);
+		int err = do_mount_root(name, p, flags, root_mount_data);
 		switch (err) {
 			case 0:
 				goto out;
@@ -305,11 +271,6 @@
 	panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV));
 out:
 	putname(fs_names);
-	sys_chdir("/root");
-	ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
-	printk("VFS: Mounted root (%s filesystem)%s.\n",
-		current->fs->pwdmnt->mnt_sb->s_type->name,
-		(current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
 }
  
 #ifdef CONFIG_ROOT_NFS
@@ -317,139 +278,16 @@
 {
 	void *data = nfs_root_data();
 
-	if (data && sys_mount("/dev/root","/root","nfs",root_mountflags,data) == 0)
+	create_dev("/dev/root", ROOT_DEV, NULL);
+	if (data &&
+	    do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
 		return 1;
 	return 0;
 }
 #endif
 
-#ifdef CONFIG_DEVFS_FS
-
-/*
- * If the dir will fit in *buf, return its length.  If it won't fit, return
- * zero.  Return -ve on error.
- */
-static int __init do_read_dir(int fd, void *buf, int len)
-{
-	long bytes, n;
-	char *p = buf;
-	lseek(fd, 0, 0);
-
-	for (bytes = 0; bytes < len; bytes += n) {
-		n = sys_getdents64(fd, p + bytes, len - bytes);
-		if (n < 0)
-			return n;
-		if (n == 0)
-			return bytes;
-	}
-	return 0;
-}
-
-/*
- * Try to read all of a directory.  Returns the contents at *p, which
- * is kmalloced memory.  Returns the number of bytes read at *len.  Returns
- * NULL on error.
- */
-static void * __init read_dir(char *path, int *len)
-{
-	int size;
-	int fd = open(path, 0, 0);
-
-	*len = 0;
-	if (fd < 0)
-		return NULL;
-
-	for (size = 1 << 9; size <= (1 << MAX_ORDER); size <<= 1) {
-		void *p = kmalloc(size, GFP_KERNEL);
-		int n;
-		if (!p)
-			break;
-		n = do_read_dir(fd, p, size);
-		if (n > 0) {
-			close(fd);
-			*len = n;
-			return p;
-		}
-		kfree(p);
-		if (n == -EINVAL)
-			continue;	/* Try a larger buffer */
-		if (n < 0)
-			break;
-	}
-	close(fd);
-	return NULL;
-}
-#endif
-
-static int __init find_in_devfs(char *path, dev_t dev)
-{
-#ifdef CONFIG_DEVFS_FS
-	struct stat buf;
-	char *end = path + strlen(path);
-	int rest = path + 64 - end;
-	int size;
-	char *p = read_dir(path, &size);
-	char *s;
-
-	if (!p)
-		return -1;
-	for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) {
-		struct linux_dirent64 *d = (struct linux_dirent64 *)s;
-		if (strlen(d->d_name) + 2 > rest)
-			continue;
-		switch (d->d_type) {
-			case DT_BLK:
-				sprintf(end, "/%s", d->d_name);
-				if (sys_newstat(path, &buf) < 0)
-					break;
-				if (!S_ISBLK(buf.st_mode))
-					break;
-				if (buf.st_rdev != dev)
-					break;
-				kfree(p);
-				return 0;
-			case DT_DIR:
-				if (strcmp(d->d_name, ".") == 0)
-					break;
-				if (strcmp(d->d_name, "..") == 0)
-					break;
-				sprintf(end, "/%s", d->d_name);
-				if (find_in_devfs(path, dev) < 0)
-					break;
-				kfree(p);
-				return 0;
-		}
-	}
-	kfree(p);
-#endif
-	return -1;
-}
-
-static int __init create_dev(char *name, dev_t dev, char *devfs_name)
-{
-	char path[64];
-
-	sys_unlink(name);
-	if (!do_devfs)
-		return sys_mknod(name, S_IFBLK|0600, dev);
-
-	if (devfs_name && devfs_name[0]) {
-		if (strncmp(devfs_name, "/dev/", 5) == 0)
-			devfs_name += 5;
-		sprintf(path, "/dev/%s", devfs_name);
-		if (sys_access(path, 0) == 0)
-			return sys_symlink(devfs_name, name);
-	}
-	if (!dev)
-		return -1;
-	strcpy(path, "/dev");
-	if (find_in_devfs(path, dev) < 0)
-		return -1;
-	return sys_symlink(path + 5, name);
-}
-
 #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
-static void __init change_floppy(char *fmt, ...)
+void __init change_floppy(char *fmt, ...)
 {
 	struct termios termios;
 	char buf[80];
@@ -478,838 +316,69 @@
 }
 #endif
 
-#ifdef CONFIG_BLK_DEV_RAM
-
-int __initdata rd_prompt = 1;	/* 1 = prompt for RAM disk, 0 = don't prompt */
-
-static int __init prompt_ramdisk(char *str)
-{
-	rd_prompt = simple_strtol(str,NULL,0) & 1;
-	return 1;
-}
-__setup("prompt_ramdisk=", prompt_ramdisk);
-
-int __initdata rd_image_start;		/* starting block # of image */
-
-static int __init ramdisk_start_setup(char *str)
-{
-	rd_image_start = simple_strtol(str,NULL,0);
-	return 1;
-}
-__setup("ramdisk_start=", ramdisk_start_setup);
-
-static int __init crd_load(int in_fd, int out_fd);
-
-/*
- * This routine tries to find a RAM disk image to load, and returns the
- * number of blocks to read for a non-compressed image, 0 if the image
- * is a compressed image, and -1 if an image with the right magic
- * numbers could not be found.
- *
- * We currently check for the following magic numbers:
- * 	minix
- * 	ext2
- *	romfs
- * 	gzip
- */
-static int __init 
-identify_ramdisk_image(int fd, int start_block)
-{
-	const int size = 512;
-	struct minix_super_block *minixsb;
-	struct ext2_super_block *ext2sb;
-	struct romfs_super_block *romfsb;
-	int nblocks = -1;
-	unsigned char *buf;
-
-	buf = kmalloc(size, GFP_KERNEL);
-	if (buf == 0)
-		return -1;
-
-	minixsb = (struct minix_super_block *) buf;
-	ext2sb = (struct ext2_super_block *) buf;
-	romfsb = (struct romfs_super_block *) buf;
-	memset(buf, 0xe5, size);
-
-	/*
-	 * Read block 0 to test for gzipped kernel
-	 */
-	lseek(fd, start_block * BLOCK_SIZE, 0);
-	read(fd, buf, size);
-
-	/*
-	 * If it matches the gzip magic numbers, return -1
-	 */
-	if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
-		printk(KERN_NOTICE
-		       "RAMDISK: Compressed image found at block %d\n",
-		       start_block);
-		nblocks = 0;
-		goto done;
-	}
-
-	/* romfs is at block zero too */
-	if (romfsb->word0 == ROMSB_WORD0 &&
-	    romfsb->word1 == ROMSB_WORD1) {
-		printk(KERN_NOTICE
-		       "RAMDISK: romfs filesystem found at block %d\n",
-		       start_block);
-		nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
-		goto done;
-	}
-
-	/*
-	 * Read block 1 to test for minix and ext2 superblock
-	 */
-	lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
-	read(fd, buf, size);
-
-	/* Try minix */
-	if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
-	    minixsb->s_magic == MINIX_SUPER_MAGIC2) {
-		printk(KERN_NOTICE
-		       "RAMDISK: Minix filesystem found at block %d\n",
-		       start_block);
-		nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
-		goto done;
-	}
-
-	/* Try ext2 */
-	if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
-		printk(KERN_NOTICE
-		       "RAMDISK: ext2 filesystem found at block %d\n",
-		       start_block);
-		nblocks = le32_to_cpu(ext2sb->s_blocks_count);
-		goto done;
-	}
-
-	printk(KERN_NOTICE
-	       "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
-	       start_block);
-	
-done:
-	lseek(fd, start_block * BLOCK_SIZE, 0);
-	kfree(buf);
-	return nblocks;
-}
-#endif
-
-static int __init rd_load_image(char *from)
-{
-	int res = 0;
-
-#ifdef CONFIG_BLK_DEV_RAM
-	int in_fd, out_fd;
-	unsigned long rd_blocks, devblocks;
-	int nblocks, i, disk;
-	char *buf;
-	unsigned short rotate = 0;
-#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
-	char rotator[4] = { '|' , '/' , '-' , '\\' };
-#endif
-
-	out_fd = open("/dev/ram", O_RDWR, 0);
-	if (out_fd < 0)
-		goto out;
-
-	in_fd = open(from, O_RDONLY, 0);
-	if (in_fd < 0)
-		goto noclose_input;
-
-	nblocks = identify_ramdisk_image(in_fd, rd_image_start);
-	if (nblocks < 0)
-		goto done;
-
-	if (nblocks == 0) {
-#ifdef BUILD_CRAMDISK
-		if (crd_load(in_fd, out_fd) == 0)
-			goto successful_load;
-#else
-		printk(KERN_NOTICE
-		       "RAMDISK: Kernel does not support compressed "
-		       "RAM disk images\n");
-#endif
-		goto done;
-	}
-
-	/*
-	 * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so
-	 * rd_load_image will work only with filesystem BLOCK_SIZE wide!
-	 * So make sure to use 1k blocksize while generating ext2fs
-	 * ramdisk-images.
-	 */
-	if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
-		rd_blocks = 0;
-	else
-		rd_blocks >>= 1;
-
-	if (nblocks > rd_blocks) {
-		printk("RAMDISK: image too big! (%d/%ld blocks)\n",
-		       nblocks, rd_blocks);
-		goto done;
-	}
-		
-	/*
-	 * OK, time to copy in the data
-	 */
-	if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
-		devblocks = 0;
-	else
-		devblocks >>= 1;
-
-	if (strcmp(from, "/dev/initrd") == 0)
-		devblocks = nblocks;
-
-	if (devblocks == 0) {
-		printk(KERN_ERR "RAMDISK: could not determine device size\n");
-		goto done;
-	}
-
-	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
-	if (buf == 0) {
-		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
-		goto done;
-	}
-
-	printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%ld disk%s] into ram disk... ", 
-		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
-	for (i = 0, disk = 1; i < nblocks; i++) {
-		if (i && (i % devblocks == 0)) {
-			printk("done disk #%d.\n", disk++);
-			rotate = 0;
-			if (close(in_fd)) {
-				printk("Error closing the disk.\n");
-				goto noclose_input;
-			}
-			change_floppy("disk #%d", disk);
-			in_fd = open(from, O_RDONLY, 0);
-			if (in_fd < 0)  {
-				printk("Error opening disk.\n");
-				goto noclose_input;
-			}
-			printk("Loading disk #%d... ", disk);
-		}
-		read(in_fd, buf, BLOCK_SIZE);
-		write(out_fd, buf, BLOCK_SIZE);
-#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
-		if (!(i % 16)) {
-			printk("%c\b", rotator[rotate & 0x3]);
-			rotate++;
-		}
-#endif
-	}
-	printk("done.\n");
-	kfree(buf);
-
-successful_load:
-	res = 1;
-done:
-	close(in_fd);
-noclose_input:
-	close(out_fd);
-out:
-	sys_unlink("/dev/ram");
-#endif
-	return res;
-}
-
-static int __init rd_load_disk(int n)
-{
-#ifdef CONFIG_BLK_DEV_RAM
-	if (rd_prompt)
-		change_floppy("root floppy disk to be loaded into RAM disk");
-	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
-#endif
-	return rd_load_image("/dev/root");
-}
-
-static void __init mount_root(void)
+void __init mount_root(void)
 {
 #ifdef CONFIG_ROOT_NFS
 	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
-		if (mount_nfs_root()) {
-			sys_chdir("/root");
-			ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
-			printk("VFS: Mounted root (nfs filesystem).\n");
+		if (mount_nfs_root())
 			return;
-		}
+
 		printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
 		ROOT_DEV = Root_FD0;
 	}
 #endif
-	create_dev("/dev/root", ROOT_DEV, root_device_name);
 #ifdef CONFIG_BLK_DEV_FD
 	if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
 		/* rd_doload is 2 for a dual initrd/ramload setup */
 		if (rd_doload==2) {
 			if (rd_load_disk(1)) {
 				ROOT_DEV = Root_RAM1;
-				create_dev("/dev/root", ROOT_DEV, NULL);
+				root_device_name = NULL;
 			}
 		} else
 			change_floppy("root floppy");
 	}
 #endif
+	create_dev("/dev/root", ROOT_DEV, root_device_name);
 	mount_block_root("/dev/root", root_mountflags);
 }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-static int old_fd, root_fd;
-static int do_linuxrc(void * shell)
-{
-	static char *argv[] = { "linuxrc", NULL, };
-	extern char * envp_init[];
-
-	close(old_fd);close(root_fd);
-	close(0);close(1);close(2);
-	setsid();
-	(void) open("/dev/console",O_RDWR,0);
-	(void) dup(0);
-	(void) dup(0);
-	return execve(shell, argv, envp_init);
-}
-
-#endif
-
-static void __init handle_initrd(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	int error;
-	int i, pid;
-
-	create_dev("/dev/root.old", Root_RAM0, NULL);
-	/* mount initrd on rootfs' /root */
-	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
-	sys_mkdir("/old", 0700);
-	root_fd = open("/", 0, 0);
-	old_fd = open("/old", 0, 0);
-	/* move initrd over / and chdir/chroot in initrd root */
-	sys_chdir("/root");
-	sys_mount(".", "/", NULL, MS_MOVE, NULL);
-	sys_chroot(".");
-	mount_devfs_fs ();
-
-	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
-	if (pid > 0) {
-		while (pid != waitpid(-1, &i, 0))
-			yield();
-	}
-
-	/* move initrd to rootfs' /old */
-	sys_fchdir(old_fd);
-	sys_mount("/", ".", NULL, MS_MOVE, NULL);
-	/* switch root and cwd back to / of rootfs */
-	sys_fchdir(root_fd);
-	sys_chroot(".");
-	close(old_fd);
-	close(root_fd);
-	sys_umount("/old/dev", 0);
-
-	if (real_root_dev == Root_RAM0) {
-		sys_chdir("/old");
-		return;
-	}
-
-	ROOT_DEV = real_root_dev;
-	mount_root();
-
-	printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
-	error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
-	if (!error)
-		printk("okay\n");
-	else {
-		int fd = open("/dev/root.old", O_RDWR, 0);
-		printk("failed\n");
-		printk(KERN_NOTICE "Unmounting old root\n");
-		sys_umount("/old", MNT_DETACH);
-		printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
-		if (fd < 0) {
-			error = fd;
-		} else {
-			error = sys_ioctl(fd, BLKFLSBUF, 0);
-			close(fd);
-		}
-		printk(!error ? "okay\n" : "failed\n");
-	}
-#endif
-}
-
-static int __init initrd_load(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
-	create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
-#endif
-	return rd_load_image("/dev/initrd");
-}
-
-static void __init md_run_setup(void);
-
 /*
  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
  */
-void prepare_namespace(void)
+void __init prepare_namespace(void)
 {
 	int is_floppy;
 
-#ifdef CONFIG_DEVFS_FS
-	sys_mount("devfs", "/dev", "devfs", 0, NULL);
-	do_devfs = 1;
-#endif
+	mount_devfs();
 
 	md_run_setup();
 
 	if (saved_root_name[0]) {
-		char *p = saved_root_name;
-		ROOT_DEV = name_to_dev_t(p);
-		if (strncmp(p, "/dev/", 5) == 0)
-			p += 5;
-		strcpy(root_device_name, p);
+		root_device_name = saved_root_name;
+		ROOT_DEV = name_to_dev_t(root_device_name);
+		if (strncmp(root_device_name, "/dev/", 5) == 0)
+			root_device_name += 5;
 	}
 
 	is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (!initrd_start)
-		mount_initrd = 0;
-	real_root_dev = ROOT_DEV;
-#endif
-
-	create_dev("/dev/root", ROOT_DEV, NULL);
-
 	/* This has to be before mounting root, because even readonly mount of reiserfs would replay
 	   log corrupting stuff */
 	software_resume();
 
-	if (mount_initrd) {
-		if (initrd_load() && ROOT_DEV != Root_RAM0) {
-			handle_initrd();
-			goto out;
-		}
-	} else if (is_floppy && rd_doload && rd_load_disk(0))
+	if (initrd_load())
+		goto out;
+
+	if (is_floppy && rd_doload && rd_load_disk(0))
 		ROOT_DEV = Root_RAM0;
+
 	mount_root();
 out:
-	sys_umount("/dev", 0);
+	umount_devfs("/dev");
 	sys_mount(".", "/", NULL, MS_MOVE, NULL);
 	sys_chroot(".");
 	security_sb_post_mountroot();
 	mount_devfs_fs ();
 }
 
-#if defined(BUILD_CRAMDISK) && defined(CONFIG_BLK_DEV_RAM)
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-
-#ifndef memzero
-#define memzero(s, n)     memset ((s), 0, (n))
-#endif
-
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define INBUFSIZ 4096
-#define WSIZE 0x8000    /* window size--must be a power of two, and */
-			/*  at least 32K for zip's deflate method */
-
-static uch *inbuf;
-static uch *window;
-
-static unsigned insize;  /* valid bytes in inbuf */
-static unsigned inptr;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt;  /* bytes in output buffer */
-static int exit_code;
-static int unzip_error;
-static long bytes_out;
-static int crd_infd, crd_outfd;
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-		
-/* Diagnostic functions (stubbed out) */
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-
-#define STATIC static
-
-static int  fill_inbuf(void);
-static void flush_window(void);
-static void *malloc(int size);
-static void free(void *where);
-static void error(char *m);
-static void gzip_mark(void **);
-static void gzip_release(void **);
-
-#include "../lib/inflate.c"
-
-static void __init *malloc(int size)
-{
-	return kmalloc(size, GFP_KERNEL);
-}
-
-static void __init free(void *where)
-{
-	kfree(where);
-}
-
-static void __init gzip_mark(void **ptr)
-{
-}
-
-static void __init gzip_release(void **ptr)
-{
-}
-
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- * Returning -1 does not guarantee that gunzip() will ever return.
- */
-static int __init fill_inbuf(void)
-{
-	if (exit_code) return -1;
-	
-	insize = read(crd_infd, inbuf, INBUFSIZ);
-	if (insize == 0) {
-		error("RAMDISK: ran out of compressed data\n");
-		return -1;
-	}
-
-	inptr = 1;
-
-	return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void __init flush_window(void)
-{
-    ulg c = crc;         /* temporary variable */
-    unsigned n, written;
-    uch *in, ch;
-    
-    written = write(crd_outfd, window, outcnt);
-    if (written != outcnt && unzip_error == 0) {
-	printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
-	       written, outcnt, bytes_out);
-	unzip_error = 1;
-    }
-    in = window;
-    for (n = 0; n < outcnt; n++) {
-	    ch = *in++;
-	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-    }
-    crc = c;
-    bytes_out += (ulg)outcnt;
-    outcnt = 0;
-}
-
-static void __init error(char *x)
-{
-	printk(KERN_ERR "%s", x);
-	exit_code = 1;
-	unzip_error = 1;
-}
-
-static int __init crd_load(int in_fd, int out_fd)
-{
-	int result;
-
-	insize = 0;		/* valid bytes in inbuf */
-	inptr = 0;		/* index of next byte to be processed in inbuf */
-	outcnt = 0;		/* bytes in output buffer */
-	exit_code = 0;
-	bytes_out = 0;
-	crc = (ulg)0xffffffffL; /* shift register contents */
-
-	crd_infd = in_fd;
-	crd_outfd = out_fd;
-	inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
-	if (inbuf == 0) {
-		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
-		return -1;
-	}
-	window = kmalloc(WSIZE, GFP_KERNEL);
-	if (window == 0) {
-		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
-		kfree(inbuf);
-		return -1;
-	}
-	makecrc();
-	result = gunzip();
-	if (unzip_error)
-		result = 1;
-	kfree(inbuf);
-	kfree(window);
-	return result;
-}
-
-#endif  /* BUILD_CRAMDISK && CONFIG_BLK_DEV_RAM */
-
-#ifdef CONFIG_BLK_DEV_MD
-
-/*
- * When md (and any require personalities) are compiled into the kernel
- * (not a module), arrays can be assembles are boot time using with AUTODETECT
- * where specially marked partitions are registered with md_autodetect_dev(),
- * and with MD_BOOT where devices to be collected are given on the boot line
- * with md=.....
- * The code for that is here.
- */
-
-struct {
-	int set;
-	int noautodetect;
-} raid_setup_args __initdata;
-
-static struct {
-	char device_set [MAX_MD_DEVS];
-	int pers[MAX_MD_DEVS];
-	int chunk[MAX_MD_DEVS];
-	char *device_names[MAX_MD_DEVS];
-} md_setup_args __initdata;
-
-/*
- * Parse the command-line parameters given our kernel, but do not
- * actually try to invoke the MD device now; that is handled by
- * md_setup_drive after the low-level disk drivers have initialised.
- *
- * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
- *             assigns the task of parsing integer arguments to the
- *             invoked program now).  Added ability to initialise all
- *             the MD devices (by specifying multiple "md=" lines)
- *             instead of just one.  -- KTK
- * 18May2000: Added support for persistent-superblock arrays:
- *             md=n,0,factor,fault,device-list   uses RAID0 for device n
- *             md=n,-1,factor,fault,device-list  uses LINEAR for device n
- *             md=n,device-list      reads a RAID superblock from the devices
- *             elements in device-list are read by name_to_kdev_t so can be
- *             a hex number or something like /dev/hda1 /dev/sdb
- * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
- *		Shifted name_to_kdev_t() and related operations to md_set_drive()
- *		for later execution. Rewrote section to make devfs compatible.
- */
-static int __init md_setup(char *str)
-{
-	int minor, level, factor, fault, pers;
-	char *pername = "";
-	char *str1 = str;
-
-	if (get_option(&str, &minor) != 2) {	/* MD Number */
-		printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
-		return 0;
-	}
-	if (minor >= MAX_MD_DEVS) {
-		printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
-		return 0;
-	} else if (md_setup_args.device_names[minor]) {
-		printk(KERN_WARNING "md: md=%d, Specified more than once. "
-		       "Replacing previous definition.\n", minor);
-	}
-	switch (get_option(&str, &level)) {	/* RAID Personality */
-	case 2: /* could be 0 or -1.. */
-		if (level == 0 || level == LEVEL_LINEAR) {
-			if (get_option(&str, &factor) != 2 ||	/* Chunk Size */
-					get_option(&str, &fault) != 2) {
-				printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
-				return 0;
-			}
-			md_setup_args.pers[minor] = level;
-			md_setup_args.chunk[minor] = 1 << (factor+12);
-			switch(level) {
-			case LEVEL_LINEAR:
-				pers = LINEAR;
-				pername = "linear";
-				break;
-			case 0:
-				pers = RAID0;
-				pername = "raid0";
-				break;
-			default:
-				printk(KERN_WARNING
-				       "md: The kernel has not been configured for raid%d support!\n",
-				       level);
-				return 0;
-			}
-			md_setup_args.pers[minor] = pers;
-			break;
-		}
-		/* FALL THROUGH */
-	case 1: /* the first device is numeric */
-		str = str1;
-		/* FALL THROUGH */
-	case 0:
-		md_setup_args.pers[minor] = 0;
-		pername="super-block";
-	}
-
-	printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
-		minor, pername, str);
-	md_setup_args.device_names[minor] = str;
-
-	return 1;
-}
-static void __init md_setup_drive(void)
-{
-	int minor, i;
-	dev_t dev;
-	dev_t devices[MD_SB_DISKS+1];
-
-	for (minor = 0; minor < MAX_MD_DEVS; minor++) {
-		int fd;
-		int err = 0;
-		char *devname;
-		mdu_disk_info_t dinfo;
-		char name[16], devfs_name[16];
-
-		if (!(devname = md_setup_args.device_names[minor]))
-			continue;
-		
-		sprintf(name, "/dev/md%d", minor);
-		sprintf(devfs_name, "/dev/md/%d", minor);
-		create_dev(name, MKDEV(MD_MAJOR, minor), devfs_name);
-		for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
-			char *p;
-			char comp_name[64];
-			struct stat buf;
-
-			p = strchr(devname, ',');
-			if (p)
-				*p++ = 0;
-
-			dev = name_to_dev_t(devname);
-			if (strncmp(devname, "/dev/", 5))
-				devname += 5;
-			snprintf(comp_name, 63, "/dev/%s", devname);
-			if (sys_newstat(comp_name, &buf) == 0 &&
-							S_ISBLK(buf.st_mode))
-				dev = buf.st_rdev;
-			if (!dev) {
-				printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
-				break;
-			}
-
-			devices[i] = dev;
-			md_setup_args.device_set[minor] = 1;
-
-			devname = p;
-		}
-		devices[i] = 0;
-
-		if (!md_setup_args.device_set[minor])
-			continue;
-
-		printk(KERN_INFO "md: Loading md%d: %s\n", minor, md_setup_args.device_names[minor]);
-
-		fd = open(name, 0, 0);
-		if (fd < 0) {
-			printk(KERN_ERR "md: open failed - cannot start array %d\n", minor);
-			continue;
-		}
-		if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
-			printk(KERN_WARNING
-			       "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
-			       minor);
-			close(fd);
-			continue;
-		}
-
-		if (md_setup_args.pers[minor]) {
-			/* non-persistent */
-			mdu_array_info_t ainfo;
-			ainfo.level = pers_to_level(md_setup_args.pers[minor]);
-			ainfo.size = 0;
-			ainfo.nr_disks =0;
-			ainfo.raid_disks =0;
-			while (devices[ainfo.raid_disks])
-				ainfo.raid_disks++;
-			ainfo.md_minor =minor;
-			ainfo.not_persistent = 1;
-
-			ainfo.state = (1 << MD_SB_CLEAN);
-			ainfo.layout = 0;
-			ainfo.chunk_size = md_setup_args.chunk[minor];
-			err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
-			for (i = 0; !err && i <= MD_SB_DISKS; i++) {
-				dev = devices[i];
-				if (!dev)
-					break;
-				dinfo.number = i;
-				dinfo.raid_disk = i;
-				dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
-				dinfo.major = MAJOR(dev);
-				dinfo.minor = MINOR(dev);
-				err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
-			}
-		} else {
-			/* persistent */
-			for (i = 0; i <= MD_SB_DISKS; i++) {
-				dev = devices[i];
-				if (!dev)
-					break;
-				dinfo.major = MAJOR(dev);
-				dinfo.minor = MINOR(dev);
-				sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
-			}
-		}
-		if (!err)
-			err = sys_ioctl(fd, RUN_ARRAY, 0);
-		if (err)
-			printk(KERN_WARNING "md: starting md%d failed\n", minor);
-		close(fd);
-	}
-}
-
-static int __init raid_setup(char *str)
-{
-	int len, pos;
-
-	len = strlen(str) + 1;
-	pos = 0;
-
-	while (pos < len) {
-		char *comma = strchr(str+pos, ',');
-		int wlen;
-		if (comma)
-			wlen = (comma-str)-pos;
-		else	wlen = (len-1)-pos;
-
-		if (!strncmp(str, "noautodetect", wlen))
-			raid_setup_args.noautodetect = 1;
-		pos += wlen+1;
-	}
-	raid_setup_args.set = 1;
-	return 1;
-}
-
-__setup("raid=", raid_setup);
-__setup("md=", md_setup);
-#endif
-
-static void __init md_run_setup(void)
-{
-#ifdef CONFIG_BLK_DEV_MD
-	create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0");
-	if (raid_setup_args.noautodetect)
-		printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
-	else {
-		int fd = open("/dev/md0", 0, 0);
-		if (fd >= 0) {
-			sys_ioctl(fd, RAID_AUTORUN, 0);
-			close(fd);
-		}
-	}
-	md_setup_drive();
-#endif
-}
diff -urN linux-2.5.63-bk5/init/do_mounts.h linux-2.5.63-bk6/init/do_mounts.h
--- linux-2.5.63-bk5/init/do_mounts.h	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/init/do_mounts.h	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,80 @@
+#define __KERNEL_SYSCALLS__
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/init.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/mount.h>
+#include <linux/blk.h>
+#include <linux/root_dev.h>
+
+asmlinkage long sys_unlink(const char *name);
+asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
+asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
+asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
+asmlinkage long sys_mkdir(const char *name, int mode);
+asmlinkage long sys_rmdir(const char *name);
+asmlinkage long sys_chdir(const char *name);
+asmlinkage long sys_fchdir(int fd);
+asmlinkage long sys_chroot(const char *name);
+asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
+				 unsigned long flags, void *data);
+asmlinkage long sys_umount(char *name, int flags);
+
+dev_t name_to_dev_t(char *name);
+void  change_floppy(char *fmt, ...);
+void  mount_block_root(char *name, int flags);
+void  mount_root(void);
+extern int root_mountflags;
+
+#ifdef CONFIG_DEVFS_FS
+
+void mount_devfs(void);
+void umount_devfs(char *path);
+int  create_dev(char *name, dev_t dev, char *devfs_name);
+
+#else
+
+static inline void mount_devfs(void) {}
+static inline void umount_devfs(const char *path) {}
+
+static inline int create_dev(char *name, dev_t dev, char *devfs_name)
+{
+	sys_unlink(name);
+	return sys_mknod(name, S_IFBLK|0600, dev);
+}
+
+#endif
+
+#ifdef CONFIG_BLK_DEV_RAM
+
+int __init rd_load_disk(int n);
+int __init rd_load_image(char *from);
+
+#else
+
+static inline int rd_load_disk(int n) { return 0; }
+static inline int rd_load_image(char *from) { return 0; }
+
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+int __init initrd_load(void);
+
+#else
+
+static inline int initrd_load(void) { return 0; }
+
+#endif
+
+#ifdef CONFIG_BLK_DEV_MD
+
+void md_run_setup(void);
+
+#else
+
+static inline void md_run_setup(void) {}
+
+#endif
diff -urN linux-2.5.63-bk5/init/do_mounts_devfs.c linux-2.5.63-bk6/init/do_mounts_devfs.c
--- linux-2.5.63-bk5/init/do_mounts_devfs.c	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/init/do_mounts_devfs.c	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,146 @@
+
+#include <linux/kernel.h>
+#include <linux/dirent.h>
+#include <linux/string.h>
+
+#include "do_mounts.h"
+
+extern asmlinkage long sys_symlink(const char *old, const char *new);
+extern asmlinkage long sys_access(const char * filename, int mode);
+extern asmlinkage long sys_getdents64(unsigned int fd, void * dirent,
+				      unsigned int count);
+
+void __init mount_devfs(void)
+{
+	sys_mount("devfs", "/dev", "devfs", 0, NULL);
+}
+
+void __init umount_devfs(char *path)
+{
+	sys_umount(path, 0);
+}
+
+/*
+ * If the dir will fit in *buf, return its length.  If it won't fit, return
+ * zero.  Return -ve on error.
+ */
+static int __init do_read_dir(int fd, void *buf, int len)
+{
+	long bytes, n;
+	char *p = buf;
+	lseek(fd, 0, 0);
+
+	for (bytes = 0; bytes < len; bytes += n) {
+		n = sys_getdents64(fd, p + bytes, len - bytes);
+		if (n < 0)
+			return n;
+		if (n == 0)
+			return bytes;
+	}
+	return 0;
+}
+
+/*
+ * Try to read all of a directory.  Returns the contents at *p, which
+ * is kmalloced memory.  Returns the number of bytes read at *len.  Returns
+ * NULL on error.
+ */
+static void * __init read_dir(char *path, int *len)
+{
+	int size;
+	int fd = open(path, 0, 0);
+
+	*len = 0;
+	if (fd < 0)
+		return NULL;
+
+	for (size = 1 << 9; size <= (1 << MAX_ORDER); size <<= 1) {
+		void *p = kmalloc(size, GFP_KERNEL);
+		int n;
+		if (!p)
+			break;
+		n = do_read_dir(fd, p, size);
+		if (n > 0) {
+			close(fd);
+			*len = n;
+			return p;
+		}
+		kfree(p);
+		if (n == -EINVAL)
+			continue;	/* Try a larger buffer */
+		if (n < 0)
+			break;
+	}
+	close(fd);
+	return NULL;
+}
+
+/*
+ * recursively scan <path>, looking for a device node of type <dev>
+ */
+static int __init find_in_devfs(char *path, dev_t dev)
+{
+	struct stat buf;
+	char *end = path + strlen(path);
+	int rest = path + 64 - end;
+	int size;
+	char *p = read_dir(path, &size);
+	char *s;
+
+	if (!p)
+		return -1;
+	for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) {
+		struct linux_dirent64 *d = (struct linux_dirent64 *)s;
+		if (strlen(d->d_name) + 2 > rest)
+			continue;
+		switch (d->d_type) {
+			case DT_BLK:
+				sprintf(end, "/%s", d->d_name);
+				if (sys_newstat(path, &buf) < 0)
+					break;
+				if (!S_ISBLK(buf.st_mode))
+					break;
+				if (buf.st_rdev != dev)
+					break;
+				kfree(p);
+				return 0;
+			case DT_DIR:
+				if (strcmp(d->d_name, ".") == 0)
+					break;
+				if (strcmp(d->d_name, "..") == 0)
+					break;
+				sprintf(end, "/%s", d->d_name);
+				if (find_in_devfs(path, dev) < 0)
+					break;
+				kfree(p);
+				return 0;
+		}
+	}
+	kfree(p);
+	return -1;
+}
+
+/*
+ * create a device node called <name> which points to
+ * <devfs_name> if possible, otherwise find a device node
+ * which matches <dev> and make <name> a symlink pointing to it.
+ */
+int __init create_dev(char *name, dev_t dev, char *devfs_name)
+{
+	char path[64];
+
+	sys_unlink(name);
+	if (devfs_name && devfs_name[0]) {
+		if (strncmp(devfs_name, "/dev/", 5) == 0)
+			devfs_name += 5;
+		sprintf(path, "/dev/%s", devfs_name);
+		if (sys_access(path, 0) == 0)
+			return sys_symlink(devfs_name, name);
+	}
+	if (!dev)
+		return -1;
+	strcpy(path, "/dev");
+	if (find_in_devfs(path, dev) < 0)
+		return -1;
+	return sys_symlink(path + 5, name);
+}
diff -urN linux-2.5.63-bk5/init/do_mounts_md.c linux-2.5.63-bk6/init/do_mounts_md.c
--- linux-2.5.63-bk5/init/do_mounts_md.c	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/init/do_mounts_md.c	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,253 @@
+
+#include <linux/raid/md.h>
+
+#include "do_mounts.h"
+
+/*
+ * When md (and any require personalities) are compiled into the kernel
+ * (not a module), arrays can be assembles are boot time using with AUTODETECT
+ * where specially marked partitions are registered with md_autodetect_dev(),
+ * and with MD_BOOT where devices to be collected are given on the boot line
+ * with md=.....
+ * The code for that is here.
+ */
+
+static int __initdata raid_noautodetect;
+
+static struct {
+	char device_set [MAX_MD_DEVS];
+	int pers[MAX_MD_DEVS];
+	int chunk[MAX_MD_DEVS];
+	char *device_names[MAX_MD_DEVS];
+} md_setup_args __initdata;
+
+/*
+ * Parse the command-line parameters given our kernel, but do not
+ * actually try to invoke the MD device now; that is handled by
+ * md_setup_drive after the low-level disk drivers have initialised.
+ *
+ * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
+ *             assigns the task of parsing integer arguments to the
+ *             invoked program now).  Added ability to initialise all
+ *             the MD devices (by specifying multiple "md=" lines)
+ *             instead of just one.  -- KTK
+ * 18May2000: Added support for persistent-superblock arrays:
+ *             md=n,0,factor,fault,device-list   uses RAID0 for device n
+ *             md=n,-1,factor,fault,device-list  uses LINEAR for device n
+ *             md=n,device-list      reads a RAID superblock from the devices
+ *             elements in device-list are read by name_to_kdev_t so can be
+ *             a hex number or something like /dev/hda1 /dev/sdb
+ * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
+ *		Shifted name_to_kdev_t() and related operations to md_set_drive()
+ *		for later execution. Rewrote section to make devfs compatible.
+ */
+static int __init md_setup(char *str)
+{
+	int minor, level, factor, fault, pers;
+	char *pername = "";
+	char *str1 = str;
+
+	if (get_option(&str, &minor) != 2) {	/* MD Number */
+		printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
+		return 0;
+	}
+	if (minor >= MAX_MD_DEVS) {
+		printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor);
+		return 0;
+	} else if (md_setup_args.device_names[minor]) {
+		printk(KERN_WARNING "md: md=%d, Specified more than once. "
+		       "Replacing previous definition.\n", minor);
+	}
+	switch (get_option(&str, &level)) {	/* RAID Personality */
+	case 2: /* could be 0 or -1.. */
+		if (level == 0 || level == LEVEL_LINEAR) {
+			if (get_option(&str, &factor) != 2 ||	/* Chunk Size */
+					get_option(&str, &fault) != 2) {
+				printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
+				return 0;
+			}
+			md_setup_args.pers[minor] = level;
+			md_setup_args.chunk[minor] = 1 << (factor+12);
+			switch(level) {
+			case LEVEL_LINEAR:
+				pers = LINEAR;
+				pername = "linear";
+				break;
+			case 0:
+				pers = RAID0;
+				pername = "raid0";
+				break;
+			default:
+				printk(KERN_WARNING
+				       "md: The kernel has not been configured for raid%d support!\n",
+				       level);
+				return 0;
+			}
+			md_setup_args.pers[minor] = pers;
+			break;
+		}
+		/* FALL THROUGH */
+	case 1: /* the first device is numeric */
+		str = str1;
+		/* FALL THROUGH */
+	case 0:
+		md_setup_args.pers[minor] = 0;
+		pername="super-block";
+	}
+
+	printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
+		minor, pername, str);
+	md_setup_args.device_names[minor] = str;
+
+	return 1;
+}
+
+static void __init md_setup_drive(void)
+{
+	int minor, i;
+	dev_t dev;
+	dev_t devices[MD_SB_DISKS+1];
+
+	for (minor = 0; minor < MAX_MD_DEVS; minor++) {
+		int fd;
+		int err = 0;
+		char *devname;
+		mdu_disk_info_t dinfo;
+		char name[16], devfs_name[16];
+
+		if (!(devname = md_setup_args.device_names[minor]))
+			continue;
+		
+		sprintf(name, "/dev/md%d", minor);
+		sprintf(devfs_name, "/dev/md/%d", minor);
+		create_dev(name, MKDEV(MD_MAJOR, minor), devfs_name);
+		for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
+			char *p;
+			char comp_name[64];
+			struct stat buf;
+
+			p = strchr(devname, ',');
+			if (p)
+				*p++ = 0;
+
+			dev = name_to_dev_t(devname);
+			if (strncmp(devname, "/dev/", 5) == 0)
+				devname += 5;
+			snprintf(comp_name, 63, "/dev/%s", devname);
+			if (sys_newstat(comp_name, &buf) == 0 &&
+							S_ISBLK(buf.st_mode))
+				dev = buf.st_rdev;
+			if (!dev) {
+				printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
+				break;
+			}
+
+			devices[i] = dev;
+			md_setup_args.device_set[minor] = 1;
+
+			devname = p;
+		}
+		devices[i] = 0;
+
+		if (!md_setup_args.device_set[minor])
+			continue;
+
+		printk(KERN_INFO "md: Loading md%d: %s\n", minor, md_setup_args.device_names[minor]);
+
+		fd = open(name, 0, 0);
+		if (fd < 0) {
+			printk(KERN_ERR "md: open failed - cannot start array %d\n", minor);
+			continue;
+		}
+		if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
+			printk(KERN_WARNING
+			       "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
+			       minor);
+			close(fd);
+			continue;
+		}
+
+		if (md_setup_args.pers[minor]) {
+			/* non-persistent */
+			mdu_array_info_t ainfo;
+			ainfo.level = pers_to_level(md_setup_args.pers[minor]);
+			ainfo.size = 0;
+			ainfo.nr_disks =0;
+			ainfo.raid_disks =0;
+			while (devices[ainfo.raid_disks])
+				ainfo.raid_disks++;
+			ainfo.md_minor =minor;
+			ainfo.not_persistent = 1;
+
+			ainfo.state = (1 << MD_SB_CLEAN);
+			ainfo.layout = 0;
+			ainfo.chunk_size = md_setup_args.chunk[minor];
+			err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
+			for (i = 0; !err && i <= MD_SB_DISKS; i++) {
+				dev = devices[i];
+				if (!dev)
+					break;
+				dinfo.number = i;
+				dinfo.raid_disk = i;
+				dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
+				dinfo.major = MAJOR(dev);
+				dinfo.minor = MINOR(dev);
+				err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
+			}
+		} else {
+			/* persistent */
+			for (i = 0; i <= MD_SB_DISKS; i++) {
+				dev = devices[i];
+				if (!dev)
+					break;
+				dinfo.major = MAJOR(dev);
+				dinfo.minor = MINOR(dev);
+				sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
+			}
+		}
+		if (!err)
+			err = sys_ioctl(fd, RUN_ARRAY, 0);
+		if (err)
+			printk(KERN_WARNING "md: starting md%d failed\n", minor);
+		close(fd);
+	}
+}
+
+static int __init raid_setup(char *str)
+{
+	int len, pos;
+
+	len = strlen(str) + 1;
+	pos = 0;
+
+	while (pos < len) {
+		char *comma = strchr(str+pos, ',');
+		int wlen;
+		if (comma)
+			wlen = (comma-str)-pos;
+		else	wlen = (len-1)-pos;
+
+		if (!strncmp(str, "noautodetect", wlen))
+			raid_noautodetect = 1;
+		pos += wlen+1;
+	}
+	return 1;
+}
+
+__setup("raid=", raid_setup);
+__setup("md=", md_setup);
+
+void __init md_run_setup(void)
+{
+	create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0");
+	if (raid_noautodetect)
+		printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
+	else {
+		int fd = open("/dev/md0", 0, 0);
+		if (fd >= 0) {
+			sys_ioctl(fd, RAID_AUTORUN, 0);
+			close(fd);
+		}
+	}
+	md_setup_drive();
+}
diff -urN linux-2.5.63-bk5/init/do_mounts_rd.c linux-2.5.63-bk6/init/do_mounts_rd.c
--- linux-2.5.63-bk5/init/do_mounts_rd.c	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/init/do_mounts_rd.c	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,516 @@
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/minix_fs.h>
+#include <linux/ext2_fs.h>
+#include <linux/romfs_fs.h>
+
+#include "do_mounts.h"
+
+#define BUILD_CRAMDISK
+
+int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
+
+static int __init prompt_ramdisk(char *str)
+{
+	rd_prompt = simple_strtol(str,NULL,0) & 1;
+	return 1;
+}
+__setup("prompt_ramdisk=", prompt_ramdisk);
+
+int __initdata rd_image_start;		/* starting block # of image */
+
+static int __init ramdisk_start_setup(char *str)
+{
+	rd_image_start = simple_strtol(str,NULL,0);
+	return 1;
+}
+__setup("ramdisk_start=", ramdisk_start_setup);
+
+static int __init crd_load(int in_fd, int out_fd);
+
+/*
+ * This routine tries to find a RAM disk image to load, and returns the
+ * number of blocks to read for a non-compressed image, 0 if the image
+ * is a compressed image, and -1 if an image with the right magic
+ * numbers could not be found.
+ *
+ * We currently check for the following magic numbers:
+ * 	minix
+ * 	ext2
+ *	romfs
+ * 	gzip
+ */
+static int __init 
+identify_ramdisk_image(int fd, int start_block)
+{
+	const int size = 512;
+	struct minix_super_block *minixsb;
+	struct ext2_super_block *ext2sb;
+	struct romfs_super_block *romfsb;
+	int nblocks = -1;
+	unsigned char *buf;
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (buf == 0)
+		return -1;
+
+	minixsb = (struct minix_super_block *) buf;
+	ext2sb = (struct ext2_super_block *) buf;
+	romfsb = (struct romfs_super_block *) buf;
+	memset(buf, 0xe5, size);
+
+	/*
+	 * Read block 0 to test for gzipped kernel
+	 */
+	lseek(fd, start_block * BLOCK_SIZE, 0);
+	read(fd, buf, size);
+
+	/*
+	 * If it matches the gzip magic numbers, return -1
+	 */
+	if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
+		printk(KERN_NOTICE
+		       "RAMDISK: Compressed image found at block %d\n",
+		       start_block);
+		nblocks = 0;
+		goto done;
+	}
+
+	/* romfs is at block zero too */
+	if (romfsb->word0 == ROMSB_WORD0 &&
+	    romfsb->word1 == ROMSB_WORD1) {
+		printk(KERN_NOTICE
+		       "RAMDISK: romfs filesystem found at block %d\n",
+		       start_block);
+		nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
+		goto done;
+	}
+
+	/*
+	 * Read block 1 to test for minix and ext2 superblock
+	 */
+	lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
+	read(fd, buf, size);
+
+	/* Try minix */
+	if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
+	    minixsb->s_magic == MINIX_SUPER_MAGIC2) {
+		printk(KERN_NOTICE
+		       "RAMDISK: Minix filesystem found at block %d\n",
+		       start_block);
+		nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
+		goto done;
+	}
+
+	/* Try ext2 */
+	if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
+		printk(KERN_NOTICE
+		       "RAMDISK: ext2 filesystem found at block %d\n",
+		       start_block);
+		nblocks = le32_to_cpu(ext2sb->s_blocks_count);
+		goto done;
+	}
+
+	printk(KERN_NOTICE
+	       "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
+	       start_block);
+	
+done:
+	lseek(fd, start_block * BLOCK_SIZE, 0);
+	kfree(buf);
+	return nblocks;
+}
+
+int __init rd_load_image(char *from)
+{
+	int res = 0;
+	int in_fd, out_fd;
+	unsigned long rd_blocks, devblocks;
+	int nblocks, i, disk;
+	char *buf;
+	unsigned short rotate = 0;
+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+	char rotator[4] = { '|' , '/' , '-' , '\\' };
+#endif
+
+	out_fd = open("/dev/ram", O_RDWR, 0);
+	if (out_fd < 0)
+		goto out;
+
+	in_fd = open(from, O_RDONLY, 0);
+	if (in_fd < 0)
+		goto noclose_input;
+
+	nblocks = identify_ramdisk_image(in_fd, rd_image_start);
+	if (nblocks < 0)
+		goto done;
+
+	if (nblocks == 0) {
+#ifdef BUILD_CRAMDISK
+		if (crd_load(in_fd, out_fd) == 0)
+			goto successful_load;
+#else
+		printk(KERN_NOTICE
+		       "RAMDISK: Kernel does not support compressed "
+		       "RAM disk images\n");
+#endif
+		goto done;
+	}
+
+	/*
+	 * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so
+	 * rd_load_image will work only with filesystem BLOCK_SIZE wide!
+	 * So make sure to use 1k blocksize while generating ext2fs
+	 * ramdisk-images.
+	 */
+	if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
+		rd_blocks = 0;
+	else
+		rd_blocks >>= 1;
+
+	if (nblocks > rd_blocks) {
+		printk("RAMDISK: image too big! (%d/%ld blocks)\n",
+		       nblocks, rd_blocks);
+		goto done;
+	}
+		
+	/*
+	 * OK, time to copy in the data
+	 */
+	if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
+		devblocks = 0;
+	else
+		devblocks >>= 1;
+
+	if (strcmp(from, "/dev/initrd") == 0)
+		devblocks = nblocks;
+
+	if (devblocks == 0) {
+		printk(KERN_ERR "RAMDISK: could not determine device size\n");
+		goto done;
+	}
+
+	buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
+	if (buf == 0) {
+		printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
+		goto done;
+	}
+
+	printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%ld disk%s] into ram disk... ", 
+		nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
+	for (i = 0, disk = 1; i < nblocks; i++) {
+		if (i && (i % devblocks == 0)) {
+			printk("done disk #%d.\n", disk++);
+			rotate = 0;
+			if (close(in_fd)) {
+				printk("Error closing the disk.\n");
+				goto noclose_input;
+			}
+			change_floppy("disk #%d", disk);
+			in_fd = open(from, O_RDONLY, 0);
+			if (in_fd < 0)  {
+				printk("Error opening disk.\n");
+				goto noclose_input;
+			}
+			printk("Loading disk #%d... ", disk);
+		}
+		read(in_fd, buf, BLOCK_SIZE);
+		write(out_fd, buf, BLOCK_SIZE);
+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+		if (!(i % 16)) {
+			printk("%c\b", rotator[rotate & 0x3]);
+			rotate++;
+		}
+#endif
+	}
+	printk("done.\n");
+	kfree(buf);
+
+successful_load:
+	res = 1;
+done:
+	close(in_fd);
+noclose_input:
+	close(out_fd);
+out:
+	sys_unlink("/dev/ram");
+	return res;
+}
+
+int __init rd_load_disk(int n)
+{
+	if (rd_prompt)
+		change_floppy("root floppy disk to be loaded into RAM disk");
+	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
+	return rd_load_image("/dev/root");
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+unsigned int real_root_dev;	/* do_proc_dointvec cannot handle kdev_t */
+static int __initdata old_fd, root_fd;
+static int __initdata mount_initrd = 1;
+
+static int __init no_initrd(char *str)
+{
+	mount_initrd = 0;
+	return 1;
+}
+
+__setup("noinitrd", no_initrd);
+
+static int __init do_linuxrc(void * shell)
+{
+	static char *argv[] = { "linuxrc", NULL, };
+	extern char * envp_init[];
+
+	close(old_fd);close(root_fd);
+	close(0);close(1);close(2);
+	setsid();
+	(void) open("/dev/console",O_RDWR,0);
+	(void) dup(0);
+	(void) dup(0);
+	return execve(shell, argv, envp_init);
+}
+
+static void __init handle_initrd(void)
+{
+	int error;
+	int i, pid;
+
+	real_root_dev = ROOT_DEV;
+	create_dev("/dev/root.old", Root_RAM0, NULL);
+	/* mount initrd on rootfs' /root */
+	mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
+	sys_mkdir("/old", 0700);
+	root_fd = open("/", 0, 0);
+	old_fd = open("/old", 0, 0);
+	/* move initrd over / and chdir/chroot in initrd root */
+	sys_chdir("/root");
+	sys_mount(".", "/", NULL, MS_MOVE, NULL);
+	sys_chroot(".");
+	mount_devfs_fs ();
+
+	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
+	if (pid > 0) {
+		while (pid != waitpid(-1, &i, 0))
+			yield();
+	}
+
+	/* move initrd to rootfs' /old */
+	sys_fchdir(old_fd);
+	sys_mount("/", ".", NULL, MS_MOVE, NULL);
+	/* switch root and cwd back to / of rootfs */
+	sys_fchdir(root_fd);
+	sys_chroot(".");
+	close(old_fd);
+	close(root_fd);
+	umount_devfs("/old/dev");
+
+	if (real_root_dev == Root_RAM0) {
+		sys_chdir("/old");
+		return;
+	}
+
+	ROOT_DEV = real_root_dev;
+	mount_root();
+
+	printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
+	error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
+	if (!error)
+		printk("okay\n");
+	else {
+		int fd = open("/dev/root.old", O_RDWR, 0);
+		printk("failed\n");
+		printk(KERN_NOTICE "Unmounting old root\n");
+		sys_umount("/old", MNT_DETACH);
+		printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
+		if (fd < 0) {
+			error = fd;
+		} else {
+			error = sys_ioctl(fd, BLKFLSBUF, 0);
+			close(fd);
+		}
+		printk(!error ? "okay\n" : "failed\n");
+	}
+}
+
+int __init initrd_load(void)
+{
+	if (!mount_initrd)
+		return 0;
+
+	create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
+	create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
+	/* Load the initrd data into /dev/ram0. Execute it as initrd unless
+	 * /dev/ram0 is supposed to be our actual root device, in
+	 * that case the ram disk is just set up here, and gets
+	 * mounted in the normal path. */
+	if (rd_load_image("/dev/initrd") && ROOT_DEV != Root_RAM0) {
+		handle_initrd();
+		return 1;
+	}
+	return 0;
+}
+#endif
+
+#ifdef BUILD_CRAMDISK
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+
+#ifndef memzero
+#define memzero(s, n)     memset ((s), 0, (n))
+#endif
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define INBUFSIZ 4096
+#define WSIZE 0x8000    /* window size--must be a power of two, and */
+			/*  at least 32K for zip's deflate method */
+
+static uch *inbuf;
+static uch *window;
+
+static unsigned insize;  /* valid bytes in inbuf */
+static unsigned inptr;   /* index of next byte to be processed in inbuf */
+static unsigned outcnt;  /* bytes in output buffer */
+static int exit_code;
+static int unzip_error;
+static long bytes_out;
+static int crd_infd, crd_outfd;
+
+#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
+		
+/* Diagnostic functions (stubbed out) */
+#define Assert(cond,msg)
+#define Trace(x)
+#define Tracev(x)
+#define Tracevv(x)
+#define Tracec(c,x)
+#define Tracecv(c,x)
+
+#define STATIC static
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+#include "../lib/inflate.c"
+
+static void __init *malloc(int size)
+{
+	return kmalloc(size, GFP_KERNEL);
+}
+
+static void __init free(void *where)
+{
+	kfree(where);
+}
+
+static void __init gzip_mark(void **ptr)
+{
+}
+
+static void __init gzip_release(void **ptr)
+{
+}
+
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ * Returning -1 does not guarantee that gunzip() will ever return.
+ */
+static int __init fill_inbuf(void)
+{
+	if (exit_code) return -1;
+	
+	insize = read(crd_infd, inbuf, INBUFSIZ);
+	if (insize == 0) {
+		error("RAMDISK: ran out of compressed data\n");
+		return -1;
+	}
+
+	inptr = 1;
+
+	return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void __init flush_window(void)
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n, written;
+    uch *in, ch;
+    
+    written = write(crd_outfd, window, outcnt);
+    if (written != outcnt && unzip_error == 0) {
+	printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
+	       written, outcnt, bytes_out);
+	unzip_error = 1;
+    }
+    in = window;
+    for (n = 0; n < outcnt; n++) {
+	    ch = *in++;
+	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void __init error(char *x)
+{
+	printk(KERN_ERR "%s", x);
+	exit_code = 1;
+	unzip_error = 1;
+}
+
+static int __init crd_load(int in_fd, int out_fd)
+{
+	int result;
+
+	insize = 0;		/* valid bytes in inbuf */
+	inptr = 0;		/* index of next byte to be processed in inbuf */
+	outcnt = 0;		/* bytes in output buffer */
+	exit_code = 0;
+	bytes_out = 0;
+	crc = (ulg)0xffffffffL; /* shift register contents */
+
+	crd_infd = in_fd;
+	crd_outfd = out_fd;
+	inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
+	if (inbuf == 0) {
+		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
+		return -1;
+	}
+	window = kmalloc(WSIZE, GFP_KERNEL);
+	if (window == 0) {
+		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
+		kfree(inbuf);
+		return -1;
+	}
+	makecrc();
+	result = gunzip();
+	if (unzip_error)
+		result = 1;
+	kfree(inbuf);
+	kfree(window);
+	return result;
+}
+
+#endif  /* BUILD_CRAMDISK */
diff -urN linux-2.5.63-bk5/kernel/cpufreq.c linux-2.5.63-bk6/kernel/cpufreq.c
--- linux-2.5.63-bk5/kernel/cpufreq.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/kernel/cpufreq.c	Mon Mar 31 12:19:34 2003
@@ -23,11 +23,6 @@
 #include <linux/device.h>
 #include <linux/slab.h>
 
-#ifdef CONFIG_CPU_FREQ_24_API
-#include <linux/proc_fs.h>
-#include <linux/sysctl.h>
-#endif
-
 /**
  * The "cpufreq driver" - the arch- or hardware-dependend low
  * level driver of CPUFreq support, and its locking mutex. 
@@ -51,15 +46,6 @@
 static DECLARE_MUTEX            (cpufreq_notifier_sem);
 
 
-#ifdef CONFIG_CPU_FREQ_24_API
-/**
- * A few values needed by the 2.4.-compatible API
- */
-static unsigned int     cpu_max_freq[NR_CPUS];
-static unsigned int     cpu_min_freq[NR_CPUS];
-static unsigned int     cpu_cur_freq[NR_CPUS];
-#endif
-
 LIST_HEAD(cpufreq_governor_list);
 
 static int cpufreq_governor(unsigned int cpu, unsigned int event);
@@ -359,13 +345,6 @@
 		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;
@@ -425,398 +404,6 @@
 
 
 /*********************************************************************
- *                      /proc/sys/cpu/ INTERFACE                     *
- *********************************************************************/
-
-#ifdef CONFIG_CPU_FREQ_24_API
-/** 
- * cpufreq_set - set the CPU frequency
- * @freq: target frequency in kHz
- * @cpu: CPU for which the frequency is to be set
- *
- * Sets the CPU frequency to freq.
- */
-int cpufreq_set(unsigned int freq, unsigned int cpu)
-{
-	struct cpufreq_policy policy;
-	down(&cpufreq_driver_sem);
-	if (!cpufreq_driver || !freq || (cpu > NR_CPUS)) {
-		up(&cpufreq_driver_sem);
-		return -EINVAL;
-	}
-
-	policy.min = freq;
-	policy.max = freq;
-	policy.policy = CPUFREQ_POLICY_POWERSAVE;
-	policy.cpu = cpu;
-	
-	up(&cpufreq_driver_sem);
-
-	if (policy.cpu == CPUFREQ_ALL_CPUS)
-	{
-		unsigned int i;
-		unsigned int ret = 0;
-		for (i=0; i<NR_CPUS; i++) 
-		{
-			policy.cpu = i;
-			if (cpu_online(i))
-				ret |= cpufreq_set_policy(&policy);
-		}
-		return ret;
-	} 
-	else
-		return cpufreq_set_policy(&policy);
-}
-EXPORT_SYMBOL_GPL(cpufreq_set);
-
-
-/** 
- * cpufreq_setmax - set the CPU to the maximum frequency
- * @cpu - affected cpu;
- *
- * Sets the CPU frequency to the maximum frequency supported by
- * this CPU.
- */
-int cpufreq_setmax(unsigned int cpu)
-{
-	if (!cpu_online(cpu) && (cpu != CPUFREQ_ALL_CPUS))
-		return -EINVAL;
-	return cpufreq_set(cpu_max_freq[cpu], cpu);
-}
-EXPORT_SYMBOL_GPL(cpufreq_setmax);
-
-
-/** 
- * cpufreq_get - get the current CPU frequency (in kHz)
- * @cpu: CPU number - currently without effect.
- *
- * Get the CPU current (static) CPU frequency
- */
-unsigned int cpufreq_get(unsigned int cpu)
-{
-	if (!cpu_online(cpu))
-		return -EINVAL;
-	return cpu_cur_freq[cpu];
-}
-EXPORT_SYMBOL(cpufreq_get);
-
-
-#ifdef CONFIG_SYSCTL
-
-
-/*********************** cpufreq_sysctl interface ********************/
-static int
-cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
-		void *buffer, size_t *lenp)
-{
-	char buf[16], *p;
-	int cpu = (int) ctl->extra1;
-	int len, left = *lenp;
-
-	if (!left || (filp->f_pos && !write) || !cpu_online(cpu)) {
-		*lenp = 0;
-		return 0;
-	}
-
-	if (write) {
-		unsigned int freq;
-
-		len = left;
-		if (left > sizeof(buf))
-			left = sizeof(buf);
-		if (copy_from_user(buf, buffer, left))
-			return -EFAULT;
-		buf[sizeof(buf) - 1] = '\0';
-
-		freq = simple_strtoul(buf, &p, 0);
-		cpufreq_set(freq, cpu);
-	} else {
-		len = sprintf(buf, "%d\n", cpufreq_get(cpu));
-		if (len > left)
-			len = left;
-		if (copy_to_user(buffer, buf, len))
-			return -EFAULT;
-	}
-
-	*lenp = len;
-	filp->f_pos += len;
-	return 0;
-}
-
-static int
-cpufreq_sysctl(ctl_table *table, int *name, int nlen,
-	       void *oldval, size_t *oldlenp,
-	       void *newval, size_t newlen, void **context)
-{
-	int cpu = (int) table->extra1;
-
-	if (!cpu_online(cpu))
-		return -EINVAL;
-
-	if (oldval && oldlenp) {
-		size_t oldlen;
-
-		if (get_user(oldlen, oldlenp))
-			return -EFAULT;
-
-		if (oldlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (put_user(cpufreq_get(cpu), (unsigned int *)oldval) ||
-		    put_user(sizeof(unsigned int), oldlenp))
-			return -EFAULT;
-	}
-	if (newval && newlen) {
-		unsigned int freq;
-
-		if (newlen != sizeof(unsigned int))
-			return -EINVAL;
-
-		if (get_user(freq, (unsigned int *)newval))
-			return -EFAULT;
-
-		cpufreq_set(freq, cpu);
-	}
-	return 1;
-}
-
-/* ctl_table ctl_cpu_vars_{0,1,...,(NR_CPUS-1)} */
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-        CTL_TABLE_CPU_VARS(0);
-#if NR_CPUS > 1
-	CTL_TABLE_CPU_VARS(1);
-#endif
-#if NR_CPUS > 2
-	CTL_TABLE_CPU_VARS(2);
-#endif
-#if NR_CPUS > 3
-	CTL_TABLE_CPU_VARS(3);
-#endif
-#if NR_CPUS > 4
-	CTL_TABLE_CPU_VARS(4);
-#endif
-#if NR_CPUS > 5
-	CTL_TABLE_CPU_VARS(5);
-#endif
-#if NR_CPUS > 6
-	CTL_TABLE_CPU_VARS(6);
-#endif
-#if NR_CPUS > 7
-	CTL_TABLE_CPU_VARS(7);
-#endif
-#if NR_CPUS > 8
-	CTL_TABLE_CPU_VARS(8);
-#endif
-#if NR_CPUS > 9
-	CTL_TABLE_CPU_VARS(9);
-#endif
-#if NR_CPUS > 10
-	CTL_TABLE_CPU_VARS(10);
-#endif
-#if NR_CPUS > 11
-	CTL_TABLE_CPU_VARS(11);
-#endif
-#if NR_CPUS > 12
-	CTL_TABLE_CPU_VARS(12);
-#endif
-#if NR_CPUS > 13
-	CTL_TABLE_CPU_VARS(13);
-#endif
-#if NR_CPUS > 14
-	CTL_TABLE_CPU_VARS(14);
-#endif
-#if NR_CPUS > 15
-	CTL_TABLE_CPU_VARS(15);
-#endif
-#if NR_CPUS > 16
-	CTL_TABLE_CPU_VARS(16);
-#endif
-#if NR_CPUS > 17
-	CTL_TABLE_CPU_VARS(17);
-#endif
-#if NR_CPUS > 18
-	CTL_TABLE_CPU_VARS(18);
-#endif
-#if NR_CPUS > 19
-	CTL_TABLE_CPU_VARS(19);
-#endif
-#if NR_CPUS > 20
-	CTL_TABLE_CPU_VARS(20);
-#endif
-#if NR_CPUS > 21
-	CTL_TABLE_CPU_VARS(21);
-#endif
-#if NR_CPUS > 22
-	CTL_TABLE_CPU_VARS(22);
-#endif
-#if NR_CPUS > 23
-	CTL_TABLE_CPU_VARS(23);
-#endif
-#if NR_CPUS > 24
-	CTL_TABLE_CPU_VARS(24);
-#endif
-#if NR_CPUS > 25
-	CTL_TABLE_CPU_VARS(25);
-#endif
-#if NR_CPUS > 26
-	CTL_TABLE_CPU_VARS(26);
-#endif
-#if NR_CPUS > 27
-	CTL_TABLE_CPU_VARS(27);
-#endif
-#if NR_CPUS > 28
-	CTL_TABLE_CPU_VARS(28);
-#endif
-#if NR_CPUS > 29
-	CTL_TABLE_CPU_VARS(29);
-#endif
-#if NR_CPUS > 30
-	CTL_TABLE_CPU_VARS(30);
-#endif
-#if NR_CPUS > 31
-	CTL_TABLE_CPU_VARS(31);
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-
-/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-static ctl_table ctl_cpu_table[NR_CPUS + 1] = {
-	CPU_ENUM(0),
-#if NR_CPUS > 1
-	CPU_ENUM(1),
-#endif
-#if NR_CPUS > 2
-	CPU_ENUM(2),
-#endif
-#if NR_CPUS > 3
-	CPU_ENUM(3),
-#endif
-#if NR_CPUS > 4
-	CPU_ENUM(4),
-#endif
-#if NR_CPUS > 5
-	CPU_ENUM(5),
-#endif
-#if NR_CPUS > 6
-	CPU_ENUM(6),
-#endif
-#if NR_CPUS > 7
-	CPU_ENUM(7),
-#endif
-#if NR_CPUS > 8
-	CPU_ENUM(8),
-#endif
-#if NR_CPUS > 9
-	CPU_ENUM(9),
-#endif
-#if NR_CPUS > 10
-	CPU_ENUM(10),
-#endif
-#if NR_CPUS > 11
-	CPU_ENUM(11),
-#endif
-#if NR_CPUS > 12
-	CPU_ENUM(12),
-#endif
-#if NR_CPUS > 13
-	CPU_ENUM(13),
-#endif
-#if NR_CPUS > 14
-	CPU_ENUM(14),
-#endif
-#if NR_CPUS > 15
-	CPU_ENUM(15),
-#endif
-#if NR_CPUS > 16
-	CPU_ENUM(16),
-#endif
-#if NR_CPUS > 17
-	CPU_ENUM(17),
-#endif
-#if NR_CPUS > 18
-	CPU_ENUM(18),
-#endif
-#if NR_CPUS > 19
-	CPU_ENUM(19),
-#endif
-#if NR_CPUS > 20
-	CPU_ENUM(20),
-#endif
-#if NR_CPUS > 21
-	CPU_ENUM(21),
-#endif
-#if NR_CPUS > 22
-	CPU_ENUM(22),
-#endif
-#if NR_CPUS > 23
-	CPU_ENUM(23),
-#endif
-#if NR_CPUS > 24
-	CPU_ENUM(24),
-#endif
-#if NR_CPUS > 25
-	CPU_ENUM(25),
-#endif
-#if NR_CPUS > 26
-	CPU_ENUM(26),
-#endif
-#if NR_CPUS > 27
-	CPU_ENUM(27),
-#endif
-#if NR_CPUS > 28
-	CPU_ENUM(28),
-#endif
-#if NR_CPUS > 29
-	CPU_ENUM(29),
-#endif
-#if NR_CPUS > 30
-	CPU_ENUM(30),
-#endif
-#if NR_CPUS > 31
-	CPU_ENUM(31),
-#endif
-#if NR_CPUS > 32
-#error please extend CPU enumeration
-#endif
-	{
-		.ctl_name	= 0,
-	}
-};
-
-static ctl_table ctl_cpu[2] = {
-	{
-		.ctl_name	= CTL_CPU,
-		.procname	= "cpu",
-		.mode		= 0555,
-		.child		= ctl_cpu_table,
-	},
-	{
-		.ctl_name	= 0,
-	}
-};
-
-struct ctl_table_header *cpufreq_sysctl_table;
-
-static inline void cpufreq_sysctl_init(void)
-{
-	cpufreq_sysctl_table = register_sysctl_table(ctl_cpu, 0);
-}
-
-static inline void cpufreq_sysctl_exit(void)
-{
-	unregister_sysctl_table(cpufreq_sysctl_table);
-}
-
-#else
-#define cpufreq_sysctl_init() do {} while(0)
-#define cpufreq_sysctl_exit() do {} while(0)
-#endif /* CONFIG_SYSCTL */
-#endif /* CONFIG_CPU_FREQ_24_API */
-
-
-
-/*********************************************************************
  *                     NOTIFIER LISTS INTERFACE                      *
  *********************************************************************/
 
@@ -1104,10 +691,6 @@
 	cpufreq_driver->policy[policy->cpu].min    = policy->min;
 	cpufreq_driver->policy[policy->cpu].max    = policy->max;
 
-#ifdef CONFIG_CPU_FREQ_24_API
-	cpu_cur_freq[policy->cpu] = policy->max;
-#endif
-
 	if (cpufreq_driver->setpolicy) {
 		cpufreq_driver->policy[policy->cpu].policy = policy->policy;
 		ret = cpufreq_driver->setpolicy(policy);
@@ -1189,9 +772,7 @@
 	case CPUFREQ_POSTCHANGE:
 		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
 		notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
-#ifdef CONFIG_CPU_FREQ_24_API
-		cpu_cur_freq[freqs->cpu] = freqs->new;
-#endif
+		cpufreq_driver->policy[freqs->cpu].cur = freqs->new;
 		break;
 	}
 	up(&cpufreq_notifier_sem);
@@ -1245,10 +826,6 @@
 	
 	up(&cpufreq_driver_sem);
 
-#ifdef CONFIG_CPU_FREQ_24_API
-	cpufreq_sysctl_init();
-#endif
-
 	ret = interface_register(&cpufreq_interface);
 
 	return ret;
@@ -1274,10 +851,6 @@
 		return -EINVAL;
 	}
 
-#ifdef CONFIG_CPU_FREQ_24_API
-	cpufreq_sysctl_exit();
-#endif
-
 	/* remove this workaround as soon as interface_add_data works */
 	{
 		unsigned int i;
diff -urN linux-2.5.63-bk5/kernel/ksyms.c linux-2.5.63-bk6/kernel/ksyms.c
--- linux-2.5.63-bk5/kernel/ksyms.c	Mon Feb 24 11:05:05 2003
+++ linux-2.5.63-bk6/kernel/ksyms.c	Mon Mar 31 12:19:34 2003
@@ -119,6 +119,7 @@
 EXPORT_SYMBOL(get_unmapped_area);
 EXPORT_SYMBOL(init_mm);
 EXPORT_SYMBOL(blk_queue_bounce);
+EXPORT_SYMBOL(blk_congestion_wait);
 #ifdef CONFIG_HIGHMEM
 EXPORT_SYMBOL(kmap_high);
 EXPORT_SYMBOL(kunmap_high);
diff -urN linux-2.5.63-bk5/mm/mmap.c linux-2.5.63-bk6/mm/mmap.c
--- linux-2.5.63-bk5/mm/mmap.c	Mon Feb 24 11:05:35 2003
+++ linux-2.5.63-bk6/mm/mmap.c	Mon Mar 31 12:19:34 2003
@@ -797,17 +797,27 @@
 		unsigned long pgoff, unsigned long flags)
 {
 	if (flags & MAP_FIXED) {
+		unsigned long ret;
+
 		if (addr > TASK_SIZE - len)
 			return -ENOMEM;
 		if (addr & ~PAGE_MASK)
 			return -EINVAL;
-		if (file && is_file_hugepages(file)) {
-			unsigned long ret;
-
+		if (file && is_file_hugepages(file))  {
+			/*
+			 * Make sure that addr and length are properly aligned.
+			 */
 			ret = is_aligned_hugepage_range(addr, len);
-			if (ret)
-				return ret;
+		} else {
+			/*
+			 * Ensure that a normal request is not falling in a
+			 * reserved hugepage range.  For some archs like IA-64,
+			 * there is a separate region for hugepages.
+			 */
+			ret = check_valid_hugepage_range(addr, len);
 		}
+		if (ret)
+			return ret;
 		return addr;
 	}
 
diff -urN linux-2.5.63-bk5/mm/slab.c linux-2.5.63-bk6/mm/slab.c
--- linux-2.5.63-bk5/mm/slab.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/mm/slab.c	Mon Mar 31 12:19:34 2003
@@ -1116,12 +1116,16 @@
 static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg)
 {
 	check_irq_on();
+	preempt_disable();
+
 	local_irq_disable();
 	func(arg);
 	local_irq_enable();
 
 	if (smp_call_function(func, arg, 1, 1))
 		BUG();
+
+	preempt_enable();
 }
 
 static void free_block (kmem_cache_t* cachep, void** objpp, int len);
diff -urN linux-2.5.63-bk5/mm/swap.c linux-2.5.63-bk6/mm/swap.c
--- linux-2.5.63-bk5/mm/swap.c	Mon Mar 31 12:19:31 2003
+++ linux-2.5.63-bk6/mm/swap.c	Mon Mar 31 12:19:34 2003
@@ -363,5 +363,4 @@
 	 * Right now other parts of the system means that we
 	 * _really_ don't want to cluster much more
 	 */
-	init_MUTEX(&swapper_space.i_shared_sem);
 }
diff -urN linux-2.5.63-bk5/mm/swap_state.c linux-2.5.63-bk6/mm/swap_state.c
--- linux-2.5.63-bk5/mm/swap_state.c	Mon Feb 24 11:05:30 2003
+++ linux-2.5.63-bk6/mm/swap_state.c	Mon Mar 31 12:19:34 2003
@@ -33,19 +33,20 @@
 extern struct address_space_operations swap_aops;
 
 struct address_space swapper_space = {
-	.page_tree		= RADIX_TREE_INIT(GFP_ATOMIC),
-	.page_lock		= RW_LOCK_UNLOCKED,
-	.clean_pages		= LIST_HEAD_INIT(swapper_space.clean_pages),
-	.dirty_pages		= LIST_HEAD_INIT(swapper_space.dirty_pages),
-	.io_pages		= LIST_HEAD_INIT(swapper_space.io_pages),
-	.locked_pages		= LIST_HEAD_INIT(swapper_space.locked_pages),
-	.host			= &swapper_inode,
-	.a_ops			= &swap_aops,
-	.backing_dev_info	= &swap_backing_dev_info,
-	.i_mmap			= LIST_HEAD_INIT(swapper_space.i_mmap),
-	.i_mmap_shared		= LIST_HEAD_INIT(swapper_space.i_mmap_shared),
-	.private_lock		= SPIN_LOCK_UNLOCKED,
-	.private_list		= LIST_HEAD_INIT(swapper_space.private_list),
+	.page_tree	= RADIX_TREE_INIT(GFP_ATOMIC),
+	.page_lock	= RW_LOCK_UNLOCKED,
+	.clean_pages	= LIST_HEAD_INIT(swapper_space.clean_pages),
+	.dirty_pages	= LIST_HEAD_INIT(swapper_space.dirty_pages),
+	.io_pages	= LIST_HEAD_INIT(swapper_space.io_pages),
+	.locked_pages	= LIST_HEAD_INIT(swapper_space.locked_pages),
+	.host		= &swapper_inode,
+	.a_ops		= &swap_aops,
+	.backing_dev_info = &swap_backing_dev_info,
+	.i_mmap		= LIST_HEAD_INIT(swapper_space.i_mmap),
+	.i_mmap_shared	= LIST_HEAD_INIT(swapper_space.i_mmap_shared),
+	.i_shared_sem	= __MUTEX_INITIALIZER(swapper_space.i_shared_sem),
+	.private_lock	= SPIN_LOCK_UNLOCKED,
+	.private_list	= LIST_HEAD_INIT(swapper_space.private_list),
 };
 
 #define INC_CACHE_INFO(x)	do { swap_cache_info.x++; } while (0)
diff -urN linux-2.5.63-bk5/scripts/Makefile linux-2.5.63-bk6/scripts/Makefile
--- linux-2.5.63-bk5/scripts/Makefile	Mon Feb 24 11:05:33 2003
+++ linux-2.5.63-bk6/scripts/Makefile	Mon Mar 31 12:19:34 2003
@@ -5,7 +5,7 @@
 # fix-dep: 	 Used to generate dependency information during build process
 # split-include: Divide all config symbols up in a number of files in
 #                include/config/...
-# docproc: 	 Preprocess .tmpl file in order to generate .sgml documentation
+# docproc: 	 Preprocess .tmpl file in order to generate .sgml docs
 # conmakehash:	 Create arrays for initializing the kernel console tables
 
 host-progs    := fixdep split-include conmakehash docproc kallsyms modpost \
@@ -14,20 +14,20 @@
 
 modpost-objs  := modpost.o file2alias.o
 
-clean-files := elfconfig.h
+subdir-$(CONFIG_MODVERSIONS)	+= genksyms
 
 # Let clean descend into subdirs
-subdir-	:= lxdialog kconfig
+subdir-	+= lxdialog kconfig
 
 # fixdep is needed to compile other host programs
-$(addprefix $(obj)/,$(filter-out fixdep,$(build-targets))): $(obj)/fixdep
+$(addprefix $(obj)/,$(filter-out fixdep,$(build-targets)) $(subdir-y)): $(obj)/fixdep
 
 # dependencies on generated files need to be listed explicitly
 
 $(obj)/modpost.o $(obj)/file2alias.o: $(obj)/elfconfig.h
 
 quiet_cmd_elfconfig = MKELF   $@
-      cmd_elfconfig = $(obj)/mk_elfconfig < $< > $@
+      cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@
 
 $(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
 	$(call if_changed,elfconfig)
diff -urN linux-2.5.63-bk5/scripts/Makefile.build linux-2.5.63-bk6/scripts/Makefile.build
--- linux-2.5.63-bk5/scripts/Makefile.build	Mon Feb 24 11:05:40 2003
+++ linux-2.5.63-bk6/scripts/Makefile.build	Mon Mar 31 12:19:34 2003
@@ -90,8 +90,7 @@
 		mv $(@D)/.tmp_$(@F) $@;					      \
 	else								      \
 		$(CPP) -D__GENKSYMS__ $(c_flags) $<			      \
-		| $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)	      \
-		| sed -n 's/\#define __ver_\([^ 	]*\)[ 	]*\([^ 	]*\)/__crc_\1 = 0x\2 ;/gp' \
+		| $(GENKSYMS)						      \
 		> $(@D)/.tmp_$(@F:.o=.ver);				      \
 									      \
 		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		      \
diff -urN linux-2.5.63-bk5/scripts/Makefile.clean linux-2.5.63-bk6/scripts/Makefile.clean
--- linux-2.5.63-bk5/scripts/Makefile.clean	Mon Feb 24 11:05:04 2003
+++ linux-2.5.63-bk6/scripts/Makefile.clean	Mon Mar 31 12:19:34 2003
@@ -35,7 +35,7 @@
 
 # ==========================================================================
 
-__clean-files := $(wildcard $(EXTRA_TARGETS) $(host-progs) $(clean-files))
+__clean-files := $(wildcard $(EXTRA_TARGETS) $(host-progs) $(clean-files) $(targets))
 
 quiet_cmd_clean = CLEAN   $(obj)
       cmd_clean = rm -f $(__clean-files); $(clean-rule)
diff -urN linux-2.5.63-bk5/scripts/Makefile.modpost linux-2.5.63-bk6/scripts/Makefile.modpost
--- linux-2.5.63-bk5/scripts/Makefile.modpost	Mon Feb 24 11:05:33 2003
+++ linux-2.5.63-bk6/scripts/Makefile.modpost	Mon Mar 31 12:19:34 2003
@@ -37,10 +37,7 @@
 quiet_cmd_cc_o_c = CC      $@
       cmd_cc_o_c = $(CC) $(CFLAGS) $(CFLAGS_MODULE) -c -o $@ $<
 
-#	We have a fake dependency on compile.h to make sure that we
-#	notice if the compiler version changes under us.
-
-$(modules:.ko=.mod.o): %.mod.o: %.mod.c include/linux/compile.h FORCE
+$(modules:.ko=.mod.o): %.mod.o: %.mod.c
 	$(call if_changed,cc_o_c)
 
 targets += $(modules:.ko=.mod.o)
diff -urN linux-2.5.63-bk5/scripts/genksyms/Makefile linux-2.5.63-bk6/scripts/genksyms/Makefile
--- linux-2.5.63-bk5/scripts/genksyms/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/Makefile	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,47 @@
+
+host-progs	:= genksyms
+build-targets	:= $(host-progs)
+
+genksyms-objs	:= genksyms.o parse.o lex.o
+
+HOSTCFLAGS_parse.o := -Wno-uninitialized
+
+# dependencies on generated files need to be listed explicitly
+
+$(obj)/lex.o: $(obj)/parse.h $(obj)/keywords.c
+
+
+ifdef GENERATE_PARSER
+
+# gperf
+
+quiet_cmd_keywords.c = GPERF   $@
+      cmd_keywords.c = gperf -L ANSI-C -a -C -E -g -H is_reserved_hash	\
+		       -k 1,3,$$ -N is_reserved_word -p -t $< > $@
+
+$(obj)/keywords.c: $(obj)/keywords.gperf FORCE
+	$(call if_changed,keywords.c)
+
+# flex
+
+quiet_cmd_lex.c = FLEX    $@
+      cmd_lex.c = flex -o$@ -d $(filter-out FORCE,$^)
+
+$(obj)/lex.c: $(obj)/lex.l $(obj)/parse.h FORCE
+	$(call if_changed,lex.c)
+
+# bison
+
+quiet_cmd_parse.c = BISON   $@
+      cmd_parse.c = bison -o$@ -dtv $(filter-out FORCE,$^)
+
+$(obj)/parse.c: $(obj)/parse.y FORCE
+	$(call if_changed,parse.c)
+
+$(obj)/parse.h: $(obj)/parse.c ;
+
+clean-files	+= parse.output
+
+endif
+
+targets += $(obj)/keywords.c $(obj)/lex.c $(obj)/parse.c $(obj)/parse.h
diff -urN linux-2.5.63-bk5/scripts/genksyms/genksyms.c linux-2.5.63-bk6/scripts/genksyms/genksyms.c
--- linux-2.5.63-bk5/scripts/genksyms/genksyms.c	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/genksyms.c	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,576 @@
+/* Generate kernel symbol version hashes.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   This file was part of the Linux modutils 2.4.22: moved back into the
+   kernel sources by Rusty Russell/Kai Germaschewski.
+
+   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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <getopt.h>
+
+#include "genksyms.h"
+
+/*----------------------------------------------------------------------*/
+
+#define HASH_BUCKETS  4096
+
+static struct symbol *symtab[HASH_BUCKETS];
+FILE *debugfile;
+
+int cur_line = 1;
+char *cur_filename, *output_directory;
+
+int flag_debug, flag_dump_defs, flag_warnings;
+
+static int errors;
+static int nsyms;
+
+static struct symbol *expansion_trail;
+
+static const char * const symbol_type_name[] = {
+  "normal", "typedef", "enum", "struct", "union"
+};
+
+/*----------------------------------------------------------------------*/
+
+static const unsigned int crctab32[] =
+{
+  0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
+  0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
+  0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
+  0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
+  0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
+  0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
+  0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
+  0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
+  0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
+  0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
+  0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
+  0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
+  0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
+  0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
+  0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
+  0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
+  0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
+  0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
+  0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
+  0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
+  0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
+  0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
+  0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
+  0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
+  0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
+  0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
+  0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
+  0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
+  0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
+  0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
+  0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
+  0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
+  0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
+  0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
+  0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
+  0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
+  0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
+  0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
+  0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
+  0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
+  0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
+  0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
+  0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
+  0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
+  0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
+  0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
+  0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
+  0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
+  0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
+  0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
+  0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
+  0x2d02ef8dU
+};
+
+static inline unsigned long
+partial_crc32_one(unsigned char c, unsigned long crc)
+{
+  return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
+}
+
+static inline unsigned long
+partial_crc32(const char *s, unsigned long crc)
+{
+  while (*s)
+    crc = partial_crc32_one(*s++, crc);
+  return crc;
+}
+
+static inline unsigned long
+crc32(const char *s)
+{
+  return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
+}
+
+
+/*----------------------------------------------------------------------*/
+
+static inline enum symbol_type
+map_to_ns(enum symbol_type t)
+{
+  if (t == SYM_TYPEDEF)
+    t = SYM_NORMAL;
+  else if (t == SYM_UNION)
+    t = SYM_STRUCT;
+  return t;
+}
+
+struct symbol *
+find_symbol(const char *name, enum symbol_type ns)
+{
+  unsigned long h = crc32(name) % HASH_BUCKETS;
+  struct symbol *sym;
+
+  for (sym = symtab[h]; sym ; sym = sym->hash_next)
+    if (map_to_ns(sym->type) == map_to_ns(ns) && strcmp(name, sym->name) == 0)
+      break;
+
+  return sym;
+}
+
+struct symbol *
+add_symbol(const char *name, enum symbol_type type, struct string_list *defn, int is_extern)
+{
+  unsigned long h = crc32(name) % HASH_BUCKETS;
+  struct symbol *sym;
+
+  for (sym = symtab[h]; sym ; sym = sym->hash_next)
+    if (map_to_ns(sym->type) == map_to_ns(type)
+	&& strcmp(name, sym->name) == 0)
+      {
+	if (!equal_list(sym->defn, defn))
+	  error_with_pos("redefinition of %s", name);
+	return sym;
+      }
+
+  sym = xmalloc(sizeof(*sym));
+  sym->name = name;
+  sym->type = type;
+  sym->defn = defn;
+  sym->expansion_trail = NULL;
+  sym->is_extern = is_extern;
+
+  sym->hash_next = symtab[h];
+  symtab[h] = sym;
+
+  if (flag_debug)
+    {
+      fprintf(debugfile, "Defn for %s %s == <", symbol_type_name[type],  name);
+      if (is_extern)
+        fputs("extern ", debugfile);
+      print_list(debugfile, defn);
+      fputs(">\n", debugfile);
+    }
+
+  ++nsyms;
+  return sym;
+}
+
+
+/*----------------------------------------------------------------------*/
+
+inline void
+free_node(struct string_list *node)
+{
+  free(node->string);
+  free(node);
+}
+
+void
+free_list(struct string_list *s, struct string_list *e)
+{
+  while (s != e)
+    {
+      struct string_list *next = s->next;
+      free_node(s);
+      s = next;
+    }
+}
+
+inline struct string_list *
+copy_node(struct string_list *node)
+{
+  struct string_list *newnode;
+
+  newnode = xmalloc(sizeof(*newnode));
+  newnode->string = xstrdup(node->string);
+  newnode->tag = node->tag;
+
+  return newnode;
+}
+
+struct string_list *
+copy_list(struct string_list *s, struct string_list *e)
+{
+  struct string_list *h, *p;
+
+  if (s == e)
+    return NULL;
+
+  p = h = copy_node(s);
+  while ((s = s->next) != e)
+    p = p->next = copy_node(s);
+  p->next = NULL;
+
+  return h;
+}
+
+int
+equal_list(struct string_list *a, struct string_list *b)
+{
+  while (a && b)
+    {
+      if (a->tag != b->tag || strcmp(a->string, b->string))
+	return 0;
+      a = a->next;
+      b = b->next;
+    }
+
+  return !a && !b;
+}
+
+static inline void
+print_node(FILE *f, struct string_list *list)
+{
+  switch (list->tag)
+    {
+    case SYM_STRUCT:
+      putc('s', f);
+      goto printit;
+    case SYM_UNION:
+      putc('u', f);
+      goto printit;
+    case SYM_ENUM:
+      putc('e', f);
+      goto printit;
+    case SYM_TYPEDEF:
+      putc('t', f);
+      goto printit;
+
+    printit:
+      putc('#', f);
+    case SYM_NORMAL:
+      fputs(list->string, f);
+      break;
+    }
+}
+
+void
+print_list(FILE *f, struct string_list *list)
+{
+  struct string_list **e, **b;
+  struct string_list *tmp, **tmp2;
+  int elem = 1;
+
+  if (list == NULL)
+    {
+      fputs("(nil)", f);
+      return;
+    }
+
+  tmp = list;
+  while((tmp = tmp->next) != NULL)
+	  elem++;
+
+  b = alloca(elem * sizeof(*e));
+  e = b + elem;
+  tmp2 = e - 1;
+
+  (*tmp2--) = list;
+  while((list = list->next) != NULL)
+	  *(tmp2--) = list;
+
+  while (b != e)
+    {
+      print_node(f, *b++);
+      putc(' ', f);
+    }
+}
+
+static unsigned long
+expand_and_crc_list(struct string_list *list, unsigned long crc)
+{
+  struct string_list **e, **b;
+  struct string_list *tmp, **tmp2;
+  int elem = 1;
+
+  if (!list)
+    return crc;
+
+  tmp = list;
+  while((tmp = tmp->next) != NULL)
+	  elem++;
+
+  b = alloca(elem * sizeof(*e));
+  e = b + elem;
+  tmp2 = e - 1;
+
+  *(tmp2--) = list;
+  while ((list = list->next) != NULL)
+    *(tmp2--) = list;
+
+  while (b != e)
+    {
+      struct string_list *cur;
+      struct symbol *subsym;
+
+      cur = *(b++);
+      switch (cur->tag)
+	{
+	case SYM_NORMAL:
+	  if (flag_dump_defs)
+	    fprintf(debugfile, "%s ", cur->string);
+	  crc = partial_crc32(cur->string, crc);
+	  crc = partial_crc32_one(' ', crc);
+	  break;
+
+	case SYM_TYPEDEF:
+	  subsym = find_symbol(cur->string, cur->tag);
+	  if (subsym->expansion_trail)
+	    {
+	      if (flag_dump_defs)
+		fprintf(debugfile, "%s ", cur->string);
+	      crc = partial_crc32(cur->string, crc);
+	      crc = partial_crc32_one(' ', crc);
+	    }
+	  else
+	    {
+	      subsym->expansion_trail = expansion_trail;
+	      expansion_trail = subsym;
+	      crc = expand_and_crc_list(subsym->defn, crc);
+	    }
+	  break;
+
+	case SYM_STRUCT:
+	case SYM_UNION:
+	case SYM_ENUM:
+	  subsym = find_symbol(cur->string, cur->tag);
+	  if (!subsym)
+	    {
+	      struct string_list *n, *t = NULL;
+
+	      error_with_pos("expand undefined %s %s",
+			     symbol_type_name[cur->tag], cur->string);
+
+	      n = xmalloc(sizeof(*n));
+	      n->string = xstrdup(symbol_type_name[cur->tag]);
+	      n->tag = SYM_NORMAL;
+	      n->next = t;
+	      t = n;
+
+	      n = xmalloc(sizeof(*n));
+	      n->string = xstrdup(cur->string);
+	      n->tag = SYM_NORMAL;
+	      n->next = t;
+	      t = n;
+
+	      n = xmalloc(sizeof(*n));
+	      n->string = xstrdup("{ UNKNOWN }");
+	      n->tag = SYM_NORMAL;
+	      n->next = t;
+
+	      subsym = add_symbol(cur->string, cur->tag, n, 0);
+	    }
+	  if (subsym->expansion_trail)
+	    {
+	      if (flag_dump_defs)
+		{
+		  fprintf(debugfile, "%s %s ", symbol_type_name[cur->tag],
+			  cur->string);
+		}
+
+	      crc = partial_crc32(symbol_type_name[cur->tag], crc);
+	      crc = partial_crc32_one(' ', crc);
+	      crc = partial_crc32(cur->string, crc);
+	      crc = partial_crc32_one(' ', crc);
+	    }
+	  else
+	    {
+	      subsym->expansion_trail = expansion_trail;
+	      expansion_trail = subsym;
+	      crc = expand_and_crc_list(subsym->defn, crc);
+	    }
+	  break;
+	}
+    }
+
+  return crc;
+}
+
+void
+export_symbol(const char *name)
+{
+  struct symbol *sym;
+
+  sym = find_symbol(name, SYM_NORMAL);
+  if (!sym)
+    error_with_pos("export undefined symbol %s", name);
+  else
+    {
+      unsigned long crc;
+
+      if (flag_dump_defs)
+	fprintf(debugfile, "Export %s == <", name);
+
+      expansion_trail = (struct symbol *)-1L;
+
+      crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff;
+
+      sym = expansion_trail;
+      while (sym != (struct symbol *)-1L)
+	{
+	  struct symbol *n = sym->expansion_trail;
+	  sym->expansion_trail = 0;
+	  sym = n;
+	}
+
+      if (flag_dump_defs)
+	fputs(">\n", debugfile);
+
+      /* Used as a linker script. */
+      printf("__crc_%s = 0x%08lx ;\n", name, crc);
+    }
+}
+
+/*----------------------------------------------------------------------*/
+
+void
+error(const char *fmt, ...)
+{
+  va_list args;
+
+  if (flag_warnings)
+    {
+      va_start(args, fmt);
+      vfprintf(stderr, fmt, args);
+      va_end(args);
+      putc('\n', stderr);
+
+      errors++;
+    }
+}
+
+void
+error_with_pos(const char *fmt, ...)
+{
+  va_list args;
+
+  if (flag_warnings)
+    {
+      fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
+
+      va_start(args, fmt);
+      vfprintf(stderr, fmt, args);
+      va_end(args);
+      putc('\n', stderr);
+
+      errors++;
+    }
+}
+
+
+void genksyms_usage(void)
+{
+	fputs("Usage:\n"
+	      "genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n"
+	      "\n"
+	      "  -d, --debug           Increment the debug level (repeatable)\n"
+	      "  -D, --dump            Dump expanded symbol defs (for debugging only)\n"
+	      "  -w, --warnings        Enable warnings\n"
+	      "  -q, --quiet           Disable warnings (default)\n"
+	      "  -h, --help            Print this message\n"
+	      "  -V, --version         Print the release version\n"
+	      , stderr);
+}
+
+int
+main(int argc, char **argv)
+{
+  int o;
+
+  struct option long_opts[] = {
+    {"debug", 0, 0, 'd'},
+    {"warnings", 0, 0, 'w'},
+    {"quiet", 0, 0, 'q'},
+    {"dump", 0, 0, 'D'},
+    {"version", 0, 0, 'V'},
+    {"help", 0, 0, 'h'},
+    {0, 0, 0, 0}
+  };
+
+  while ((o = getopt_long(argc, argv, "dwqVDk:p:",
+			  &long_opts[0], NULL)) != EOF)
+    switch (o)
+      {
+      case 'd':
+	flag_debug++;
+	break;
+      case 'w':
+	flag_warnings = 1;
+	break;
+      case 'q':
+	flag_warnings = 0;
+	break;
+      case 'V':
+	fputs("genksyms version 2.5.60\n", stderr);
+	break;
+      case 'D':
+	flag_dump_defs = 1;
+	break;
+      case 'h':
+	genksyms_usage();
+	return 0;
+      default:
+	genksyms_usage();
+	return 1;
+      }
+
+    {
+      extern int yydebug;
+      extern int yy_flex_debug;
+
+      yydebug = (flag_debug > 1);
+      yy_flex_debug = (flag_debug > 2);
+
+      debugfile = stderr;
+      /* setlinebuf(debugfile); */
+    }
+
+  yyparse();
+
+  if (flag_debug)
+    {
+      fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
+	      nsyms, HASH_BUCKETS, (double)nsyms / (double)HASH_BUCKETS);
+    }
+
+  return errors != 0;
+}
diff -urN linux-2.5.63-bk5/scripts/genksyms/genksyms.h linux-2.5.63-bk6/scripts/genksyms/genksyms.h
--- linux-2.5.63-bk5/scripts/genksyms/genksyms.h	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/genksyms.h	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,96 @@
+/* Generate kernel symbol version hashes.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   This file is part of the Linux modutils.
+
+   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.  */
+
+
+#ifndef MODUTILS_GENKSYMS_H
+#define MODUTILS_GENKSYMS_H 1
+
+#include <stdio.h>
+#include <assert.h>
+
+
+enum symbol_type
+{
+  SYM_NORMAL, SYM_TYPEDEF, SYM_ENUM, SYM_STRUCT, SYM_UNION
+};
+
+struct string_list
+{
+  struct string_list *next;
+  enum symbol_type tag;
+  char *string;
+};
+
+struct symbol
+{
+  struct symbol *hash_next;
+  const char *name;
+  enum symbol_type type;
+  struct string_list *defn;
+  struct symbol *expansion_trail;
+  int is_extern;
+};
+
+typedef struct string_list **yystype;
+#define YYSTYPE yystype
+
+extern FILE *outfile, *debugfile;
+
+extern int cur_line;
+extern char *cur_filename, *output_directory;
+
+extern int flag_debug, flag_dump_defs, flag_warnings;
+extern int checksum_version, kernel_version;
+
+extern int want_brace_phrase, want_exp_phrase, discard_phrase_contents;
+extern struct string_list *current_list, *next_list;
+
+
+struct symbol *find_symbol(const char *name, enum symbol_type ns);
+struct symbol *add_symbol(const char *name, enum symbol_type type,
+			   struct string_list *defn, int is_extern);
+void export_symbol(const char *);
+
+struct string_list *reset_list(void);
+void free_list(struct string_list *s, struct string_list *e);
+void free_node(struct string_list *list);
+struct string_list *copy_node(struct string_list *);
+struct string_list *copy_list(struct string_list *s, struct string_list *e);
+int equal_list(struct string_list *a, struct string_list *b);
+void print_list(FILE *, struct string_list *list);
+
+int yylex(void);
+int yyparse(void);
+
+void error_with_pos(const char *, ...);
+
+#define version(a,b,c)  ((a << 16) | (b << 8) | (c))
+
+/*----------------------------------------------------------------------*/
+
+#define MODUTILS_VERSION "<in-kernel>"
+
+#define xmalloc(size) ({ void *__ptr = malloc(size); assert(__ptr || size == 0); __ptr; })
+#define xstrdup(str)  ({ char *__str = strdup(str); assert(__str); __str; })
+
+
+#endif /* genksyms.h */
diff -urN linux-2.5.63-bk5/scripts/genksyms/keywords.c_shipped linux-2.5.63-bk6/scripts/genksyms/keywords.c_shipped
--- linux-2.5.63-bk5/scripts/genksyms/keywords.c_shipped	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/keywords.c_shipped	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,145 @@
+/* ANSI-C code produced by gperf version 2.7.2 */
+/* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf  */
+struct resword { const char *name; int token; };
+/* maximum key range = 109, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+is_reserved_hash (register const char *str, register unsigned int len)
+{
+  static const unsigned char asso_values[] =
+    {
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113,   5,
+      113, 113, 113, 113, 113, 113,   0, 113, 113, 113,
+        0, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113,   0, 113,   0, 113,  20,
+       25,   0,  35,  30, 113,  20, 113, 113,  40,  30,
+       30,   0,   0, 113,   0,  51,   0,  15,   5, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+      113, 113, 113, 113, 113, 113
+    };
+  return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
+}
+
+#ifdef __GNUC__
+__inline
+#endif
+const struct resword *
+is_reserved_word (register const char *str, register unsigned int len)
+{
+  enum
+    {
+      TOTAL_KEYWORDS = 41,
+      MIN_WORD_LENGTH = 3,
+      MAX_WORD_LENGTH = 17,
+      MIN_HASH_VALUE = 4,
+      MAX_HASH_VALUE = 112
+    };
+
+  static const struct resword wordlist[] =
+    {
+      {""}, {""}, {""}, {""},
+      {"auto", AUTO_KEYW},
+      {""}, {""},
+      {"__asm__", ASM_KEYW},
+      {""},
+      {"_restrict", RESTRICT_KEYW},
+      {"__typeof__", TYPEOF_KEYW},
+      {"__attribute", ATTRIBUTE_KEYW},
+      {"__restrict__", RESTRICT_KEYW},
+      {"__attribute__", ATTRIBUTE_KEYW},
+      {""},
+      {"__volatile", VOLATILE_KEYW},
+      {""},
+      {"__volatile__", VOLATILE_KEYW},
+      {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
+      {""}, {""}, {""},
+      {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
+      {"int", INT_KEYW},
+      {"char", CHAR_KEYW},
+      {""}, {""},
+      {"__const", CONST_KEYW},
+      {"__inline", INLINE_KEYW},
+      {"__const__", CONST_KEYW},
+      {"__inline__", INLINE_KEYW},
+      {""}, {""}, {""}, {""},
+      {"__asm", ASM_KEYW},
+      {"extern", EXTERN_KEYW},
+      {""},
+      {"register", REGISTER_KEYW},
+      {""},
+      {"float", FLOAT_KEYW},
+      {"typeof", TYPEOF_KEYW},
+      {"typedef", TYPEDEF_KEYW},
+      {""}, {""},
+      {"_Bool", BOOL_KEYW},
+      {"double", DOUBLE_KEYW},
+      {""}, {""},
+      {"enum", ENUM_KEYW},
+      {""}, {""}, {""},
+      {"volatile", VOLATILE_KEYW},
+      {"void", VOID_KEYW},
+      {"const", CONST_KEYW},
+      {"short", SHORT_KEYW},
+      {"struct", STRUCT_KEYW},
+      {""},
+      {"restrict", RESTRICT_KEYW},
+      {""},
+      {"__signed__", SIGNED_KEYW},
+      {""},
+      {"asm", ASM_KEYW},
+      {""}, {""},
+      {"inline", INLINE_KEYW},
+      {""}, {""}, {""},
+      {"union", UNION_KEYW},
+      {""}, {""}, {""}, {""}, {""}, {""},
+      {"static", STATIC_KEYW},
+      {""}, {""}, {""}, {""}, {""}, {""},
+      {"__signed", SIGNED_KEYW},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""},
+      {"unsigned", UNSIGNED_KEYW},
+      {""}, {""}, {""}, {""},
+      {"long", LONG_KEYW},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {"signed", SIGNED_KEYW}
+    };
+
+  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+    {
+      register int key = is_reserved_hash (str, len);
+
+      if (key <= MAX_HASH_VALUE && key >= 0)
+        {
+          register const char *s = wordlist[key].name;
+
+          if (*str == *s && !strcmp (str + 1, s + 1))
+            return &wordlist[key];
+        }
+    }
+  return 0;
+}
diff -urN linux-2.5.63-bk5/scripts/genksyms/keywords.gperf linux-2.5.63-bk6/scripts/genksyms/keywords.gperf
--- linux-2.5.63-bk5/scripts/genksyms/keywords.gperf	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/keywords.gperf	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,50 @@
+%{
+%}
+struct resword { const char *name; int token; }
+%%
+EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
+EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
+__asm, ASM_KEYW
+__asm__, ASM_KEYW
+__attribute, ATTRIBUTE_KEYW
+__attribute__, ATTRIBUTE_KEYW
+__const, CONST_KEYW
+__const__, CONST_KEYW
+__inline, INLINE_KEYW
+__inline__, INLINE_KEYW
+__signed, SIGNED_KEYW
+__signed__, SIGNED_KEYW
+__volatile, VOLATILE_KEYW
+__volatile__, VOLATILE_KEYW
+# According to rth, c99 defines _Bool, __restrict, __restrict__, restrict.  KAO
+_Bool, BOOL_KEYW
+_restrict, RESTRICT_KEYW
+__restrict__, RESTRICT_KEYW
+restrict, RESTRICT_KEYW
+asm, ASM_KEYW
+# attribute commented out in modutils 2.4.2.  People are using 'attribute' as a
+# field name which breaks the genksyms parser.  It is not a gcc keyword anyway.
+# KAO.
+#   attribute, ATTRIBUTE_KEYW
+auto, AUTO_KEYW
+char, CHAR_KEYW
+const, CONST_KEYW
+double, DOUBLE_KEYW
+enum, ENUM_KEYW
+extern, EXTERN_KEYW
+float, FLOAT_KEYW
+inline, INLINE_KEYW
+int, INT_KEYW
+long, LONG_KEYW
+register, REGISTER_KEYW
+short, SHORT_KEYW
+signed, SIGNED_KEYW
+static, STATIC_KEYW
+struct, STRUCT_KEYW
+typedef, TYPEDEF_KEYW
+union, UNION_KEYW
+unsigned, UNSIGNED_KEYW
+void, VOID_KEYW
+volatile, VOLATILE_KEYW
+typeof, TYPEOF_KEYW
+__typeof__, TYPEOF_KEYW
diff -urN linux-2.5.63-bk5/scripts/genksyms/lex.c_shipped linux-2.5.63-bk6/scripts/genksyms/lex.c_shipped
--- linux-2.5.63-bk5/scripts/genksyms/lex.c_shipped	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/lex.c_shipped	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,2082 @@
+#line 2 "scripts/genksyms/lex.c"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define yywrap() 1
+#define YY_SKIP_YYWRAP
+
+#define FLEX_DEBUG
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+
+#define FLEX_DEBUG
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yyleng = (int) (yy_cp - yy_bp); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 13
+#define YY_END_OF_BUFFER 14
+static yyconst short int yy_accept[76] =
+    {   0,
+        0,    0,    0,    0,   14,   12,    4,    3,   12,   12,
+       12,    7,    7,   12,   12,   12,   12,   12,    9,    9,
+       12,   12,   12,    4,    0,    5,    0,    0,    6,    0,
+        0,    7,    0,    0,    0,    0,    2,    8,   10,   10,
+        9,    0,    0,    9,    9,    0,    9,    0,    0,   11,
+        0,    0,    0,   10,    0,   10,    9,    9,    0,    0,
+        0,    0,    0,    0,    0,   10,   10,    0,    0,    0,
+        0,    0,    0,    1,    0
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        4,    4,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    5,    6,    1,    7,    8,    9,    1,
+        1,    7,   10,    1,   11,   12,    7,   13,   14,   14,
+       14,   14,   14,   14,   14,   15,   15,    1,    1,   16,
+       17,   18,    1,    1,   19,   19,   19,   19,   20,   21,
+       22,   22,   22,   22,   22,   23,   22,   22,   22,   22,
+       22,   22,   22,   22,   24,   22,   22,   25,   22,   22,
+        1,   26,    1,    7,   22,    1,   19,   19,   19,   19,
+
+       20,   21,   22,   22,   22,   22,   22,   27,   22,   22,
+       22,   22,   22,   22,   22,   22,   24,   22,   22,   25,
+       22,   22,    1,   28,    1,    7,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst int yy_meta[29] =
+    {   0,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    3,
+        3,    4,    5,    5,    5,    1,    1,    1,    6,    7,
+        6,    8,    8,    8,    8,    1,    8,    1
+    } ;
+
+static yyconst short int yy_base[88] =
+    {   0,
+        0,  166,   22,  152,  151,  282,   39,  282,   26,   33,
+      138,    0,   39,   43,  124,   39,   36,   48,   52,   55,
+       41,   56,   54,   47,   73,  282,    0,   72,  282,    0,
+      116,    0,   78,   75,  122,  103,  282,  282,  106,    0,
+       97,   73,   76,   91,   65,    0,    0,   84,   81,  282,
+      132,   98,   84,  282,  117,  147,  282,   73,  134,   89,
+      100,  140,  172,  139,  134,  181,  282,  135,  106,  142,
+      168,   88,   52,  282,  282,  208,  216,  220,  228,  236,
+      244,  249,  254,  255,  260,  265,  273
+    } ;
+
+static yyconst short int yy_def[88] =
+    {   0,
+       75,    1,    1,    3,   75,   75,   75,   75,   76,   77,
+       75,   78,   78,   79,   75,   75,   75,   75,   75,   19,
+       75,   75,   75,   75,   76,   75,   80,   77,   75,   81,
+       75,   78,   76,   77,   79,   79,   75,   75,   75,   39,
+       19,   82,   83,   75,   75,   84,   20,   76,   77,   75,
+       79,   51,   85,   75,   75,   75,   75,   84,   79,   51,
+       79,   79,   79,   51,   75,   75,   75,   86,   79,   63,
+       86,   87,   87,   75,    0,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75
+    } ;
+
+static yyconst short int yy_nxt[311] =
+    {   0,
+        6,    7,    8,    7,    9,    6,    6,    6,   10,    6,
+        6,   11,    6,    6,    6,    6,    6,    6,   12,   12,
+       12,   12,   13,   12,   12,    6,   12,    6,   15,   16,
+       26,   15,   17,   18,   19,   20,   20,   21,   15,   22,
+       24,   29,   24,   33,   36,   37,   38,   34,   24,   23,
+       24,   27,   38,   38,   74,   38,   38,   38,   30,   31,
+       39,   39,   39,   40,   41,   41,   42,   47,   47,   47,
+       38,   43,   38,   38,   44,   45,   46,   26,   44,   75,
+       29,   38,   26,   29,   40,   55,   55,   57,   26,   29,
+       74,   57,   43,   65,   65,   44,   45,   30,   27,   44,
+
+       30,   59,   37,   27,   36,   37,   30,   59,   37,   27,
+       64,   64,   64,   35,   57,   51,   52,   52,   39,   39,
+       39,   75,   35,   69,   37,   53,   54,   50,   54,   56,
+       56,   56,   54,   59,   37,   59,   37,   37,   68,   35,
+       38,   59,   37,   59,   60,   60,   66,   66,   66,   31,
+       75,   64,   64,   64,   61,   62,   63,   14,   61,   56,
+       56,   56,   69,   35,   61,   62,   69,   67,   61,   67,
+       37,   14,   72,   67,   37,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   70,   70,   70,   75,   75,   75,
+       70,   70,   70,   66,   66,   66,   75,   75,   75,   75,
+
+       75,   54,   75,   54,   75,   75,   75,   54,   25,   25,
+       25,   25,   25,   25,   25,   25,   28,   28,   28,   28,
+       28,   28,   28,   28,   32,   32,   32,   32,   35,   35,
+       35,   35,   35,   35,   35,   35,   48,   75,   48,   48,
+       48,   48,   48,   48,   49,   75,   49,   49,   49,   49,
+       49,   49,   42,   42,   75,   42,   56,   75,   56,   58,
+       58,   58,   66,   75,   66,   71,   71,   71,   71,   71,
+       71,   71,   71,   73,   73,   73,   73,   73,   73,   73,
+       73,    5,   75,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75
+    } ;
+
+static yyconst short int yy_chk[311] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    3,    3,
+        9,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        7,   10,    7,   13,   14,   14,   16,   13,   24,    3,
+       24,    9,   17,   17,   73,   16,   21,   21,   10,   18,
+       18,   18,   18,   19,   19,   19,   19,   20,   20,   20,
+       23,   19,   22,   22,   19,   19,   19,   25,   19,   20,
+       28,   23,   33,   34,   42,   43,   43,   45,   48,   49,
+       72,   45,   42,   53,   53,   58,   58,   28,   25,   58,
+
+       34,   61,   61,   33,   36,   36,   49,   69,   69,   48,
+       52,   52,   52,   60,   44,   36,   36,   36,   39,   39,
+       39,   41,   52,   61,   35,   39,   39,   31,   39,   55,
+       55,   55,   39,   51,   51,   59,   59,   68,   59,   68,
+       15,   62,   62,   70,   51,   51,   65,   65,   65,   11,
+        5,   64,   64,   64,   51,   51,   51,    4,   51,   56,
+       56,   56,   62,   64,   70,   70,   62,   56,   70,   56,
+       71,    2,   71,   56,   63,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,   63,   63,   63,    0,    0,    0,
+       63,   63,   63,   66,   66,   66,    0,    0,    0,    0,
+
+        0,   66,    0,   66,    0,    0,    0,   66,   76,   76,
+       76,   76,   76,   76,   76,   76,   77,   77,   77,   77,
+       77,   77,   77,   77,   78,   78,   78,   78,   79,   79,
+       79,   79,   79,   79,   79,   79,   80,    0,   80,   80,
+       80,   80,   80,   80,   81,    0,   81,   81,   81,   81,
+       81,   81,   82,   82,    0,   82,   83,    0,   83,   84,
+       84,   84,   85,    0,   85,   86,   86,   86,   86,   86,
+       86,   86,   86,   87,   87,   87,   87,   87,   87,   87,
+       87,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 1;
+
+static yyconst short int yy_rule_linenum[13] =
+    {   0,
+       69,   70,   71,   74,   77,   78,   79,   85,   86,   87,
+       89,   92
+    } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "scripts/genksyms/lex.l"
+#define INITIAL 0
+/* Lexical analysis for genksyms.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   Taken from Linux modutils 2.4.22.
+
+   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.  */
+#line 25 "scripts/genksyms/lex.l"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "genksyms.h"
+#include "parse.h"
+
+/* We've got a two-level lexer here.  We let flex do basic tokenization
+   and then we categorize those basic tokens in the second stage.  */
+#define YY_DECL		static int yylex1(void)
+
+/* Version 2 checksumming does proper tokenization; version 1 wasn't
+   quite so pedantic.  */
+#define V2_TOKENS 1
+
+/* We don't do multiple input files.  */
+#line 511 "scripts/genksyms/lex.c"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( yy_current_buffer->yy_is_interactive ) \
+		{ \
+		int c = '*', n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+		  && ferror( yyin ) ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	if ( yyleng > 0 ) \
+		yy_current_buffer->yy_at_bol = \
+				(yytext[yyleng - 1] == '\n'); \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp = NULL, *yy_bp = NULL;
+	register int yy_act;
+
+#line 65 "scripts/genksyms/lex.l"
+
+
+
+ /* Keep track of our location in the original source files.  */
+#line 670 "scripts/genksyms/lex.c"
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+		yy_current_state += YY_AT_BOL();
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				yy_last_accepting_state = yy_current_state;
+				yy_last_accepting_cpos = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 76 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 282 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		if ( yy_flex_debug )
+			{
+			if ( yy_act == 0 )
+				fprintf( stderr, "--scanner backing up\n" );
+			else if ( yy_act < 13 )
+				fprintf( stderr, "--accepting rule at line %d (\"%s\")\n",
+				         yy_rule_linenum[yy_act], yytext );
+			else if ( yy_act == 13 )
+				fprintf( stderr, "--accepting default rule (\"%s\")\n",
+				         yytext );
+			else if ( yy_act == 14 )
+				fprintf( stderr, "--(end of buffer or a NUL)\n" );
+			else
+				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
+			}
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = yy_hold_char;
+			yy_cp = yy_last_accepting_cpos;
+			yy_current_state = yy_last_accepting_state;
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 69 "scripts/genksyms/lex.l"
+return FILENAME;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 70 "scripts/genksyms/lex.l"
+cur_line++;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 71 "scripts/genksyms/lex.l"
+cur_line++;
+	YY_BREAK
+/* Ignore all other whitespace.  */
+case 4:
+YY_RULE_SETUP
+#line 74 "scripts/genksyms/lex.l"
+;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 77 "scripts/genksyms/lex.l"
+return STRING;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 78 "scripts/genksyms/lex.l"
+return CHAR;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 79 "scripts/genksyms/lex.l"
+return IDENT;
+	YY_BREAK
+/* The Pedant requires that the other C multi-character tokens be
+    recognized as tokens.  We don't actually use them since we don't
+    parse expressions, but we do want whitespace to be arranged
+    around them properly.  */
+case 8:
+YY_RULE_SETUP
+#line 85 "scripts/genksyms/lex.l"
+return OTHER;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 86 "scripts/genksyms/lex.l"
+return INT;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 87 "scripts/genksyms/lex.l"
+return REAL;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 89 "scripts/genksyms/lex.l"
+return DOTS;
+	YY_BREAK
+/* All other tokens are single characters.  */
+case 12:
+YY_RULE_SETUP
+#line 92 "scripts/genksyms/lex.l"
+return yytext[0];
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 95 "scripts/genksyms/lex.l"
+ECHO;
+	YY_BREAK
+#line 840 "scripts/genksyms/lex.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(V2_TOKENS):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+	yy_current_state += YY_AT_BOL();
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			yy_last_accepting_state = yy_current_state;
+			yy_last_accepting_cpos = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 76 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+	{
+	register int yy_is_jam;
+	register char *yy_cp = yy_c_buf_p;
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		yy_last_accepting_state = yy_current_state;
+		yy_last_accepting_cpos = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 76 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 75);
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+#endif	/* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+	yy_current_buffer->yy_at_bol = (c == '\n');
+
+	return c;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+	b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+	b->yy_is_interactive = 0;
+#else
+	b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b );
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+	{
+	int len;
+	for ( len = 0; yy_str[len]; ++len )
+		;
+
+	return yy_scan_bytes( yy_str, len );
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+	{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = len + 2;
+	buf = (char *) yy_flex_alloc( n );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < len; ++i )
+		buf[i] = bytes[i];
+
+	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+	{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 95 "scripts/genksyms/lex.l"
+
+
+/* Bring in the keyword recognizer.  */
+
+#include "keywords.c"
+
+
+/* Macros to append to our phrase collection list.  */
+
+#define _APP(T,L)	do {						   \
+			  cur_node = next_node;				   \
+			  next_node = xmalloc(sizeof(*next_node));	   \
+			  next_node->next = cur_node;			   \
+			  cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
+			  cur_node->tag = SYM_NORMAL;			   \
+			} while (0)
+
+#define APP		_APP(yytext, yyleng)
+
+
+/* The second stage lexer.  Here we incorporate knowledge of the state
+   of the parser to tailor the tokens that are returned.  */
+
+int
+yylex(void)
+{
+  static enum {
+    ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_BRACKET, ST_BRACE,
+    ST_EXPRESSION, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
+    ST_TABLE_5, ST_TABLE_6
+  } lexstate = ST_NOTSTARTED;
+
+  static int suppress_type_lookup, dont_want_brace_phrase;
+  static struct string_list *next_node;
+
+  int token, count = 0;
+  struct string_list *cur_node;
+
+  if (lexstate == ST_NOTSTARTED)
+    {
+      BEGIN(V2_TOKENS);
+      next_node = xmalloc(sizeof(*next_node));
+      next_node->next = NULL;
+      lexstate = ST_NORMAL;
+    }
+
+repeat:
+  token = yylex1();
+
+  if (token == 0)
+    return 0;
+  else if (token == FILENAME)
+    {
+      char *file, *e;
+
+      /* Save the filename and line number for later error messages.  */
+
+      if (cur_filename)
+	free(cur_filename);
+
+      file = strchr(yytext, '\"')+1;
+      e = strchr(file, '\"');
+      *e = '\0';
+      cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
+      cur_line = atoi(yytext+2);
+
+      goto repeat;
+    }
+
+  switch (lexstate)
+    {
+    case ST_NORMAL:
+      switch (token)
+	{
+	case IDENT:
+	  APP;
+	  {
+	    const struct resword *r = is_reserved_word(yytext, yyleng);
+	    if (r)
+	      {
+		switch (token = r->token)
+		  {
+		  case ATTRIBUTE_KEYW:
+		    lexstate = ST_ATTRIBUTE;
+		    count = 0;
+		    goto repeat;
+		  case ASM_KEYW:
+		    lexstate = ST_ASM;
+		    count = 0;
+		    goto repeat;
+
+		  case STRUCT_KEYW:
+		  case UNION_KEYW:
+		    dont_want_brace_phrase = 3;
+		  case ENUM_KEYW:
+		    suppress_type_lookup = 2;
+		    goto fini;
+
+		  case EXPORT_SYMBOL_KEYW:
+		      goto fini;
+		  }
+	      }
+	    if (!suppress_type_lookup)
+	      {
+		struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
+		if (sym && sym->type == SYM_TYPEDEF)
+		  token = TYPE;
+	      }
+	  }
+	  break;
+
+	case '[':
+	  APP;
+	  lexstate = ST_BRACKET;
+	  count = 1;
+	  goto repeat;
+
+	case '{':
+	  APP;
+	  if (dont_want_brace_phrase)
+	    break;
+	  lexstate = ST_BRACE;
+	  count = 1;
+	  goto repeat;
+
+	case '=': case ':':
+	  APP;
+	  lexstate = ST_EXPRESSION;
+	  break;
+
+	case DOTS:
+	default:
+	  APP;
+	  break;
+	}
+      break;
+
+    case ST_ATTRIBUTE:
+      APP;
+      switch (token)
+	{
+	case '(':
+	  ++count;
+	  goto repeat;
+	case ')':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = ATTRIBUTE_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_ASM:
+      APP;
+      switch (token)
+	{
+	case '(':
+	  ++count;
+	  goto repeat;
+	case ')':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = ASM_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_BRACKET:
+      APP;
+      switch (token)
+	{
+	case '[':
+	  ++count;
+	  goto repeat;
+	case ']':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = BRACKET_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_BRACE:
+      APP;
+      switch (token)
+	{
+	case '{':
+	  ++count;
+	  goto repeat;
+	case '}':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = BRACE_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_EXPRESSION:
+      switch (token)
+	{
+	case '(': case '[': case '{':
+	  ++count;
+	  APP;
+	  goto repeat;
+	case ')': case ']': case '}':
+	  --count;
+	  APP;
+	  goto repeat;
+	case ',': case ';':
+	  if (count == 0)
+	    {
+	      /* Put back the token we just read so's we can find it again
+		 after registering the expression.  */
+	      unput(token);
+
+	      lexstate = ST_NORMAL;
+	      token = EXPRESSION_PHRASE;
+	      break;
+	    }
+	  APP;
+	  goto repeat;
+	default:
+	  APP;
+	  goto repeat;
+	}
+      break;
+
+    case ST_TABLE_1:
+      goto repeat;
+
+    case ST_TABLE_2:
+      if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
+	{
+	  token = EXPORT_SYMBOL_KEYW;
+	  lexstate = ST_TABLE_5;
+	  APP;
+	  break;
+	}
+      lexstate = ST_TABLE_6;
+      /* FALLTHRU */
+
+    case ST_TABLE_6:
+      switch (token)
+	{
+	case '{': case '[': case '(':
+	  ++count;
+	  break;
+	case '}': case ']': case ')':
+	  --count;
+	  break;
+	case ',':
+	  if (count == 0)
+	    lexstate = ST_TABLE_2;
+	  break;
+	};
+      goto repeat;
+
+    case ST_TABLE_3:
+      goto repeat;
+
+    case ST_TABLE_4:
+      if (token == ';')
+	lexstate = ST_NORMAL;
+      goto repeat;
+
+    case ST_TABLE_5:
+      switch (token)
+	{
+	case ',':
+	  token = ';';
+	  lexstate = ST_TABLE_2;
+	  APP;
+	  break;
+	default:
+	  APP;
+	  break;
+	}
+      break;
+
+    default:
+      abort();
+    }
+fini:
+
+  if (suppress_type_lookup > 0)
+    --suppress_type_lookup;
+  if (dont_want_brace_phrase > 0)
+    --dont_want_brace_phrase;
+
+  yylval = &next_node->next;
+
+  return token;
+}
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#define	ASM_KEYW	257
+#define	ATTRIBUTE_KEYW	258
+#define	AUTO_KEYW	259
+#define	BOOL_KEYW	260
+#define	CHAR_KEYW	261
+#define	CONST_KEYW	262
+#define	DOUBLE_KEYW	263
+#define	ENUM_KEYW	264
+#define	EXTERN_KEYW	265
+#define	FLOAT_KEYW	266
+#define	INLINE_KEYW	267
+#define	INT_KEYW	268
+#define	LONG_KEYW	269
+#define	REGISTER_KEYW	270
+#define	RESTRICT_KEYW	271
+#define	SHORT_KEYW	272
+#define	SIGNED_KEYW	273
+#define	STATIC_KEYW	274
+#define	STRUCT_KEYW	275
+#define	TYPEDEF_KEYW	276
+#define	UNION_KEYW	277
+#define	UNSIGNED_KEYW	278
+#define	VOID_KEYW	279
+#define	VOLATILE_KEYW	280
+#define	TYPEOF_KEYW	281
+#define	EXPORT_SYMBOL_KEYW	282
+#define	ASM_PHRASE	283
+#define	ATTRIBUTE_PHRASE	284
+#define	BRACE_PHRASE	285
+#define	BRACKET_PHRASE	286
+#define	EXPRESSION_PHRASE	287
+#define	CHAR	288
+#define	DOTS	289
+#define	IDENT	290
+#define	INT	291
+#define	REAL	292
+#define	STRING	293
+#define	TYPE	294
+#define	OTHER	295
+#define	FILENAME	296
+
+
+extern YYSTYPE yylval;
diff -urN linux-2.5.63-bk5/scripts/genksyms/lex.l linux-2.5.63-bk6/scripts/genksyms/lex.l
--- linux-2.5.63-bk5/scripts/genksyms/lex.l	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/lex.l	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,407 @@
+/* Lexical analysis for genksyms.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   Taken from Linux modutils 2.4.22.
+
+   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 <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "genksyms.h"
+#include "parse.h"
+
+/* We've got a two-level lexer here.  We let flex do basic tokenization
+   and then we categorize those basic tokens in the second stage.  */
+#define YY_DECL		static int yylex1(void)
+
+%}
+
+IDENT			[A-Za-z_][A-Za-z0-9_]*
+
+O_INT			0[0-7]*
+D_INT			[1-9][0-9]*
+X_INT			0[Xx][0-9A-Fa-f]+
+I_SUF			[Uu]|[Ll]|[Uu][Ll]|[Ll][Uu]
+INT			({O_INT}|{D_INT}|{X_INT}){I_SUF}?
+
+FRAC			([0-9]*\.[0-9]+)|([0-9]+\.)
+EXP			[Ee][+-]?[0-9]+
+F_SUF			[FfLl]
+REAL			({FRAC}{EXP}?{F_SUF}?)|([0-9]+{EXP}{F_SUF}?)
+
+STRING			L?\"([^\\\"]*\\.)*[^\\\"]*\"
+CHAR			L?\'([^\\\']*\\.)*[^\\\']*\'
+
+MC_TOKEN		([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
+
+/* Version 2 checksumming does proper tokenization; version 1 wasn't
+   quite so pedantic.  */
+%s V2_TOKENS
+
+/* We don't do multiple input files.  */
+%option noyywrap
+
+%%
+
+
+ /* Keep track of our location in the original source files.  */
+^#[ \t]+{INT}[ \t]+\"[^\"\n]+\".*\n	return FILENAME;
+^#.*\n					cur_line++;
+\n					cur_line++;
+
+ /* Ignore all other whitespace.  */
+[ \t\f\v\r]+				;
+
+
+{STRING}				return STRING;
+{CHAR}					return CHAR;
+{IDENT}					return IDENT;
+
+ /* The Pedant requires that the other C multi-character tokens be
+    recognized as tokens.  We don't actually use them since we don't
+    parse expressions, but we do want whitespace to be arranged
+    around them properly.  */
+<V2_TOKENS>{MC_TOKEN}			return OTHER;
+<V2_TOKENS>{INT}			return INT;
+<V2_TOKENS>{REAL}			return REAL;
+
+"..."					return DOTS;
+
+ /* All other tokens are single characters.  */
+.					return yytext[0];
+
+
+%%
+
+/* Bring in the keyword recognizer.  */
+
+#include "keywords.c"
+
+
+/* Macros to append to our phrase collection list.  */
+
+#define _APP(T,L)	do {						   \
+			  cur_node = next_node;				   \
+			  next_node = xmalloc(sizeof(*next_node));	   \
+			  next_node->next = cur_node;			   \
+			  cur_node->string = memcpy(xmalloc(L+1), T, L+1); \
+			  cur_node->tag = SYM_NORMAL;			   \
+			} while (0)
+
+#define APP		_APP(yytext, yyleng)
+
+
+/* The second stage lexer.  Here we incorporate knowledge of the state
+   of the parser to tailor the tokens that are returned.  */
+
+int
+yylex(void)
+{
+  static enum {
+    ST_NOTSTARTED, ST_NORMAL, ST_ATTRIBUTE, ST_ASM, ST_BRACKET, ST_BRACE,
+    ST_EXPRESSION, ST_TABLE_1, ST_TABLE_2, ST_TABLE_3, ST_TABLE_4,
+    ST_TABLE_5, ST_TABLE_6
+  } lexstate = ST_NOTSTARTED;
+
+  static int suppress_type_lookup, dont_want_brace_phrase;
+  static struct string_list *next_node;
+
+  int token, count = 0;
+  struct string_list *cur_node;
+
+  if (lexstate == ST_NOTSTARTED)
+    {
+      BEGIN(V2_TOKENS);
+      next_node = xmalloc(sizeof(*next_node));
+      next_node->next = NULL;
+      lexstate = ST_NORMAL;
+    }
+
+repeat:
+  token = yylex1();
+
+  if (token == 0)
+    return 0;
+  else if (token == FILENAME)
+    {
+      char *file, *e;
+
+      /* Save the filename and line number for later error messages.  */
+
+      if (cur_filename)
+	free(cur_filename);
+
+      file = strchr(yytext, '\"')+1;
+      e = strchr(file, '\"');
+      *e = '\0';
+      cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
+      cur_line = atoi(yytext+2);
+
+      goto repeat;
+    }
+
+  switch (lexstate)
+    {
+    case ST_NORMAL:
+      switch (token)
+	{
+	case IDENT:
+	  APP;
+	  {
+	    const struct resword *r = is_reserved_word(yytext, yyleng);
+	    if (r)
+	      {
+		switch (token = r->token)
+		  {
+		  case ATTRIBUTE_KEYW:
+		    lexstate = ST_ATTRIBUTE;
+		    count = 0;
+		    goto repeat;
+		  case ASM_KEYW:
+		    lexstate = ST_ASM;
+		    count = 0;
+		    goto repeat;
+
+		  case STRUCT_KEYW:
+		  case UNION_KEYW:
+		    dont_want_brace_phrase = 3;
+		  case ENUM_KEYW:
+		    suppress_type_lookup = 2;
+		    goto fini;
+
+		  case EXPORT_SYMBOL_KEYW:
+		      goto fini;
+		  }
+	      }
+	    if (!suppress_type_lookup)
+	      {
+		struct symbol *sym = find_symbol(yytext, SYM_TYPEDEF);
+		if (sym && sym->type == SYM_TYPEDEF)
+		  token = TYPE;
+	      }
+	  }
+	  break;
+
+	case '[':
+	  APP;
+	  lexstate = ST_BRACKET;
+	  count = 1;
+	  goto repeat;
+
+	case '{':
+	  APP;
+	  if (dont_want_brace_phrase)
+	    break;
+	  lexstate = ST_BRACE;
+	  count = 1;
+	  goto repeat;
+
+	case '=': case ':':
+	  APP;
+	  lexstate = ST_EXPRESSION;
+	  break;
+
+	case DOTS:
+	default:
+	  APP;
+	  break;
+	}
+      break;
+
+    case ST_ATTRIBUTE:
+      APP;
+      switch (token)
+	{
+	case '(':
+	  ++count;
+	  goto repeat;
+	case ')':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = ATTRIBUTE_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_ASM:
+      APP;
+      switch (token)
+	{
+	case '(':
+	  ++count;
+	  goto repeat;
+	case ')':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = ASM_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_BRACKET:
+      APP;
+      switch (token)
+	{
+	case '[':
+	  ++count;
+	  goto repeat;
+	case ']':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = BRACKET_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_BRACE:
+      APP;
+      switch (token)
+	{
+	case '{':
+	  ++count;
+	  goto repeat;
+	case '}':
+	  if (--count == 0)
+	    {
+	      lexstate = ST_NORMAL;
+	      token = BRACE_PHRASE;
+	      break;
+	    }
+	  goto repeat;
+	default:
+	  goto repeat;
+	}
+      break;
+
+    case ST_EXPRESSION:
+      switch (token)
+	{
+	case '(': case '[': case '{':
+	  ++count;
+	  APP;
+	  goto repeat;
+	case ')': case ']': case '}':
+	  --count;
+	  APP;
+	  goto repeat;
+	case ',': case ';':
+	  if (count == 0)
+	    {
+	      /* Put back the token we just read so's we can find it again
+		 after registering the expression.  */
+	      unput(token);
+
+	      lexstate = ST_NORMAL;
+	      token = EXPRESSION_PHRASE;
+	      break;
+	    }
+	  APP;
+	  goto repeat;
+	default:
+	  APP;
+	  goto repeat;
+	}
+      break;
+
+    case ST_TABLE_1:
+      goto repeat;
+
+    case ST_TABLE_2:
+      if (token == IDENT && yyleng == 1 && yytext[0] == 'X')
+	{
+	  token = EXPORT_SYMBOL_KEYW;
+	  lexstate = ST_TABLE_5;
+	  APP;
+	  break;
+	}
+      lexstate = ST_TABLE_6;
+      /* FALLTHRU */
+
+    case ST_TABLE_6:
+      switch (token)
+	{
+	case '{': case '[': case '(':
+	  ++count;
+	  break;
+	case '}': case ']': case ')':
+	  --count;
+	  break;
+	case ',':
+	  if (count == 0)
+	    lexstate = ST_TABLE_2;
+	  break;
+	};
+      goto repeat;
+
+    case ST_TABLE_3:
+      goto repeat;
+
+    case ST_TABLE_4:
+      if (token == ';')
+	lexstate = ST_NORMAL;
+      goto repeat;
+
+    case ST_TABLE_5:
+      switch (token)
+	{
+	case ',':
+	  token = ';';
+	  lexstate = ST_TABLE_2;
+	  APP;
+	  break;
+	default:
+	  APP;
+	  break;
+	}
+      break;
+
+    default:
+      abort();
+    }
+fini:
+
+  if (suppress_type_lookup > 0)
+    --suppress_type_lookup;
+  if (dont_want_brace_phrase > 0)
+    --dont_want_brace_phrase;
+
+  yylval = &next_node->next;
+
+  return token;
+}
diff -urN linux-2.5.63-bk5/scripts/genksyms/parse.c_shipped linux-2.5.63-bk6/scripts/genksyms/parse.c_shipped
--- linux-2.5.63-bk5/scripts/genksyms/parse.c_shipped	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/parse.c_shipped	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,1569 @@
+
+/*  A Bison parser, made from scripts/genksyms/parse.y
+    by GNU Bison version 1.28  */
+
+#define YYBISON 1  /* Identify Bison output.  */
+
+#define	ASM_KEYW	257
+#define	ATTRIBUTE_KEYW	258
+#define	AUTO_KEYW	259
+#define	BOOL_KEYW	260
+#define	CHAR_KEYW	261
+#define	CONST_KEYW	262
+#define	DOUBLE_KEYW	263
+#define	ENUM_KEYW	264
+#define	EXTERN_KEYW	265
+#define	FLOAT_KEYW	266
+#define	INLINE_KEYW	267
+#define	INT_KEYW	268
+#define	LONG_KEYW	269
+#define	REGISTER_KEYW	270
+#define	RESTRICT_KEYW	271
+#define	SHORT_KEYW	272
+#define	SIGNED_KEYW	273
+#define	STATIC_KEYW	274
+#define	STRUCT_KEYW	275
+#define	TYPEDEF_KEYW	276
+#define	UNION_KEYW	277
+#define	UNSIGNED_KEYW	278
+#define	VOID_KEYW	279
+#define	VOLATILE_KEYW	280
+#define	TYPEOF_KEYW	281
+#define	EXPORT_SYMBOL_KEYW	282
+#define	ASM_PHRASE	283
+#define	ATTRIBUTE_PHRASE	284
+#define	BRACE_PHRASE	285
+#define	BRACKET_PHRASE	286
+#define	EXPRESSION_PHRASE	287
+#define	CHAR	288
+#define	DOTS	289
+#define	IDENT	290
+#define	INT	291
+#define	REAL	292
+#define	STRING	293
+#define	TYPE	294
+#define	OTHER	295
+#define	FILENAME	296
+
+#line 24 "scripts/genksyms/parse.y"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include "genksyms.h"
+
+static int is_typedef;
+static int is_extern;
+static char *current_name;
+static struct string_list *decl_spec;
+
+static void yyerror(const char *);
+
+static inline void
+remove_node(struct string_list **p)
+{
+  struct string_list *node = *p;
+  *p = node->next;
+  free_node(node);
+}
+
+static inline void
+remove_list(struct string_list **pb, struct string_list **pe)
+{
+  struct string_list *b = *pb, *e = *pe;
+  *pb = e;
+  free_list(b, e);
+}
+
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#ifndef YYDEBUG
+#define YYDEBUG 1
+#endif
+
+#include <stdio.h>
+
+#ifndef __cplusplus
+#ifndef __STDC__
+#define const
+#endif
+#endif
+
+
+
+#define	YYFINAL		172
+#define	YYFLAG		-32768
+#define	YYNTBASE	52
+
+#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 96)
+
+static const char yytranslate[] = {     0,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,    46,
+    47,    48,     2,    45,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,    51,    43,     2,
+    49,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,    50,     2,    44,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
+     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+    27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+    37,    38,    39,    40,    41,    42
+};
+
+#if YYDEBUG != 0
+static const short yyprhs[] = {     0,
+     0,     2,     5,     6,     9,    10,    14,    16,    18,    20,
+    22,    25,    28,    32,    33,    35,    37,    41,    46,    47,
+    49,    51,    54,    56,    58,    60,    62,    64,    66,    68,
+    70,    72,    77,    80,    83,    86,    90,    94,    98,   101,
+   104,   107,   109,   111,   113,   115,   117,   119,   121,   123,
+   125,   127,   129,   132,   133,   135,   137,   140,   142,   144,
+   146,   148,   151,   153,   155,   160,   165,   168,   172,   176,
+   179,   181,   183,   185,   190,   195,   198,   202,   206,   209,
+   211,   215,   216,   218,   220,   224,   227,   230,   232,   233,
+   235,   237,   242,   247,   250,   254,   258,   262,   263,   265,
+   268,   272,   276,   277,   279,   281,   284,   288,   291,   292,
+   294,   296,   300,   303,   306,   308,   311,   312,   314,   317,
+   318,   320
+};
+
+static const short yyrhs[] = {    53,
+     0,    52,    53,     0,     0,    54,    55,     0,     0,    22,
+    56,    57,     0,    57,     0,    81,     0,    93,     0,    95,
+     0,     1,    43,     0,     1,    44,     0,    61,    58,    43,
+     0,     0,    59,     0,    60,     0,    59,    45,    60,     0,
+    71,    94,    92,    82,     0,     0,    62,     0,    63,     0,
+    62,    63,     0,    64,     0,    65,     0,     5,     0,    16,
+     0,    20,     0,    11,     0,    13,     0,    66,     0,    70,
+     0,    27,    46,    65,    47,     0,    21,    36,     0,    23,
+    36,     0,    10,    36,     0,    21,    36,    84,     0,    23,
+    36,    84,     0,    10,    36,    31,     0,    10,    31,     0,
+    21,    84,     0,    23,    84,     0,     7,     0,    18,     0,
+    14,     0,    15,     0,    19,     0,    24,     0,    12,     0,
+     9,     0,    25,     0,     6,     0,    40,     0,    48,    68,
+     0,     0,    69,     0,    70,     0,    69,    70,     0,     8,
+     0,    26,     0,    30,     0,    17,     0,    67,    71,     0,
+    72,     0,    36,     0,    72,    46,    75,    47,     0,    72,
+    46,     1,    47,     0,    72,    32,     0,    46,    71,    47,
+     0,    46,     1,    47,     0,    67,    73,     0,    74,     0,
+    36,     0,    40,     0,    74,    46,    75,    47,     0,    74,
+    46,     1,    47,     0,    74,    32,     0,    46,    73,    47,
+     0,    46,     1,    47,     0,    76,    35,     0,    76,     0,
+    77,    45,    35,     0,     0,    77,     0,    78,     0,    77,
+    45,    78,     0,    62,    79,     0,    67,    79,     0,    80,
+     0,     0,    36,     0,    40,     0,    80,    46,    75,    47,
+     0,    80,    46,     1,    47,     0,    80,    32,     0,    46,
+    79,    47,     0,    46,     1,    47,     0,    61,    71,    31,
+     0,     0,    83,     0,    49,    33,     0,    50,    85,    44,
+     0,    50,     1,    44,     0,     0,    86,     0,    87,     0,
+    86,    87,     0,    61,    88,    43,     0,     1,    43,     0,
+     0,    89,     0,    90,     0,    89,    45,    90,     0,    73,
+    92,     0,    36,    91,     0,    91,     0,    51,    33,     0,
+     0,    30,     0,    29,    43,     0,     0,    29,     0,    28,
+    46,    36,    47,    43,     0
+};
+
+#endif
+
+#if YYDEBUG != 0
+static const short yyrline[] = { 0,
+   101,   103,   106,   109,   112,   114,   115,   116,   117,   118,
+   119,   120,   123,   137,   139,   142,   151,   163,   169,   171,
+   174,   176,   179,   186,   189,   191,   192,   193,   194,   197,
+   199,   200,   204,   206,   208,   212,   219,   226,   235,   236,
+   237,   240,   242,   243,   244,   245,   246,   247,   248,   249,
+   250,   251,   254,   259,   261,   264,   266,   269,   270,   270,
+   271,   278,   280,   283,   293,   295,   297,   299,   301,   307,
+   309,   312,   314,   315,   317,   319,   321,   323,   327,   329,
+   330,   333,   335,   338,   340,   344,   349,   352,   355,   357,
+   365,   369,   371,   373,   375,   377,   381,   390,   392,   396,
+   401,   403,   406,   408,   411,   413,   416,   419,   423,   425,
+   428,   430,   433,   435,   436,   439,   443,   445,   448,   452,
+   454,   457
+};
+#endif
+
+
+#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
+
+static const char * const yytname[] = {   "$","error","$undefined.","ASM_KEYW",
+"ATTRIBUTE_KEYW","AUTO_KEYW","BOOL_KEYW","CHAR_KEYW","CONST_KEYW","DOUBLE_KEYW",
+"ENUM_KEYW","EXTERN_KEYW","FLOAT_KEYW","INLINE_KEYW","INT_KEYW","LONG_KEYW",
+"REGISTER_KEYW","RESTRICT_KEYW","SHORT_KEYW","SIGNED_KEYW","STATIC_KEYW","STRUCT_KEYW",
+"TYPEDEF_KEYW","UNION_KEYW","UNSIGNED_KEYW","VOID_KEYW","VOLATILE_KEYW","TYPEOF_KEYW",
+"EXPORT_SYMBOL_KEYW","ASM_PHRASE","ATTRIBUTE_PHRASE","BRACE_PHRASE","BRACKET_PHRASE",
+"EXPRESSION_PHRASE","CHAR","DOTS","IDENT","INT","REAL","STRING","TYPE","OTHER",
+"FILENAME","';'","'}'","','","'('","')'","'*'","'='","'{'","':'","declaration_seq",
+"declaration","@1","declaration1","@2","simple_declaration","init_declarator_list_opt",
+"init_declarator_list","init_declarator","decl_specifier_seq_opt","decl_specifier_seq",
+"decl_specifier","storage_class_specifier","type_specifier","simple_type_specifier",
+"ptr_operator","cvar_qualifier_seq_opt","cvar_qualifier_seq","cvar_qualifier",
+"declarator","direct_declarator","nested_declarator","direct_nested_declarator",
+"parameter_declaration_clause","parameter_declaration_list_opt","parameter_declaration_list",
+"parameter_declaration","m_abstract_declarator","direct_m_abstract_declarator",
+"function_definition","initializer_opt","initializer","class_body","member_specification_opt",
+"member_specification","member_declaration","member_declarator_list_opt","member_declarator_list",
+"member_declarator","member_bitfield_declarator","attribute_opt","asm_definition",
+"asm_phrase_opt","export_definition", NULL
+};
+#endif
+
+static const short yyr1[] = {     0,
+    52,    52,    54,    53,    56,    55,    55,    55,    55,    55,
+    55,    55,    57,    58,    58,    59,    59,    60,    61,    61,
+    62,    62,    63,    63,    64,    64,    64,    64,    64,    65,
+    65,    65,    65,    65,    65,    65,    65,    65,    65,    65,
+    65,    66,    66,    66,    66,    66,    66,    66,    66,    66,
+    66,    66,    67,    68,    68,    69,    69,    70,    70,    70,
+    70,    71,    71,    72,    72,    72,    72,    72,    72,    73,
+    73,    74,    74,    74,    74,    74,    74,    74,    75,    75,
+    75,    76,    76,    77,    77,    78,    79,    79,    80,    80,
+    80,    80,    80,    80,    80,    80,    81,    82,    82,    83,
+    84,    84,    85,    85,    86,    86,    87,    87,    88,    88,
+    89,    89,    90,    90,    90,    91,    92,    92,    93,    94,
+    94,    95
+};
+
+static const short yyr2[] = {     0,
+     1,     2,     0,     2,     0,     3,     1,     1,     1,     1,
+     2,     2,     3,     0,     1,     1,     3,     4,     0,     1,
+     1,     2,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     4,     2,     2,     2,     3,     3,     3,     2,     2,
+     2,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     1,     1,     2,     0,     1,     1,     2,     1,     1,     1,
+     1,     2,     1,     1,     4,     4,     2,     3,     3,     2,
+     1,     1,     1,     4,     4,     2,     3,     3,     2,     1,
+     3,     0,     1,     1,     3,     2,     2,     1,     0,     1,
+     1,     4,     4,     2,     3,     3,     3,     0,     1,     2,
+     3,     3,     0,     1,     1,     2,     3,     2,     0,     1,
+     1,     3,     2,     2,     1,     2,     0,     1,     2,     0,
+     1,     5
+};
+
+static const short yydefact[] = {     3,
+     3,     1,     0,     2,     0,    25,    51,    42,    58,    49,
+     0,    28,    48,    29,    44,    45,    26,    61,    43,    46,
+    27,     0,     5,     0,    47,    50,    59,     0,     0,     0,
+    60,    52,     4,     7,    14,    20,    21,    23,    24,    30,
+    31,     8,     9,    10,    11,    12,    39,    35,    33,     0,
+    40,    19,    34,    41,     0,     0,   119,    64,     0,    54,
+     0,    15,    16,     0,   120,    63,    22,    38,    36,     0,
+   109,     0,     0,   105,     6,    14,    37,     0,     0,     0,
+     0,    53,    55,    56,    13,     0,    62,   121,    97,   117,
+    67,     0,   108,   102,    72,    73,     0,     0,     0,   117,
+    71,     0,   110,   111,   115,   101,     0,   106,   120,    32,
+     0,    69,    68,    57,    17,   118,    98,     0,    89,     0,
+    80,    83,    84,   114,     0,    72,     0,   116,    70,   113,
+    76,     0,   107,     0,   122,     0,    18,    99,    66,    90,
+    52,     0,    89,    86,    88,    65,    79,     0,    78,    77,
+     0,     0,   112,   100,     0,    91,     0,    87,    94,     0,
+    81,    85,    75,    74,    96,    95,     0,     0,    93,    92,
+     0,     0
+};
+
+static const short yydefgoto[] = {     1,
+     2,     3,    33,    52,    34,    61,    62,    63,    71,    36,
+    37,    38,    39,    40,    64,    82,    83,    41,   109,    66,
+   100,   101,   120,   121,   122,   123,   144,   145,    42,   137,
+   138,    51,    72,    73,    74,   102,   103,   104,   105,   117,
+    43,    90,    44
+};
+
+static const short yypact[] = {-32768,
+    19,-32768,   175,-32768,    32,-32768,-32768,-32768,-32768,-32768,
+   -18,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,   -30,-32768,   -26,-32768,-32768,-32768,   -32,   -10,    -2,
+-32768,-32768,-32768,-32768,     2,   428,-32768,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768,    34,    12,    79,
+-32768,   428,    12,-32768,   455,    33,-32768,-32768,    15,    14,
+    35,    29,-32768,     2,   -14,   -21,-32768,-32768,-32768,    67,
+    31,    37,   127,-32768,-32768,     2,-32768,    54,    60,    66,
+    69,-32768,    14,-32768,-32768,     2,-32768,-32768,-32768,    84,
+-32768,   219,-32768,-32768,    70,-32768,    20,    91,    72,    84,
+   -20,    74,    81,-32768,-32768,-32768,    86,-32768,   102,-32768,
+   106,-32768,-32768,-32768,-32768,-32768,   109,   108,   348,   112,
+   126,   117,-32768,-32768,   118,-32768,   122,-32768,-32768,-32768,
+-32768,   262,-32768,    31,-32768,   131,-32768,-32768,-32768,-32768,
+-32768,     7,   120,-32768,    -9,-32768,-32768,   392,-32768,-32768,
+   125,   130,-32768,-32768,   132,-32768,   159,-32768,-32768,   305,
+-32768,-32768,-32768,-32768,-32768,-32768,   160,   161,-32768,-32768,
+   174,-32768
+};
+
+static const short yypgoto[] = {-32768,
+   208,-32768,-32768,-32768,   158,-32768,-32768,   128,     0,   -90,
+   -36,-32768,   157,-32768,   -70,-32768,-32768,   -51,   -31,-32768,
+   -40,-32768,  -125,-32768,-32768,    65,   -97,-32768,-32768,-32768,
+-32768,   -19,-32768,-32768,   143,-32768,-32768,    83,   124,   141,
+-32768,-32768,-32768
+};
+
+
+#define	YYLAST		495
+
+
+static const short yytable[] = {    67,
+    99,   119,    35,    65,    54,    49,   152,   155,    84,    53,
+    91,   131,    47,    55,    88,    80,    89,    48,   171,    50,
+   125,     9,   159,    50,    92,   132,    99,    81,    99,    69,
+    18,   114,    87,    77,   168,    56,   160,    58,   -89,    27,
+    57,   119,   140,    31,   157,   158,   156,    59,   143,    60,
+    58,    76,   142,   -89,    60,   126,   127,   119,   129,    96,
+    59,    50,    60,    99,    68,    97,    95,    60,    79,   119,
+    96,   143,   143,    86,    45,    46,    97,    85,    60,    70,
+   106,    98,    67,     6,     7,     8,     9,    10,    11,    12,
+    13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+   110,    24,    25,    26,    27,    28,   111,   126,    31,    93,
+    94,    96,   112,   116,   -19,   113,   133,    97,    32,    60,
+    98,   -19,  -103,   128,   -19,   134,   -19,   107,    93,   -19,
+    88,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+    15,    16,    17,    18,    19,    20,    21,    22,   135,    24,
+    25,    26,    27,    28,   139,   140,    31,   136,   146,   156,
+   147,   148,   -19,   154,   149,   142,    32,    60,   150,   -19,
+  -104,   163,   -19,   172,   -19,     5,   164,   -19,   165,     6,
+     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+    27,    28,    29,    30,    31,   166,   169,   170,     4,    75,
+   -19,    78,   162,   115,    32,   108,   153,   -19,   124,   118,
+   -19,     0,   -19,     6,     7,     8,     9,    10,    11,    12,
+    13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+   130,    24,    25,    26,    27,    28,     0,     0,    31,     0,
+     0,     0,     0,   -82,     0,     0,     0,     0,    32,     0,
+     0,     0,   151,     0,     0,   -82,     6,     7,     8,     9,
+    10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+    20,    21,    22,     0,    24,    25,    26,    27,    28,     0,
+     0,    31,     0,     0,     0,     0,   -82,     0,     0,     0,
+     0,    32,     0,     0,     0,   167,     0,     0,   -82,     6,
+     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+    17,    18,    19,    20,    21,    22,     0,    24,    25,    26,
+    27,    28,     0,     0,    31,     0,     0,     0,     0,   -82,
+     0,     0,     0,     0,    32,     0,     0,     0,     0,     0,
+     0,   -82,     6,     7,     8,     9,    10,    11,    12,    13,
+    14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+    24,    25,    26,    27,    28,     0,     0,    31,     0,     0,
+     0,     0,     0,   140,     0,     0,     0,   141,     0,     0,
+     0,     0,     0,   142,     0,    60,     6,     7,     8,     9,
+    10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+    20,    21,    22,     0,    24,    25,    26,    27,    28,     0,
+     0,    31,     0,     0,     0,     0,   161,     0,     0,     0,
+     0,    32,     6,     7,     8,     9,    10,    11,    12,    13,
+    14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+    24,    25,    26,    27,    28,     0,     0,    31,     0,     0,
+     7,     8,     9,    10,    11,     0,    13,    32,    15,    16,
+     0,    18,    19,    20,     0,    22,     0,    24,    25,    26,
+    27,    28,     0,     0,    31,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,    32
+};
+
+static const short yycheck[] = {    36,
+    71,    92,     3,    35,    24,    36,   132,     1,    60,    36,
+    32,    32,    31,    46,    29,     1,    31,    36,     0,    50,
+     1,     8,    32,    50,    46,    46,    97,    59,    99,    49,
+    17,    83,    64,    53,   160,    46,    46,    36,    32,    26,
+    43,   132,    36,    30,   142,   143,    40,    46,   119,    48,
+    36,    52,    46,    47,    48,    36,    97,   148,    99,    40,
+    46,    50,    48,   134,    31,    46,    36,    48,    36,   160,
+    40,   142,   143,    45,    43,    44,    46,    43,    48,     1,
+    44,    51,   119,     5,     6,     7,     8,     9,    10,    11,
+    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+    47,    23,    24,    25,    26,    27,    47,    36,    30,    43,
+    44,    40,    47,    30,    36,    47,    43,    46,    40,    48,
+    51,    43,    44,    33,    46,    45,    48,     1,    43,    51,
+    29,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+    14,    15,    16,    17,    18,    19,    20,    21,    43,    23,
+    24,    25,    26,    27,    47,    36,    30,    49,    47,    40,
+    35,    45,    36,    33,    47,    46,    40,    48,    47,    43,
+    44,    47,    46,     0,    48,     1,    47,    51,    47,     5,
+     6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+    16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
+    26,    27,    28,    29,    30,    47,    47,    47,     1,    52,
+    36,    55,   148,    86,    40,    73,   134,    43,    95,     1,
+    46,    -1,    48,     5,     6,     7,     8,     9,    10,    11,
+    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+   100,    23,    24,    25,    26,    27,    -1,    -1,    30,    -1,
+    -1,    -1,    -1,    35,    -1,    -1,    -1,    -1,    40,    -1,
+    -1,    -1,     1,    -1,    -1,    47,     5,     6,     7,     8,
+     9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+    19,    20,    21,    -1,    23,    24,    25,    26,    27,    -1,
+    -1,    30,    -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,
+    -1,    40,    -1,    -1,    -1,     1,    -1,    -1,    47,     5,
+     6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+    16,    17,    18,    19,    20,    21,    -1,    23,    24,    25,
+    26,    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,    35,
+    -1,    -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,
+    -1,    47,     5,     6,     7,     8,     9,    10,    11,    12,
+    13,    14,    15,    16,    17,    18,    19,    20,    21,    -1,
+    23,    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,
+    -1,    -1,    -1,    36,    -1,    -1,    -1,    40,    -1,    -1,
+    -1,    -1,    -1,    46,    -1,    48,     5,     6,     7,     8,
+     9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+    19,    20,    21,    -1,    23,    24,    25,    26,    27,    -1,
+    -1,    30,    -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,
+    -1,    40,     5,     6,     7,     8,     9,    10,    11,    12,
+    13,    14,    15,    16,    17,    18,    19,    20,    21,    -1,
+    23,    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,
+     6,     7,     8,     9,    10,    -1,    12,    40,    14,    15,
+    -1,    17,    18,    19,    -1,    21,    -1,    23,    24,    25,
+    26,    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    40
+};
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/lib/bison.simple"
+/* This file comes from bison-1.28.  */
+
+/* Skeleton output parser for bison,
+   Copyright (C) 1984, 1989, 1990 Free Software Foundation, 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, 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.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* This is the parser code that is written into each bison parser
+  when the %semantic_parser declaration is not specified in the grammar.
+  It was written by Richard Stallman by simplifying the hairy parser
+  used when %semantic_parser is specified.  */
+
+#ifndef YYSTACK_USE_ALLOCA
+#ifdef alloca
+#define YYSTACK_USE_ALLOCA
+#else /* alloca not defined */
+#ifdef __GNUC__
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#else /* not GNU C.  */
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
+#define YYSTACK_USE_ALLOCA
+#include <alloca.h>
+#else /* not sparc */
+/* We think this test detects Watcom and Microsoft C.  */
+/* This used to test MSDOS, but that is a bad idea
+   since that symbol is in the user namespace.  */
+#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
+#if 0 /* No need for malloc.h, which pollutes the namespace;
+	 instead, just don't use alloca.  */
+#include <malloc.h>
+#endif
+#else /* not MSDOS, or __TURBOC__ */
+#if defined(_AIX)
+/* I don't know what this was needed for, but it pollutes the namespace.
+   So I turned it off.   rms, 2 May 1997.  */
+/* #include <malloc.h>  */
+ #pragma alloca
+#define YYSTACK_USE_ALLOCA
+#else /* not MSDOS, or __TURBOC__, or _AIX */
+#if 0
+#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
+		 and on HPUX 10.  Eventually we can turn this on.  */
+#define YYSTACK_USE_ALLOCA
+#define alloca __builtin_alloca
+#endif /* __hpux */
+#endif
+#endif /* not _AIX */
+#endif /* not MSDOS, or __TURBOC__ */
+#endif /* not sparc */
+#endif /* not GNU C */
+#endif /* alloca not defined */
+#endif /* YYSTACK_USE_ALLOCA not defined */
+
+#ifdef YYSTACK_USE_ALLOCA
+#define YYSTACK_ALLOC alloca
+#else
+#define YYSTACK_ALLOC malloc
+#endif
+
+/* Note: there must be only one dollar sign in this file.
+   It is replaced by the list of actions, each action
+   as one case of the switch.  */
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		-2
+#define YYEOF		0
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT 	goto yyabortlab
+#define YYERROR		goto yyerrlab1
+/* Like YYERROR except do call yyerror.
+   This remains here temporarily to ease the
+   transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+#define YYFAIL		goto yyerrlab
+#define YYRECOVERING()  (!!yyerrstatus)
+#define YYBACKUP(token, value) \
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    { yychar = (token), yylval = (value);			\
+      yychar1 = YYTRANSLATE (yychar);				\
+      YYPOPSTACK;						\
+      goto yybackup;						\
+    }								\
+  else								\
+    { yyerror ("syntax error: cannot back up"); YYERROR; }	\
+while (0)
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+#ifndef YYPURE
+#define YYLEX		yylex()
+#endif
+
+#ifdef YYPURE
+#ifdef YYLSP_NEEDED
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, &yylloc, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval, &yylloc)
+#endif
+#else /* not YYLSP_NEEDED */
+#ifdef YYLEX_PARAM
+#define YYLEX		yylex(&yylval, YYLEX_PARAM)
+#else
+#define YYLEX		yylex(&yylval)
+#endif
+#endif /* not YYLSP_NEEDED */
+#endif
+
+/* If nonreentrant, generate the variables here */
+
+#ifndef YYPURE
+
+int	yychar;			/*  the lookahead symbol		*/
+YYSTYPE	yylval;			/*  the semantic value of the		*/
+				/*  lookahead symbol			*/
+
+#ifdef YYLSP_NEEDED
+YYLTYPE yylloc;			/*  location data for the lookahead	*/
+				/*  symbol				*/
+#endif
+
+int yynerrs;			/*  number of parse errors so far       */
+#endif  /* not YYPURE */
+
+#if YYDEBUG != 0
+int yydebug;			/*  nonzero means print parse trace	*/
+/* Since this is uninitialized, it does not stop multiple parsers
+   from coexisting.  */
+#endif
+
+/*  YYINITDEPTH indicates the initial size of the parser's stacks	*/
+
+#ifndef	YYINITDEPTH
+#define YYINITDEPTH 200
+#endif
+
+/*  YYMAXDEPTH is the maximum size the stacks can grow to
+    (effective only if the built-in stack extension method is used).  */
+
+#if YYMAXDEPTH == 0
+#undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 10000
+#endif
+
+/* Define __yy_memcpy.  Note that the size argument
+   should be passed with type unsigned int, because that is what the non-GCC
+   definitions require.  With GCC, __builtin_memcpy takes an arg
+   of type size_t, but it can handle unsigned int.  */
+
+#if __GNUC__ > 1		/* GNU C and GNU C++ define this.  */
+#define __yy_memcpy(TO,FROM,COUNT)	__builtin_memcpy(TO,FROM,COUNT)
+#else				/* not GNU C or C++ */
+#ifndef __cplusplus
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (to, from, count)
+     char *to;
+     char *from;
+     unsigned int count;
+{
+  register char *f = from;
+  register char *t = to;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#else /* __cplusplus */
+
+/* This is the most reliable way to avoid incompatibilities
+   in available built-in functions on various systems.  */
+static void
+__yy_memcpy (char *to, char *from, unsigned int count)
+{
+  register char *t = to;
+  register char *f = from;
+  register int i = count;
+
+  while (i-- > 0)
+    *t++ = *f++;
+}
+
+#endif
+#endif
+
+#line 217 "/usr/lib/bison.simple"
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+#ifdef __cplusplus
+#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL
+#else /* not __cplusplus */
+#define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#endif /* not __cplusplus */
+#else /* not YYPARSE_PARAM */
+#define YYPARSE_PARAM_ARG
+#define YYPARSE_PARAM_DECL
+#endif /* not YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+#ifdef YYPARSE_PARAM
+int yyparse (void *);
+#else
+int yyparse (void);
+#endif
+#endif
+
+int
+yyparse(YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  register int yystate;
+  register int yyn;
+  register short *yyssp;
+  register YYSTYPE *yyvsp;
+  int yyerrstatus;	/*  number of tokens to shift before error messages enabled */
+  int yychar1 = 0;		/*  lookahead token as an internal (translated) token number */
+
+  short	yyssa[YYINITDEPTH];	/*  the state stack			*/
+  YYSTYPE yyvsa[YYINITDEPTH];	/*  the semantic value stack		*/
+
+  short *yyss = yyssa;		/*  refer to the stacks thru separate pointers */
+  YYSTYPE *yyvs = yyvsa;	/*  to allow yyoverflow to reallocate them elsewhere */
+
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylsa[YYINITDEPTH];	/*  the location stack			*/
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
+#define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
+
+  int yystacksize = YYINITDEPTH;
+  int yyfree_stacks = 0;
+
+#ifdef YYPURE
+  int yychar;
+  YYSTYPE yylval;
+  int yynerrs;
+#ifdef YYLSP_NEEDED
+  YYLTYPE yylloc;
+#endif
+#endif
+
+  YYSTYPE yyval;		/*  the variable used to return		*/
+				/*  semantic values from the action	*/
+				/*  routines				*/
+
+  int yylen;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Starting parse\n");
+#endif
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss - 1;
+  yyvsp = yyvs;
+#ifdef YYLSP_NEEDED
+  yylsp = yyls;
+#endif
+
+/* Push a new state, which is found in  yystate  .  */
+/* In all cases, when you get here, the value and location stacks
+   have just been pushed. so pushing a state here evens the stacks.  */
+yynewstate:
+
+  *++yyssp = yystate;
+
+  if (yyssp >= yyss + yystacksize - 1)
+    {
+      /* Give user a chance to reallocate the stack */
+      /* Use copies of these so that the &'s don't force the real ones into memory. */
+      YYSTYPE *yyvs1 = yyvs;
+      short *yyss1 = yyss;
+#ifdef YYLSP_NEEDED
+      YYLTYPE *yyls1 = yyls;
+#endif
+
+      /* Get the current used size of the three stacks, in elements.  */
+      int size = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      /* Each stack pointer address is followed by the size of
+	 the data in use in that stack, in bytes.  */
+#ifdef YYLSP_NEEDED
+      /* This used to be a conditional around just the two extra args,
+	 but that might be undefined if yyoverflow is a macro.  */
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yyls1, size * sizeof (*yylsp),
+		 &yystacksize);
+#else
+      yyoverflow("parser stack overflow",
+		 &yyss1, size * sizeof (*yyssp),
+		 &yyvs1, size * sizeof (*yyvsp),
+		 &yystacksize);
+#endif
+
+      yyss = yyss1; yyvs = yyvs1;
+#ifdef YYLSP_NEEDED
+      yyls = yyls1;
+#endif
+#else /* no yyoverflow */
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+	{
+	  yyerror("parser stack overflow");
+	  if (yyfree_stacks)
+	    {
+	      free (yyss);
+	      free (yyvs);
+#ifdef YYLSP_NEEDED
+	      free (yyls);
+#endif
+	    }
+	  return 2;
+	}
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+	yystacksize = YYMAXDEPTH;
+#ifndef YYSTACK_USE_ALLOCA
+      yyfree_stacks = 1;
+#endif
+      yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
+      __yy_memcpy ((char *)yyss, (char *)yyss1,
+		   size * (unsigned int) sizeof (*yyssp));
+      yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
+      __yy_memcpy ((char *)yyvs, (char *)yyvs1,
+		   size * (unsigned int) sizeof (*yyvsp));
+#ifdef YYLSP_NEEDED
+      yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
+      __yy_memcpy ((char *)yyls, (char *)yyls1,
+		   size * (unsigned int) sizeof (*yylsp));
+#endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + size - 1;
+      yyvsp = yyvs + size - 1;
+#ifdef YYLSP_NEEDED
+      yylsp = yyls + size - 1;
+#endif
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Stack size increased to %d\n", yystacksize);
+#endif
+
+      if (yyssp >= yyss + yystacksize - 1)
+	YYABORT;
+    }
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Entering state %d\n", yystate);
+#endif
+
+  goto yybackup;
+ yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Reading a token: ");
+#endif
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)		/* This means end of input. */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;		/* Don't call YYLEX any more */
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Now at end of input.\n");
+#endif
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE(yychar);
+
+#if YYDEBUG != 0
+      if (yydebug)
+	{
+	  fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
+	  /* Give the individual parser a way to print the precise meaning
+	     of a token, for further debugging info.  */
+#ifdef YYPRINT
+	  YYPRINT (stderr, yychar, yylval);
+#endif
+	  fprintf (stderr, ")\n");
+	}
+#endif
+    }
+
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+    goto yydefault;
+
+  yyn = yytable[yyn];
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrlab;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
+#endif
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  /* count tokens shifted since error; after three, turn off error status.  */
+  if (yyerrstatus) yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+/* Do the default action for the current state.  */
+yydefault:
+
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+
+/* Do a reduction.  yyn is the number of a rule to reduce with.  */
+yyreduce:
+  yylen = yyr2[yyn];
+  if (yylen > 0)
+    yyval = yyvsp[1-yylen]; /* implement default value of the action */
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      int i;
+
+      fprintf (stderr, "Reducing via rule %d (line %d), ",
+	       yyn, yyrline[yyn]);
+
+      /* Print the symbols being reduced, and their result.  */
+      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
+	fprintf (stderr, "%s ", yytname[yyrhs[i]]);
+      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
+
+
+  switch (yyn) {
+
+case 3:
+#line 107 "scripts/genksyms/parse.y"
+{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;
+    break;}
+case 4:
+#line 109 "scripts/genksyms/parse.y"
+{ free_list(*yyvsp[0], NULL); *yyvsp[0] = NULL; ;
+    break;}
+case 5:
+#line 113 "scripts/genksyms/parse.y"
+{ is_typedef = 1; ;
+    break;}
+case 6:
+#line 114 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 11:
+#line 119 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 12:
+#line 120 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 13:
+#line 125 "scripts/genksyms/parse.y"
+{ if (current_name) {
+		    struct string_list *decl = (*yyvsp[0])->next;
+		    (*yyvsp[0])->next = NULL;
+		    add_symbol(current_name,
+			       is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
+			       decl, is_extern);
+		    current_name = NULL;
+		  }
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 14:
+#line 138 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 16:
+#line 144 "scripts/genksyms/parse.y"
+{ struct string_list *decl = *yyvsp[0];
+		  *yyvsp[0] = NULL;
+		  add_symbol(current_name,
+			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+		  current_name = NULL;
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 17:
+#line 152 "scripts/genksyms/parse.y"
+{ struct string_list *decl = *yyvsp[0];
+		  *yyvsp[0] = NULL;
+		  free_list(*yyvsp[-1], NULL);
+		  *yyvsp[-1] = decl_spec;
+		  add_symbol(current_name,
+			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+		  current_name = NULL;
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 18:
+#line 165 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1] ? yyvsp[-1] : yyvsp[-2] ? yyvsp[-2] : yyvsp[-3]; ;
+    break;}
+case 19:
+#line 170 "scripts/genksyms/parse.y"
+{ decl_spec = NULL; ;
+    break;}
+case 21:
+#line 175 "scripts/genksyms/parse.y"
+{ decl_spec = *yyvsp[0]; ;
+    break;}
+case 22:
+#line 176 "scripts/genksyms/parse.y"
+{ decl_spec = *yyvsp[0]; ;
+    break;}
+case 23:
+#line 181 "scripts/genksyms/parse.y"
+{ /* Version 2 checksumming ignores storage class, as that
+		     is really irrelevant to the linkage.  */
+		  remove_node(yyvsp[0]);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 28:
+#line 193 "scripts/genksyms/parse.y"
+{ is_extern = 1; yyval = yyvsp[0]; ;
+    break;}
+case 29:
+#line 194 "scripts/genksyms/parse.y"
+{ is_extern = 0; yyval = yyvsp[0]; ;
+    break;}
+case 33:
+#line 205 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_STRUCT; yyval = yyvsp[0]; ;
+    break;}
+case 34:
+#line 207 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_UNION; yyval = yyvsp[0]; ;
+    break;}
+case 35:
+#line 209 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_ENUM; yyval = yyvsp[0]; ;
+    break;}
+case 36:
+#line 213 "scripts/genksyms/parse.y"
+{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+		  r = copy_node(i); r->tag = SYM_STRUCT;
+		  r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+		  add_symbol(i->string, SYM_STRUCT, s, is_extern);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 37:
+#line 220 "scripts/genksyms/parse.y"
+{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+		  r = copy_node(i); r->tag = SYM_UNION;
+		  r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+		  add_symbol(i->string, SYM_UNION, s, is_extern);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 38:
+#line 227 "scripts/genksyms/parse.y"
+{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+		  r = copy_node(i); r->tag = SYM_ENUM;
+		  r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+		  add_symbol(i->string, SYM_ENUM, s, is_extern);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 39:
+#line 235 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 40:
+#line 236 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 41:
+#line 237 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 52:
+#line 251 "scripts/genksyms/parse.y"
+{ (*yyvsp[0])->tag = SYM_TYPEDEF; yyval = yyvsp[0]; ;
+    break;}
+case 53:
+#line 256 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+    break;}
+case 54:
+#line 260 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 57:
+#line 266 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 61:
+#line 272 "scripts/genksyms/parse.y"
+{ /* restrict has no effect in prototypes so ignore it */
+		  remove_node(yyvsp[0]);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 62:
+#line 279 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 64:
+#line 285 "scripts/genksyms/parse.y"
+{ if (current_name != NULL) {
+		    error_with_pos("unexpected second declaration name");
+		    YYERROR;
+		  } else {
+		    current_name = (*yyvsp[0])->string;
+		    yyval = yyvsp[0];
+		  }
+		;
+    break;}
+case 65:
+#line 294 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 66:
+#line 296 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 67:
+#line 298 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 68:
+#line 300 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 69:
+#line 302 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 70:
+#line 308 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 74:
+#line 316 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 75:
+#line 318 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 76:
+#line 320 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 77:
+#line 322 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 78:
+#line 324 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 79:
+#line 328 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 81:
+#line 330 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 82:
+#line 334 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 85:
+#line 341 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 86:
+#line 346 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+    break;}
+case 87:
+#line 351 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+    break;}
+case 89:
+#line 356 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 90:
+#line 358 "scripts/genksyms/parse.y"
+{ /* For version 2 checksums, we don't want to remember
+		     private parameter names.  */
+		  remove_node(yyvsp[0]);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 91:
+#line 366 "scripts/genksyms/parse.y"
+{ remove_node(yyvsp[0]);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 92:
+#line 370 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 93:
+#line 372 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 94:
+#line 374 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 95:
+#line 376 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 96:
+#line 378 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 97:
+#line 383 "scripts/genksyms/parse.y"
+{ struct string_list *decl = *yyvsp[-1];
+		  *yyvsp[-1] = NULL;
+		  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
+		  yyval = yyvsp[0];
+		;
+    break;}
+case 98:
+#line 391 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 100:
+#line 398 "scripts/genksyms/parse.y"
+{ remove_list(yyvsp[0], &(*yyvsp[-1])->next); yyval = yyvsp[0]; ;
+    break;}
+case 101:
+#line 402 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 102:
+#line 403 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 103:
+#line 407 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 106:
+#line 413 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 107:
+#line 418 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 108:
+#line 420 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 109:
+#line 424 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 112:
+#line 430 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 113:
+#line 434 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
+    break;}
+case 114:
+#line 435 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 116:
+#line 440 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 117:
+#line 444 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 119:
+#line 449 "scripts/genksyms/parse.y"
+{ yyval = yyvsp[0]; ;
+    break;}
+case 120:
+#line 453 "scripts/genksyms/parse.y"
+{ yyval = NULL; ;
+    break;}
+case 122:
+#line 459 "scripts/genksyms/parse.y"
+{ export_symbol((*yyvsp[-2])->string); yyval = yyvsp[0]; ;
+    break;}
+}
+   /* the action file gets copied in in place of this dollarsign */
+#line 543 "/usr/lib/bison.simple"
+
+  yyvsp -= yylen;
+  yyssp -= yylen;
+#ifdef YYLSP_NEEDED
+  yylsp -= yylen;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+
+#ifdef YYLSP_NEEDED
+  yylsp++;
+  if (yylen == 0)
+    {
+      yylsp->first_line = yylloc.first_line;
+      yylsp->first_column = yylloc.first_column;
+      yylsp->last_line = (yylsp-1)->last_line;
+      yylsp->last_column = (yylsp-1)->last_column;
+      yylsp->text = 0;
+    }
+  else
+    {
+      yylsp->last_line = (yylsp+yylen-1)->last_line;
+      yylsp->last_column = (yylsp+yylen-1)->last_column;
+    }
+#endif
+
+  /* Now "shift" the result of the reduction.
+     Determine what state that goes to,
+     based on the state we popped back to
+     and the rule number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTBASE];
+
+  goto yynewstate;
+
+yyerrlab:   /* here on detecting error */
+
+  if (! yyerrstatus)
+    /* If not already recovering from an error, report this error.  */
+    {
+      ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (yyn > YYFLAG && yyn < YYLAST)
+	{
+	  int size = 0;
+	  char *msg;
+	  int x, count;
+
+	  count = 0;
+	  /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
+	  for (x = (yyn < 0 ? -yyn : 0);
+	       x < (sizeof(yytname) / sizeof(char *)); x++)
+	    if (yycheck[x + yyn] == x)
+	      size += strlen(yytname[x]) + 15, count++;
+	  msg = (char *) malloc(size + 15);
+	  if (msg != 0)
+	    {
+	      strcpy(msg, "parse error");
+
+	      if (count < 5)
+		{
+		  count = 0;
+		  for (x = (yyn < 0 ? -yyn : 0);
+		       x < (sizeof(yytname) / sizeof(char *)); x++)
+		    if (yycheck[x + yyn] == x)
+		      {
+			strcat(msg, count == 0 ? ", expecting `" : " or `");
+			strcat(msg, yytname[x]);
+			strcat(msg, "'");
+			count++;
+		      }
+		}
+	      yyerror(msg);
+	      free(msg);
+	    }
+	  else
+	    yyerror ("parse error; also virtual memory exceeded");
+	}
+      else
+#endif /* YYERROR_VERBOSE */
+	yyerror("parse error");
+    }
+
+  goto yyerrlab1;
+yyerrlab1:   /* here on error raised explicitly by an action */
+
+  if (yyerrstatus == 3)
+    {
+      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
+
+      /* return failure if at end of input */
+      if (yychar == YYEOF)
+	YYABORT;
+
+#if YYDEBUG != 0
+      if (yydebug)
+	fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
+#endif
+
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token
+     after shifting the error token.  */
+
+  yyerrstatus = 3;		/* Each real token shifted decrements this */
+
+  goto yyerrhandle;
+
+yyerrdefault:  /* current state does not do anything special for the error token. */
+
+#if 0
+  /* This is wrong; only states that explicitly want error tokens
+     should shift them.  */
+  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
+  if (yyn) goto yydefault;
+#endif
+
+yyerrpop:   /* pop the current state because it cannot handle the error token */
+
+  if (yyssp == yyss) YYABORT;
+  yyvsp--;
+  yystate = *--yyssp;
+#ifdef YYLSP_NEEDED
+  yylsp--;
+#endif
+
+#if YYDEBUG != 0
+  if (yydebug)
+    {
+      short *ssp1 = yyss - 1;
+      fprintf (stderr, "Error: state stack now");
+      while (ssp1 != yyssp)
+	fprintf (stderr, " %d", *++ssp1);
+      fprintf (stderr, "\n");
+    }
+#endif
+
+yyerrhandle:
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yyerrdefault;
+
+  yyn += YYTERROR;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+    goto yyerrdefault;
+
+  yyn = yytable[yyn];
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+	goto yyerrpop;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrpop;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+#if YYDEBUG != 0
+  if (yydebug)
+    fprintf(stderr, "Shifting error token, ");
+#endif
+
+  *++yyvsp = yylval;
+#ifdef YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  yystate = yyn;
+  goto yynewstate;
+
+ yyacceptlab:
+  /* YYACCEPT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
+#endif
+    }
+  return 0;
+
+ yyabortlab:
+  /* YYABORT comes here.  */
+  if (yyfree_stacks)
+    {
+      free (yyss);
+      free (yyvs);
+#ifdef YYLSP_NEEDED
+      free (yyls);
+#endif
+    }
+  return 1;
+}
+#line 463 "scripts/genksyms/parse.y"
+
+
+static void
+yyerror(const char *e)
+{
+  error_with_pos("%s", e);
+}
diff -urN linux-2.5.63-bk5/scripts/genksyms/parse.h_shipped linux-2.5.63-bk6/scripts/genksyms/parse.h_shipped
--- linux-2.5.63-bk5/scripts/genksyms/parse.h_shipped	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/parse.h_shipped	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,46 @@
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+#define	ASM_KEYW	257
+#define	ATTRIBUTE_KEYW	258
+#define	AUTO_KEYW	259
+#define	BOOL_KEYW	260
+#define	CHAR_KEYW	261
+#define	CONST_KEYW	262
+#define	DOUBLE_KEYW	263
+#define	ENUM_KEYW	264
+#define	EXTERN_KEYW	265
+#define	FLOAT_KEYW	266
+#define	INLINE_KEYW	267
+#define	INT_KEYW	268
+#define	LONG_KEYW	269
+#define	REGISTER_KEYW	270
+#define	RESTRICT_KEYW	271
+#define	SHORT_KEYW	272
+#define	SIGNED_KEYW	273
+#define	STATIC_KEYW	274
+#define	STRUCT_KEYW	275
+#define	TYPEDEF_KEYW	276
+#define	UNION_KEYW	277
+#define	UNSIGNED_KEYW	278
+#define	VOID_KEYW	279
+#define	VOLATILE_KEYW	280
+#define	TYPEOF_KEYW	281
+#define	EXPORT_SYMBOL_KEYW	282
+#define	ASM_PHRASE	283
+#define	ATTRIBUTE_PHRASE	284
+#define	BRACE_PHRASE	285
+#define	BRACKET_PHRASE	286
+#define	EXPRESSION_PHRASE	287
+#define	CHAR	288
+#define	DOTS	289
+#define	IDENT	290
+#define	INT	291
+#define	REAL	292
+#define	STRING	293
+#define	TYPE	294
+#define	OTHER	295
+#define	FILENAME	296
+
+
+extern YYSTYPE yylval;
diff -urN linux-2.5.63-bk5/scripts/genksyms/parse.y linux-2.5.63-bk6/scripts/genksyms/parse.y
--- linux-2.5.63-bk5/scripts/genksyms/parse.y	Wed Dec 31 16:00:00 1969
+++ linux-2.5.63-bk6/scripts/genksyms/parse.y	Mon Mar 31 12:19:34 2003
@@ -0,0 +1,469 @@
+/* C global declaration parser for genksyms.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth@tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn@blox.se>
+
+   This file is part of the Linux modutils.
+
+   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 <assert.h>
+#include <malloc.h>
+#include "genksyms.h"
+
+static int is_typedef;
+static int is_extern;
+static char *current_name;
+static struct string_list *decl_spec;
+
+static void yyerror(const char *);
+
+static inline void
+remove_node(struct string_list **p)
+{
+  struct string_list *node = *p;
+  *p = node->next;
+  free_node(node);
+}
+
+static inline void
+remove_list(struct string_list **pb, struct string_list **pe)
+{
+  struct string_list *b = *pb, *e = *pe;
+  *pb = e;
+  free_list(b, e);
+}
+
+%}
+
+%token ASM_KEYW
+%token ATTRIBUTE_KEYW
+%token AUTO_KEYW
+%token BOOL_KEYW
+%token CHAR_KEYW
+%token CONST_KEYW
+%token DOUBLE_KEYW
+%token ENUM_KEYW
+%token EXTERN_KEYW
+%token FLOAT_KEYW
+%token INLINE_KEYW
+%token INT_KEYW
+%token LONG_KEYW
+%token REGISTER_KEYW
+%token RESTRICT_KEYW
+%token SHORT_KEYW
+%token SIGNED_KEYW
+%token STATIC_KEYW
+%token STRUCT_KEYW
+%token TYPEDEF_KEYW
+%token UNION_KEYW
+%token UNSIGNED_KEYW
+%token VOID_KEYW
+%token VOLATILE_KEYW
+%token TYPEOF_KEYW
+
+%token EXPORT_SYMBOL_KEYW
+
+%token ASM_PHRASE
+%token ATTRIBUTE_PHRASE
+%token BRACE_PHRASE
+%token BRACKET_PHRASE
+%token EXPRESSION_PHRASE
+
+%token CHAR
+%token DOTS
+%token IDENT
+%token INT
+%token REAL
+%token STRING
+%token TYPE
+%token OTHER
+%token FILENAME
+
+%%
+
+declaration_seq:
+	declaration
+	| declaration_seq declaration
+	;
+
+declaration:
+	{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
+	declaration1
+	{ free_list(*$2, NULL); *$2 = NULL; }
+	;
+
+declaration1:
+	TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
+		{ $$ = $3; }
+	| simple_declaration
+	| function_definition
+	| asm_definition
+	| export_definition
+	| error ';'				{ $$ = $2; }
+	| error '}'				{ $$ = $2; }
+	;
+
+simple_declaration:
+	decl_specifier_seq_opt init_declarator_list_opt ';'
+		{ if (current_name) {
+		    struct string_list *decl = (*$3)->next;
+		    (*$3)->next = NULL;
+		    add_symbol(current_name,
+			       is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
+			       decl, is_extern);
+		    current_name = NULL;
+		  }
+		  $$ = $3;
+		}
+	;
+
+init_declarator_list_opt:
+	/* empty */				{ $$ = NULL; }
+	| init_declarator_list
+	;
+
+init_declarator_list:
+	init_declarator
+		{ struct string_list *decl = *$1;
+		  *$1 = NULL;
+		  add_symbol(current_name,
+			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+		  current_name = NULL;
+		  $$ = $1;
+		}
+	| init_declarator_list ',' init_declarator
+		{ struct string_list *decl = *$3;
+		  *$3 = NULL;
+		  free_list(*$2, NULL);
+		  *$2 = decl_spec;
+		  add_symbol(current_name,
+			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
+		  current_name = NULL;
+		  $$ = $3;
+		}
+	;
+
+init_declarator:
+	declarator asm_phrase_opt attribute_opt initializer_opt
+		{ $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
+	;
+
+/* Hang on to the specifiers so that we can reuse them.  */
+decl_specifier_seq_opt:
+	/* empty */				{ decl_spec = NULL; }
+	| decl_specifier_seq
+	;
+
+decl_specifier_seq:
+	decl_specifier				{ decl_spec = *$1; }
+	| decl_specifier_seq decl_specifier	{ decl_spec = *$2; }
+	;
+
+decl_specifier:
+	storage_class_specifier
+		{ /* Version 2 checksumming ignores storage class, as that
+		     is really irrelevant to the linkage.  */
+		  remove_node($1);
+		  $$ = $1;
+		}
+	| type_specifier
+	;
+
+storage_class_specifier:
+	AUTO_KEYW
+	| REGISTER_KEYW
+	| STATIC_KEYW
+	| EXTERN_KEYW	{ is_extern = 1; $$ = $1; }
+	| INLINE_KEYW	{ is_extern = 0; $$ = $1; }
+	;
+
+type_specifier:
+	simple_type_specifier
+	| cvar_qualifier
+	| TYPEOF_KEYW '(' type_specifier ')'
+
+	/* References to s/u/e's defined elsewhere.  Rearrange things
+	   so that it is easier to expand the definition fully later.  */
+	| STRUCT_KEYW IDENT
+		{ remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
+	| UNION_KEYW IDENT
+		{ remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
+	| ENUM_KEYW IDENT
+		{ remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
+
+	/* Full definitions of an s/u/e.  Record it.  */
+	| STRUCT_KEYW IDENT class_body
+		{ struct string_list *s = *$3, *i = *$2, *r;
+		  r = copy_node(i); r->tag = SYM_STRUCT;
+		  r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
+		  add_symbol(i->string, SYM_STRUCT, s, is_extern);
+		  $$ = $3;
+		}
+	| UNION_KEYW IDENT class_body
+		{ struct string_list *s = *$3, *i = *$2, *r;
+		  r = copy_node(i); r->tag = SYM_UNION;
+		  r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
+		  add_symbol(i->string, SYM_UNION, s, is_extern);
+		  $$ = $3;
+		}
+	| ENUM_KEYW IDENT BRACE_PHRASE
+		{ struct string_list *s = *$3, *i = *$2, *r;
+		  r = copy_node(i); r->tag = SYM_ENUM;
+		  r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
+		  add_symbol(i->string, SYM_ENUM, s, is_extern);
+		  $$ = $3;
+		}
+
+	/* Anonymous s/u/e definitions.  Nothing needs doing.  */
+	| ENUM_KEYW BRACE_PHRASE			{ $$ = $2; }
+	| STRUCT_KEYW class_body			{ $$ = $2; }
+	| UNION_KEYW class_body				{ $$ = $2; }
+	;
+
+simple_type_specifier:
+	CHAR_KEYW
+	| SHORT_KEYW
+	| INT_KEYW
+	| LONG_KEYW
+	| SIGNED_KEYW
+	| UNSIGNED_KEYW
+	| FLOAT_KEYW
+	| DOUBLE_KEYW
+	| VOID_KEYW
+	| BOOL_KEYW
+	| TYPE			{ (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
+	;
+
+ptr_operator:
+	'*' cvar_qualifier_seq_opt
+		{ $$ = $2 ? $2 : $1; }
+	;
+
+cvar_qualifier_seq_opt:
+	/* empty */					{ $$ = NULL; }
+	| cvar_qualifier_seq
+	;
+
+cvar_qualifier_seq:
+	cvar_qualifier
+	| cvar_qualifier_seq cvar_qualifier		{ $$ = $2; }
+	;
+
+cvar_qualifier:
+	CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
+	| RESTRICT_KEYW
+		{ /* restrict has no effect in prototypes so ignore it */
+		  remove_node($1);
+		  $$ = $1;
+		}
+	;
+
+declarator:
+	ptr_operator declarator			{ $$ = $2; }
+	| direct_declarator
+	;
+
+direct_declarator:
+	IDENT
+		{ if (current_name != NULL) {
+		    error_with_pos("unexpected second declaration name");
+		    YYERROR;
+		  } else {
+		    current_name = (*$1)->string;
+		    $$ = $1;
+		  }
+		}
+	| direct_declarator '(' parameter_declaration_clause ')'
+		{ $$ = $4; }
+	| direct_declarator '(' error ')'
+		{ $$ = $4; }
+	| direct_declarator BRACKET_PHRASE
+		{ $$ = $2; }
+	| '(' declarator ')'
+		{ $$ = $3; }
+	| '(' error ')'
+		{ $$ = $3; }
+	;
+
+/* Nested declarators differ from regular declarators in that they do
+   not record the symbols they find in the global symbol table.  */
+nested_declarator:
+	ptr_operator nested_declarator		{ $$ = $2; }
+	| direct_nested_declarator
+	;
+
+direct_nested_declarator:
+	IDENT
+	| TYPE
+	| direct_nested_declarator '(' parameter_declaration_clause ')'
+		{ $$ = $4; }
+	| direct_nested_declarator '(' error ')'
+		{ $$ = $4; }
+	| direct_nested_declarator BRACKET_PHRASE
+		{ $$ = $2; }
+	| '(' nested_declarator ')'
+		{ $$ = $3; }
+	| '(' error ')'
+		{ $$ = $3; }
+	;
+
+parameter_declaration_clause:
+	parameter_declaration_list_opt DOTS		{ $$ = $2; }
+	| parameter_declaration_list_opt
+	| parameter_declaration_list ',' DOTS		{ $$ = $3; }
+	;
+
+parameter_declaration_list_opt:
+	/* empty */					{ $$ = NULL; }
+	| parameter_declaration_list
+	;
+
+parameter_declaration_list:
+	parameter_declaration
+	| parameter_declaration_list ',' parameter_declaration
+		{ $$ = $3; }
+	;
+
+parameter_declaration:
+	decl_specifier_seq m_abstract_declarator
+		{ $$ = $2 ? $2 : $1; }
+	;
+
+m_abstract_declarator:
+	ptr_operator m_abstract_declarator
+		{ $$ = $2 ? $2 : $1; }
+	| direct_m_abstract_declarator
+	;
+
+direct_m_abstract_declarator:
+	/* empty */					{ $$ = NULL; }
+	| IDENT
+		{ /* For version 2 checksums, we don't want to remember
+		     private parameter names.  */
+		  remove_node($1);
+		  $$ = $1;
+		}
+	/* This wasn't really a typedef name but an identifier that
+	   shadows one.  */
+	| TYPE
+		{ remove_node($1);
+		  $$ = $1;
+		}
+	| direct_m_abstract_declarator '(' parameter_declaration_clause ')'
+		{ $$ = $4; }
+	| direct_m_abstract_declarator '(' error ')'
+		{ $$ = $4; }
+	| direct_m_abstract_declarator BRACKET_PHRASE
+		{ $$ = $2; }
+	| '(' m_abstract_declarator ')'
+		{ $$ = $3; }
+	| '(' error ')'
+		{ $$ = $3; }
+	;
+
+function_definition:
+	decl_specifier_seq_opt declarator BRACE_PHRASE
+		{ struct string_list *decl = *$2;
+		  *$2 = NULL;
+		  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
+		  $$ = $3;
+		}
+	;
+
+initializer_opt:
+	/* empty */					{ $$ = NULL; }
+	| initializer
+	;
+
+/* We never care about the contents of an initializer.  */
+initializer:
+	'=' EXPRESSION_PHRASE
+		{ remove_list($2, &(*$1)->next); $$ = $2; }
+	;
+
+class_body:
+	'{' member_specification_opt '}'		{ $$ = $3; }
+	| '{' error '}'					{ $$ = $3; }
+	;
+
+member_specification_opt:
+	/* empty */					{ $$ = NULL; }
+	| member_specification
+	;
+
+member_specification:
+	member_declaration
+	| member_specification member_declaration	{ $$ = $2; }
+	;
+
+member_declaration:
+	decl_specifier_seq_opt member_declarator_list_opt ';'
+		{ $$ = $3; }
+	| error ';'
+		{ $$ = $2; }
+	;
+
+member_declarator_list_opt:
+	/* empty */					{ $$ = NULL; }
+	| member_declarator_list
+	;
+
+member_declarator_list:
+	member_declarator
+	| member_declarator_list ',' member_declarator	{ $$ = $3; }
+	;
+
+member_declarator:
+	nested_declarator attribute_opt			{ $$ = $2 ? $2 : $1; }
+	| IDENT member_bitfield_declarator		{ $$ = $2; }
+	| member_bitfield_declarator
+	;
+
+member_bitfield_declarator:
+	':' EXPRESSION_PHRASE				{ $$ = $2; }
+	;
+
+attribute_opt:
+	/* empty */					{ $$ = NULL; }
+	| ATTRIBUTE_PHRASE
+	;
+
+asm_definition:
+	ASM_PHRASE ';'					{ $$ = $2; }
+	;
+
+asm_phrase_opt:
+	/* empty */					{ $$ = NULL; }
+	| ASM_PHRASE
+	;
+
+export_definition:
+	EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
+		{ export_symbol((*$3)->string); $$ = $5; }
+	;
+
+
+%%
+
+static void
+yyerror(const char *e)
+{
+  error_with_pos("%s", e);
+}
diff -urN linux-2.5.63-bk5/scripts/mk_elfconfig.c linux-2.5.63-bk6/scripts/mk_elfconfig.c
--- linux-2.5.63-bk5/scripts/mk_elfconfig.c	Mon Feb 24 11:05:47 2003
+++ linux-2.5.63-bk6/scripts/mk_elfconfig.c	Mon Mar 31 12:19:34 2003
@@ -9,6 +9,9 @@
 	unsigned char ei[EI_NIDENT];	
 	union { short s; char c[2]; } endian_test;
 
+	if (argc != 2) {
+		fprintf(stderr, "Error: no arch\n");
+	}
 	if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
 		fprintf(stderr, "Error: input truncated\n");
 		return 1;
@@ -52,6 +55,11 @@
 	else
 		abort();
 
+	if (strcmp(argv[1], "v850") == 0)
+		printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
+	else 
+		printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
+
 	return 0;
 }
 
diff -urN linux-2.5.63-bk5/scripts/modpost.c linux-2.5.63-bk6/scripts/modpost.c
--- linux-2.5.63-bk5/scripts/modpost.c	Mon Feb 24 11:05:11 2003
+++ linux-2.5.63-bk6/scripts/modpost.c	Mon Mar 31 12:19:34 2003
@@ -265,6 +265,9 @@
 	munmap(info->hdr, info->size);
 }
 
+#define CRC_PFX     MODULE_SYMBOL_PREFIX "__crc_"
+#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
+
 void
 handle_modversions(struct module *mod, struct elf_info *info,
 		   Elf_Sym *sym, const char *symname)
@@ -279,9 +282,10 @@
 		break;
 	case SHN_ABS:
 		/* CRC'd symbol */
-		if (memcmp(symname, "__crc_", 6) == 0) {
+		if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
 			crc = (unsigned int) sym->st_value;
-			add_exported_symbol(symname+6, mod, &crc);
+			add_exported_symbol(symname + strlen(CRC_PFX),
+					    mod, &crc);
 			modversions = 1;
 		}
 		break;
@@ -290,15 +294,20 @@
 		if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
 			break;
 		
-		s = alloc_symbol(symname);
-		/* add to list */
-		s->next = mod->unres;
-		mod->unres = s;
+		if (memcmp(symname, MODULE_SYMBOL_PREFIX,
+			   strlen(MODULE_SYMBOL_PREFIX)) == 0) {
+			s = alloc_symbol(symname + 
+					 strlen(MODULE_SYMBOL_PREFIX));
+			/* add to list */
+			s->next = mod->unres;
+			mod->unres = s;
+		}
 		break;
 	default:
 		/* All exported symbols */
-		if (memcmp(symname, "__ksymtab_", 10) == 0) {
-			add_exported_symbol(symname+10, mod, NULL);
+		if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
+			add_exported_symbol(symname + strlen(KSYMTAB_PFX),
+					    mod, NULL);
 		}
 		break;
 	}
